Author: coheigea
Date: Tue Feb 28 12:16:45 2012
New Revision: 1294613
URL: http://svn.apache.org/viewvc?rev=1294613&view=rev
Log:
Add the ability to specify an optional DigestMethod parameter when creating an
EncryptedKey
- This allows the use of > SHA-1
Modified:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/EncryptionUtils.java
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
Modified:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java?rev=1294613&r1=1294612&r2=1294613&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
(original)
+++
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
Tue Feb 28 12:16:45 2012
@@ -112,6 +112,7 @@ public abstract class AbstractXmlEncInHa
// now start decrypting
String algorithm = getEncodingMethodAlgorithm(encKeyElement);
+ String digestAlgorithm = getDigestMethodAlgorithm(encKeyElement);
Element cipherValue = getNode(encKeyElement, WSConstants.ENC_NS,
"CipherValue", 0);
if (cipherValue == null) {
@@ -122,6 +123,7 @@ public abstract class AbstractXmlEncInHa
cert,
crypto,
algorithm,
+ digestAlgorithm,
message);
} catch (Exception ex) {
throwFault(ex.getMessage(), ex);
@@ -166,6 +168,17 @@ public abstract class AbstractXmlEncInHa
}
return encMethod.getAttribute("Algorithm");
}
+
+ private String getDigestMethodAlgorithm(Element parent) {
+ Element encMethod = getNode(parent, WSConstants.ENC_NS,
"EncryptionMethod", 0);
+ if (encMethod != null) {
+ Element digestMethod = getNode(encMethod, WSConstants.SIG_NS,
"DigestMethod", 0);
+ if (digestMethod != null) {
+ return digestMethod.getAttributeNS(null, "Algorithm");
+ }
+ }
+ return null;
+ }
//TODO: Support symmetric keys if requested
protected byte[] decryptSymmetricKey(String base64EncodedKey,
@@ -173,6 +186,16 @@ public abstract class AbstractXmlEncInHa
Crypto crypto,
String keyEncAlgo,
Message message) throws
WSSecurityException {
+ return decryptSymmetricKey(base64EncodedKey, cert, crypto, keyEncAlgo,
null, message);
+ }
+
+ //TODO: Support symmetric keys if requested
+ protected byte[] decryptSymmetricKey(String base64EncodedKey,
+ X509Certificate cert,
+ Crypto crypto,
+ String keyEncAlgo,
+ String digestAlgo,
+ Message message) throws
WSSecurityException {
CallbackHandler callback = SecurityUtils.getCallbackHandler(message,
this.getClass());
PrivateKey key = null;
try {
@@ -181,7 +204,7 @@ public abstract class AbstractXmlEncInHa
throwFault("Encrypted key can not be decrypted", ex);
}
Cipher cipher =
- EncryptionUtils.initCipherWithKey(keyEncAlgo, Cipher.DECRYPT_MODE,
key);
+ EncryptionUtils.initCipherWithKey(keyEncAlgo, digestAlgo,
Cipher.DECRYPT_MODE, key);
try {
byte[] encryptedBytes = Base64Utility.decode(base64EncodedKey);
return cipher.doFinal(encryptedBytes);
Modified:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/EncryptionUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/EncryptionUtils.java?rev=1294613&r1=1294612&r2=1294613&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/EncryptionUtils.java
(original)
+++
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/EncryptionUtils.java
Tue Feb 28 12:16:45 2012
@@ -30,8 +30,10 @@ import javax.crypto.spec.PSource;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.apache.xml.security.utils.EncryptionConstants;
public final class EncryptionUtils {
private EncryptionUtils() {
@@ -40,18 +42,25 @@ public final class EncryptionUtils {
public static Cipher initCipherWithCert(String keyEncAlgo, int mode,
X509Certificate cert)
throws WSSecurityException {
+ return initCipherWithCert(keyEncAlgo, null, mode, cert);
+ }
+
+ public static Cipher initCipherWithCert(
+ String keyEncAlgo,
+ String digestAlg,
+ int mode,
+ X509Certificate cert
+ ) throws WSSecurityException {
Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
try {
- OAEPParameterSpec oaepParameterSpec = null;
- if (XMLCipher.RSA_OAEP.equals(keyEncAlgo)) {
- oaepParameterSpec = new OAEPParameterSpec(
- "SHA-1", "MGF1", new MGF1ParameterSpec("SHA-1"),
PSource.PSpecified.DEFAULT
+ OAEPParameterSpec oaepParameters =
+ constructOAEPParameters(
+ keyEncAlgo, digestAlg, null, null
);
- }
- if (oaepParameterSpec == null) {
+ if (oaepParameters == null) {
cipher.init(mode, cert);
} else {
- cipher.init(mode, cert.getPublicKey(), oaepParameterSpec);
+ cipher.init(mode, cert.getPublicKey(), oaepParameters);
}
} catch (InvalidKeyException e) {
throw new WSSecurityException(
@@ -67,18 +76,21 @@ public final class EncryptionUtils {
public static Cipher initCipherWithKey(String keyEncAlgo, int mode, Key
key)
throws WSSecurityException {
+ return initCipherWithKey(keyEncAlgo, null, mode, key);
+ }
+
+ public static Cipher initCipherWithKey(String keyEncAlgo, String
digestAlgo, int mode, Key key)
+ throws WSSecurityException {
Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
try {
- OAEPParameterSpec oaepParameterSpec = null;
- if (XMLCipher.RSA_OAEP.equals(keyEncAlgo)) {
- oaepParameterSpec = new OAEPParameterSpec(
- "SHA-1", "MGF1", new MGF1ParameterSpec("SHA-1"),
PSource.PSpecified.DEFAULT
+ OAEPParameterSpec oaepParameters =
+ constructOAEPParameters(
+ keyEncAlgo, digestAlgo, null, null
);
- }
- if (oaepParameterSpec == null) {
+ if (oaepParameters == null) {
cipher.init(mode, key);
} else {
- cipher.init(mode, key, oaepParameterSpec);
+ cipher.init(mode, key, oaepParameters);
}
} catch (InvalidKeyException e) {
throw new WSSecurityException(
@@ -92,6 +104,44 @@ public final class EncryptionUtils {
return cipher;
}
+ /**
+ * Construct an OAEPParameterSpec object from the given parameters
+ */
+ public static OAEPParameterSpec constructOAEPParameters(
+ String encryptionAlgorithm,
+ String digestAlgorithm,
+ String mgfAlgorithm,
+ byte[] oaepParams
+ ) {
+ if (XMLCipher.RSA_OAEP.equals(encryptionAlgorithm)
+ || XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
+
+ String jceDigestAlgorithm = "SHA-1";
+ if (digestAlgorithm != null) {
+ jceDigestAlgorithm =
JCEMapper.translateURItoJCEID(digestAlgorithm);
+ }
+
+ PSource.PSpecified pSource = PSource.PSpecified.DEFAULT;
+ if (oaepParams != null) {
+ pSource = new PSource.PSpecified(oaepParams);
+ }
+
+ MGF1ParameterSpec mgfParameterSpec = new
MGF1ParameterSpec("SHA-1");
+ if (XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
+ if (EncryptionConstants.MGF1_SHA256.equals(mgfAlgorithm)) {
+ mgfParameterSpec = new MGF1ParameterSpec("SHA-256");
+ } else if
(EncryptionConstants.MGF1_SHA384.equals(mgfAlgorithm)) {
+ mgfParameterSpec = new MGF1ParameterSpec("SHA-384");
+ } else if
(EncryptionConstants.MGF1_SHA512.equals(mgfAlgorithm)) {
+ mgfParameterSpec = new MGF1ParameterSpec("SHA-512");
+ }
+ }
+ return new OAEPParameterSpec(jceDigestAlgorithm, "MGF1",
mgfParameterSpec, pSource);
+ }
+
+ return null;
+ }
+
public static XMLCipher initXMLCipher(String symEncAlgo, int mode, Key
key)
throws WSSecurityException {
try {
Modified:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java?rev=1294613&r1=1294612&r2=1294613&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java
(original)
+++
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java
Tue Feb 28 12:16:45 2012
@@ -67,6 +67,7 @@ public class XmlEncOutInterceptor extend
private String keyEncAlgo = XMLCipher.RSA_OAEP;
private String symEncAlgo = XMLCipher.AES_256;
private String keyIdentifierType = SecurityUtils.X509_KEY;
+ private String digestAlgo;
public XmlEncOutInterceptor() {
addAfter(XmlSigOutInterceptor.class.getName());
@@ -88,6 +89,10 @@ public class XmlEncOutInterceptor extend
keyEncAlgo = algo;
}
+ public void setDigestAlgorithm(String algo) {
+ digestAlgo = algo;
+ }
+
protected Document processDocument(Message message, Document payloadDoc)
throws Exception {
return encryptDocument(message, payloadDoc);
@@ -181,7 +186,9 @@ public class XmlEncOutInterceptor extend
X509Certificate remoteCert,
Crypto crypto) throws
WSSecurityException {
Cipher cipher =
- EncryptionUtils.initCipherWithCert(keyEncAlgo,
Cipher.ENCRYPT_MODE, remoteCert);
+ EncryptionUtils.initCipherWithCert(
+ keyEncAlgo, digestAlgo, Cipher.ENCRYPT_MODE, remoteCert
+ );
int blockSize = cipher.getBlockSize();
if (blockSize > 0 && blockSize < keyBytes.length) {
String message = "Public key algorithm too weak to encrypt
symmetric key";
@@ -308,6 +315,13 @@ public class XmlEncOutInterceptor extend
encryptedDataDoc.createElementNS(WSConstants.ENC_NS,
WSConstants.ENC_PREFIX
+ ":EncryptionMethod");
encryptionMethod.setAttributeNS(null, "Algorithm", keyEncAlgo);
+ if (digestAlgo != null) {
+ Element digestMethod =
+ encryptedDataDoc.createElementNS(WSConstants.SIG_NS,
WSConstants.SIG_PREFIX
+ + ":DigestMethod");
+ digestMethod.setAttributeNS(null, "Algorithm", digestAlgo);
+ encryptionMethod.appendChild(digestMethod);
+ }
encryptedKey.appendChild(encryptionMethod);
return encryptedKey;
}
Modified:
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java?rev=1294613&r1=1294612&r2=1294613&view=diff
==============================================================================
---
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
(original)
+++
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
Tue Feb 28 12:16:45 2012
@@ -167,7 +167,21 @@ public class JAXRSXmlSecTest extends Abs
properties.put("ws-security.encryption.properties",
"org/apache/cxf/systest/jaxrs/security/bob.properties");
String aes128GCM = "http://www.w3.org/2009/xmlenc11#aes128-gcm";
- doTestPostEncryptedBook(address, properties, SecurityUtils.X509_KEY,
aes128GCM);
+ doTestPostEncryptedBook(address, properties, SecurityUtils.X509_KEY,
aes128GCM, null);
+ }
+
+ @Test
+ public void testPostEncryptedBookSHA256() throws Exception {
+ String address = "https://localhost:" + PORT +
"/xmlenc/bookstore/books";
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put("ws-security.callback-handler",
+
"org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+ properties.put("ws-security.encryption.username", "bob");
+ properties.put("ws-security.encryption.properties",
+ "org/apache/cxf/systest/jaxrs/security/bob.properties");
+ doTestPostEncryptedBook(
+ address, properties, SecurityUtils.X509_KEY, XMLCipher.AES_128,
XMLCipher.SHA256
+ );
}
@Test
@@ -179,7 +193,9 @@ public class JAXRSXmlSecTest extends Abs
properties.put("ws-security.encryption.username", "bob");
properties.put("ws-security.encryption.properties",
"org/apache/cxf/systest/jaxrs/security/bob.properties");
- doTestPostEncryptedBook(address, properties,
SecurityUtils.X509_ISSUER_SERIAL, XMLCipher.AES_128);
+ doTestPostEncryptedBook(
+ address, properties, SecurityUtils.X509_ISSUER_SERIAL,
XMLCipher.AES_128, null
+ );
}
@Test
@@ -214,12 +230,16 @@ public class JAXRSXmlSecTest extends Abs
public void doTestPostEncryptedBook(String address, Map<String, Object>
properties)
throws Exception {
- doTestPostEncryptedBook(address, properties, SecurityUtils.X509_KEY,
XMLCipher.AES_128);
+ doTestPostEncryptedBook(
+ address, properties, SecurityUtils.X509_KEY, XMLCipher.AES_128,
null
+ );
}
- public void doTestPostEncryptedBook(String address, Map<String, Object>
properties,
- String keyIdentifierType, String
symmetricAlgorithm)
- throws Exception {
+ public void doTestPostEncryptedBook(
+ String address, Map<String, Object> properties,
+ String keyIdentifierType, String symmetricAlgorithm,
+ String digestAlgorithm
+ ) throws Exception {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(address);
@@ -233,6 +253,7 @@ public class JAXRSXmlSecTest extends Abs
XmlEncOutInterceptor encInterceptor = new XmlEncOutInterceptor();
encInterceptor.setKeyIdentifierType(keyIdentifierType);
encInterceptor.setSymmetricEncAlgorithm(symmetricAlgorithm);
+ encInterceptor.setDigestAlgorithm(digestAlgorithm);
bean.getOutInterceptors().add(encInterceptor);
bean.getInInterceptors().add(new XmlEncInInterceptor());