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/03/25 15:54:33 UTC

svn commit: r522265 - in /webservices/wss4j/trunk: src/org/apache/ws/security/components/crypto/ test/wssec/

Author: ruchithf
Date: Sun Mar 25 06:54:30 2007
New Revision: 522265

URL: http://svn.apache.org/viewvc?view=rev&rev=522265
Log:
Applied the patch from Fred : https://issues.apache.org/jira/browse/WSS-45


Added:
    webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java
Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/AbstractCrypto.java
    webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoFactory.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityNew.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=522265&r1=522264&r2=522265
==============================================================================
--- 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 Sun Mar 25 06:54:30 2007
@@ -24,7 +24,6 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.math.BigInteger;
 import java.security.GeneralSecurityException;
 import java.security.Key;
 import java.security.KeyStore;
@@ -52,13 +51,12 @@
  * Time: 9:50:40 AM
  * To change this template use File | Settings | File Templates.
  */
-public abstract class AbstractCrypto implements Crypto {
+public abstract class AbstractCrypto extends CryptoBase {
     private static Log log = LogFactory.getLog(AbstractCrypto.class);
     protected static CertificateFactory certFact;
     protected Properties properties = null;
-    protected KeyStore keystore = null;
     static String SKI_OID = "2.5.29.14";
-
+    
     /**
      * Constructor
      *
@@ -76,24 +74,24 @@
      * @throws IOException
      */
     public AbstractCrypto(Properties properties, ClassLoader loader) throws CredentialException, IOException {
-        /*
-        * if no properties .. just return an instance, the rest will be
-        * done later or this instance is just used to handle certificate
-        * conversions in this implementatio
-        */
-        if (properties == null) {
-            return;
-        }
         this.properties = properties;
         String location = this.properties.getProperty("org.apache.ws.security.crypto.merlin.file");
-
-		InputStream is = null;
-		java.net.URL url = Loader.getResource(loader, location);
-		if(url != null) {
-			is =  url.openStream();
-		} else {
-			is = new java.io.FileInputStream(location);
-		}
+
+
+		InputStream is = null;
+
+		java.net.URL url = Loader.getResource(loader, location);
+
+		if(url != null) {
+
+			is =  url.openStream();
+
+		} else {
+
+			is = new java.io.FileInputStream(location);
+
+		}
+
 
         /**
          * If we don't find it, then look on the file system.
@@ -116,257 +114,9 @@
         }
     }
 
-    
-    /**
-     * Singleton certificate factory for this Crypto instance.
-     * <p/>
-     *
-     * @return Returns a <code>CertificateFactory</code> to construct
-     *         X509 certficates
-     * @throws org.apache.ws.security.WSSecurityException
-     *
-     */
-    public synchronized CertificateFactory getCertificateFactory() throws WSSecurityException {
-        if (certFact == null) {
-            try {
-                String provider = properties.getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
-                if (provider == null || provider.length() == 0) {
-                    certFact = CertificateFactory.getInstance("X.509");
-                } else {
-                    certFact = CertificateFactory.getInstance("X.509", provider);
-                }
-            } catch (CertificateException e) {
-                throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
-                        "unsupportedCertType");
-            } catch (NoSuchProviderException e) {
-                throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
-                        "noSecProvider");
-            }
-        }
-        return certFact;
-    }
-
-    /**
-     * load a X509Certificate from the input stream.
-     * <p/>
-     *
-     * @param in The <code>InputStream</code> array containg the X509 data
-     * @return Returns a X509 certificate
-     * @throws org.apache.ws.security.WSSecurityException
-     *
-     */
-    public X509Certificate loadCertificate(InputStream in) throws WSSecurityException {
-        X509Certificate cert = null;
-        try {
-            cert =
-                    (X509Certificate) getCertificateFactory().generateCertificate(in);
-        } catch (CertificateException e) {
-            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
-                    "parseError");
-        }
-        return cert;
-    }
-
-    /**
-     * Gets the private key identified by <code>alias</> and <code>password</code>.
-     * <p/>
-     *
-     * @param alias    The alias (<code>KeyStore</code>) of the key owner
-     * @param password The password needed to access the private key
-     * @return The private key
-     * @throws Exception
-     */
-    public PrivateKey getPrivateKey(String alias, String password) throws Exception {
-        if (alias == null) {
-            throw new Exception("alias is null");
-        }
-        boolean b = keystore.isKeyEntry(alias);
-        if (!b) {
-            log.error("Cannot find key for alias: " + alias);
-            throw new Exception("Cannot find key for alias: " + alias);
-        }
-        Key keyTmp = keystore.getKey(alias, password.toCharArray());
-        if (!(keyTmp instanceof PrivateKey)) {
-            throw new Exception("Key is not a private key, alias: " + alias);
-        }
-        return (PrivateKey) keyTmp;
-    }
-
-    private Vector splitAndTrim(String inString) {
-        X509NameTokenizer nmTokens = new X509NameTokenizer(inString);
-        Vector vr = new Vector();
-
-        while (nmTokens.hasMoreTokens()) {
-            vr.add(nmTokens.nextToken());
-        }
-        java.util.Collections.sort(vr);
-        return vr;
-    }
-
-    /**
-     * Lookup a X509 Certificate in the keystore according to a given
-     * the issuer of a Certficate.
-     * <p/>
-     * The search gets all alias names of the keystore and gets the certificate chain
-     * for each alias. Then the Issuer fo each certificate of the chain
-     * is compared with the parameters.
-     *
-     * @param issuer The issuer's name for the certificate
-     * @return alias name of the certificate that matches the issuer name
-     *         or null if no such certificate was found.
-     */
-    public String getAliasForX509Cert(String issuer)
-            throws WSSecurityException {
-        return getAliasForX509Cert(issuer, null, false);
-    }
-
-    /**
-     * Lookup a X509 Certificate in the keystore according to a given serial number and
-     * the issuer of a Certficate.
-     * <p/>
-     * The search gets all alias names of the keystore and gets the certificate chain
-     * for each alias. Then the SerialNumber and Issuer fo each certificate of the chain
-     * is compared with the parameters.
-     *
-     * @param issuer       The issuer's name for the certificate
-     * @param serialNumber The serial number of the certificate from the named issuer
-     * @return alias name of the certificate that matches serialNumber and issuer name
-     *         or null if no such certificate was found.
-     */
-    public String getAliasForX509Cert(String issuer, BigInteger serialNumber)
-            throws WSSecurityException {
-        return getAliasForX509Cert(issuer, serialNumber, true);
-    }
-
-    /*
-    * need to check if "getCertificateChain" also finds certificates that are
-    * used for enryption only, i.e. they may not be signed by a CA
-    * Otherwise we must define a restriction how to use certificate:
-    * each certificate must be signed by a CA or is a self signed Certificate
-    * (this should work as well).
-    * --- remains to be tested in several ways --
-    */
-    private String getAliasForX509Cert(String issuer, BigInteger serialNumber,
-                                       boolean useSerialNumber)
-            throws WSSecurityException {
-        Vector issuerRDN = splitAndTrim(issuer);
-        X509Certificate x509cert = null;
-        Vector certRDN = null;
-        Certificate cert = null;
-
-        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;
-                }
-                x509cert = (X509Certificate) cert;
-                if (!useSerialNumber ||
-                        useSerialNumber && x509cert.getSerialNumber().compareTo(serialNumber) == 0) {
-                    certRDN = splitAndTrim(x509cert.getIssuerDN().getName());
-                    if (certRDN.equals(issuerRDN)) {
-                        return alias;
-                    }
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "keystore");
-        }
-        return null;
-    }
-
-    /**
-     * Lookup a X509 Certificate in the keystore according to a given
-     * SubjectKeyIdentifier.
-     * <p/>
-     * The search gets all alias names of the keystore and gets the certificate chain
-     * or certificate for each alias. Then the SKI for each user certificate
-     * is compared with the SKI parameter.
-     *
-     * @param skiBytes The SKI info bytes
-     * @return alias name of the certificate that matches serialNumber and issuer name
-     *         or null if no such certificate was found.
-     * @throws org.apache.ws.security.WSSecurityException
-     *          if problems during keystore handling or wrong certificate (no SKI data)
-     */
-
-    public String getAliasForX509Cert(byte[] skiBytes) throws WSSecurityException {
-        Certificate cert = null;
-        boolean found = false;
-
-        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;
-                }
-                byte[] data = getSKIBytesFromCert((X509Certificate) cert);
-                if (data.length != skiBytes.length) {
-                    continue;
-                }
-                if (Arrays.equals(data, skiBytes)) {
-                    return alias;
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "keystore");
-        }
-        return null;
-    }
-
-    /**
-     * Return a X509 Certificate alias in the keystore according to a given Certificate
-     * <p/>
-     *
-     * @param cert The certificate to lookup
-     * @return alias name of the certificate that matches the given certificate
-     *         or null if no such certificate was found.
-     */
-
-/*
-     * See comment above
-     */
-    public String getAliasForX509Cert(Certificate cert) throws WSSecurityException {
-        try {
-            String alias = keystore.getCertificateAlias(cert);
-            if (alias != null)
-                return alias;
-            // Use brute force search
-            Enumeration e = keystore.aliases();
-            while (e.hasMoreElements()) {
-                alias = (String) e.nextElement();
-                X509Certificate cert2 = (X509Certificate) keystore.getCertificate(alias);
-                if (cert2.equals(cert)) {
-                    return alias;
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "keystore");
-        }
-        return null;
+    protected String
+    getCryptoProvider() {
+        return properties.getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
     }
 
     /**
@@ -385,109 +135,6 @@
         return properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
     }
 
-    /**
-     * Gets the list of certificates for a given alias.
-     * <p/>
-     *
-     * @param alias Lookup certificate chain for this alias
-     * @return Array of X509 certificates for this alias name, or
-     *         null if this alias does not exist in the keystore
-     */
-    public X509Certificate[] getCertificates(String alias) throws WSSecurityException {
-        Certificate[] certs = 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;
-                }
-                certs = new Certificate[]{cert};
-            }
-        } catch (KeyStoreException e) {
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "keystore");
-        }
-        X509Certificate[] x509certs = new X509Certificate[certs.length];
-        for (int i = 0; i < certs.length; i++) {
-            x509certs[i] = (X509Certificate) certs[i];
-        }
-        return x509certs;
-    }
-
-    /**
-     * Lookup a X509 Certificate in the keystore according to a given
-     * Thumbprint.
-     * <p/>
-     * 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 org.apache.ws.security.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;
-    }
-
-    /**
-     * A Hook for subclasses to set the keystore without having to
-     * load it from an <code>InputStream</code>.
-     *
-     * @param ks existing keystore
-     */
-    public void setKeyStore(KeyStore ks) {
-        keystore = ks;
-    }
 
     /**
      * Loads the the keystore from an <code>InputStream </code>.
@@ -525,124 +172,5 @@
             e.printStackTrace();
             throw new CredentialException(-1, "error00", e);
         }
-    }
-
-    /**
-     * Reads the SubjectKeyIdentifier information from the certificate.
-     * <p/>
-     * If the the certificate does not contain a SKI extension then
-     * try to compute the SKI according to RFC3280 using the
-     * SHA-1 hash value of the public key. The second method described
-     * in RFC3280 is not support. Also only RSA public keys are supported.
-     * If we cannot compute the SKI throw a WSSecurityException.
-     *
-     * @param cert The certificate to read SKI
-     * @return The byte array conating the binary SKI data
-     */
-    public byte[] getSKIBytesFromCert(X509Certificate cert)
-            throws WSSecurityException {
-        /*
-           * Gets the DER-encoded OCTET string for the extension value (extnValue)
-           * identified by the passed-in oid String. The oid string is represented
-           * by a set of positive whole numbers separated by periods.
-           */
-        byte[] derEncodedValue = cert.getExtensionValue(SKI_OID);
-
-        if (cert.getVersion() < 3 || derEncodedValue == null) {
-            PublicKey key = cert.getPublicKey();
-            if (!(key instanceof RSAPublicKey)) {
-                throw new WSSecurityException(
-                        1,
-                        "noSKIHandling",
-                        new Object[]{"Support for RSA key only"});
-            }
-            byte[] encoded = key.getEncoded();
-            // remove 22-byte algorithm ID and header
-            byte[] value = new byte[encoded.length - 22];
-            System.arraycopy(encoded, 22, value, 0, value.length);
-            MessageDigest sha;
-            try {
-                sha = MessageDigest.getInstance("SHA-1");
-            } catch (NoSuchAlgorithmException ex) {
-                throw new WSSecurityException(
-                        1,
-                        "noSKIHandling",
-                        new Object[]{"Wrong certificate version (<3) and no SHA1 message digest availabe"});
-            }
-            sha.reset();
-            sha.update(value);
-            return sha.digest();
-        }
-
-        /**
-         * Strip away first four bytes from the DerValue (tag and length of
-         * ExtensionValue OCTET STRING and KeyIdentifier OCTET STRING)
-         */
-        byte abyte0[] = new byte[derEncodedValue.length - 4];
-
-        System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length);
-        return abyte0;
-    }
-
-    public KeyStore getKeyStore() {
-        return this.keystore;
-    }
-
-    /**
-     * Lookup X509 Certificates in the keystore according to a given DN of the subject of the certificate
-     * <p/>
-     * The search gets all alias names of the keystore and gets the certificate (chain)
-     * for each alias. Then the DN of the certificate is compared with the parameters.
-     *
-     * @param subjectDN The DN of subject to look for in the keystore
-     * @return Vector with all alias of certificates with the same DN as given in the parameters
-     * @throws org.apache.ws.security.WSSecurityException
-     *
-     */
-    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");
-        }
-
-        // Convert the vector into an array
-        String[] result = new String[aliases.size()];
-        for (int i = 0; i < aliases.size(); i++)
-            result[i] = (String) aliases.elementAt(i);
-
-        return result;
     }
 }

