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 ru...@apache.org on 2007/04/03 21:12:13 UTC
svn commit: r525249 - in /webservices/wss4j/trunk/src/org/apache/ws/security:
components/crypto/AbstractCrypto.java components/crypto/CryptoBase.java
components/crypto/Merlin.java handler/WSHandler.java
Author: ruchithf
Date: Tue Apr 3 12:12:12 2007
New Revision: 525249
URL: http://svn.apache.org/viewvc?view=rev&rev=525249
Log:
Fixed WSS-71
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/AbstractCrypto.java
webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java
webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java
webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/AbstractCrypto.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/AbstractCrypto.java?view=diff&rev=525249&r1=525248&r2=525249
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/AbstractCrypto.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/AbstractCrypto.java Tue Apr 3 12:12:12 2007
@@ -18,31 +18,15 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.util.Loader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
-import java.security.Key;
import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Arrays;
-import java.util.Enumeration;
import java.util.Properties;
-import java.util.Vector;
/**
* Created by IntelliJ IDEA.
@@ -55,7 +39,6 @@
private static Log log = LogFactory.getLog(AbstractCrypto.class);
protected static CertificateFactory certFact;
protected Properties properties = null;
- static String SKI_OID = "2.5.29.14";
/**
* Constructor
@@ -108,31 +91,25 @@
* Load the keystore
*/
try {
- load(is);
+ String provider = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.provider");
+ String passwd = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.password","security");
+ String type = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type", KeyStore.getDefaultType());
+ this.keystore = load(is, passwd, provider, type);
} finally {
is.close();
}
- }
-
- protected String
- getCryptoProvider() {
- return properties.getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
- }
- /**
- * Retrieves the alias name of the default certificate which has been
- * specified as a property. This should be the certificate that is used for
- * signature and encryption. This alias corresponds to the certificate that
- * should be used whenever KeyInfo is not poresent in a signed or
- * an encrypted message. May return null.
- *
- * @return alias name of the default X509 certificate
- */
- public String getDefaultX509Alias() {
- if (properties == null) {
- return null;
+ /**
+ * Load cacerts
+ */
+ String cacertsPath = System.getProperty("java.home") + "/lib/security/cacerts";
+ InputStream cacertsIs = new FileInputStream(cacertsPath);
+ try {
+ String cacertsPasswd = properties.getProperty("org.apache.ws.security.crypto.merlin.cacerts.password", "changeit");
+ this.cacerts = load(cacertsIs, cacertsPasswd, null, KeyStore.getDefaultType());
+ } finally {
+ cacertsIs.close();
}
- return properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
}
@@ -143,25 +120,22 @@
* @param input <code>InputStream</code> to read from
* @throws CredentialException
*/
- public void load(InputStream input) throws CredentialException {
+ public KeyStore load(InputStream input, String storepass, String provider, String type) throws CredentialException {
if (input == null) {
throw new IllegalArgumentException("input stream cannot be null");
}
+
+ KeyStore ks = null;
+
try {
- String provider = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.provider");
if (provider == null || provider.length() == 0) {
- keystore = KeyStore.getInstance
- (properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type",
- KeyStore.getDefaultType()));
+ ks = KeyStore.getInstance(type);
} else {
- keystore = KeyStore.getInstance
- (properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type",
- KeyStore.getDefaultType()), provider);
+ ks = KeyStore.getInstance(type, provider);
}
- String password =
- properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.password",
- "security");
- keystore.load(input, (password == null || password.length() == 0) ? new char[0] : password.toCharArray());
+
+
+ ks.load(input, (storepass == null || storepass.length() == 0) ? new char[0] : storepass.toCharArray());
} catch (IOException e) {
e.printStackTrace();
throw new CredentialException(3, "ioError00", e);
@@ -172,5 +146,28 @@
e.printStackTrace();
throw new CredentialException(-1, "error00", e);
}
+ return ks;
+ }
+
+
+ protected String
+ getCryptoProvider() {
+ return properties.getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
+ }
+
+ /**
+ * Retrieves the alias name of the default certificate which has been
+ * specified as a property. This should be the certificate that is used for
+ * signature and encryption. This alias corresponds to the certificate that
+ * should be used whenever KeyInfo is not poresent in a signed or
+ * an encrypted message. May return null.
+ *
+ * @return alias name of the default X509 certificate
+ */
+ public String getDefaultX509Alias() {
+ if (properties == null) {
+ return null;
+ }
+ return properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
}
}
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java?view=diff&rev=525249&r1=525248&r2=525249
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java Tue Apr 3 12:12:12 2007
@@ -20,8 +20,8 @@
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSSecurityException;
-import java.io.InputStream;
import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyStore;
@@ -31,11 +31,11 @@
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.cert.CertPath;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.util.Arrays;
@@ -56,7 +56,8 @@
protected static CertificateFactory certFact;
protected KeyStore keystore = null;
static String SKI_OID = "2.5.29.14";
-
+ protected KeyStore cacerts = null;
+
/**
* Constructor
*
@@ -324,6 +325,7 @@
return null;
}
+
/**
* Gets the list of certificates for a given alias.
* <p/>
@@ -334,20 +336,37 @@
*/
public X509Certificate[] getCertificates(String alias) throws WSSecurityException {
Certificate[] certs = null;
+ Certificate cert = null;
try {
- certs = keystore.getCertificateChain(alias);
- if (certs == null || certs.length == 0) {
- // no cert chain, so lets check if getCertificate gives us a result.
- Certificate cert = keystore.getCertificate(alias);
- if (cert == null) {
- return null;
+ if (this.keystore != null) {
+ //There's a chance that there can only be a set of trust stores
+ 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 (certs == null && cert == null && cacerts != null) {
+ // Now look into the trust stores
+ certs = cacerts.getCertificateChain(alias);
+ if (certs == null) {
+ cert = cacerts.getCertificate(alias);
+ }
+ }
+
+ if (cert != null) {
certs = new Certificate[]{cert};
+ } else if (certs == null) {
+ // At this pont we don't have certs or a cert
+ return null;
}
} catch (KeyStoreException e) {
throw new WSSecurityException(WSSecurityException.FAILURE,
- "keystore");
+ "keystore");
}
+
X509Certificate[] x509certs = new X509Certificate[certs.length];
for (int i = 0; i < certs.length; i++) {
x509certs[i] = (X509Certificate) certs[i];
@@ -488,7 +507,6 @@
public KeyStore getKeyStore() {
return this.keystore;
}
-
/**
* Lookup X509 Certificates in the keystore according to a given DN of the subject of the certificate
* <p/>
@@ -502,43 +520,16 @@
*/
public String[] getAliasesForDN(String subjectDN) throws WSSecurityException {
- // Store the aliases found
- Vector aliases = new Vector();
-
- Certificate cert = null;
// The DN to search the keystore for
Vector subjectRDN = splitAndTrim(subjectDN);
-
- // Look at every certificate in the keystore
- 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;
- }
- certs = new Certificate[]{cert};
- } else {
- cert = certs[0];
- }
- if (cert instanceof X509Certificate) {
- Vector foundRDN = splitAndTrim(((X509Certificate) cert).getSubjectDN().getName());
-
- if (subjectRDN.equals(foundRDN)) {
- aliases.add(alias);
- }
- }
- }
- } catch (KeyStoreException e) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "keystore");
+ Vector aliases = getAlias(subjectRDN, keystore);
+
+ //If we can't find the issuer in the keystore then look at cacerts
+ if(aliases.size() == 0) {
+ aliases = getAlias(subjectRDN, cacerts);
}
-
+
// Convert the vector into an array
String[] result = new String[aliases.size()];
for (int i = 0; i < aliases.size(); i++)
@@ -546,7 +537,7 @@
return result;
}
-
+
/**
* get a byte array given an array of X509 certificates.
* <p/>
@@ -695,5 +686,41 @@
}
return true;
+ }
+
+ private Vector getAlias(Vector subjectRDN, KeyStore store) throws WSSecurityException {
+ // Store the aliases found
+ Vector aliases = new Vector();
+
+ Certificate cert = null;
+
+ try {
+ for (Enumeration e = store.aliases(); e.hasMoreElements();) {
+ String alias = (String) e.nextElement();
+
+ Certificate[] certs = store.getCertificateChain(alias);
+ if (certs == null || certs.length == 0) {
+ // no cert chain, so lets check if getCertificate gives us a result.
+ cert = store.getCertificate(alias);
+ if (cert == null) {
+ return null;
+ }
+ certs = new Certificate[]{cert};
+ } else {
+ cert = certs[0];
+ }
+ if (cert instanceof X509Certificate) {
+ Vector foundRDN = splitAndTrim(((X509Certificate) cert).getSubjectDN().getName());
+
+ if (subjectRDN.equals(foundRDN)) {
+ aliases.add(alias);
+ }
+ }
+ }
+ } catch (KeyStoreException e) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "keystore");
+ }
+ return aliases;
}
}
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/Merlin.java?view=diff&rev=525249&r1=525248&r2=525249
==============================================================================
--- 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 Tue Apr 3 12:12:12 2007
@@ -32,45 +32,49 @@
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
/**
- * JDK1.4 based implementation of Crypto (uses keystore).
- * <p/>
- *
+ * JDK1.4 based implementation of Crypto (uses keystore). <p/>
+ *
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class Merlin extends AbstractCrypto {
/**
- * Constructor.
- * <p/>
- *
+ * Constructor. <p/>
+ *
* @param properties
* @throws CredentialException
* @throws IOException
*/
- public Merlin(Properties properties) throws CredentialException, IOException {
+ public Merlin(Properties properties) throws CredentialException,
+ IOException {
super(properties);
}
-
- public Merlin(Properties properties, ClassLoader loader) throws CredentialException, IOException {
- super(properties,loader);
+
+ public Merlin(Properties properties, ClassLoader loader)
+ throws CredentialException, IOException {
+ super(properties, loader);
}
/**
- * Construct an array of X509Certificate's from the byte array.
- * <p/>
- *
- * @param data The <code>byte</code> array containg the X509 data
- * @param reverse If set the first certificate in input data will
- * the last in the array
- * @return An array of X509 certificates, ordered according to
- * the reverse flag
+ * Construct an array of X509Certificate's from the byte array. <p/>
+ *
+ * @param data
+ * The <code>byte</code> array containg the X509 data
+ * @param reverse
+ * If set the first certificate in input data will the last in
+ * the array
+ * @return An array of X509 certificates, ordered according to the reverse
+ * flag
* @throws WSSecurityException
*/
public X509Certificate[] getX509Certificates(byte[] data, boolean reverse)
@@ -80,27 +84,30 @@
try {
path = getCertificateFactory().generateCertPath(in);
} catch (CertificateException e) {
- throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"parseError");
}
List l = path.getCertificates();
X509Certificate[] certs = new X509Certificate[l.size()];
Iterator iterator = l.iterator();
for (int i = 0; i < l.size(); i++) {
- certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate) iterator.next();
+ certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate) iterator
+ .next();
}
return certs;
}
/**
- * get a byte array given an array of X509 certificates.
- * <p/>
- *
- * @param reverse If set the first certificate in the array data will
- * the last in the byte array
- * @param certs The certificates to convert
- * @return The byte array for the certficates ordered according
- * to the reverse flag
+ * get a byte array given an array of X509 certificates. <p/>
+ *
+ * @param reverse
+ * If set the first certificate in the array data will the last
+ * in the byte array
+ * @param certs
+ * The certificates to convert
+ * @return The byte array for the certficates ordered according to the
+ * reverse flag
* @throws WSSecurityException
*/
public byte[] getCertificateData(boolean reverse, X509Certificate[] certs)
@@ -117,77 +124,89 @@
CertPath path = getCertificateFactory().generateCertPath(list);
return path.getEncoded();
} catch (CertificateEncodingException e) {
- throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"encodeError");
} catch (CertificateException e) {
- throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"parseError");
}
}
-
- /**
- * Overridden because there's a bug in the base class where they don't use
- * the provider variant for the certificate validator.
- *
- * @param certs
- * Certificate chain to validate
- * @return true if the certificate chain is valid, false otherwise
- * @throws WSSecurityException
- */
public boolean validateCertPath(X509Certificate[] certs)
- throws WSSecurityException {
- try {
- // Generate cert path
- java.util.List certList = java.util.Arrays.asList(certs);
- CertPath path = this.getCertificateFactory().generateCertPath(
- certList);
-
- // Use the certificates in the keystore as TrustAnchors
- PKIXParameters param = new PKIXParameters(this.keystore);
-
- // Do not check a revocation list
- param.setRevocationEnabled(false);
-
- // Verify the trust path using the above settings
- String provider = properties
- .getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
- CertPathValidator certPathValidator;
- if (provider == null || provider.length() == 0) {
- certPathValidator = CertPathValidator.getInstance("PKIX");
- } else {
- certPathValidator = CertPathValidator.getInstance("PKIX",
- provider);
- }
- certPathValidator.validate(path, param);
- } catch (NoSuchProviderException ex) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "certpath", new Object[] { ex.getMessage() },
- (Throwable) ex);
- } catch (NoSuchAlgorithmException ex) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "certpath", new Object[] { ex.getMessage() },
- (Throwable) ex);
- } catch (CertificateException ex) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "certpath", new Object[] { ex.getMessage() },
- (Throwable) ex);
- } catch (InvalidAlgorithmParameterException ex) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "certpath", new Object[] { ex.getMessage() },
- (Throwable) ex);
- } catch (CertPathValidatorException ex) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "certpath", new Object[] { ex.getMessage() },
- (Throwable) ex);
- } catch (KeyStoreException ex) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "certpath", new Object[] { ex.getMessage() },
- (Throwable) ex);
- }
+ throws WSSecurityException {
+ try {
+ // Generate cert path
+ java.util.List certList = java.util.Arrays.asList(certs);
+ CertPath path = this.getCertificateFactory().generateCertPath(
+ certList);
+
+ HashSet set = new HashSet();
+
+ Enumeration cacertsAliases = this.cacerts.aliases();
+ while (cacertsAliases.hasMoreElements()) {
+ String alias = (String) cacertsAliases.nextElement();
+ X509Certificate cert = (X509Certificate) this.cacerts
+ .getCertificate(alias);
+ TrustAnchor anchor = new TrustAnchor(cert, cert
+ .getExtensionValue("NameConstraints"));
+ set.add(anchor);
+ }
- return true;
- }
-}
+ // Add certificates from the keystore
+ Enumeration aliases = this.keystore.aliases();
+ while (aliases.hasMoreElements()) {
+ String alias = (String) aliases.nextElement();
+ X509Certificate cert = (X509Certificate) this.keystore
+ .getCertificate(alias);
+ TrustAnchor anchor = new TrustAnchor(cert, cert
+ .getExtensionValue("NameConstraints"));
+ set.add(anchor);
+ }
+
+ PKIXParameters param = new PKIXParameters(set);
+
+ // Do not check a revocation list
+ param.setRevocationEnabled(false);
+ // Verify the trust path using the above settings
+ String provider = properties
+ .getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
+ CertPathValidator certPathValidator;
+ if (provider == null || provider.length() == 0) {
+ certPathValidator = CertPathValidator.getInstance("PKIX");
+ } else {
+ certPathValidator = CertPathValidator.getInstance("PKIX",
+ provider);
+ }
+ certPathValidator.validate(path, param);
+ } catch (NoSuchProviderException ex) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "certpath", new Object[] { ex.getMessage() },
+ (Throwable) ex);
+ } catch (NoSuchAlgorithmException ex) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "certpath", new Object[] { ex.getMessage() },
+ (Throwable) ex);
+ } catch (CertificateException ex) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "certpath", new Object[] { ex.getMessage() },
+ (Throwable) ex);
+ } catch (InvalidAlgorithmParameterException ex) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "certpath", new Object[] { ex.getMessage() },
+ (Throwable) ex);
+ } catch (CertPathValidatorException ex) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "certpath", new Object[] { ex.getMessage() },
+ (Throwable) ex);
+ } catch (KeyStoreException ex) {
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "certpath", new Object[] { ex.getMessage() },
+ (Throwable) ex);
+ }
+ return true;
+ }
+}
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java?view=diff&rev=525249&r1=525248&r2=525249
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java Tue Apr 3 12:12:12 2007
@@ -1013,19 +1013,6 @@
throw new WSSecurityException("WSHandler: Could not get certificates for alias " + alias);
}
- // Form a certificate chain from the transmitted certificate
- // and the certificate(s) of the issuer from the keystore
- // First, create new array
- X509Certificate[] x509certs = new X509Certificate[certs.length + 1];
- // Then add the first certificate ...
- x509certs[0] = cert;
- // ... and the other certificates
- for (int j = 0; j < certs.length; j++) {
- cert = certs[i];
- x509certs[certs.length + j] = cert;
- }
- certs = x509certs;
-
// Use the validation method from the crypto to check whether the subjects certificate was really signed by the issuer stated in the certificate
try {
if (reqData.getSigCrypto().validateCertPath(certs)) {
---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org