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