Added: 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=auto&rev=522265
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java (added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoBase.java Sun Mar 25 06:54:30 2007
@@ -0,0 +1,699 @@
+/*
+ * 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.components.crypto;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+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.CertPath;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dims
+ * Date: Sep 15, 2005
+ * Time: 9:50:40 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class CryptoBase implements Crypto {
+    private static Log log = LogFactory.getLog(CryptoBase.class);
+    protected static CertificateFactory certFact;
+    protected KeyStore keystore = null;
+    static String SKI_OID = "2.5.29.14";
+
+    /**
+     * Constructor
+     *
+     * @param properties
+     */
+    protected CryptoBase() {
+    }
+    
+    /**
+     * @return      a crypto provider name.  This operation should
+     *              return null if the default crypto provider should
+     *              be used.
+     */
+    protected abstract String getCryptoProvider();
+    
+    /**
+     * Singleton certificate factory for this Crypto instance.
+     * <p/>
+     *
+     * @return Returns a <code>CertificateFactory</code> to construct
+     *         X509 certficates
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    public synchronized CertificateFactory getCertificateFactory() throws WSSecurityException {
+        if (certFact == null) {
+            try {
+                String provider = getCryptoProvider();
+                if (provider == null || provider.length() == 0) {
+                    certFact = CertificateFactory.getInstance("X.509");
+                } else {
+                    certFact = CertificateFactory.getInstance("X.509", provider);
+                }
+            } catch (CertificateException e) {
+                throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                        "unsupportedCertType");
+            } catch (NoSuchProviderException e) {
+                throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                        "noSecProvider");
+            }
+        }
+        return certFact;
+    }
+
+    /**
+     * load a X509Certificate from the input stream.
+     * <p/>
+     *
+     * @param in The <code>InputStream</code> array containg the X509 data
+     * @return Returns a X509 certificate
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    public X509Certificate loadCertificate(InputStream in) throws WSSecurityException {
+        X509Certificate cert = null;
+        try {
+            cert =
+                    (X509Certificate) getCertificateFactory().generateCertificate(in);
+        } catch (CertificateException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "parseError");
+        }
+        return cert;
+    }
+
+    /**
+     * Gets the private key identified by <code>alias</> and <code>password</code>.
+     * <p/>
+     *
+     * @param alias    The alias (<code>KeyStore</code>) of the key owner
+     * @param password The password needed to access the private key
+     * @return The private key
+     * @throws Exception
+     */
+    public PrivateKey getPrivateKey(String alias, String password) throws Exception {
+        if (alias == null) {
+            throw new Exception("alias is null");
+        }
+        boolean b = keystore.isKeyEntry(alias);
+        if (!b) {
+            log.error("Cannot find key for alias: " + alias);
+            throw new Exception("Cannot find key for alias: " + alias);
+        }
+        Key keyTmp = keystore.getKey(alias, password.toCharArray());
+        if (!(keyTmp instanceof PrivateKey)) {
+            throw new Exception("Key is not a private key, alias: " + alias);
+        }
+        return (PrivateKey) keyTmp;
+    }
+
+    protected Vector splitAndTrim(String inString) {
+        X509NameTokenizer nmTokens = new X509NameTokenizer(inString);
+        Vector vr = new Vector();
+
+        while (nmTokens.hasMoreTokens()) {
+            vr.add(nmTokens.nextToken());
+        }
+        java.util.Collections.sort(vr);
+        return vr;
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * the issuer of a Certficate.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * for each alias. Then the Issuer fo each certificate of the chain
+     * is compared with the parameters.
+     *
+     * @param issuer The issuer's name for the certificate
+     * @return alias name of the certificate that matches the issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(String issuer)
+            throws WSSecurityException {
+        return getAliasForX509Cert(issuer, null, false);
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given serial number and
+     * the issuer of a Certficate.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * for each alias. Then the SerialNumber and Issuer fo each certificate of the chain
+     * is compared with the parameters.
+     *
+     * @param issuer       The issuer's name for the certificate
+     * @param serialNumber The serial number of the certificate from the named issuer
+     * @return alias name of the certificate that matches serialNumber and issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(String issuer, BigInteger serialNumber)
+            throws WSSecurityException {
+        return getAliasForX509Cert(issuer, serialNumber, true);
+    }
+
+    /*
+    * need to check if "getCertificateChain" also finds certificates that are
+    * used for enryption only, i.e. they may not be signed by a CA
+    * Otherwise we must define a restriction how to use certificate:
+    * each certificate must be signed by a CA or is a self signed Certificate
+    * (this should work as well).
+    * --- remains to be tested in several ways --
+    */
+    private String getAliasForX509Cert(String issuer, BigInteger serialNumber,
+                                       boolean useSerialNumber)
+            throws WSSecurityException {
+        Vector issuerRDN = splitAndTrim(issuer);
+        X509Certificate x509cert = null;
+        Vector certRDN = null;
+        Certificate cert = null;
+
+        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;
+                }
+                x509cert = (X509Certificate) cert;
+                if (!useSerialNumber ||
+                        useSerialNumber && x509cert.getSerialNumber().compareTo(serialNumber) == 0) {
+                    certRDN = splitAndTrim(x509cert.getIssuerDN().getName());
+                    if (certRDN.equals(issuerRDN)) {
+                        return alias;
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * SubjectKeyIdentifier.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * or certificate for each alias. Then the SKI for each user certificate
+     * is compared with the SKI parameter.
+     *
+     * @param skiBytes The SKI info bytes
+     * @return alias name of the certificate that matches serialNumber and issuer name
+     *         or null if no such certificate was found.
+     * @throws org.apache.ws.security.WSSecurityException
+     *          if problems during keystore handling or wrong certificate (no SKI data)
+     */
+
+    public String getAliasForX509Cert(byte[] skiBytes) throws WSSecurityException {
+        Certificate cert = null;
+        boolean found = false;
+
+        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;
+                }
+                byte[] data = getSKIBytesFromCert((X509Certificate) cert);
+                if (data.length != skiBytes.length) {
+                    continue;
+                }
+                if (Arrays.equals(data, skiBytes)) {
+                    return alias;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * Return a X509 Certificate alias in the keystore according to a given Certificate
+     * <p/>
+     *
+     * @param cert The certificate to lookup
+     * @return alias name of the certificate that matches the given certificate
+     *         or null if no such certificate was found.
+     */
+
+/*
+     * See comment above
+     */
+    public String getAliasForX509Cert(Certificate cert) throws WSSecurityException {
+        try {
+            String alias = keystore.getCertificateAlias(cert);
+            if (alias != null)
+                return alias;
+            // Use brute force search
+            Enumeration e = keystore.aliases();
+            while (e.hasMoreElements()) {
+                alias = (String) e.nextElement();
+                X509Certificate cert2 = (X509Certificate) keystore.getCertificate(alias);
+                if (cert2.equals(cert)) {
+                    return alias;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * Gets the list of certificates for a given alias.
+     * <p/>
+     *
+     * @param alias Lookup certificate chain for this alias
+     * @return Array of X509 certificates for this alias name, or
+     *         null if this alias does not exist in the keystore
+     */
+    public X509Certificate[] getCertificates(String alias) throws WSSecurityException {
+        Certificate[] certs = 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;
+                }
+                certs = new Certificate[]{cert};
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * Thumbprint.
+     * <p/>
+     * 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 org.apache.ws.security.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;
+    }
+
+    /**
+     * A Hook for subclasses to set the keystore without having to
+     * load it from an <code>InputStream</code>.
+     *
+     * @param ks existing keystore
+     */
+    public void setKeyStore(KeyStore ks) {
+        keystore = ks;
+    }
+
+    /**
+     * Reads the SubjectKeyIdentifier information from the certificate.
+     * <p/>
+     * If the the certificate does not contain a SKI extension then
+     * try to compute the SKI according to RFC3280 using the
+     * SHA-1 hash value of the public key. The second method described
+     * in RFC3280 is not support. Also only RSA public keys are supported.
+     * If we cannot compute the SKI throw a WSSecurityException.
+     *
+     * @param cert The certificate to read SKI
+     * @return The byte array conating the binary SKI data
+     */
+    public byte[] getSKIBytesFromCert(X509Certificate cert)
+            throws WSSecurityException {
+        /*
+           * Gets the DER-encoded OCTET string for the extension value (extnValue)
+           * identified by the passed-in oid String. The oid string is represented
+           * by a set of positive whole numbers separated by periods.
+           */
+        byte[] derEncodedValue = cert.getExtensionValue(SKI_OID);
+
+        if (cert.getVersion() < 3 || derEncodedValue == null) {
+            PublicKey key = cert.getPublicKey();
+            if (!(key instanceof RSAPublicKey)) {
+                throw new WSSecurityException(
+                        1,
+                        "noSKIHandling",
+                        new Object[]{"Support for RSA key only"});
+            }
+            byte[] encoded = key.getEncoded();
+            // remove 22-byte algorithm ID and header
+            byte[] value = new byte[encoded.length - 22];
+            System.arraycopy(encoded, 22, value, 0, value.length);
+            MessageDigest sha;
+            try {
+                sha = MessageDigest.getInstance("SHA-1");
+            } catch (NoSuchAlgorithmException ex) {
+                throw new WSSecurityException(
+                        1,
+                        "noSKIHandling",
+                        new Object[]{"Wrong certificate version (<3) and no SHA1 message digest availabe"});
+            }
+            sha.reset();
+            sha.update(value);
+            return sha.digest();
+        }
+
+        /**
+         * Strip away first four bytes from the DerValue (tag and length of
+         * ExtensionValue OCTET STRING and KeyIdentifier OCTET STRING)
+         */
+        byte abyte0[] = new byte[derEncodedValue.length - 4];
+
+        System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length);
+        return abyte0;
+    }
+
+    public KeyStore getKeyStore() {
+        return this.keystore;
+    }
+
+    /**
+     * Lookup X509 Certificates in the keystore according to a given DN of the subject of the certificate
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate (chain)
+     * for each alias. Then the DN of the certificate is compared with the parameters.
+     *
+     * @param subjectDN The DN of subject to look for in the keystore
+     * @return Vector with all alias of certificates with the same DN as given in the parameters
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    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");
+        }
+
+        // Convert the vector into an array
+        String[] result = new String[aliases.size()];
+        for (int i = 0; i < aliases.size(); i++)
+            result[i] = (String) aliases.elementAt(i);
+
+        return result;
+    }
+
+    /**
+     * 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)
+            throws WSSecurityException {
+        Vector list = new Vector();
+        for (int i = 0; i < certs.length; i++) {
+            if (reverse) {
+                list.insertElementAt(certs[i], 0);
+            } else {
+                list.add(certs[i]);
+            }
+        }
+        try {
+            CertPath path = getCertificateFactory().generateCertPath(list);
+            return path.getEncoded();
+        } catch (CertificateEncodingException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "encodeError");
+        } catch (CertificateException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "parseError");
+        }
+    }
+
+    /**
+     * 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)
+            throws WSSecurityException {
+        InputStream in = new ByteArrayInputStream(data);
+        CertPath path = null;
+        try {
+            path = getCertificateFactory().generateCertPath(in);
+        } catch (CertificateException e) {
+            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();
+        }
+        return certs;
+    }
+
+    /**
+     * 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(
+        java.security.cert.X509Certificate[] certs
+    )
+        throws org.apache.ws.security.WSSecurityException {
+
+        try {
+            // Generate cert path
+            java.util.List cert_list = java.util.Arrays.asList(certs);
+            java.security.cert.CertPath path =
+                getCertificateFactory().generateCertPath(cert_list);
+
+            // Use the certificates in the keystore as TrustAnchors
+            java.security.cert.PKIXParameters param =
+                new java.security.cert.PKIXParameters(this.keystore);
+
+            // Do not check a revocation list
+            param.setRevocationEnabled(false);
+
+            // Verify the trust path using the above settings
+            String provider = getCryptoProvider();
+            java.security.cert.CertPathValidator validator = null;
+            if (provider == null || provider.length() == 0) {
+                validator =
+                    java.security.cert.CertPathValidator.getInstance("PKIX");
+            } else {
+                validator =
+                    java.security.cert.CertPathValidator.getInstance(
+                        "PKIX",
+                        provider
+                    );
+            }
+            validator.validate(path, param);
+        } catch (java.security.NoSuchProviderException e) {
+                throw new org.apache.ws.security.WSSecurityException(
+                    org.apache.ws.security.WSSecurityException.FAILURE,
+                    "certpath",
+                    new Object[] { e.getMessage() },
+                    e
+                );
+        } catch (java.security.NoSuchAlgorithmException e) {
+                throw new org.apache.ws.security.WSSecurityException(
+                    org.apache.ws.security.WSSecurityException.FAILURE,
+                    "certpath", new Object[] { e.getMessage() },
+                    e
+                );
+        } catch (java.security.cert.CertificateException e) {
+                throw new org.apache.ws.security.WSSecurityException(
+                    org.apache.ws.security.WSSecurityException.FAILURE,
+                    "certpath", new Object[] { e.getMessage() },
+                    e
+                );
+        } catch (java.security.InvalidAlgorithmParameterException e) {
+                throw new org.apache.ws.security.WSSecurityException(
+                    org.apache.ws.security.WSSecurityException.FAILURE,
+                    "certpath",
+                    new Object[] { e.getMessage() },
+                    e
+                );
+        } catch (java.security.cert.CertPathValidatorException e) {
+                throw new org.apache.ws.security.WSSecurityException(
+                    org.apache.ws.security.WSSecurityException.FAILURE,
+                    "certpath",
+                    new Object[] { e.getMessage() },
+                    e
+                );
+        } catch (java.security.KeyStoreException e) {
+                throw new org.apache.ws.security.WSSecurityException(
+                    org.apache.ws.security.WSSecurityException.FAILURE,
+                    "certpath",
+                    new Object[] { e.getMessage() },
+                    e
+                );
+        }
+
+        return true;
+    }
+}

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoFactory.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoFactory.java?view=diff&rev=522265&r1=522264&r2=522265
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoFactory.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/components/crypto/CryptoFactory.java Sun Mar 25 06:54:30 2007
@@ -23,6 +23,7 @@
 
 import java.lang.reflect.Constructor;
 import java.net.URL;
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -105,10 +106,32 @@
      * @param properties      The Properties that are forwarded to the crypto implementaion.
      *                        These properties are dependend on the crypto implementatin
      * @return The cyrpto implementation or null if no cryptoClassName was defined
+     *
+     * @deprecated            use @link{#getInstance(java.lang.String, java.util.Map)} instead.
      */
     public static Crypto getInstance(String cryptoClassName, Properties properties) {
         return loadClass(cryptoClassName, properties);
     }
+    
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of Crypto. The supplied map is handed over the the crypto
+     * implementation. The map can be <code>null</code>. It is depenend on the
+     * Crypto implementation how the initialization is done in this case.
+     * <p/>
+     *
+     * @param cryptoClassName This is the crypto implementation class. No default is
+     *                        provided here.
+     * @param map             The Maps that is forwarded to the crypto implementaion.
+     *                        These contents of the map are dependent on the 
+     *                        underlying crypto implementation specified in the 
+     *                        cryptoClassName parameter.
+     * @return The cyrpto implementation or null if no cryptoClassName was defined
+     */
+    public static Crypto getInstance(String cryptoClassName, Map map) {
+        return loadClass(cryptoClassName, map);
+    }
 
     /**
      * getInstance
@@ -153,8 +176,8 @@
         return loadClass(cryptoClassName, properties,customClassLoader);
     }
 
-    private static Crypto loadClass(String cryptoClassName, Properties properties) {
-    	return loadClass(cryptoClassName,properties,CryptoFactory.class.getClassLoader());
+    private static Crypto loadClass(String cryptoClassName, Map map) {
+    	return loadClass(cryptoClassName,map,CryptoFactory.class.getClassLoader());
     }
 
     /**
@@ -164,7 +187,7 @@
      * @param loader
      * @return
      */
-    private static Crypto loadClass(String cryptoClassName, Properties properties, ClassLoader loader) {
+    private static Crypto loadClass(String cryptoClassName, Map map, ClassLoader loader) {
         Class cryptogenClass = null;
         Crypto crypto = null;
         try {
@@ -175,9 +198,17 @@
         }
         log.debug("Using Crypto Engine [" + cryptoClassName + "]");
         try {
-            Class[] classes = new Class[]{Properties.class,ClassLoader.class};
+            Class[] classes = null;
+            //
+            // for backwards compat
+            //
+            if (map instanceof Properties) {
+                classes = new Class[]{Properties.class,ClassLoader.class};
+            } else {
+                classes = new Class[]{Map.class,ClassLoader.class};
+            }
             Constructor c = cryptogenClass.getConstructor(classes);
-            crypto = (Crypto) c.newInstance(new Object[]{properties,loader});
+            crypto = (Crypto) c.newInstance(new Object[]{map,loader});
             return crypto;
         } catch (java.lang.Exception e) {
             e.printStackTrace();

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNew.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityNew.java?view=diff&rev=522265&r1=522264&r2=522265
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNew.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNew.java Sun Mar 25 06:54:30 2007
@@ -31,6 +31,7 @@
 import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoBase;
 import org.apache.ws.security.components.crypto.CryptoFactory;
 import org.apache.ws.security.message.WSSecSignature;
 import org.apache.ws.security.message.WSSecHeader;
@@ -179,5 +180,20 @@
      */
     private void verify(Document doc) throws Exception {
         secEngine.processSecurityHeader(doc, null, null, crypto);
+    }
+    
+    /**
+     * Ensure that we can load a custom crypto implementation using a Map
+     */
+    public void testCustomCrypto() {
+        java.util.Map tmp = new java.util.TreeMap();
+        Crypto crypto = CryptoFactory.getInstance(
+            "wssec.CustomCrypto",
+            tmp
+        );
+        assertNotNull(crypto);
+        assertTrue(crypto instanceof CustomCrypto);
+        CustomCrypto custom = (CustomCrypto)crypto;
+        assertSame(tmp, custom.config);
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org