You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2011/08/08 16:44:01 UTC
svn commit: r1154974 - in
/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security:
common/SecurityUtils.java xml/JAXRSXmlSecTest.java xml/XmlEncInHandler.java
xml/XmlEncOutInterceptor.java xml/XmlSigOutInterceptor.java
Author: sergeyb
Date: Mon Aug 8 14:44:01 2011
New Revision: 1154974
URL: http://svn.apache.org/viewvc?rev=1154974&view=rev
Log:
[CXF-3677] Fixing the position of EncryptedKey, some flexibility in the way X509 key identifiers are handled
Modified:
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/common/SecurityUtils.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/common/SecurityUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/common/SecurityUtils.java?rev=1154974&r1=1154973&r2=1154974&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/common/SecurityUtils.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/common/SecurityUtils.java Mon Aug 8 14:44:01 2011
@@ -19,12 +19,18 @@
package org.apache.cxf.systest.jaxrs.security.common;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.math.BigInteger;
import java.security.cert.X509Certificate;
import javax.security.auth.callback.CallbackHandler;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
@@ -33,13 +39,36 @@ import org.apache.ws.security.WSPassword
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoType;
+import org.apache.xml.security.utils.Constants;
public final class SecurityUtils {
+ public static final String X509_KEY = "X509_KEY";
+ public static final String X509_ISSUER_SERIAL = "X509_ISSUER_SERIAL";
+
private SecurityUtils() {
}
+ public static X509Certificate loadX509Certificate(Crypto crypto, Element certNode)
+ throws Exception {
+ String base64Value = certNode.getTextContent().trim();
+ byte[] certBytes = Base64Utility.decode(base64Value);
+ return crypto.loadCertificate(new ByteArrayInputStream(certBytes));
+ }
+
+ public static X509Certificate loadX509IssuerSerial(Crypto crypto, Element certNode)
+ throws Exception {
+ Node issuerNameNode =
+ certNode.getElementsByTagNameNS(Constants.SignatureSpecNS, "X509IssuerName").item(0);
+ Node serialNumberNode =
+ certNode.getElementsByTagNameNS(Constants.SignatureSpecNS, "X509SerialNumber").item(0);
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ISSUER_SERIAL);
+ cryptoType.setIssuerSerial(issuerNameNode.getTextContent(),
+ new BigInteger(serialNumberNode.getTextContent()));
+ return crypto.getX509Certificates(cryptoType)[0];
+ }
+
public static X509Certificate[] getCertificates(Crypto crypto, String user)
throws WSSecurityException {
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
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=1154974&r1=1154973&r2=1154974&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 Mon Aug 8 14:44:01 2011
@@ -30,6 +30,7 @@ import org.apache.cxf.jaxrs.client.JAXRS
import org.apache.cxf.jaxrs.client.ServerWebApplicationException;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.systest.jaxrs.security.Book;
+import org.apache.cxf.systest.jaxrs.security.common.SecurityUtils;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
import org.apache.xml.security.encryption.XMLCipher;
import org.junit.BeforeClass;
@@ -84,39 +85,25 @@ public class JAXRSXmlSecTest extends Abs
@Test
public void testPostEncryptedBook() throws Exception {
String address = "https://localhost:" + PORT + "/xmlenc/bookstore/books";
- JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
- bean.setAddress(address);
-
- SpringBusFactory bf = new SpringBusFactory();
- URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
- Bus springBus = bf.createBus(busFile.toString());
- bean.setBus(springBus);
-
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");
- bean.setProperties(properties);
- XmlEncOutInterceptor encInterceptor = new XmlEncOutInterceptor();
- encInterceptor.setSymmetricEncAlgorithm(XMLCipher.AES_128);
- bean.getOutInterceptors().add(encInterceptor);
-
- WebClient wc = bean.createWebClient();
- try {
- Book book = wc.post(new Book("CXF", 126L), Book.class);
- assertEquals(126L, book.getId());
- } catch (ServerWebApplicationException ex) {
- fail(ex.getMessage());
- } catch (ClientWebApplicationException ex) {
- if (ex.getCause() != null && ex.getCause().getMessage() != null) {
- fail(ex.getCause().getMessage());
- } else {
- fail(ex.getMessage());
- }
- }
-
+ doTestPostEncryptedBook(address, properties);
+ }
+
+ @Test
+ public void testPostEncryptedBookIssuerSerial() 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_ISSUER_SERIAL);
}
@Test
@@ -131,7 +118,7 @@ public class JAXRSXmlSecTest extends Abs
properties.put("ws-security.signature.username", "alice");
properties.put("ws-security.signature.properties",
"org/apache/cxf/systest/jaxrs/security/alice.properties");
- doTestPostEncryptedSignedBook(address, properties);
+ doTestPostEncryptedBook(address, properties);
}
@@ -145,11 +132,17 @@ 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");
- doTestPostEncryptedSignedBook(address, properties);
+ doTestPostEncryptedBook(address, properties);
}
- public void doTestPostEncryptedSignedBook(String address, Map<String, Object> properties)
+ public void doTestPostEncryptedBook(String address, Map<String, Object> properties)
+ throws Exception {
+ doTestPostEncryptedBook(address, properties, SecurityUtils.X509_KEY);
+ }
+
+ public void doTestPostEncryptedBook(String address, Map<String, Object> properties,
+ String keyIdentifierType)
throws Exception {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(address);
@@ -162,6 +155,7 @@ public class JAXRSXmlSecTest extends Abs
bean.setProperties(properties);
bean.getOutInterceptors().add(new XmlSigOutInterceptor());
XmlEncOutInterceptor encInterceptor = new XmlEncOutInterceptor();
+ encInterceptor.setKeyIdentifierType(keyIdentifierType);
encInterceptor.setSymmetricEncAlgorithm(XMLCipher.AES_128);
bean.getOutInterceptors().add(encInterceptor);
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java?rev=1154974&r1=1154973&r2=1154974&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java Mon Aug 8 14:44:01 2011
@@ -109,26 +109,8 @@ public class XmlEncInHandler implements
return null;
}
+ // Subclasses can overwrite it and return the bytes, assuming they know the actual key
protected byte[] getSymmetricKeyBytes(Message message, Element encDataElement) {
- // Subclasses can overwrite it and return the bytes, assuming they know the actual key
- Element encKeyElement = getNode(encDataElement, WSConstants.ENC_NS, "EncryptedKey", 0);
- if (encKeyElement == null) {
- //TODO: support EncryptedData/ds:KeyInfo - the encrypted key is passed out of band
- throwFault("EncryptedKey element is not available", null);
- }
-
- Element certNode = getNode(encKeyElement,
- Constants.SignatureSpecNS, "X509Certificate", 0);
- if (certNode == null) {
- throwFault("Certificate is missing", null);
- }
- byte[] certBytes = null;
- try {
- certBytes = Base64Utility.decode(certNode.getTextContent().trim());
- } catch (Base64Exception ex) {
- throwFault("Base64 decoding has failed", ex);
- }
-
Crypto crypto = null;
try {
crypto = new CryptoLoader().getCrypto(message,
@@ -138,13 +120,14 @@ public class XmlEncInHandler implements
throwFault("Crypto can not be loaded", ex);
}
- X509Certificate cert = null;
- try {
- cert = crypto.loadCertificate(new ByteArrayInputStream(certBytes));
- } catch (Exception ex) {
- throwFault("X509Certificate can not be created", ex);
+ Element encKeyElement = getNode(encDataElement, WSConstants.ENC_NS, "EncryptedKey", 0);
+ if (encKeyElement == null) {
+ //TODO: support EncryptedData/ds:KeyInfo - the encrypted key is passed out of band
+ throwFault("EncryptedKey element is not available", null);
}
+ X509Certificate cert = loadCertificate(crypto, encKeyElement);
+
try {
new TrustValidator().validateTrust(crypto, cert, null);
} catch (Exception ex) {
@@ -170,6 +153,36 @@ public class XmlEncInHandler implements
return null;
}
+ private X509Certificate loadCertificate(Crypto crypto, Element encKeyElement) {
+ /**
+ * TODO: the following can be easily supported too
+ <X509SKI>31d97bd7</X509SKI>
+ <X509SubjectName>Subject of Certificate B</X509SubjectName>
+ *
+ */
+
+ Element certNode = getNode(encKeyElement,
+ Constants.SignatureSpecNS, "X509Certificate", 0);
+ if (certNode != null) {
+ try {
+ return SecurityUtils.loadX509Certificate(crypto, certNode);
+ } catch (Exception ex) {
+ throwFault("X509Certificate can not be created", ex);
+ }
+ }
+ certNode = getNode(encKeyElement,
+ Constants.SignatureSpecNS, "X509IssuerSerial", 0);
+ if (certNode != null) {
+ try {
+ return SecurityUtils.loadX509IssuerSerial(crypto, certNode);
+ } catch (Exception ex) {
+ throwFault("X509Certificate can not be created", ex);
+ }
+ }
+ throwFault("Certificate is missing", null);
+ return null;
+ }
+
private String getEncodingMethodAlgorithm(Element parent) {
Element encMethod = getNode(parent, WSConstants.ENC_NS, "EncryptionMethod", 0);
if (encMethod == null) {
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java?rev=1154974&r1=1154973&r2=1154974&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java Mon Aug 8 14:44:01 2011
@@ -55,18 +55,26 @@ import org.apache.xml.security.algorithm
import org.apache.xml.security.encryption.XMLCipher;
public class XmlEncOutInterceptor extends AbstractXmlSecOutInterceptor {
+
private static final Logger LOG =
LogUtils.getL7dLogger(XmlEncOutInterceptor.class);
+ private static final String DEFAULT_RETRIEVAL_METHOD_TYPE =
+ "http://www.w3.org/2001/04/xmlenc#EncryptedKey";
private boolean encryptSymmetricKey = true;
private SecretKey symmetricKey;
private String keyEncAlgo = XMLCipher.RSA_OAEP;
private String symEncAlgo = XMLCipher.AES_256;
+ private String keyIdentifierType = SecurityUtils.X509_KEY;
public XmlEncOutInterceptor() {
addAfter(XmlSigOutInterceptor.class.getName());
}
+ public void setKeyIdentifierType(String type) {
+ keyIdentifierType = type;
+ }
+
public void setSymmetricEncAlgorithm(String algo) {
symEncAlgo = algo;
}
@@ -208,14 +216,26 @@ public class XmlEncOutInterceptor extend
String encKeyId = "EK-" + UUIDGenerator.getUUID();
encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
- Element keyInfoElement = createKeyInfoElement(doc, cert, WSConstants.X509_KEY_IDENTIFIER);
+ Element keyInfoElement = createKeyInfoElement(doc, cert);
encryptedKeyElement.appendChild(keyInfoElement);
Element xencCipherValue = createCipherValue(doc, encryptedKeyElement);
xencCipherValue.appendChild(doc.createTextNode(encodedKey));
+ Element topKeyInfoElement =
+ doc.createElementNS(
+ WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
+ );
+ Element retrievalMethodElement =
+ doc.createElementNS(
+ WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":RetrievalMethod"
+ );
+ retrievalMethodElement.setAttribute("Type", DEFAULT_RETRIEVAL_METHOD_TYPE);
+ topKeyInfoElement.appendChild(retrievalMethodElement);
+
+ topKeyInfoElement.appendChild(encryptedKeyElement);
- encryptedDataElement.appendChild(encryptedKeyElement);
+ encryptedDataElement.appendChild(topKeyInfoElement);
}
protected Element createCipherValue(Document doc, Element encryptedKey) {
@@ -229,16 +249,14 @@ public class XmlEncOutInterceptor extend
}
private Element createKeyInfoElement(Document encryptedDataDoc,
- X509Certificate remoteCert,
- int keyIdentifierType) throws Exception {
+ X509Certificate remoteCert) throws Exception {
Element keyInfoElement =
encryptedDataDoc.createElementNS(
WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
);
Node keyIdentifierNode = null;
- switch (keyIdentifierType) {
- case WSConstants.X509_KEY_IDENTIFIER:
+ if (keyIdentifierType.equals(SecurityUtils.X509_KEY)) {
byte data[] = null;
try {
data = remoteCert.getEncoded();
@@ -255,10 +273,8 @@ public class XmlEncOutInterceptor extend
WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.X509_DATA_LN);
x509Data.appendChild(cert);
- keyIdentifierNode = x509Data;
- break;
-
- case WSConstants.ISSUER_SERIAL:
+ keyIdentifierNode = x509Data;
+ } else if (keyIdentifierType.equals(SecurityUtils.X509_ISSUER_SERIAL)) {
String issuer = remoteCert.getIssuerDN().getName();
java.math.BigInteger serialNumber = remoteCert.getSerialNumber();
DOMX509IssuerSerial domIssuerSerial =
@@ -267,8 +283,7 @@ public class XmlEncOutInterceptor extend
);
DOMX509Data domX509Data = new DOMX509Data(encryptedDataDoc, domIssuerSerial);
keyIdentifierNode = domX509Data.getElement();
- break;
- default:
+ } else {
throw new WSSecurityException("Unsupported key identifier:" + keyIdentifierType);
}
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java?rev=1154974&r1=1154973&r2=1154974&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java Mon Aug 8 14:44:01 2011
@@ -46,10 +46,20 @@ public class XmlSigOutInterceptor extend
LogUtils.getL7dLogger(XmlSigOutInterceptor.class);
private boolean createReferenceId = true;
+ private String defaultSigAlgo = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
+ private String digestAlgo = Constants.ALGO_ID_DIGEST_SHA1;
public XmlSigOutInterceptor() {
}
+ public void setSignatureAlgorithm(String algo) {
+ defaultSigAlgo = algo;
+ }
+
+ public void setDigestAlgorithm(String algo) {
+ digestAlgo = algo;
+ }
+
public void setCreateReferenceId(boolean create) {
createReferenceId = create;
}
@@ -87,7 +97,7 @@ public class XmlSigOutInterceptor extend
X509Certificate[] issuerCerts = SecurityUtils.getCertificates(crypto, user);
- String sigAlgo = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
+ String sigAlgo = defaultSigAlgo;
String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
@@ -116,7 +126,7 @@ public class XmlSigOutInterceptor extend
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
- sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1, referenceId, null);
+ sig.addDocument("", transforms, digestAlgo, referenceId, null);
sig.addKeyInfo(issuerCerts[0]);
sig.addKeyInfo(issuerCerts[0].getPublicKey());