1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 package com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations; 24 25 import java.security.PublicKey; 26 import java.security.cert.Certificate; 27 import java.security.cert.X509Certificate; 28 import java.util.Arrays; 29 import java.util.Iterator; 30 31 import javax.crypto.SecretKey; 32 33 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; 34 import com.sun.org.apache.xml.internal.security.keys.content.X509Data; 35 import com.sun.org.apache.xml.internal.security.keys.content.x509.XMLX509Digest; 36 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException; 37 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi; 38 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver; 39 import com.sun.org.apache.xml.internal.security.utils.Constants; 40 import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 41 import org.w3c.dom.Element; 42 43 /** 44 * KeyResolverSpi implementation which resolves public keys and X.509 certificates from a 45 * {@code dsig11:X509Digest} element. 46 * 47 */ 48 public class X509DigestResolver extends KeyResolverSpi { 49 50 private static final com.sun.org.slf4j.internal.Logger LOG = 51 com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509DigestResolver.class); 52 53 /** {{@inheritDoc}}. */ engineCanResolve(Element element, String baseURI, StorageResolver storage)54 public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) { 55 if (XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_X509DATA)) { 56 try { 57 X509Data x509Data = new X509Data(element, baseURI); 58 return x509Data.containsDigest(); 59 } catch (XMLSecurityException e) { 60 return false; 61 } 62 } else { 63 return false; 64 } 65 } 66 67 /** {{@inheritDoc}}. */ engineLookupAndResolvePublicKey(Element element, String baseURI, StorageResolver storage)68 public PublicKey engineLookupAndResolvePublicKey(Element element, String baseURI, StorageResolver storage) 69 throws KeyResolverException { 70 71 X509Certificate cert = this.engineLookupResolveX509Certificate(element, baseURI, storage); 72 73 if (cert != null) { 74 return cert.getPublicKey(); 75 } 76 77 return null; 78 } 79 80 /** {{@inheritDoc}}. */ engineLookupResolveX509Certificate(Element element, String baseURI, StorageResolver storage)81 public X509Certificate engineLookupResolveX509Certificate(Element element, String baseURI, StorageResolver storage) 82 throws KeyResolverException { 83 84 LOG.debug("Can I resolve {}", element.getTagName()); 85 86 if (!engineCanResolve(element, baseURI, storage)) { 87 return null; 88 } 89 90 try { 91 return resolveCertificate(element, baseURI, storage); 92 } catch (XMLSecurityException e) { 93 LOG.debug("XMLSecurityException", e); 94 } 95 96 return null; 97 } 98 99 /** {{@inheritDoc}}. */ engineLookupAndResolveSecretKey(Element element, String baseURI, StorageResolver storage)100 public SecretKey engineLookupAndResolveSecretKey(Element element, String baseURI, StorageResolver storage) 101 throws KeyResolverException { 102 return null; 103 } 104 105 /** 106 * Resolves from the storage resolver the actual certificate represented by the digest. 107 * 108 * @param element 109 * @param baseURI 110 * @param storage 111 * @return the certificate represented by the digest. 112 * @throws XMLSecurityException 113 */ resolveCertificate(Element element, String baseURI, StorageResolver storage)114 private X509Certificate resolveCertificate(Element element, String baseURI, StorageResolver storage) 115 throws XMLSecurityException { 116 117 XMLX509Digest x509Digests[] = null; 118 119 Element x509childNodes[] = XMLUtils.selectDs11Nodes(element.getFirstChild(), Constants._TAG_X509DIGEST); 120 121 if (x509childNodes == null || x509childNodes.length <= 0) { 122 return null; 123 } 124 125 try { 126 checkStorage(storage); 127 128 x509Digests = new XMLX509Digest[x509childNodes.length]; 129 130 for (int i = 0; i < x509childNodes.length; i++) { 131 x509Digests[i] = new XMLX509Digest(x509childNodes[i], baseURI); 132 } 133 134 Iterator<Certificate> storageIterator = storage.getIterator(); 135 while (storageIterator.hasNext()) { 136 X509Certificate cert = (X509Certificate) storageIterator.next(); 137 138 for (int i = 0; i < x509Digests.length; i++) { 139 XMLX509Digest keyInfoDigest = x509Digests[i]; 140 byte[] certDigestBytes = XMLX509Digest.getDigestBytesFromCert(cert, keyInfoDigest.getAlgorithm()); 141 142 if (Arrays.equals(keyInfoDigest.getDigestBytes(), certDigestBytes)) { 143 LOG.debug("Found certificate with: {}", cert.getSubjectX500Principal().getName()); 144 return cert; 145 } 146 147 } 148 } 149 150 } catch (XMLSecurityException ex) { 151 throw new KeyResolverException(ex); 152 } 153 154 return null; 155 } 156 157 /** 158 * Method checkSrorage 159 * 160 * @param storage 161 * @throws KeyResolverException 162 */ checkStorage(StorageResolver storage)163 private void checkStorage(StorageResolver storage) throws KeyResolverException { 164 if (storage == null) { 165 Object exArgs[] = { Constants._TAG_X509DIGEST }; 166 KeyResolverException ex = new KeyResolverException("KeyResolver.needStorageResolver", exArgs); 167 LOG.debug("", ex); 168 throw ex; 169 } 170 } 171 172 } 173