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 * <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