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.Key; 26 import java.security.PublicKey; 27 import java.security.cert.X509Certificate; 28 import java.util.ArrayList; 29 import java.util.List; 30 31 import javax.crypto.SecretKey; 32 33 import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey; 34 import com.sun.org.apache.xml.internal.security.encryption.XMLCipher; 35 import com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException; 36 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi; 37 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver; 38 import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants; 39 import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 40 import org.w3c.dom.Element; 41 42 /** 43 * The <code>EncryptedKeyResolver</code> is not a generic resolver. It can 44 * only be for specific instantiations, as the key being unwrapped will 45 * always be of a particular type and will always have been wrapped by 46 * another key which needs to be recursively resolved. 47 * 48 * The <code>EncryptedKeyResolver</code> can therefore only be instantiated 49 * with an algorithm. It can also be instantiated with a key (the KEK) or 50 * will search the static KeyResolvers to find the appropriate key. 51 * 52 * @author Berin Lautenbach 53 */ 54 public class EncryptedKeyResolver extends KeyResolverSpi { 55 56 /** {@link org.apache.commons.logging} logging facility */ 57 private static java.util.logging.Logger log = 58 java.util.logging.Logger.getLogger(EncryptedKeyResolver.class.getName()); 59 60 private Key kek; 61 private String algorithm; 62 private List<KeyResolverSpi> internalKeyResolvers; 63 64 /** 65 * Constructor for use when a KEK needs to be derived from a KeyInfo 66 * list 67 * @param algorithm 68 */ 69 public EncryptedKeyResolver(String algorithm) { 70 kek = null; 71 this.algorithm = algorithm; 72 } 73 74 /** 75 * Constructor used for when a KEK has been set 76 * @param algorithm 77 * @param kek 78 */ 79 public EncryptedKeyResolver(String algorithm, Key kek) { 80 this.algorithm = algorithm; 81 this.kek = kek; 82 } 83 84 /** 85 * This method is used to add a custom {@link KeyResolverSpi} to help 86 * resolve the KEK. 87 * 88 * @param realKeyResolver 89 */ 90 public void registerInternalKeyResolver(KeyResolverSpi realKeyResolver) { 91 if (internalKeyResolvers == null) { 92 internalKeyResolvers = new ArrayList<KeyResolverSpi>(); 93 } 94 internalKeyResolvers.add(realKeyResolver); 95 } 96 97 /** @inheritDoc */ 98 public PublicKey engineLookupAndResolvePublicKey( 99 Element element, String BaseURI, StorageResolver storage 100 ) { 101 return null; 102 } 103 104 /** @inheritDoc */ 105 public X509Certificate engineLookupResolveX509Certificate( 106 Element element, String BaseURI, StorageResolver storage 107 ) { 108 return null; 109 } 110 111 /** @inheritDoc */ 112 public javax.crypto.SecretKey engineLookupAndResolveSecretKey( 113 Element element, String BaseURI, StorageResolver storage 114 ) { 115 if (log.isLoggable(java.util.logging.Level.FINE)) { 116 log.log(java.util.logging.Level.FINE, "EncryptedKeyResolver - Can I resolve " + element.getTagName()); 117 } 118 119 if (element == null) { 120 return null; 121 } 122 123 SecretKey key = null; 124 boolean isEncryptedKey = 125 XMLUtils.elementIsInEncryptionSpace(element, EncryptionConstants._TAG_ENCRYPTEDKEY); 126 if (isEncryptedKey) { 127 if (log.isLoggable(java.util.logging.Level.FINE)) { 128 log.log(java.util.logging.Level.FINE, "Passed an Encrypted Key"); 129 } 130 try { 131 XMLCipher cipher = XMLCipher.getInstance(); 132 cipher.init(XMLCipher.UNWRAP_MODE, kek); 133 if (internalKeyResolvers != null) { 134 int size = internalKeyResolvers.size(); 135 for (int i = 0; i < size; i++) { 136 cipher.registerInternalKeyResolver(internalKeyResolvers.get(i)); 137 } 138 } 139 EncryptedKey ek = cipher.loadEncryptedKey(element); 140 key = (SecretKey) cipher.decryptKey(ek, algorithm); 141 } catch (XMLEncryptionException e) { 142 if (log.isLoggable(java.util.logging.Level.FINE)) { 143 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 144 } 145 } 146 } 147 148 return key; 149 } 150 }