You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by co...@apache.org on 2010/09/18 16:04:05 UTC
svn commit: r998472 - in /webservices/wss4j/trunk:
src/org/apache/ws/security/processor/ src/org/apache/ws/security/saml/
test/ test/wssec/
Author: coheigea
Date: Sat Sep 18 14:04:04 2010
New Revision: 998472
URL: http://svn.apache.org/viewvc?rev=998472&view=rev
Log:
[WSS-240] - Support KeyValue in SAML subject
- Patch applied, thanks.
Added:
webservices/wss4j/trunk/test/saml4sendKeyValue.properties
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLIssuerImpl.java
webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java
webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java
webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java
webservices/wss4j/trunk/test/saml4.properties
webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java Sat Sep 18 14:04:04 2010
@@ -328,6 +328,7 @@ public class SignatureProcessor implemen
certs = samlKi.getCerts();
validateCertificates(certs, crypto);
secretKey = samlKi.getSecret();
+ publicKey = samlKi.getPublicKey();
principal = createPrincipalFromSAMLKeyInfo(samlKi);
}
} else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
@@ -351,6 +352,7 @@ public class SignatureProcessor implemen
certs = samlKi.getCerts();
validateCertificates(certs, crypto);
secretKey = samlKi.getSecret();
+ publicKey = samlKi.getPublicKey();
principal = createPrincipalFromSAMLKeyInfo(samlKi);
} else {
certs = secRef.getKeyIdentifier(crypto);
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLIssuerImpl.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLIssuerImpl.java?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLIssuerImpl.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLIssuerImpl.java Sat Sep 18 14:04:04 2010
@@ -28,6 +28,8 @@ import org.apache.ws.security.components
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.keyvalues.DSAKeyValue;
+import org.apache.xml.security.keys.content.keyvalues.RSAKeyValue;
import org.apache.xml.security.signature.XMLSignature;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLAuthenticationStatement;
@@ -38,6 +40,7 @@ import org.opensaml.SAMLSubject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
@@ -69,6 +72,14 @@ public class SAMLIssuerImpl implements S
private String[] confirmationMethods = new String[1];
private Crypto userCrypto = null;
private String username = null;
+
+ /**
+ * Flag indicating what format to put the subject's key material in when
+ * NOT using Sender Vouches as the confirmation method. The default is
+ * to use ds:X509Data and include the entire certificate. If this flag
+ * is set to true, a ds:KeyValue is used instead with just the key material.
+ */
+ private boolean sendKeyValue = false;
/**
* Constructor.
@@ -96,6 +107,12 @@ public class SAMLIssuerImpl implements S
issuerKeyPassword =
properties.getProperty("org.apache.ws.security.saml.issuer.key.password");
}
+
+ String sendKeyValueProp =
+ properties.getProperty("org.apache.ws.security.saml.issuer.sendKeyValue");
+ if (sendKeyValueProp != null) {
+ sendKeyValue = Boolean.valueOf(sendKeyValueProp).booleanValue();
+ }
if ("senderVouches"
.equals(properties.getProperty("org.apache.ws.security.saml.confirmationMethod"))) {
@@ -170,9 +187,22 @@ public class SAMLIssuerImpl implements S
try {
X509Certificate[] certs =
userCrypto.getCertificates(username);
- X509Data certElem = new X509Data(instanceDoc);
- certElem.addCertificate(certs[0]);
- ki.add(certElem);
+ if (sendKeyValue) {
+ PublicKey key = certs[0].getPublicKey();
+ String pubKeyAlgo = key.getAlgorithm();
+
+ if ("DSA".equalsIgnoreCase(pubKeyAlgo)) {
+ DSAKeyValue dsaKeyValue = new DSAKeyValue(instanceDoc, key);
+ ki.add(dsaKeyValue);
+ } else if ("RSA".equalsIgnoreCase(pubKeyAlgo)) {
+ RSAKeyValue rsaKeyValue = new RSAKeyValue(instanceDoc, key);
+ ki.add(rsaKeyValue);
+ }
+ } else {
+ X509Data certElem = new X509Data(instanceDoc);
+ certElem.addCertificate(certs[0]);
+ ki.add(certElem);
+ }
} catch (WSSecurityException ex) {
if (log.isDebugEnabled()) {
log.debug(ex.getMessage(), ex);
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java Sat Sep 18 14:04:04 2010
@@ -21,6 +21,7 @@ package org.apache.ws.security.saml;
import org.opensaml.SAMLAssertion;
+import java.security.PublicKey;
import java.security.cert.X509Certificate;
/**
@@ -39,6 +40,11 @@ public class SAMLKeyInfo {
private byte[] secret;
/**
+ * The public key {e.g.: held in a ds:KeyInfo).
+ */
+ private PublicKey publicKey;
+
+ /**
* SAMLAssertion
*/
SAMLAssertion assertion;
@@ -53,15 +59,24 @@ public class SAMLKeyInfo {
this.assertion = assertions;
}
+ public SAMLKeyInfo(SAMLAssertion assertions, PublicKey publicKey) {
+ this.publicKey = publicKey;
+ this.assertion = assertions;
+ }
+
public X509Certificate[] getCerts() {
return certs;
}
+
public byte[] getSecret() {
return secret;
}
+ public PublicKey getPublicKey() {
+ return this.publicKey;
+ }
+
public SAMLAssertion getAssertion() {
return assertion;
}
-
-}
\ No newline at end of file
+}
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java Sat Sep 18 14:04:04 2010
@@ -49,6 +49,7 @@ import javax.security.auth.callback.Call
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
+import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Iterator;
@@ -148,6 +149,9 @@ public class SAMLUtil {
certs[0] = cert;
return new SAMLKeyInfo(assertion, certs);
}
+ } else if (ki.containsKeyValue()) {
+ PublicKey pk = ki.getPublicKey();
+ return new SAMLKeyInfo(assertion, pk);
}
} catch (XMLSecurityException e3) {
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java Sat Sep 18 14:04:04 2010
@@ -42,6 +42,7 @@ import org.opensaml.SAMLSubjectStatement
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
@@ -237,6 +238,7 @@ public class WSSecSignatureSAML extends
wsDocInfo = new WSDocInfo(doc);
X509Certificate[] certs = null;
+ PublicKey publicKey = null;
if (senderVouches) {
certs = issuerCrypto.getCertificates(issuerKeyName);
@@ -272,6 +274,8 @@ public class WSSecSignatureSAML extends
certs = new X509Certificate[1];
certs[0] = cert;
}
+ } else if (ki.containsKeyValue()) {
+ publicKey = ki.getPublicKey();
}
// TODO: get alias name for cert, check against username set by
// caller
@@ -285,15 +289,24 @@ public class WSSecSignatureSAML extends
}
wsDocInfo.setCrypto(userCrypto);
}
- if (certs == null || certs.length <= 0) {
+ if ((certs == null || certs.length == 0 || certs[0] == null)
+ && publicKey == null) {
throw new WSSecurityException(
WSSecurityException.FAILURE,
"noCertsFound",
new Object[] { "SAML signature" }
);
}
+
if (sigAlgo == null) {
- String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
+ PublicKey key = null;
+ if (certs != null && certs[0] != null) {
+ key = certs[0].getPublicKey();
+ } else if (publicKey != null) {
+ key = publicKey;
+ }
+
+ String pubKeyAlgo = key.getAlgorithm();
log.debug("automatic sig algo detection: " + pubKeyAlgo);
if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
sigAlgo = WSConstants.DSA;
@@ -330,7 +343,10 @@ public class WSSecSignatureSAML extends
secRef = new SecurityTokenReference(doc);
strUri = wssConfig.getIdAllocator().createSecureId("STRId-", secRef);
secRef.setID(strUri);
- certUri = wssConfig.getIdAllocator().createSecureId("CertId-", certs[0]);
+
+ if (certs != null && certs.length != 0) {
+ certUri = wssConfig.getIdAllocator().createSecureId("CertId-", certs[0]);
+ }
//
// If the sender vouches, then we must sign the SAML token _and_ at
Modified: webservices/wss4j/trunk/test/saml4.properties
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/saml4.properties?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/saml4.properties (original)
+++ webservices/wss4j/trunk/test/saml4.properties Sat Sep 18 14:04:04 2010
@@ -3,6 +3,7 @@ org.apache.ws.security.saml.issuer.crypt
org.apache.ws.security.saml.issuer.key.name=16c73ab6-b892-458f-abf5-2f875f74882e
org.apache.ws.security.saml.issuer.key.password=security
org.apache.ws.security.saml.issuer=www.example.com
+org.apache.ws.security.saml.issuer.sendKeyValue=false
org.apache.ws.security.saml.subjectNameId.name=uid=joe,ou=people,ou=saml-demo,o=example.com
org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com
org.apache.ws.security.saml.authenticationMethod=password
Added: webservices/wss4j/trunk/test/saml4sendKeyValue.properties
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/saml4sendKeyValue.properties?rev=998472&view=auto
==============================================================================
--- webservices/wss4j/trunk/test/saml4sendKeyValue.properties (added)
+++ webservices/wss4j/trunk/test/saml4sendKeyValue.properties Sat Sep 18 14:04:04 2010
@@ -0,0 +1,13 @@
+org.apache.ws.security.saml.issuerClass=org.apache.ws.security.saml.SAMLIssuerImpl
+org.apache.ws.security.saml.issuer.cryptoProp.file=crypto.properties
+org.apache.ws.security.saml.issuer.key.name=16c73ab6-b892-458f-abf5-2f875f74882e
+org.apache.ws.security.saml.issuer.key.password=security
+org.apache.ws.security.saml.issuer=www.example.com
+org.apache.ws.security.saml.issuer.sendKeyValue=true
+org.apache.ws.security.saml.subjectNameId.name=uid=joe,ou=people,ou=saml-demo,o=example.com
+org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com
+org.apache.ws.security.saml.authenticationMethod=password
+#org.apache.ws.security.saml.confirmationMethod=senderVouches
+org.apache.ws.security.saml.confirmationMethod=keyHolder
+#org.apache.ws.security.saml
+#org.apache.ws.security.saml
Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java?rev=998472&r1=998471&r2=998472&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java Sat Sep 18 14:04:04 2010
@@ -136,6 +136,55 @@ public class TestWSSecurityNewST3 extend
assertTrue(receivedAssertion != null);
}
+ /**
+ * Test that creates, sends and processes a signed SAML assertion containing
+ * only key material and not an entire X509Certificate.
+ */
+ public void testSAMLSignedKeyHolderSendKeyValue() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
+
+ SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml4sendKeyValue.properties");
+ // Provide info to SAML issuer that it can construct a Holder-of-key
+ // SAML token.
+ saml.setInstanceDoc(doc);
+ saml.setUserCrypto(crypto);
+ saml.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
+ SAMLAssertion assertion = saml.newAssertion();
+
+ WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+ wsSign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
+ wsSign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
+ wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+ wsSign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ LOG.info("Before SAMLSignedKeyHolder....");
+
+ //
+ // set up for keyHolder
+ //
+ Document signedDoc = wsSign.build(doc, crypto, assertion, null, null, null, secHeader);
+ LOG.info("After SAMLSignedKeyHolder....");
+
+ String outputString =
+ org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Signed SAML message (key holder):");
+ LOG.debug(outputString);
+ }
+ assertTrue(outputString.indexOf("http://www.w3.org/2001/04/xmlenc#sha256") != -1);
+ assertTrue(outputString.indexOf("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") != -1);
+
+ List results = verify(signedDoc);
+ WSSecurityEngineResult actionResult =
+ WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+ SAMLAssertion receivedAssertion =
+ (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+ assertTrue(receivedAssertion != null);
+ }
+
/**
* Test that creates, sends and processes an signed SAML assertion using a KeyIdentifier
---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org