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