Author: coheigea
Date: Wed Mar 4 12:04:49 2009
New Revision: 749972
URL: http://svn.apache.org/viewvc?rev=749972&view=rev
Log:
[WSS-156] - Add support for transmitting a public key via
ds:KeyInfo/ds:KeyValue when signing
- Support for both RSAKeyValue and DSAKeyValue added
- I took the approach that the key itself is extracted from the configured
KeyStore, rather than just passing it into WSSecSignature.
- Note that the problem of verifying the identity of the initiator is left up
to the user.
Added:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java
(with props)
webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java (with props)
Removed:
webservices/wss4j/trunk/keys/.keystore
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
webservices/wss4j/trunk/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
webservices/wss4j/trunk/test/crypto.properties
webservices/wss4j/trunk/test/nofile.properties
webservices/wss4j/trunk/test/wss86.properties
webservices/wss4j/trunk/test/wssec/PackageTests.java
webservices/wss4j/trunk/test/wssec/TestWSSecurityNew3.java
Added:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java?rev=749972&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java
(added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java
Wed Mar 4 12:04:49 2009
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004,2005 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.ws.security;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.security.PublicKey;
+
+/**
+ * This class encapsulates a principal defined by a Public Key. In particular,
this class
+ * is used for the ds:KeyInfo/ds:KeyValue case in the SignatureProcessor.
+ */
+public class PublicKeyPrincipal implements Principal, Serializable {
+
+ private PublicKey publicKey;
+
+ public PublicKeyPrincipal(PublicKey publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public PublicKey getPublicKey() {
+ return publicKey;
+ }
+
+ public String getName() {
+ return publicKey.toString();
+ }
+
+ public void setPublicKey(PublicKey publicKey) {
+ this.publicKey = publicKey;
+ }
+
+}
Propchange:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyPrincipal.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java Wed Mar
4 12:04:49 2009
@@ -396,6 +396,12 @@
public static final int CUSTOM_KEY_IDENTIFIER = 12;
+ /**
+ * <code>KEY_VALUE</code> is used to set a ds:KeyInfo/ds:KeyValue element
to refer to
+ * either an RSA or DSA public key.
+ */
+ public static final int KEY_VALUE = 13;
+
public static final String ENCRYPTED_HEADER = "EncryptedHeader";
/*
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java
(original)
+++
webservices/wss4j/trunk/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java
Wed Mar 4 12:04:49 2009
@@ -21,7 +21,7 @@
/**
* This class implements the <code>Principal</code> interface and
* represents a <code>DerivedKeyToken</code>.
- * The principal's name will be the <code>wsu:Id</code> valud of the
+ * The principal's name will be the <code>wsu:Id</code> value of the
* <code>DerivedKeyToken</code>
*
* @author Ruchith Fernando ([email protected])
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java
(original)
+++
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java
Wed Mar 4 12:04:49 2009
@@ -40,6 +40,8 @@
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+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.apache.xml.security.signature.XMLSignatureException;
import org.apache.xml.security.transforms.TransformationException;
@@ -116,7 +118,7 @@
private String customTokenId;
private String digestAlgo = "http://www.w3.org/2000/09/xmldsig#sha1";
-
+
/**
* Constructor.
*/
@@ -442,12 +444,29 @@
case WSConstants.CUSTOM_KEY_IDENTIFIER:
secRef.setKeyIdentifier(customTokenValueType, customTokenId);
break;
-
+ case WSConstants.KEY_VALUE:
+ java.security.PublicKey publicKey = certs[0].getPublicKey();
+ String pubKeyAlgo = publicKey.getAlgorithm();
+ if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+ DSAKeyValue dsaKeyValue = new DSAKeyValue(document, publicKey);
+ keyInfo.add(dsaKeyValue);
+ } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
+ RSAKeyValue rsaKeyValue = new RSAKeyValue(document, publicKey);
+ keyInfo.add(rsaKeyValue);
+ } else {
+ throw new WSSecurityException(
+ WSSecurityException.FAILURE,
+ "unknownSignatureAlgorithm",
+ new Object[] {pubKeyAlgo}
+ );
+ }
+ break;
default:
throw new WSSecurityException(WSSecurityException.FAILURE,
"unsupportedKeyId");
}
- keyInfo.addUnknownElement(secRef.getElement());
-
+ if (keyIdentifierType != WSConstants.KEY_VALUE) {
+ keyInfo.addUnknownElement(secRef.getElement());
+ }
}
/**
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=749972&r1=749971&r2=749972&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
Wed Mar 4 12:04:49 2009
@@ -21,6 +21,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.CustomTokenPrincipal;
+import org.apache.ws.security.PublicKeyPrincipal;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDerivedKeyTokenPrincipal;
import org.apache.ws.security.WSDocInfo;
@@ -200,8 +201,15 @@
DerivedKeyToken dkt = null;
SAMLKeyInfo samlKi = null;
String customTokenId = null;
+ java.security.PublicKey publicKey = null;
- if (info != null) {
+ if (info != null && info.containsKeyValue()) {
+ try {
+ publicKey = info.getPublicKey();
+ } catch (Exception ex) {
+ throw new WSSecurityException(ex.getMessage(), ex);
+ }
+ } else if (info != null) {
Node node =
WSSecurityUtil.getDirectChild(
info.getElement(),
@@ -361,7 +369,9 @@
if (tlog.isDebugEnabled()) {
t1 = System.currentTimeMillis();
}
- if ((certs == null || certs.length == 0 || certs[0] == null) &&
secretKey == null) {
+ if ((certs == null || certs.length == 0 || certs[0] == null)
+ && secretKey == null
+ && publicKey == null) {
throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
}
if (certs != null) {
@@ -381,6 +391,8 @@
boolean signatureOk = false;
if (certs != null) {
signatureOk = sig.checkSignatureValue(certs[0]);
+ } else if (publicKey != null) {
+ signatureOk = sig.checkSignatureValue(publicKey);
} else {
signatureOk =
sig.checkSignatureValue(sig.createSecretKey(secretKey));
}
@@ -431,7 +443,9 @@
if (certs != null) {
returnCert[0] = certs[0];
return certs[0].getSubjectDN();
- } else if (ut != null){
+ } else if (publicKey != null) {
+ return new PublicKeyPrincipal(publicKey);
+ } else if (ut != null) {
WSUsernameTokenPrincipal principal =
new WSUsernameTokenPrincipal(ut.getName(),
ut.isHashed());
principal.setNonce(ut.getNonce());
Modified: webservices/wss4j/trunk/test/crypto.properties
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/crypto.properties?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/crypto.properties (original)
+++ webservices/wss4j/trunk/test/crypto.properties Wed Mar 4 12:04:49 2009
@@ -2,5 +2,4 @@
org.apache.ws.security.crypto.merlin.keystore.type=pkcs12
org.apache.ws.security.crypto.merlin.keystore.password=security
org.apache.ws.security.crypto.merlin.keystore.alias=16c73ab6-b892-458f-abf5-2f875f74882e
-org.apache.ws.security.crypto.merlin.alias.password=security
org.apache.ws.security.crypto.merlin.file=keys/x509.PFX.MSFT
Modified: webservices/wss4j/trunk/test/nofile.properties
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/nofile.properties?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/nofile.properties (original)
+++ webservices/wss4j/trunk/test/nofile.properties Wed Mar 4 12:04:49 2009
@@ -2,4 +2,3 @@
org.apache.ws.security.crypto.merlin.keystore.type=pkcs12
org.apache.ws.security.crypto.merlin.keystore.password=security
org.apache.ws.security.crypto.merlin.keystore.alias=16c73ab6-b892-458f-abf5-2f875f74882e
-org.apache.ws.security.crypto.merlin.alias.password=security
Modified: webservices/wss4j/trunk/test/wss86.properties
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wss86.properties?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wss86.properties (original)
+++ webservices/wss4j/trunk/test/wss86.properties Wed Mar 4 12:04:49 2009
@@ -2,5 +2,4 @@
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=security
org.apache.ws.security.crypto.merlin.keystore.alias=wss86
-org.apache.ws.security.crypto.merlin.alias.password=security
org.apache.ws.security.crypto.merlin.file=keys/wss86.keystore
Modified: webservices/wss4j/trunk/test/wssec/PackageTests.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/PackageTests.java?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/PackageTests.java (original)
+++ webservices/wss4j/trunk/test/wssec/PackageTests.java Wed Mar 4 12:04:49
2009
@@ -82,6 +82,7 @@
suite.addTestSuite(TestWSSecurityWSS86.class);
suite.addTestSuite(TestWSSecurityKerberosTokenProfile.class);
suite.addTestSuite(TestWSSecurityTimestamp.class);
+ suite.addTestSuite(SignatureKeyValueTest.class);
return suite;
}
Added: webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java?rev=749972&view=auto
==============================================================================
--- webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java (added)
+++ webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java Wed Mar 4
12:04:49 2009
@@ -0,0 +1,213 @@
+/*
+ * 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
+ *
+ * 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;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.PublicKeyPrincipal;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This class tests signing where the the public key is transmitted in the
message via
+ * a ds:KeyInfo/ds:KeyValue element. Although this isn't strictly recommended
for use in
+ * WS-Security, it's necessary to support it for WCF interop.
+ */
+public class SignatureKeyValueTest extends TestCase implements CallbackHandler
{
+ private static final Log LOG =
LogFactory.getLog(SignatureKeyValueTest.class);
+ private static final String SOAPMSG =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<SOAP-ENV:Envelope "
+ + "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+ + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + "<SOAP-ENV:Body>"
+ + "<add
xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
+ + "<value xmlns=\"\">15</value>"
+ + "</add>"
+ + "</SOAP-ENV:Body>"
+ + "</SOAP-ENV:Envelope>";
+
+ private WSSecurityEngine secEngine = new WSSecurityEngine();
+ private Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");
+ private MessageContext msgContext;
+ private SOAPEnvelope unsignedEnvelope;
+
+ /**
+ * TestWSSecurity constructor
+ * <p/>
+ *
+ * @param name name of the test
+ */
+ public SignatureKeyValueTest(String name) {
+ super(name);
+ }
+
+ /**
+ * JUnit suite
+ * <p/>
+ *
+ * @return a junit test suite
+ */
+ public static Test suite() {
+ return new TestSuite(SignatureKeyValueTest.class);
+ }
+
+ /**
+ * Setup method
+ * <p/>
+ *
+ * @throws java.lang.Exception Thrown when there is a problem in setup
+ */
+ protected void setUp() throws Exception {
+ AxisClient tmpEngine = new AxisClient(new NullProvider());
+ msgContext = new MessageContext(tmpEngine);
+ unsignedEnvelope = getSOAPEnvelope();
+ }
+
+ /**
+ * Constructs a soap envelope
+ * <p/>
+ *
+ * @return soap envelope
+ * @throws java.lang.Exception if there is any problem constructing the
soap envelope
+ */
+ protected SOAPEnvelope getSOAPEnvelope() throws Exception {
+ InputStream in = new ByteArrayInputStream(SOAPMSG.getBytes());
+ Message msg = new Message(in);
+ msg.setMessageContext(msgContext);
+ return msg.getSOAPEnvelope();
+ }
+
+ /**
+ * Successful RSAKeyValue test.
+ */
+ public void testRSAKeyValue() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("wss4jcert", "security");
+ builder.setKeyIdentifierType(WSConstants.KEY_VALUE);
+ Document doc = unsignedEnvelope.getAsDocument();
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ String outputString =
+
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(outputString);
+ }
+ assertTrue(outputString.indexOf("RSAKeyValue") != -1);
+
+ final java.util.Vector results = verify(signedDoc);
+ WSSecurityEngineResult actionResult =
+ WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
+ assertTrue(actionResult != null);
+
+ java.security.Principal principal =
+
(java.security.Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+ assertTrue(principal instanceof PublicKeyPrincipal);
+ java.security.PublicKey publicKey =
+ ((PublicKeyPrincipal)principal).getPublicKey();
+ assertTrue(publicKey instanceof java.security.interfaces.RSAPublicKey);
+ }
+
+ /**
+ * Successful DSAKeyValue test.
+ */
+ public void testDSAKeyValue() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("wss4jcertdsa", "security");
+ builder.setKeyIdentifierType(WSConstants.KEY_VALUE);
+ Document doc = unsignedEnvelope.getAsDocument();
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ String outputString =
+
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(outputString);
+ }
+ assertTrue(outputString.indexOf("DSAKeyValue") != -1);
+
+ final java.util.Vector results = verify(signedDoc);
+ WSSecurityEngineResult actionResult =
+ WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
+ assertTrue(actionResult != null);
+
+ java.security.Principal principal =
+
(java.security.Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+ assertTrue(principal instanceof PublicKeyPrincipal);
+ java.security.PublicKey publicKey =
+ ((PublicKeyPrincipal)principal).getPublicKey();
+ assertTrue(publicKey instanceof java.security.interfaces.DSAPublicKey);
+ }
+
+
+ /**
+ * Verifies the soap envelope
+ * <p/>
+ *
+ * @param env soap envelope
+ * @throws java.lang.Exception Thrown when there is a problem in
verification
+ */
+ private java.util.Vector verify(Document doc) throws Exception {
+ return secEngine.processSecurityHeader(doc, null, this, null);
+ }
+
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ if (callbacks[i] instanceof WSPasswordCallback) {
+ WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+ /*
+ * here call a function/method to lookup the password for
+ * the given identifier (e.g. a user name or keystore alias)
+ * e.g.:
pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+ * for Testing we supply a fixed name here.
+ */
+ pc.setPassword("password");
+ } else {
+ throw new UnsupportedCallbackException(callbacks[i],
"Unrecognized Callback");
+ }
+ }
+ }
+}
Propchange: webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNew3.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityNew3.java?rev=749972&r1=749971&r2=749972&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNew3.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNew3.java Wed Mar 4
12:04:49 2009
@@ -127,7 +127,7 @@
Document doc = unsignedEnvelope.getAsDocument();
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
- Document signedDoc = builder.build(doc, CryptoFactory.getInstance(),
secHeader);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
LOG.info("After Signing....");
verify(signedDoc);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]