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;
24 
25 import java.io.ByteArrayInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.security.PrivateKey;
29 import java.security.PublicKey;
30 import java.security.cert.X509Certificate;
31 import java.util.HashMap;
32 
33 import javax.crypto.SecretKey;
34 import javax.xml.parsers.ParserConfigurationException;
35 
36 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
37 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Element;
40 import org.xml.sax.SAXException;
41 
42 /**
43  * This class is an abstract class for a child KeyInfo Element.
44  *
45  * If you want the your KeyResolver, at firstly you must extend this class, and register
46  * as following in config.xml
47  * <PRE>
48  *  &lt;KeyResolver URI="http://www.w3.org/2000/09/xmldsig#KeyValue"
49  *   JAVACLASS="MyPackage.MyKeyValueImpl"//gt;
50  * </PRE>
51  */
52 public abstract class KeyResolverSpi {
53 
54     /** Field properties */
55     protected java.util.Map<String, String> properties;
56 
57     protected boolean globalResolver = false;
58 
59     protected boolean secureValidation;
60 
61     /**
62      * Set whether secure validation is enabled or not. The default is false.
63      */
setSecureValidation(boolean secureValidation)64     public void setSecureValidation(boolean secureValidation) {
65         this.secureValidation = secureValidation;
66     }
67 
68     /**
69      * This method returns whether the KeyResolverSpi is able to perform the requested action.
70      *
71      * @param element
72      * @param baseURI
73      * @param storage
74      * @return whether the KeyResolverSpi is able to perform the requested action.
75      */
engineCanResolve(Element element, String baseURI, StorageResolver storage)76     public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) {
77         throw new UnsupportedOperationException();
78     }
79 
80     /**
81      * Method engineResolvePublicKey
82      *
83      * @param element
84      * @param baseURI
85      * @param storage
86      * @return resolved public key from the registered from the element.
87      *
88      * @throws KeyResolverException
89      */
engineResolvePublicKey( Element element, String baseURI, StorageResolver storage )90     public PublicKey engineResolvePublicKey(
91         Element element, String baseURI, StorageResolver storage
92     ) throws KeyResolverException {
93         throw new UnsupportedOperationException();
94     }
95 
96     /**
97      * Method engineLookupAndResolvePublicKey
98      *
99      * @param element
100      * @param baseURI
101      * @param storage
102      * @return resolved public key from the registered from the element.
103      *
104      * @throws KeyResolverException
105      */
engineLookupAndResolvePublicKey( Element element, String baseURI, StorageResolver storage )106     public PublicKey engineLookupAndResolvePublicKey(
107         Element element, String baseURI, StorageResolver storage
108     ) throws KeyResolverException {
109         KeyResolverSpi tmp = cloneIfNeeded();
110         if (!tmp.engineCanResolve(element, baseURI, storage)) {
111             return null;
112         }
113         return tmp.engineResolvePublicKey(element, baseURI, storage);
114     }
115 
cloneIfNeeded()116     private KeyResolverSpi cloneIfNeeded() throws KeyResolverException {
117         if (globalResolver) {
118             try {
119                 @SuppressWarnings("deprecation")
120                 KeyResolverSpi tmp = getClass().newInstance();
121                 return tmp;
122             } catch (InstantiationException e) {
123                 throw new KeyResolverException(e, "");
124             } catch (IllegalAccessException e) {
125                 throw new KeyResolverException(e, "");
126             }
127         }
128         return this;
129     }
130 
131     /**
132      * Method engineResolveCertificate
133      *
134      * @param element
135      * @param baseURI
136      * @param storage
137      * @return resolved X509Certificate key from the registered from the elements
138      *
139      * @throws KeyResolverException
140      */
engineResolveX509Certificate( Element element, String baseURI, StorageResolver storage )141     public X509Certificate engineResolveX509Certificate(
142         Element element, String baseURI, StorageResolver storage
143     ) throws KeyResolverException{
144         throw new UnsupportedOperationException();
145     }
146 
147     /**
148      * Method engineLookupResolveX509Certificate
149      *
150      * @param element
151      * @param baseURI
152      * @param storage
153      * @return resolved X509Certificate key from the registered from the elements
154      *
155      * @throws KeyResolverException
156      */
engineLookupResolveX509Certificate( Element element, String baseURI, StorageResolver storage )157     public X509Certificate engineLookupResolveX509Certificate(
158         Element element, String baseURI, StorageResolver storage
159     ) throws KeyResolverException {
160         KeyResolverSpi tmp = cloneIfNeeded();
161         if (!tmp.engineCanResolve(element, baseURI, storage)) {
162             return null;
163         }
164         return tmp.engineResolveX509Certificate(element, baseURI, storage);
165 
166     }
167     /**
168      * Method engineResolveSecretKey
169      *
170      * @param element
171      * @param baseURI
172      * @param storage
173      * @return resolved SecretKey key from the registered from the elements
174      *
175      * @throws KeyResolverException
176      */
engineResolveSecretKey( Element element, String baseURI, StorageResolver storage )177     public SecretKey engineResolveSecretKey(
178         Element element, String baseURI, StorageResolver storage
179     ) throws KeyResolverException{
180         throw new UnsupportedOperationException();
181     }
182 
183     /**
184      * Method engineLookupAndResolveSecretKey
185      *
186      * @param element
187      * @param baseURI
188      * @param storage
189      * @return resolved SecretKey key from the registered from the elements
190      *
191      * @throws KeyResolverException
192      */
engineLookupAndResolveSecretKey( Element element, String baseURI, StorageResolver storage )193     public SecretKey engineLookupAndResolveSecretKey(
194         Element element, String baseURI, StorageResolver storage
195     ) throws KeyResolverException {
196         KeyResolverSpi tmp = cloneIfNeeded();
197         if (!tmp.engineCanResolve(element, baseURI, storage)) {
198             return null;
199         }
200         return tmp.engineResolveSecretKey(element, baseURI, storage);
201     }
202 
203     /**
204      * Method engineLookupAndResolvePrivateKey
205      *
206      * @param element
207      * @param baseURI
208      * @param storage
209      * @return resolved PrivateKey key from the registered from the elements
210      *
211      * @throws KeyResolverException
212      */
engineLookupAndResolvePrivateKey( Element element, String baseURI, StorageResolver storage )213     public PrivateKey engineLookupAndResolvePrivateKey(
214         Element element, String baseURI, StorageResolver storage
215     ) throws KeyResolverException {
216         // This method was added later, it has no equivalent
217         // engineResolvePrivateKey() in the old API.
218         // We cannot throw UnsupportedOperationException because
219         // KeyResolverSpi implementations who don't know about
220         // this method would stop the search too early.
221         return null;
222     }
223 
224     /**
225      * Method engineSetProperty
226      *
227      * @param key
228      * @param value
229      */
engineSetProperty(String key, String value)230     public void engineSetProperty(String key, String value) {
231         if (properties == null) {
232             properties = new HashMap<>();
233         }
234         properties.put(key, value);
235     }
236 
237     /**
238      * Method engineGetProperty
239      *
240      * @param key
241      * @return obtain the property appointed by key
242      */
engineGetProperty(String key)243     public String engineGetProperty(String key) {
244         if (properties == null) {
245             return null;
246         }
247 
248         return properties.get(key);
249     }
250 
251     /**
252      * Method understandsProperty
253      *
254      * @param propertyToTest
255      * @return true if understood the property
256      */
understandsProperty(String propertyToTest)257     public boolean understandsProperty(String propertyToTest) {
258         if (properties == null) {
259             return false;
260         }
261 
262         return properties.get(propertyToTest) != null;
263     }
264 
setGlobalResolver(boolean globalResolver)265     public void setGlobalResolver(boolean globalResolver) {
266         this.globalResolver = globalResolver;
267     }
268 
269 
270     /**
271      * Parses a byte array and returns the parsed Element.
272      *
273      * @param bytes
274      * @return the Document Element after parsing bytes
275      * @throws KeyResolverException if something goes wrong
276      */
getDocFromBytes(byte[] bytes, boolean secureValidation)277     protected static Element getDocFromBytes(byte[] bytes, boolean secureValidation) throws KeyResolverException {
278         try (InputStream is = new ByteArrayInputStream(bytes)) {
279             Document doc = XMLUtils.read(is, secureValidation);
280             return doc.getDocumentElement();
281         } catch (SAXException ex) {
282             throw new KeyResolverException(ex);
283         } catch (IOException ex) {
284             throw new KeyResolverException(ex);
285         } catch (ParserConfigurationException ex) {
286             throw new KeyResolverException(ex);
287         }
288     }
289 
290 }
291