Author: coheigea Date: Sat Sep 18 14:01:55 2010 New Revision: 998471 URL: http://svn.apache.org/viewvc?rev=998471&view=rev Log: [WSS-240] - Support KeyValue in SAML subject - Patch applied, thanks.
Added: webservices/wss4j/branches/1_5_x-fixes/test/saml4sendKeyValue.properties Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLIssuerImpl.java webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLKeyInfo.java webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLUtil.java webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/WSSecSignatureSAML.java webservices/wss4j/branches/1_5_x-fixes/test/saml4.properties webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityNewST3.java Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java (original) +++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java Sat Sep 18 14:01:55 2010 @@ -349,6 +349,7 @@ public class SignatureProcessor implemen samlKi = SAMLUtil.getSAMLKeyInfo(samlp.getSamlTokenElement(), crypto, cb); certs = samlKi.getCerts(); secretKey = samlKi.getSecret(); + publicKey = samlKi.getPublicKey(); } } else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) { certs = secRef.getX509IssuerSerial(crypto); @@ -386,6 +387,7 @@ public class SignatureProcessor implemen samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto, cb); certs = samlKi.getCerts(); secretKey = samlKi.getSecret(); + publicKey = samlKi.getPublicKey(); } else { certs = secRef.getKeyIdentifier(crypto); } Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLIssuerImpl.java URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLIssuerImpl.java?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLIssuerImpl.java (original) +++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLIssuerImpl.java Sat Sep 18 14:01:55 2010 @@ -1,19 +1,22 @@ -/* - * Copyright 2003-2004 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 +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 * - * 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. + * 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.ws.security.saml; import org.apache.commons.logging.Log; @@ -25,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; @@ -35,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; @@ -66,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. @@ -93,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"))) { @@ -167,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/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLKeyInfo.java URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLKeyInfo.java?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLKeyInfo.java (original) +++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLKeyInfo.java Sat Sep 18 14:01:55 2010 @@ -1,23 +1,27 @@ -/* - * Copyright 20046,2007 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 +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * 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. + * 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.ws.security.saml; import org.opensaml.SAMLAssertion; +import java.security.PublicKey; import java.security.cert.X509Certificate; /** @@ -36,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; @@ -50,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/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLUtil.java URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLUtil.java?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLUtil.java (original) +++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/SAMLUtil.java Sat Sep 18 14:01:55 2010 @@ -1,20 +1,23 @@ -/* - * Copyright 2003-2008 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 +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 * - * 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. + * 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.ws.security.saml; import org.apache.commons.logging.Log; @@ -48,6 +51,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; @@ -151,8 +155,10 @@ 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) { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity", Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/WSSecSignatureSAML.java URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/WSSecSignatureSAML.java?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/WSSecSignatureSAML.java (original) +++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/saml/WSSecSignatureSAML.java Sat Sep 18 14:01:55 2010 @@ -56,6 +56,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.Set; @@ -227,6 +228,7 @@ public class WSSecSignatureSAML extends wsDocInfo = new WSDocInfo(doc); X509Certificate[] certs = null; + PublicKey publicKey = null; if (senderVouches) { certs = issuerCrypto.getCertificates(issuerKeyName); @@ -261,6 +263,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 @@ -274,7 +278,8 @@ 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", @@ -282,7 +287,14 @@ public class WSSecSignatureSAML extends ); } 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 = XMLSignature.ALGO_ID_SIGNATURE_DSA; @@ -347,7 +359,9 @@ public class WSSecSignatureSAML extends 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/branches/1_5_x-fixes/test/saml4.properties URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/saml4.properties?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/test/saml4.properties (original) +++ webservices/wss4j/branches/1_5_x-fixes/test/saml4.properties Sat Sep 18 14:01:55 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/branches/1_5_x-fixes/test/saml4sendKeyValue.properties URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/saml4sendKeyValue.properties?rev=998471&view=auto ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/test/saml4sendKeyValue.properties (added) +++ webservices/wss4j/branches/1_5_x-fixes/test/saml4sendKeyValue.properties Sat Sep 18 14:01:55 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/branches/1_5_x-fixes/test/wssec/TestWSSecurityNewST3.java URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityNewST3.java?rev=998471&r1=998470&r2=998471&view=diff ============================================================================== --- webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityNewST3.java (original) +++ webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityNewST3.java Sat Sep 18 14:01:55 2010 @@ -1,18 +1,20 @@ -/* - * Copyright 2003-2004 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 +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 * - * 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. + * 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 wssec; @@ -33,6 +35,7 @@ import org.apache.axis.configuration.Nul import org.apache.axis.message.SOAPEnvelope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ws.security.PublicKeyCallback; import org.apache.ws.security.WSConstants; import org.apache.ws.security.WSPasswordCallback; import org.apache.ws.security.WSSecurityEngine; @@ -168,6 +171,57 @@ 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 { + SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope(); + + Document doc = unsignedEnvelope.getAsDocument(); + + 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); + + Vector 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 @@ -243,6 +297,9 @@ public class TestWSSecurityNewST3 extend * for Testing we supply a fixed name here. */ pc.setPassword("security"); + } else if (callbacks[i] instanceof PublicKeyCallback) { + PublicKeyCallback pkcb = (PublicKeyCallback) callbacks[i]; + pkcb.setVerified(true); } else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); } --------------------------------------------------------------------- To unsubscribe, e-mail: wss4j-dev-unsubscr...@ws.apache.org For additional commands, e-mail: wss4j-dev-h...@ws.apache.org