You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fx-dev@ws.apache.org by we...@apache.org on 2005/09/10 21:41:30 UTC
svn commit: r280033 - in
/webservices/wss4j/trunk/src/org/apache/ws/security: ./ components/crypto/
handler/ message/ message/token/
Author: werner
Date: Sat Sep 10 12:41:18 2005
New Revision: 280033
URL: http://svn.apache.org/viewcvs?rev=280033&view=rev
Log:
Implment the WSS 1.1 Thumprint key identifier.
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Crypto.java
webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java
webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/errors.properties
webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandlerConstants.java
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSEncryptBody.java
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSignEnvelope.java
webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java Sat Sep 10 12:41:18 2005
@@ -36,18 +36,28 @@
/*
* The base UIRs for the various profiles.
- * No new base URIs in WSS specification 1.1
*/
public static final String SOAPMESSAGE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0";
- public static final String USERNAMETOKEN_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0";
+ public static final String SOAPMESSAGE_NS11 = "http://docs.oasis-open.org/wss/2004/xx/oasis-2004xx-wss-soap-message-security-1.0";
+ public static final String USERNAMETOKEN_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.1";
public static final String X509TOKEN_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0";
-
+ public static final String SAMLTOKEN_NS = "http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0";
/*
* The Element name (local name) of the security header
*/
public static final String WSSE_LN = "Security";
/*
+ * The Thumbprint relative URI string (without #)
+ * Combine it with SOAPMESSAGE_NS11, #, to get the full URL
+ */
+ public static final String THUMBPRINT ="ThumbprintSHA1";
+
+ /*
+ * The SAMLAssertionID relative URI string (without #)
+ */
+ public static final String SAML_ASSERTION_ID = "SAMLAssertionID";
+ /*
* The namespace prefixes used. We uses the same prefix convention
* as shown in the specifications
*/
@@ -306,6 +316,17 @@
* to WS-Trust specification.
*/
public static final int UT_SIGNING = 7;
+
+ /**
+ * <code>THUMPRINT_IDENTIFIER</code> is used to set the specific key identifier
+ * ThumbprintSHA1.
+ *
+ * This identifier uses the SHA-1 digest of a security token to
+ * identify the security token. Please refer to chapter 7.2 of the OASIS WSS 1.1
+ * specification.
+ *
+ */
+ public static final int THUMBPRINT_IDENTIFIER = 8;
/*
* The following values are bits that can be combined to for a set.
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Crypto.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Crypto.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Crypto.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Crypto.java Sat Sep 10 12:41:18 2005
@@ -172,7 +172,23 @@
* @return The byte array conating the binary SKI data
*/
public byte[] getSKIBytesFromCert(X509Certificate cert) throws WSSecurityException;
+
+ /**
+ * Lookup a X509 Certificate in the keystore according to a given
+ * Thumbprint.
+ *
+ * The search gets all alias names of the keystore, then reads the certificate chain
+ * or certificate for each alias. Then the thumbprint for each user certificate
+ * is compared with the thumbprint parameter.
+ *
+ * @param thumb The SHA1 thumbprint info bytes
+ * @return alias name of the certificate that matches the thumbprint
+ * or null if no such certificate was found.
+ * @throws WSSecurityException if problems during keystore handling or wrong certificate
+ */
+ public String getAliasForX509CertThumb(byte[] thumb) throws WSSecurityException;
+
/**
* Gets the Keystore that was loaded by the underlying implementation
*
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java Sat Sep 10 12:41:18 2005
@@ -24,6 +24,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
@@ -55,6 +56,7 @@
import java.util.List;
import java.util.Properties;
import java.util.Vector;
+import java.util.Arrays;
/**
* JDK1.4 based implementation of Crypto (uses keystore).
@@ -390,14 +392,7 @@
if (data.length != skiBytes.length) {
continue;
}
- for (int ii = 0; ii < data.length; ii++) {
- if (data[ii] != skiBytes[ii]) {
- found = false;
- break;
- }
- found = true;
- }
- if (found) {
+ if (Arrays.equals(data, skiBytes)) {
return alias;
}
}
@@ -487,6 +482,68 @@
x509certs[i] = (X509Certificate) certs[i];
}
return x509certs;
+ }
+
+ /**
+ * Lookup a X509 Certificate in the keystore according to a given
+ * Thumbprint.
+ *
+ * The search gets all alias names of the keystore, then reads the certificate chain
+ * or certificate for each alias. Then the thumbprint for each user certificate
+ * is compared with the thumbprint parameter.
+ *
+ * @param thumb The SHA1 thumbprint info bytes
+ * @return alias name of the certificate that matches the thumbprint
+ * or null if no such certificate was found.
+ * @throws WSSecurityException if problems during keystore handling or wrong certificate
+ */
+
+ public String getAliasForX509CertThumb(byte[] thumb) throws WSSecurityException {
+ Certificate cert = null;
+ MessageDigest sha = null;
+
+ try {
+ sha = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e1) {
+ throw new WSSecurityException(
+ 0,
+ "noSHA1availabe");
+ }
+ try {
+ for (Enumeration e = keystore.aliases(); e.hasMoreElements();) {
+ String alias = (String) e.nextElement();
+ Certificate[] certs = keystore.getCertificateChain(alias);
+ 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) {
+ return null;
+ }
+ } else {
+ cert = certs[0];
+ }
+ if (!(cert instanceof X509Certificate)) {
+ continue;
+ }
+ sha.reset();
+ try {
+ sha.update(cert.getEncoded());
+ } catch (CertificateEncodingException e1) {
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+ "encodeError");
+ }
+ byte[] data = sha.digest();
+
+ if (Arrays.equals(data, thumb)) {
+ return alias;
+ }
+ }
+ } catch (KeyStoreException e) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "keystore");
+ }
+ return null;
}
/**
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/errors.properties
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/errors.properties?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/errors.properties (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/errors.properties Sat Sep 10 12:41:18 2005
@@ -17,3 +17,4 @@
noSKIHandling = Problem with SKI information: {0}
badBase64Data = Unable to decode Base64 encoded data
badEncoding = Problem with Encoding: {0}
+noSHA1availabe = Crypto provider does not suppor1 SHA-1 digest
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java Sat Sep 10 12:41:18 2005
@@ -716,7 +716,8 @@
if (!(reqData.getSigKeyId() == WSConstants.ISSUER_SERIAL
|| reqData.getSigKeyId() == WSConstants.BST_DIRECT_REFERENCE
|| reqData.getSigKeyId() == WSConstants.X509_KEY_IDENTIFIER
- || reqData.getSigKeyId() == WSConstants.SKI_KEY_IDENTIFIER)) {
+ || reqData.getSigKeyId() == WSConstants.SKI_KEY_IDENTIFIER
+ || reqData.getSigKeyId() == WSConstants.THUMBPRINT_IDENTIFIER)) {
throw new WSSecurityException("WSHandler: Signature: illegal key identification");
}
}
@@ -770,7 +771,8 @@
|| reqData.getEncKeyId() == WSConstants.X509_KEY_IDENTIFIER
|| reqData.getEncKeyId() == WSConstants.SKI_KEY_IDENTIFIER
|| reqData.getEncKeyId() == WSConstants.BST_DIRECT_REFERENCE
- || reqData.getEncKeyId() == WSConstants.EMBEDDED_KEYNAME)) {
+ || reqData.getEncKeyId() == WSConstants.EMBEDDED_KEYNAME
+ || reqData.getSigKeyId() == WSConstants.THUMBPRINT_IDENTIFIER)) {
throw new WSSecurityException("WSHandler: Encryption: illegal key identification");
}
}
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandlerConstants.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandlerConstants.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandlerConstants.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandlerConstants.java Sat Sep 10 12:41:18 2005
@@ -314,6 +314,7 @@
/**
* Specifying this name as {@link ENCRYPTION_USER}
* triggers a special action to get the public key to use for encryption.
+ * <p/>
* The handler uses the public key of the sender's certificate. Using this
* way to define an encryption key simplifies certificate management to
* a large extend.
@@ -668,6 +669,8 @@
* </li>
* <li><code>EmbeddedKeyName</code> for {@link WSConstants#EMBEDDED_KEYNAME}
* </li>
+ * <li><code>Thumbprint</code> for {@link WSConstants#THUMBPRINT}
+ * </li>
* </ul
* See {@link #SIG_KEY_ID} {@link #ENC_KEY_ID}.
*/
@@ -684,6 +687,8 @@
new Integer(WSConstants.SKI_KEY_IDENTIFIER));
keyIdentifier.put("EmbeddedKeyName",
new Integer(WSConstants.EMBEDDED_KEYNAME));
+ keyIdentifier.put("Thumbprint",
+ new Integer(WSConstants.THUMBPRINT_IDENTIFIER));
}
/*
* internally used property names to store values inside the message context
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/message/WSEncryptBody.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSEncryptBody.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/WSEncryptBody.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/WSEncryptBody.java Sat Sep 10 12:41:18 2005
@@ -393,6 +393,10 @@
case WSConstants.SKI_KEY_IDENTIFIER:
secToken.setKeyIdentifierSKI(remoteCert, crypto);
break;
+
+ case WSConstants.THUMBPRINT_IDENTIFIER:
+ secToken.setKeyIdentifierThumb(remoteCert);
+ break;
case WSConstants.ISSUER_SERIAL:
XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, remoteCert);
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSignEnvelope.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSignEnvelope.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSignEnvelope.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSignEnvelope.java Sat Sep 10 12:41:18 2005
@@ -519,6 +519,10 @@
secretKey = usernameToken.getSecretKey();
break;
+ case WSConstants.THUMBPRINT_IDENTIFIER:
+ secRef.setKeyIdentifierThumb(certs[0]);
+ break;
+
default:
throw new WSSecurityException(WSSecurityException.FAILURE,
"unsupportedKeyId");
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java?rev=280033&r1=280032&r2=280033&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java Sat Sep 10 12:41:18 2005
@@ -32,6 +32,8 @@
import org.apache.xml.security.utils.Constants;
import org.w3c.dom.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
@@ -48,6 +50,8 @@
public static final String SECURITY_TOKEN_REFERENCE = "SecurityTokenReference";
public static final String KEY_NAME = "KeyName";
public static final String SKI_URI = WSConstants.X509TOKEN_NS + "#X509SubjectKeyIdentifier";
+ public static final String THUMB_URI = WSConstants.SOAPMESSAGE_NS11 + "#" + WSConstants.THUMBPRINT;
+ public static final String SAML_ID_URI = WSConstants.SAMLTOKEN_NS + "#" + WSConstants.SAML_ASSERTION_ID;
protected Element element = null;
private XMLX509IssuerSerial issuerSerial = null;
private byte[] skiBytes = null;
@@ -231,45 +235,74 @@
throws WSSecurityException {
Document doc = this.element.getOwnerDocument();
byte data[] = crypto.getSKIBytesFromCert(cert);
- org.w3c.dom.Text skiText = doc.createTextNode(Base64.encode(data));
- Element keyId =
- doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
- keyId.setAttributeNS(null, "ValueType", SKI_URI);
- keyId.setAttributeNS(null,
- "EncodingType",
- BinarySecurity.BASE64_ENCODING);
+
+ org.w3c.dom.Text text = doc.createTextNode(Base64.encode(data));
+ createKeyIdentifier(doc, SKI_URI, text);
+ }
- keyId.appendChild(skiText);
- Element elem = getFirstElement();
- if (elem != null) {
- this.element.replaceChild(keyId, elem);
- } else {
- this.element.appendChild(keyId);
+ /**
+ * Sets the KeyIdentifer Element as a Thumbprint.
+ *
+ * Takes a X509 certificate, computes its thumbprint using SHA-1, converts
+ * into base 64 and inserts it into a <code>wsse:KeyIdentifier</code>
+ * element, which is placed in the <code>wsse:SecurityTokenReference</code>
+ * element.
+ *
+ * @param cert
+ * is the X509 certficate to get the thumbprint
+ * @param crypto
+ * is the Crypto implementation. Used to read SKI info bytes from
+ * certificate
+ */
+ public void setKeyIdentifierThumb(X509Certificate cert)
+ throws WSSecurityException {
+ Document doc = this.element.getOwnerDocument();
+ MessageDigest sha = null;
+ try {
+ sha = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e1) {
+ throw new WSSecurityException(0, "noSHA1availabe");
}
- }
+ sha.reset();
+ try {
+ sha.update(cert.getEncoded());
+ } catch (CertificateEncodingException e1) {
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+ "encodeError");
+ }
+ byte[] data = sha.digest();
+ org.w3c.dom.Text text = doc.createTextNode(Base64.encode(data));
+ createKeyIdentifier(doc, THUMB_URI, text);
+ }
+
public void setSAMLKeyIdentifier(String keyIdVal)
throws WSSecurityException {
Document doc = this.element.getOwnerDocument();
- Element keyId =
- doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
- keyId.setAttributeNS(WSConstants.WSSE_NS,
- "ValueType",
- "http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#SAMLAssertionID");
- keyId.appendChild(doc.createTextNode(keyIdVal));
- Element elem = getFirstElement();
- if (elem != null) {
- this.element.replaceChild(keyId, elem);
- } else {
- this.element.appendChild(keyId);
- }
+ createKeyIdentifier(doc, SAML_ID_URI, doc.createTextNode(keyIdVal));
}
+ private void createKeyIdentifier(Document doc, String uri, Node node) {
+
+ Element keyId = doc.createElementNS(WSConstants.WSSE_NS,
+ "wsse:KeyIdentifier");
+ keyId.setAttributeNS(null, "ValueType", uri);
+ keyId.setAttributeNS(null, "EncodingType",
+ BinarySecurity.BASE64_ENCODING);
+
+ keyId.appendChild(node);
+ Element elem = getFirstElement();
+ if (elem != null) {
+ this.element.replaceChild(keyId, elem);
+ } else {
+ this.element.appendChild(keyId);
+ }
+ }
/**
* Gets the KeyIdentifer.
*
- * @return the {@link BinarySecurity} containing the X509
- * certificate or zero if a unknown key identifier
+ * @return the the X509 certficate or zero if a unknown key identifier
* type was detected.
*/
public X509Certificate[] getKeyIdentifier(Crypto crypto)
@@ -277,6 +310,7 @@
X509Security token = null;
Element elem = getFirstElement();
String value = elem.getAttribute("ValueType");
+ String alias = null;
if (X509Security.getType().equals(value)) {
token = new X509Security(elem);
@@ -287,10 +321,21 @@
return certs;
}
} else if (SKI_URI.equals(value)) {
- String alias = getX509SKIAlias(crypto);
- if (alias != null) {
- return crypto.getCertificates(alias);
+ alias = getX509SKIAlias(crypto);
+ }
+ else if (THUMB_URI.equals(value)) {
+ Node node = getFirstElement().getFirstChild();
+ if (node == null) {
+ return null;
}
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ byte[] thumb = Base64.decode(((Text) node).getData());
+ alias = crypto.getAliasForX509CertThumb(thumb);
+ }
+
+ }
+ if (alias != null) {
+ return crypto.getCertificates(alias);
}
return null;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org