Author: coheigea
Date: Fri Mar 6 17:58:38 2009
New Revision: 751008
URL: http://svn.apache.org/viewvc?rev=751008&view=rev
Log:
[WSS-156] - Better testing + added a "PublicKeyCallback" for trust verification
of sorts.
Added:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
(with props)
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java
Added: webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java?rev=751008&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
(added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
Fri Mar 6 17:58:38 2009
@@ -0,0 +1,93 @@
+/*
+ * 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 org.apache.ws.security;
+
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
+import javax.security.auth.callback.Callback;
+
+
+/**
+ */
+public class PublicKeyCallback implements Callback {
+
+ private java.security.PublicKey publicKey;
+
+ public PublicKeyCallback(java.security.PublicKey publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public void setPublicKey(java.security.PublicKey publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public java.security.PublicKey getPublicKey() {
+ return publicKey;
+ }
+
+ /**
+ * Evaluate whether a given public key should be trusted.
+ * Essentially, this amounts to checking to see if there is a certificate
in the keystore,
+ * whose public key matches the transmitted public key.
+ */
+ public boolean verifyTrust(
+ java.security.KeyStore keyStore
+ ) throws WSSecurityException {
+ //
+ // If the public key is null, do not trust the signature
+ //
+ if (publicKey == null || keyStore == null) {
+ return false;
+ }
+
+ //
+ // Search the keystore for the transmitted public key (direct trust)
+ //
+ try {
+ for (Enumeration e = keyStore.aliases(); e.hasMoreElements();) {
+ String alias = (String) e.nextElement();
+ Certificate[] certs = keyStore.getCertificateChain(alias);
+ Certificate cert;
+ if (certs == null || certs.length == 0) {
+ // no cert chain, so lets check if getCertificate gives us
a result.
+ cert = keyStore.getCertificate(alias);
+ if (cert == null) {
+ continue;
+ }
+ } else {
+ cert = certs[0];
+ }
+ if (!(cert instanceof X509Certificate)) {
+ continue;
+ }
+ X509Certificate x509cert = (X509Certificate) cert;
+ if (publicKey.equals(x509cert.getPublicKey())) {
+ return true;
+ }
+ }
+ } catch (KeyStoreException e) {
+ return false;
+ }
+ return false;
+ }
+}
+
+
Propchange:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=751008&r1=751007&r2=751008&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
Fri Mar 6 17:58:38 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.PublicKeyCallback;
import org.apache.ws.security.PublicKeyPrincipal;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDerivedKeyTokenPrincipal;
@@ -89,6 +90,7 @@
Set protectedElements = new java.util.TreeSet();
byte[][] signatureValue = new byte[1][];
Principal lastPrincipalFound = null;
+
try {
lastPrincipalFound =
verifyXMLSignature(
@@ -387,6 +389,21 @@
);
}
}
+ //
+ // Delegate verification of a public key to a Callback Handler
+ //
+ if (publicKey != null) {
+ PublicKeyCallback pwcb =
+ new PublicKeyCallback(publicKey);
+ try {
+ Callback[] callbacks = new Callback[]{pwcb};
+ cb.handle(callbacks);
+ } catch (Exception e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+ );
+ }
+ }
try {
boolean signatureOk = false;
if (certs != null) {
@@ -422,7 +439,7 @@
);
}
String uri = siRef.getURI();
- if(uri != null && !"".equals(uri)) {
+ if (uri != null && !"".equals(uri)) {
Element se =
WSSecurityUtil.getElementByWsuId(elem.getOwnerDocument(), uri);
if (se == null) {
se =
WSSecurityUtil.getElementByGenId(elem.getOwnerDocument(), uri);
@@ -517,6 +534,7 @@
return null;
}
+
/**
* Checks the <code>element</code> and creates appropriate binary security
object.
*
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
(original)
+++
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
Fri Mar 6 17:58:38 2009
@@ -52,8 +52,10 @@
handleCustomPasswordTypes = wsc.getHandleCustomPasswordTypes();
Principal lastPrincipalFound = handleUsernameToken((Element) elem, cb);
- returnResults.add(0, new WSSecurityEngineResult(WSConstants.UT,
- lastPrincipalFound, null, null, null));
+ returnResults.add(
+ 0,
+ new WSSecurityEngineResult(WSConstants.UT, lastPrincipalFound,
null, null, null)
+ );
utId = ut.getID();
}
Modified: webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java (original)
+++ webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java Fri Mar 6
17:58:38 2009
@@ -27,9 +27,9 @@
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.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;
@@ -39,13 +39,14 @@
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;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
/**
* 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
@@ -68,6 +69,7 @@
private WSSecurityEngine secEngine = new WSSecurityEngine();
private Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");
+ private java.security.KeyStore keyStore = null;
private MessageContext msgContext;
private SOAPEnvelope unsignedEnvelope;
@@ -79,6 +81,7 @@
*/
public SignatureKeyValueTest(String name) {
super(name);
+ keyStore = crypto.getKeyStore();
}
/**
@@ -147,8 +150,41 @@
java.security.PublicKey publicKey =
((PublicKeyPrincipal)principal).getPublicKey();
assertTrue(publicKey instanceof java.security.interfaces.RSAPublicKey);
+
+ }
+
+
+ /**
+ * Failed RSAKeyValue test, where a message is signed using a key-pair
which doesn't
+ * correspond to the public key in the "trust"-store.
+ */
+ public void testBadRSAKeyValue() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("wss86", "security");
+ builder.setKeyIdentifierType(WSConstants.KEY_VALUE);
+ Document doc = unsignedEnvelope.getAsDocument();
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc =
+ builder.build(doc, CryptoFactory.getInstance("wss86.properties"),
secHeader);
+
+ String outputString =
+
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(outputString);
+ }
+ assertTrue(outputString.indexOf("RSAKeyValue") != -1);
+
+ try {
+ verify(signedDoc);
+ fail("Failure expected on bad public key");
+ } catch (Exception ex) {
+ // expected
+ }
+
}
+
/**
* Successful DSAKeyValue test.
*/
@@ -192,22 +228,20 @@
private java.util.Vector verify(Document doc) throws Exception {
return secEngine.processSecurityHeader(doc, null, this, null);
}
-
- public void handle(Callback[] callbacks)
+
+ 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");
+ if (callbacks[i] instanceof PublicKeyCallback) {
+ PublicKeyCallback pc = (PublicKeyCallback) callbacks[i];
+ java.security.PublicKey publicKey = pc.getPublicKey();
+ if (publicKey == null || !pc.verifyTrust(keyStore)) {
+ throw new IOException("Authentication of public key
failed");
+ }
} else {
throw new UnsupportedCallbackException(callbacks[i],
"Unrecognized Callback");
}
}
}
+
}
Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java Fri Mar 6
17:58:38 2009
@@ -35,7 +35,6 @@
import org.apache.ws.security.message.WSSecEncrypt;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.message.WSSecHeader;
-import org.apache.xml.security.utils.RFC2253Parser;
import org.w3c.dom.Document;
import javax.security.auth.callback.Callback;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]