You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2010/09/30 20:40:46 UTC
svn commit: r1003198 - in /santuario/trunk: ./
src/org/apache/xml/security/encryption/ src/org/apache/xml/security/keys/
src/org/apache/xml/security/keys/keyresolver/
src/org/apache/xml/security/keys/keyresolver/implementations/
src_unitTests/org/apach...
Author: coheigea
Date: Thu Sep 30 18:40:45 2010
New Revision: 1003198
URL: http://svn.apache.org/viewvc?rev=1003198&view=rev
Log:
[Bug 49493] - Cannot resolve PrivateKeys used in Key Transport algorithms
- Thanks to Clement for the patch, and Sean for reviewing it.
Added:
santuario/trunk/src_unitTests/org/apache/xml/security/test/keys/keyresolver/
santuario/trunk/src_unitTests/org/apache/xml/security/test/keys/keyresolver/KeyResolverTest.java
Modified:
santuario/trunk/CHANGELOG.txt
santuario/trunk/src/org/apache/xml/security/encryption/XMLCipher.java
santuario/trunk/src/org/apache/xml/security/keys/KeyInfo.java
santuario/trunk/src/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java
santuario/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
santuario/trunk/src_unitTests/org/apache/xml/security/test/ModuleTest.java
Modified: santuario/trunk/CHANGELOG.txt
URL: http://svn.apache.org/viewvc/santuario/trunk/CHANGELOG.txt?rev=1003198&r1=1003197&r2=1003198&view=diff
==============================================================================
--- santuario/trunk/CHANGELOG.txt (original)
+++ santuario/trunk/CHANGELOG.txt Thu Sep 30 18:40:45 2010
@@ -1,5 +1,6 @@
Changelog for "Apache xml-security" <http://santuario.apache.org/>
New in v1.4.4-SNAPSHOT
+ Fixed Bug 49493 - Cannot resolve PrivateKeys used in Key Transport algorithms. Thanks to Clement Pellerin.
Fixed Bug 49577: DOMSubTreeData allows for only one iteration over referenced data.
Fixed Bug 49692: Xmlsec 1.4.3 not compatible with xmlbeans 2.4.0.
Fixed Bug 49629: Some changes to the build system.
Modified: santuario/trunk/src/org/apache/xml/security/encryption/XMLCipher.java
URL: http://svn.apache.org/viewvc/santuario/trunk/src/org/apache/xml/security/encryption/XMLCipher.java?rev=1003198&r1=1003197&r2=1003198&view=diff
==============================================================================
--- santuario/trunk/src/org/apache/xml/security/encryption/XMLCipher.java (original)
+++ santuario/trunk/src/org/apache/xml/security/encryption/XMLCipher.java Thu Sep 30 18:40:45 2010
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 The Apache Software Foundation.
+ * Copyright 2003-2010 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1264,7 +1264,14 @@ public class XMLCipher {
KeyInfo ki = encryptedKey.getKeyInfo();
if (ki != null) {
try {
- _key = ki.getSecretKey();
+ String keyWrapAlg = encryptedKey.getEncryptionMethod().getAlgorithm();
+ String keyType = JCEMapper.getJCEKeyAlgorithmFromURI(keyWrapAlg);
+ if ("RSA".equals(keyType)) {
+ _key = ki.getPrivateKey();
+ }
+ else {
+ _key = ki.getSecretKey();
+ }
}
catch (Exception e) {
}
Modified: santuario/trunk/src/org/apache/xml/security/keys/KeyInfo.java
URL: http://svn.apache.org/viewvc/santuario/trunk/src/org/apache/xml/security/keys/KeyInfo.java?rev=1003198&r1=1003197&r2=1003198&view=diff
==============================================================================
--- santuario/trunk/src/org/apache/xml/security/keys/KeyInfo.java (original)
+++ santuario/trunk/src/org/apache/xml/security/keys/KeyInfo.java Thu Sep 30 18:40:45 2010
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2010 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.apache.xml.security.keys;
+import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -93,9 +94,14 @@ public class KeyInfo extends SignatureEl
/** {@link org.apache.commons.logging} logging facility */
static org.apache.commons.logging.Log log =
org.apache.commons.logging.LogFactory.getLog(KeyInfo.class.getName());
+
List x509Datas=null;
List encryptedKeys=null;
+ // We need at least one StorageResolver otherwise
+ // the KeyResolvers would not be called.
+ // The default StorageResolver is null.
+
static final List nullList;
static {
List list = new ArrayList();
@@ -716,9 +722,9 @@ public class KeyInfo extends SignatureEl
}
/**
- * Searches the library wide keyresolvers for public keys
+ * Searches the library wide KeyResolvers for public keys
*
- * @return The publick contained in this Node.
+ * @return The public key contained in this Node.
* @throws KeyResolverException
*/
PublicKey getPublicKeyFromStaticResolvers() throws KeyResolverException {
@@ -753,9 +759,9 @@ public class KeyInfo extends SignatureEl
}
/**
- * Searches the per-KeyInfo keyresolvers for public keys
+ * Searches the per-KeyInfo KeyResolvers for public keys
*
- * @return The publick contained in this Node.
+ * @return The public key contained in this Node.
* @throws KeyResolverException
*/
PublicKey getPublicKeyFromInternalResolvers() throws KeyResolverException {
@@ -791,7 +797,7 @@ public class KeyInfo extends SignatureEl
/**
* Method getX509Certificate
*
- * @return The certificate contined in this KeyInfo
+ * @return The certificate contained in this KeyInfo
* @throws KeyResolverException
*/
public X509Certificate getX509Certificate() throws KeyResolverException {
@@ -931,16 +937,16 @@ public class KeyInfo extends SignatureEl
}
/**
- * Searches the library wide keyresolvers for Secret keys
+ * Searches the library wide KeyResolvers for Secret keys
*
* @return the secret key contained in this KeyInfo
* @throws KeyResolverException
*/
SecretKey getSecretKeyFromStaticResolvers() throws KeyResolverException {
- final int length=KeyResolver.length();
- int storageLength=this._storageResolvers.size();
- Iterator it = KeyResolver.iterator();
+ final int length=KeyResolver.length();
+ int storageLength=this._storageResolvers.size();
+ Iterator it = KeyResolver.iterator();
for (int i = 0; i < length; i++) {
KeyResolverSpi keyResolver = (KeyResolverSpi) it.next();
@@ -969,18 +975,18 @@ public class KeyInfo extends SignatureEl
}
/**
- * Searches the per-KeyInfo keyresolvers for secret keys
+ * Searches the per-KeyInfo KeyResolvers for secret keys
*
* @return the secret key contained in this KeyInfo
* @throws KeyResolverException
*/
SecretKey getSecretKeyFromInternalResolvers() throws KeyResolverException {
- int storageLength=this._storageResolvers.size();
+ int storageLength=this._storageResolvers.size();
for (int i = 0; i < this.lengthInternalKeyResolver(); i++) {
KeyResolverSpi keyResolver = this.itemInternalKeyResolver(i);
if (log.isDebugEnabled())
- log.debug("Try " + keyResolver.getClass().getName());
+ log.debug("Try " + keyResolver.getClass().getName());
Node currentChild=this._constructionElement.getFirstChild();
String uri=this.getBaseURI();
@@ -1006,6 +1012,98 @@ public class KeyInfo extends SignatureEl
}
/**
+ * This method returns a private key. This is for Key Transport in XML Encryption.
+ * @return the private key contained in this KeyInfo
+ * @throws KeyResolverException
+ */
+ public PrivateKey getPrivateKey() throws KeyResolverException {
+ PrivateKey pk = this.getPrivateKeyFromInternalResolvers();
+
+ if (pk != null) {
+ log.debug("I could find a private key using the per-KeyInfo key resolvers");
+ return pk;
+ }
+ log.debug("I couldn't find a secret key using the per-KeyInfo key resolvers");
+
+ pk = this.getPrivateKeyFromStaticResolvers();
+ if (pk != null) {
+ log.debug("I could find a private key using the system-wide key resolvers");
+ return pk;
+ }
+ log.debug("I couldn't find a private key using the system-wide key resolvers");
+
+ return null;
+ }
+
+ /**
+ * Searches the library wide KeyResolvers for Private keys
+ *
+ * @return the private key contained in this KeyInfo
+ * @throws KeyResolverException
+ */
+ PrivateKey getPrivateKeyFromStaticResolvers() throws KeyResolverException {
+ final int length=KeyResolver.length();
+ Iterator it = KeyResolver.iterator();
+ for (int i = 0; i < length; i++) {
+ KeyResolverSpi keyResolver = (KeyResolverSpi) it.next();
+
+ Node currentChild=this._constructionElement.getFirstChild();
+ String uri=this.getBaseURI();
+ while (currentChild!=null) {
+ if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
+ // not using StorageResolvers at the moment
+ // since they cannot return private keys
+ StorageResolver storage = null;
+ PrivateKey pk = keyResolver.engineLookupAndResolvePrivateKey(
+ (Element) currentChild,
+ uri,
+ storage);
+
+ if (pk != null) {
+ return pk;
+ }
+ }
+ currentChild=currentChild.getNextSibling();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Searches the per-KeyInfo KeyResolvers for private keys
+ *
+ * @return the private key contained in this KeyInfo
+ * @throws KeyResolverException
+ */
+
+ PrivateKey getPrivateKeyFromInternalResolvers() throws KeyResolverException {
+ for (int i = 0; i < this.lengthInternalKeyResolver(); i++) {
+ KeyResolverSpi keyResolver = this.itemInternalKeyResolver(i);
+ if (log.isDebugEnabled())
+ log.debug("Try " + keyResolver.getClass().getName());
+
+ Node currentChild=this._constructionElement.getFirstChild();
+ String uri=this.getBaseURI();
+ while (currentChild!=null) {
+ if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
+ // not using StorageResolvers at the moment
+ // since they cannot return private keys
+ StorageResolver storage = null;
+ PrivateKey pk = keyResolver
+ .engineLookupAndResolvePrivateKey((Element) currentChild, uri, storage);
+
+ if (pk != null) {
+ return pk;
+ }
+ }
+ currentChild=currentChild.getNextSibling();
+ }
+ }
+
+ return null;
+ }
+
+ /**
* Stores the individual (per-KeyInfo) {@link KeyResolver}s
*/
List _internalKeyResolvers = null;
@@ -1052,11 +1150,11 @@ public class KeyInfo extends SignatureEl
* @param storageResolver
*/
public void addStorageResolver(StorageResolver storageResolver) {
- if (_storageResolvers == nullList ){
- _storageResolvers=new ArrayList();
+ if (_storageResolvers == nullList) {
+ // Replace the default null StorageResolver
+ _storageResolvers = new ArrayList();
}
- this._storageResolvers.add(storageResolver);
-
+ this._storageResolvers.add(storageResolver);
}
//J-
Modified: santuario/trunk/src/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java
URL: http://svn.apache.org/viewvc/santuario/trunk/src/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java?rev=1003198&r1=1003197&r2=1003198&view=diff
==============================================================================
--- santuario/trunk/src/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java (original)
+++ santuario/trunk/src/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java Thu Sep 30 18:40:45 2010
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2010 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
*/
package org.apache.xml.security.keys.keyresolver;
+import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.HashMap;
@@ -40,8 +41,7 @@ import org.w3c.dom.Element;
*/
public abstract class KeyResolverSpi {
/**
- * This method helps the {@link org.apache.xml.security.utils.resolver.ResourceResolver} to decide whether a
- * {@link org.apache.xml.security.utils.resolver.ResourceResolverSpi} is able to perform the requested action.
+ * This method returns whether the KeyResolverSpi is able to perform the requested action.
*
* @param element
* @param BaseURI
@@ -70,7 +70,7 @@ public abstract class KeyResolverSpi {
};
/**
- * Method engineResolvePublicKey
+ * Method engineLookupAndResolvePublicKey
*
* @param element
* @param BaseURI
@@ -119,7 +119,7 @@ public abstract class KeyResolverSpi {
};
/**
- * Method engineResolveCertificate
+ * Method engineLookupResolveX509Certificate
*
* @param element
* @param BaseURI
@@ -154,7 +154,7 @@ public abstract class KeyResolverSpi {
};
/**
- * Method engineResolveSecretKey
+ * Method engineLookupAndResolveSecretKey
*
* @param element
* @param BaseURI
@@ -171,6 +171,27 @@ public abstract class KeyResolverSpi {
return null;
return tmp.engineResolveSecretKey(element, BaseURI, storage);
}
+
+ /**
+ * Method engineLookupAndResolvePrivateKey
+ *
+ * @param element
+ * @param BaseURI
+ * @param storage
+ * @return resolved PrivateKey key from the registered from the elements
+ *
+ * @throws KeyResolverException
+ */
+ public PrivateKey engineLookupAndResolvePrivateKey(
+ Element element, String BaseURI, StorageResolver storage)
+ throws KeyResolverException {
+ // This method was added later, it has no equivalent
+ // engineResolvePrivateKey() in the old API.
+ // We cannot throw UnsupportedOperationException because
+ // KeyResolverSpi implementations who don't know about
+ // this method would stop the search too early.
+ return null;
+ }
/** Field _properties */
protected java.util.Map _properties = null;
Modified: santuario/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
URL: http://svn.apache.org/viewvc/santuario/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java?rev=1003198&r1=1003197&r2=1003198&view=diff
==============================================================================
--- santuario/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java (original)
+++ santuario/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java Thu Sep 30 18:40:45 2010
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 The Apache Software Foundation.
+ * Copyright 1999-2010 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -193,7 +193,7 @@ public class RetrievalMethodResolver ext
}
/**
- * Retrieves a x509Certificate from the given information
+ * Retrieves a PublicKey from the given information
* @param e
* @param BaseURI
* @param storage
Modified: santuario/trunk/src_unitTests/org/apache/xml/security/test/ModuleTest.java
URL: http://svn.apache.org/viewvc/santuario/trunk/src_unitTests/org/apache/xml/security/test/ModuleTest.java?rev=1003198&r1=1003197&r2=1003198&view=diff
==============================================================================
--- santuario/trunk/src_unitTests/org/apache/xml/security/test/ModuleTest.java (original)
+++ santuario/trunk/src_unitTests/org/apache/xml/security/test/ModuleTest.java Thu Sep 30 18:40:45 2010
@@ -57,6 +57,7 @@ public class ModuleTest extends TestCase
suite.addTest(org.apache.xml.security.test.transforms.implementations.AllTests.suite());
suite.addTest(org.apache.xml.security.test.transforms.RegisterTest.suite());
suite.addTest(org.apache.xml.security.test.algorithms.AllTests.suite());
+ suite.addTest(org.apache.xml.security.test.keys.keyresolver.KeyResolverTest.suite());
suite.addTest(org.apache.xml.security.test.keys.content.x509.XMLX509SKITest.suite());
suite.addTest(org.apache.xml.security.test.keys.content.x509.XMLX509IssuerSerialTest.suite());
suite.addTest(org.apache.xml.security.test.keys.content.x509.XMLX509CertificateTest.suite());
Added: santuario/trunk/src_unitTests/org/apache/xml/security/test/keys/keyresolver/KeyResolverTest.java
URL: http://svn.apache.org/viewvc/santuario/trunk/src_unitTests/org/apache/xml/security/test/keys/keyresolver/KeyResolverTest.java?rev=1003198&view=auto
==============================================================================
--- santuario/trunk/src_unitTests/org/apache/xml/security/test/keys/keyresolver/KeyResolverTest.java (added)
+++ santuario/trunk/src_unitTests/org/apache/xml/security/test/keys/keyresolver/KeyResolverTest.java Thu Sep 30 18:40:45 2010
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2010 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.xml.security.test.keys.keyresolver;
+
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.xml.security.encryption.EncryptedData;
+import org.apache.xml.security.encryption.EncryptedKey;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.keyresolver.KeyResolver;
+import org.apache.xml.security.keys.keyresolver.KeyResolverException;
+import org.apache.xml.security.keys.keyresolver.KeyResolverSpi;
+import org.apache.xml.security.keys.storage.StorageResolver;
+import org.apache.xml.security.utils.Constants;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * KeyResolver test.
+ */
+public class KeyResolverTest extends TestCase {
+
+ public KeyResolverTest() {
+ super("KeyResolverTest");
+ }
+
+ public KeyResolverTest(String name) {
+ super(name);
+ org.apache.xml.security.Init.init();
+ }
+
+ public static Test suite() {
+ return new TestSuite(KeyResolverTest.class);
+ }
+
+ /**
+ * Encrypt some data, embedded the data encryption key
+ * in the message using the key transport algorithm rsa-1_5.
+ * Decrypt the data by resolving the Key Encryption Key.
+ * This test verifies if a KeyResolver can return a PrivateKey.
+ */
+ public void testResolvePrivateKey() throws Exception {
+ // Create a sample XML document
+ DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = fac.newDocumentBuilder();
+ Document document = builder.newDocument();
+
+ Element rootElement = document.createElement("root");
+ document.appendChild(rootElement);
+ Element elem = document.createElement("elem");
+ Text text = document.createTextNode("text");
+ elem.appendChild(text);
+ rootElement.appendChild(elem);
+
+ // Create a data encryption key
+ byte[] keyBytes = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 };
+ SecretKeySpec dataEncryptKey = new SecretKeySpec(keyBytes, "AES");
+
+ // Create public and private keys
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger(
+ "8710a2bcb2f3fdac177f0ae0461c2dd0ebf72e0d88a5400583a7d8bdabd6" +
+ "ae009d30cfdf6acb5b6a64cdc730bc630a39d946d08babffe62ea20a87e37c93b3b0e8a8e576045b" +
+ "bddfbde83ca9bfa180fe6a5f5eee60661936d728314e809201ef52cd71d9fa3c8ce83f9d30ab5e08" +
+ "1539219e7e45dd6a60be65ac95d2049b8f21", 16),
+ new BigInteger("10001", 16));
+
+ RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(
+ new BigInteger(
+ "8710a2bcb2f3fdac177f0ae0461c2dd0ebf72e0d88a5400583a7d8bdabd" +
+ "6ae009d30cfdf6acb5b6a64cdc730bc630a39d946d08babffe62ea20a87e37c93b3b0e8a8e576045" +
+ "bbddfbde83ca9bfa180fe6a5f5eee60661936d728314e809201ef52cd71d9fa3c8ce83f9d30ab5e0" +
+ "81539219e7e45dd6a60be65ac95d2049b8f21", 16),
+ new BigInteger(
+ "20c39e569c2aa80cc91e5e6b0d56e49e5bbf78827bf56a546c1d996c597" +
+ "5187cb9a50fa828e5efe51d52f5d112c20bc700b836facadca6e0051afcdfe866841e37d207c0295" +
+ "36ff8674b301e2198b2c56abb0a0313f8ff84c1fcd6fa541aa6e5d9c018fab4784d2940def5dc709" +
+ "ddc714d73b6c23b5d178eaa5933577b8e8ae9", 16));
+
+ RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
+ RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privKeySpec);
+
+ // Encrypt the data encryption key with the key encryption key
+ XMLCipher keyCipher = XMLCipher.getInstance(XMLCipher.RSA_v1dot5);
+ keyCipher.init(XMLCipher.WRAP_MODE, pubKey);
+ EncryptedKey encryptedKey = keyCipher.encryptKey(document, dataEncryptKey);
+
+ String keyName = "testResolvePrivateKey";
+ KeyInfo kekInfo = new KeyInfo(document);
+ kekInfo.addKeyName(keyName);
+ encryptedKey.setKeyInfo(kekInfo);
+
+ // Encrypt the data
+ XMLCipher xmlCipher = XMLCipher.getInstance(XMLCipher.AES_128);
+ xmlCipher.init(XMLCipher.ENCRYPT_MODE, dataEncryptKey);
+
+ EncryptedData encryptedData = xmlCipher.getEncryptedData();
+ KeyInfo keyInfo = new KeyInfo(document);
+ keyInfo.add(encryptedKey);
+ encryptedData.setKeyInfo(keyInfo);
+
+ xmlCipher.doFinal(document, rootElement, true);
+
+ Element encryptedDataElement = (Element) rootElement.getFirstChild();
+ assertEquals("EncryptedData", encryptedDataElement.getLocalName());
+
+ // Register a KeyResolver for the PrivateKey
+ MyPrivateKeyResolver.pk = privKey;
+ MyPrivateKeyResolver.pkName = keyName;
+ KeyResolver.registerAtStart(MyPrivateKeyResolver.class.getName());
+ KeyResolverSpi resolver = (KeyResolverSpi)KeyResolver.iterator().next();
+ assertEquals(MyPrivateKeyResolver.class.getName(), resolver.getClass().getName());
+
+ // Decrypt the data by resolving the private key used as the KEK
+ XMLCipher decryptCipher = XMLCipher.getInstance();
+ decryptCipher.init(XMLCipher.DECRYPT_MODE, null);
+ decryptCipher.doFinal(document, encryptedDataElement);
+
+ Element decryptedElement = (Element) rootElement.getFirstChild();
+ assertEquals("elem", decryptedElement.getLocalName());
+ }
+
+ // A KeyResolver that returns a PrivateKey for a specific KeyName.
+ public static class MyPrivateKeyResolver extends KeyResolverSpi {
+
+ // We use static variables because KeyResolver.register() demands
+ // the use of the default constructor.
+ private static PrivateKey pk;
+ private static String pkName;
+
+ public boolean engineCanResolve(Element element, String BaseURI,
+ StorageResolver storage) {
+ return false;
+ }
+
+ public PrivateKey engineLookupAndResolvePrivateKey(Element element,
+ String BaseURI, StorageResolver storage)
+ throws KeyResolverException {
+
+ if (Constants.SignatureSpecNS.equals(element.getNamespaceURI()) &&
+ Constants._TAG_KEYNAME.equals(element.getLocalName())) {
+ String keyName = element.getFirstChild().getNodeValue();
+ if (pkName.equals(keyName)) {
+ return pk;
+ }
+ }
+
+ return null;
+ }
+ }
+}