ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1241502 [2/3] - in /webservices/wss4j/branches/swssf: ./ streaming-ws-policy/src/test/java/org/swssf/policy/test/ streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/input/ streaming-ws-security/src/main/java/org/swssf/wss/imp...
Date Tue, 07 Feb 2012 15:51:16 GMT
Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoBase.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoBase.java?rev=1241502&r1=1241501&r2=1241502&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoBase.java (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoBase.java Tue Feb  7 15:51:14 2012
@@ -16,586 +16,181 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.swssf.xmlsec.crypto;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.swssf.xmlsec.config.ConfigurationProperties;
-import org.swssf.xmlsec.ext.XMLSecurityException;
+package org.swssf.xmlsec.crypto;
 
-import javax.security.auth.x500.X500Principal;
 import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
-import java.math.BigInteger;
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-import java.security.interfaces.RSAPublicKey;
-import java.util.*;
+import java.security.MessageDigest;
+import java.security.NoSuchProviderException;
+import java.security.cert.CertPath;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.security.auth.x500.X500Principal;
 
-/**
- * class lent from apache wss4j
- */
+import org.swssf.xmlsec.ext.XMLSecurityException;
 
 /**
- * Created by IntelliJ IDEA.
- * User: dims
- * Date: Sep 15, 2005
- * Time: 9:50:40 AM
- * To change this template use File | Settings | File Templates.
+ * This Abstract Base Class implements the accessor and keystore-independent methods and
+ * functionality of the Crypto interface.
  */
 public abstract class CryptoBase implements Crypto {
-    private static Log log = LogFactory.getLog(CryptoBase.class);
-    private static final Constructor<?> BC_509CLASS_CONS;
-
-
-    protected static Map<String, CertificateFactory> certFactMap = new HashMap<String, CertificateFactory>();
-    protected KeyStore keystore = null;
-    static String SKI_OID = "2.5.29.14";
-    protected static KeyStore cacerts = null;
+    public static final String SKI_OID = "2.5.29.14";
     /**
      * OID For the NameConstraints Extension to X.509
-     * <p/>
+     *
      * http://java.sun.com/j2se/1.4.2/docs/api/
      * http://www.ietf.org/rfc/rfc3280.txt (s. 4.2.1.11)
      */
     public static final String NAME_CONSTRAINTS_OID = "2.5.29.30";
+    
+    private static final Constructor<?> BC_509CLASS_CONS;
 
+    protected Map<String, CertificateFactory> certFactMap = 
+        new HashMap<String, CertificateFactory>();
+    protected String defaultAlias = null;
+    protected String cryptoProvider = null;
+    
     static {
         Constructor<?> cons = null;
         try {
             Class<?> c = Class.forName("org.bouncycastle.asn1.x509.X509Name");
-            cons = c.getConstructor(new Class[]{String.class});
+            cons = c.getConstructor(new Class[] {String.class});
         } catch (Exception e) {
             //ignore
         }
         BC_509CLASS_CONS = cons;
     }
-
-
+    
     /**
      * Constructor
      */
     protected CryptoBase() {
-        if (cacerts == null) {
-            InputStream cacertsIs = null;
-
-            try {
-                String cacertsPath = System.getProperty("java.home") + "/lib/security/cacerts";
-                cacertsIs = new FileInputStream(cacertsPath);
-                String cacertsPasswd = ConfigurationProperties.getProperty("CACertKeyStorePassword");
-
-                cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
-                cacerts.load(cacertsIs, cacertsPasswd.toCharArray());
-
-            } catch (Exception e) {
-                log.warn("CA certs could not be loaded: " + e.getMessage());
-            } finally {
-                if (cacertsIs != null) {
-                    try {
-                        cacertsIs.close();
-                    } catch (IOException e) {
-                        //ignore
-                    }
-                }
-            }
-        }
     }
-
+    
     /**
-     * A Hook for subclasses to set the keystore without having to
-     * load it from an <code>InputStream</code>.
+     * Get the crypto provider associated with this implementation
+     * @return the crypto provider
+     */
+    public String getCryptoProvider() {
+        return cryptoProvider;
+    }
+    
+    /**
+     * Set the crypto provider associated with this implementation
+     * @param provider the crypto provider to set
+     */
+    public void setCryptoProvider(String provider) {
+        cryptoProvider = provider;
+    }
+    
+    /**
+     * Retrieves the identifier name of the default certificate. This should be the certificate 
+     * that is used for signature and encryption. This identifier corresponds to the certificate 
+     * that should be used whenever KeyInfo is not present in a signed or an encrypted 
+     * message. May return null. The identifier is implementation specific, e.g. it could be the
+     * KeyStore alias.
      *
-     * @param ks existing keystore
+     * @return name of the default X509 certificate.
      */
-    public void setKeyStore(KeyStore ks) {
-        keystore = ks;
+    public String getDefaultX509Identifier() throws XMLSecurityException {
+        return defaultAlias;
     }
-
-    public KeyStore getKeyStore() {
-        return this.keystore;
+    
+    /**
+     * Sets the identifier name of the default certificate. This should be the certificate 
+     * that is used for signature and encryption. This identifier corresponds to the certificate 
+     * that should be used whenever KeyInfo is not present in a signed or an encrypted 
+     * message. The identifier is implementation specific, e.g. it could be the KeyStore alias.
+     *
+     * @param identifier name of the default X509 certificate.
+     */
+    public void setDefaultX509Identifier(String identifier) {
+        defaultAlias = identifier;
     }
-
+    
     /**
-     * @return a crypto provider name.  This operation should
-     *         return null if the default crypto provider should
-     *         be used.
+     * Sets the CertificateFactory instance on this Crypto instance
+     *
+     * @param provider the CertificateFactory provider name
+     * @param certFactory the CertificateFactory the CertificateFactory instance to set
      */
-    protected abstract String getCryptoProvider();
-
-
-    private String mapKeystoreProviderToCertProvider(String s) {
-        if ("SunJSSE".equals(s)) {
-            return "SUN";
+    public void setCertificateFactory(String provider, CertificateFactory certFactory) {
+        if (provider == null || provider.length() == 0) {
+            certFactMap.put(certFactory.getProvider().getName(), certFactory);
+        } else {
+            certFactMap.put(provider, certFactory);
         }
-        return s;
     }
-
+    
     /**
-     * Singleton certificate factory for this Crypto instance.
-     * <p/>
+     * Get the CertificateFactory instance on this Crypto instance
      *
      * @return Returns a <code>CertificateFactory</code> to construct
      *         X509 certificates
-     * @throws org.swssf.ext.XMLSecurityException
-     *
+     * @throws org.apache.ws.security.XMLSecurityException
      */
     public CertificateFactory getCertificateFactory() throws XMLSecurityException {
         String provider = getCryptoProvider();
-        String keyStoreProvider = null;
-        if (keystore != null) {
-            keyStoreProvider = keystore.getProvider().getName();
-        }
 
         //Try to find a CertificateFactory that generates certs that are fully
         //compatible with the certs in the KeyStore  (Sun -> Sun, BC -> BC, etc...)
         CertificateFactory factory = null;
-        if (provider != null) {
+        if (provider != null && provider.length() != 0) {
             factory = certFactMap.get(provider);
-        } else if (keyStoreProvider != null) {
-            factory =
-                    certFactMap.get(
-                            mapKeystoreProviderToCertProvider(keyStoreProvider)
-                    );
-            if (factory == null) {
-                factory = certFactMap.get(keyStoreProvider);
-            }
         } else {
             factory = certFactMap.get("DEFAULT");
         }
         if (factory == null) {
-            synchronized (this) {
-                try {
-                    if (provider == null || provider.length() == 0) {
-                        if (keyStoreProvider != null && keyStoreProvider.length() != 0) {
-                            try {
-                                factory =
-                                        CertificateFactory.getInstance(
-                                                "X.509",
-                                                mapKeystoreProviderToCertProvider(keyStoreProvider)
-                                        );
-                                certFactMap.put(keyStoreProvider, factory);
-                                certFactMap.put(
-                                        mapKeystoreProviderToCertProvider(keyStoreProvider), factory
-                                );
-                            } catch (Exception ex) {
-                                log.debug(ex);
-                                //Ignore, we'll just use the default since they didn't specify one.
-                                //Hopefully that will work for them.
-                            }
-                        }
-                        if (factory == null) {
-                            factory = CertificateFactory.getInstance("X.509");
-                            certFactMap.put("DEFAULT", factory);
-                        }
-                    } else {
-                        factory = CertificateFactory.getInstance("X.509", provider);
-                        certFactMap.put(provider, factory);
-                    }
-                    certFactMap.put(factory.getProvider().getName(), factory);
-                } catch (CertificateException e) {
-                    throw new XMLSecurityException(XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "unsupportedCertType", e);
-                } catch (NoSuchProviderException e) {
-                    throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "noSecProvider", e);
+            try {
+                if (provider == null || provider.length() == 0) {
+                    factory = CertificateFactory.getInstance("X.509");
+                    certFactMap.put("DEFAULT", factory);
+                } else {
+                    factory = CertificateFactory.getInstance("X.509", provider);
+                    certFactMap.put(provider, factory);
                 }
+                certFactMap.put(factory.getProvider().getName(), factory);
+            } catch (CertificateException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "unsupportedCertType",
+                    null, e
+                );
+            } catch (NoSuchProviderException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "noSecProvider",
+                    null, e
+                );
             }
         }
         return factory;
     }
 
     /**
-     * load a X509Certificate from the input stream.
-     * <p/>
-     *
-     * @param in The <code>InputStream</code> array containing the X509 data
-     * @return Returns a X509 certificate
-     * @throws org.swssf.ext.XMLSecurityException
+     * Load a X509Certificate from the input stream.
      *
+     * @param in The <code>InputStream</code> containing the X509Certificate
+     * @return An X509 certificate
+     * @throws org.apache.ws.security.XMLSecurityException
      */
     public X509Certificate loadCertificate(InputStream in) throws XMLSecurityException {
         try {
-            return (X509Certificate) getCertificateFactory().generateCertificate(in);
+            CertificateFactory certFactory = getCertificateFactory();
+            return (X509Certificate) certFactory.generateCertificate(in);
         } catch (CertificateException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "parseError", e);
-        }
-    }
-
-    /**
-     * 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 XMLSecurityException {
-        if (alias == null) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, "aliasIsNull");
-        }
-        try {
-            boolean b = keystore.isKeyEntry(alias);
-            if (!b) {
-                String msg = "Cannot find key for alias: [" + alias + "]";
-                String logMsg = createKeyStoreErrorMessage(keystore);
-                throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, "keyError", msg + logMsg);
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, null, e);
-        }
-
-        Key keyTmp;
-        try {
-            keyTmp = keystore.getKey(alias, password.toCharArray());
-            if (!(keyTmp instanceof PrivateKey)) {
-                String msg = "Key is not a private key, alias: [" + alias + "]";
-                String logMsg = null;
-                logMsg = createKeyStoreErrorMessage(keystore);
-                throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, "keyError", msg + logMsg);
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, e);
-        } catch (UnrecoverableKeyException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, e);
-        } catch (NoSuchAlgorithmException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, e);
-        }
-        return (PrivateKey) keyTmp;
-    }
-
-    protected static String createKeyStoreErrorMessage(KeyStore keystore) throws KeyStoreException {
-        Enumeration<String> aliases = keystore.aliases();
-        StringBuilder sb = new StringBuilder(keystore.size() * 7);
-        boolean firstAlias = true;
-        while (aliases.hasMoreElements()) {
-            if (!firstAlias) {
-                sb.append(", ");
-            }
-            sb.append(aliases.nextElement());
-            firstAlias = false;
-        }
-        return " in keystore of type [" + keystore.getType()
-                + "] from provider [" + keystore.getProvider()
-                + "] with size [" + keystore.size() + "] and aliases: {"
-                + sb.toString() + "}";
-    }
-
-    private Object createBCX509Name(String s) {
-        if (BC_509CLASS_CONS != null) {
-            try {
-                return BC_509CLASS_CONS.newInstance(s);
-            } catch (Exception e) {
-                //ignore
-            }
-        }
-        return new X500Principal(s);
-    }
-
-    public String getAliasForX509Cert(String issuer, BigInteger serialNumber) throws XMLSecurityException {
-        Object issuerName;
-        Certificate[] certificates;
-
-        //
-        // Convert the issuer DN to a java X500Principal object first. This is to ensure
-        // interop with a DN constructed from .NET, where e.g. it uses "S" instead of "ST".
-        // Then convert it to a BouncyCastle X509Name, which will order the attributes of
-        // the DN in a particular way (see WSS-168). If the conversion to an X500Principal
-        // object fails (e.g. if the DN contains "E" instead of "EMAILADDRESS"), then fall
-        // back on a direct conversion to a BC X509Name
-        //
-        try {
-            X500Principal issuerRDN = new X500Principal(issuer);
-            issuerName = createBCX509Name(issuerRDN.getName());
-        } catch (IllegalArgumentException ex) {
-            issuerName = createBCX509Name(issuer);
-        }
-
-        try {
-            for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements(); ) {
-                String alias = 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.
-                    Certificate cert = keystore.getCertificate(alias);
-                    if (cert == null) {
-                        return null;
-                    }
-                    certificates = new Certificate[]{cert};
-                } else {
-                    certificates = certs;
-                }
-                if (!(certificates[0] instanceof X509Certificate)) {
-                    continue;
-                }
-                X509Certificate x509cert = (X509Certificate) certificates[0];
-                if (x509cert.getSerialNumber().compareTo(serialNumber) == 0) {
-                    Object certName = createBCX509Name(x509cert.getIssuerDN().getName());
-                    if (certName.equals(issuerName)) {
-                        return alias;
-                    }
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", e);
-        }
-        return null;
-    }
-
-    /**
-     * Lookup a X509 Certificate in the keystore according to a given serial number and
-     * the issuer of a Certificate.
-     * <p/>
-     * The search gets all alias names of the keystore and gets the certificate chain
-     * for each alias. Then the SerialNumber and Issuer for 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 X509Certificate[] getCertificates(String issuer, BigInteger serialNumber) throws XMLSecurityException {
-        Object issuerName;
-        Certificate[] certificates;
-
-        //
-        // Convert the issuer DN to a java X500Principal object first. This is to ensure
-        // interop with a DN constructed from .NET, where e.g. it uses "S" instead of "ST".
-        // Then convert it to a BouncyCastle X509Name, which will order the attributes of
-        // the DN in a particular way (see WSS-168). If the conversion to an X500Principal
-        // object fails (e.g. if the DN contains "E" instead of "EMAILADDRESS"), then fall
-        // back on a direct conversion to a BC X509Name
-        //
-        try {
-            X500Principal issuerRDN = new X500Principal(issuer);
-            issuerName = createBCX509Name(issuerRDN.getName());
-        } catch (IllegalArgumentException ex) {
-            issuerName = createBCX509Name(issuer);
-        }
-
-        try {
-            for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements(); ) {
-                String alias = 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.
-                    Certificate cert = keystore.getCertificate(alias);
-                    if (cert == null) {
-                        return null;
-                    }
-                    certificates = new Certificate[]{cert};
-                } else {
-                    certificates = certs;
-                }
-                if (!(certificates[0] instanceof X509Certificate)) {
-                    continue;
-                }
-                X509Certificate x509cert = (X509Certificate) certificates[0];
-                if (x509cert.getSerialNumber().compareTo(serialNumber) == 0) {
-                    Object certName = createBCX509Name(x509cert.getIssuerDN().getName());
-                    if (certName.equals(issuerName)) {
-                        X509Certificate[] x509certs = new X509Certificate[certificates.length];
-                        for (int i = 0; i < certificates.length; i++) {
-                            x509certs[i] = (X509Certificate) certificates[i];
-                        }
-                        return x509certs;
-                    }
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", e);
-        }
-        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.swssf.ext.XMLSecurityException
-     *          if problems during keystore handling or wrong certificate (no SKI data)
-     */
-    public String getAliasForX509Cert(byte[] skiBytes) throws XMLSecurityException {
-        Certificate cert = null;
-
-        try {
-            for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements(); ) {
-                String alias = 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 XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", e);
-        }
-        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.
-     */
-    public String getAliasForX509Cert(Certificate cert) throws XMLSecurityException {
-        try {
-            if (keystore == null) {
-                return null;
-            }
-            //
-            // The following code produces the wrong alias in BouncyCastle and so
-            // we'll just use the brute-force search
-            //
-            // String alias = keystore.getCertificateAlias(cert);
-            // if (alias != null) {
-            //     return alias;
-            // }
-            Enumeration<String> e = keystore.aliases();
-            while (e.hasMoreElements()) {
-                String alias = e.nextElement();
-                X509Certificate cert2 = (X509Certificate) keystore.getCertificate(alias);
-                if (cert2.equals(cert)) {
-                    return alias;
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", e);
-        }
-        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 XMLSecurityException {
-        Certificate[] certs = null;
-        Certificate cert = null;
-        try {
-            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 point we don't have certs or a cert
-                return null;
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", e);
-        }
-
-        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.swssf.ext.XMLSecurityException
-     *          if problems during keystore handling or wrong certificate
-     */
-    public String getAliasForX509CertThumb(byte[] thumb) throws XMLSecurityException {
-        Certificate cert = null;
-        MessageDigest sha = null;
-
-        try {
-            sha = MessageDigest.getInstance("SHA-1");
-            sha.reset();
-        } catch (NoSuchAlgorithmException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "noSHA1availabe", e);
-        }
-        try {
-            for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements(); ) {
-                String alias = 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;
-                }
-                try {
-                    sha.update(cert.getEncoded());
-                } catch (CertificateEncodingException ex) {
-                    throw new XMLSecurityException(XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "encodeError", ex);
-                }
-                byte[] data = sha.digest();
-
-                if (Arrays.equals(data, thumb)) {
-                    return alias;
-                }
-            }
-        } catch (KeyStoreException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", e);
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "parseError",
+                null, e
+            );
         }
-        return null;
     }
 
     /**
@@ -619,221 +214,96 @@ public abstract class CryptoBase impleme
         byte[] derEncodedValue = cert.getExtensionValue(SKI_OID);
 
         if (cert.getVersion() < 3 || derEncodedValue == null) {
-            PublicKey key = cert.getPublicKey();
-            if (!(key instanceof RSAPublicKey)) {
-                throw new XMLSecurityException(XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN, "noSKIHandling", "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;
+            X509SubjectPublicKeyInfo spki = new X509SubjectPublicKeyInfo(cert.getPublicKey());
+            byte[] value = spki.getSubjectPublicKey();
             try {
-                sha = MessageDigest.getInstance("SHA-1");
-            } catch (NoSuchAlgorithmException ex) {
+                MessageDigest digest = MessageDigest.getInstance("SHA-1");
+                return digest.digest(value);
+            } catch (Exception ex) {
                 throw new XMLSecurityException(
-                        XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN, "noSKIHandling",
-                        ex, "Wrong certificate version (<3) and no SHA1 message digest availabe"
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN, "noSKIHandling",
+                    new Object[]{"No SKI certificate extension and no SHA1 message digest available"},
+                    ex
                 );
             }
-            sha.reset();
-            sha.update(value);
-            return sha.digest();
         }
 
         //
-        // Strip away first four bytes from the DerValue (tag and length of
+        // 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;
+        DERDecoder extVal = new DERDecoder(derEncodedValue);
+        extVal.expect(DERDecoder.TYPE_OCTET_STRING);  // ExtensionValue OCTET STRING
+        extVal.getLength();
+        extVal.expect(DERDecoder.TYPE_OCTET_STRING);  // KeyIdentifier OCTET STRING
+        int keyIDLen = extVal.getLength();
+        return extVal.getBytes(keyIDLen);
     }
 
     /**
-     * Construct an array of X509Certificate's from the byte array.
+     * Get a byte array given an array of X509 certificates.
      * <p/>
      *
-     * @param data    The <code>byte</code> array containing 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 org.swssf.ext.XMLSecurityException
-     *
+     * @param certs The certificates to convert
+     * @return The byte array for the certificates
+     * @throws XMLSecurityException
      */
-    public X509Certificate[] getX509Certificates(byte[] data, boolean reverse) throws XMLSecurityException {
-        InputStream in = new ByteArrayInputStream(data);
-        CertPath path = null;
+    public byte[] getBytesFromCertificates(X509Certificate[] certs)
+        throws XMLSecurityException {
         try {
-            path = getCertificateFactory().generateCertPath(in);
-        } catch (CertificateException e) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "parseError", e);
-        }
-        List<? extends Certificate> l = path.getCertificates();
-        X509Certificate[] certs = new X509Certificate[l.size()];
-        Iterator<? extends Certificate> iterator = l.iterator();
-        for (int i = 0; i < l.size(); i++) {
-            certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate) iterator.next();
-        }
-        return certs;
-    }
-
-    /**
-     * Evaluate whether a given certificate chain should be trusted.
-     * Uses the CertPath API to validate a given certificate chain.
-     *
-     * @param certs Certificate chain to validate
-     * @return true if the certificate chain is valid, false otherwise
-     * @throws org.swssf.ext.XMLSecurityException
-     *
-     */
-    public boolean verifyTrust(X509Certificate[] certs) throws XMLSecurityException {
-        try {
-            // Generate cert path
-            List<X509Certificate> certList = Arrays.asList(certs);
-            CertPath path = getCertificateFactory().generateCertPath(certList);
-
-            Set<TrustAnchor> set = new HashSet<TrustAnchor>();
-            if (cacerts != null) {
-                Enumeration<String> truststoreAliases = cacerts.aliases();
-                while (truststoreAliases.hasMoreElements()) {
-                    String alias = truststoreAliases.nextElement();
-                    X509Certificate cert =
-                            (X509Certificate) cacerts.getCertificate(alias);
-                    if (cert != null) {
-                        TrustAnchor anchor =
-                                new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
-                        set.add(anchor);
-                    }
-                }
-            }
-
-            // Add certificates from the keystore
-            if (keystore != null) {
-                Enumeration<String> aliases = keystore.aliases();
-                while (aliases.hasMoreElements()) {
-                    String alias = aliases.nextElement();
-                    X509Certificate cert =
-                            (X509Certificate) keystore.getCertificate(alias);
-                    if (cert != null) {
-                        TrustAnchor anchor =
-                                new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
-                        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 = getCryptoProvider();
-            CertPathValidator validator = null;
-            if (provider == null || provider.length() == 0) {
-                validator = CertPathValidator.getInstance("PKIX");
-            } else {
-                validator = CertPathValidator.getInstance("PKIX", provider);
-            }
-            validator.validate(path, param);
-            return true;
-        } catch (java.security.NoSuchProviderException e) {
-            throw new XMLSecurityException(
-                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
-                    e, e.getMessage()
-            );
-        } catch (java.security.NoSuchAlgorithmException e) {
-            throw new XMLSecurityException(
-                    XMLSecurityException.ErrorCode.FAILURE,
-                    "certpath", e, e.getMessage()
-            );
-        } catch (java.security.cert.CertificateException e) {
-            throw new XMLSecurityException(
-                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
-                    e, e.getMessage()
-            );
-        } catch (java.security.InvalidAlgorithmParameterException e) {
-            throw new XMLSecurityException(
-                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
-                    e, e.getMessage()
-            );
-        } catch (java.security.cert.CertPathValidatorException e) {
+            CertPath path = getCertificateFactory().generateCertPath(Arrays.asList(certs));
+            return path.getEncoded();
+        } catch (CertificateEncodingException e) {
             throw new XMLSecurityException(
-                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
-                    e, e.getMessage()
+                XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "encodeError",
+                null, e
             );
-        } catch (java.security.KeyStoreException e) {
+        } catch (CertificateException e) {
             throw new XMLSecurityException(
-                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
-                    e, e.getMessage()
+                XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "parseError",
+                null, e
             );
         }
     }
 
     /**
-     * Evaluate whether a given public key should be trusted.
+     * Construct an array of X509Certificate's from the byte array.
+     * <p/>
      *
-     * @param publicKey The PublicKey to be evaluated
-     * @return whether the PublicKey parameter is trusted or not
+     * @param data The <code>byte</code> array containing the X509 data
+     * @return An array of X509 certificates
+     * @throws XMLSecurityException
      */
-    public boolean verifyTrust(PublicKey publicKey) throws XMLSecurityException {
-        //
-        // If the public key is null, do not trust the signature
-        //
-        if (publicKey == null) {
-            return false;
+    public X509Certificate[] getCertificatesFromBytes(byte[] data)
+        throws XMLSecurityException {
+        InputStream in = new ByteArrayInputStream(data);
+        CertPath path = null;
+        try {
+            path = getCertificateFactory().generateCertPath(in);
+        } catch (CertificateException e) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "parseError",
+                null, e
+            );
         }
-
-        //
-        // Search the keystore for the transmitted public key (direct trust)
-        //
-        boolean trust = findPublicKeyInKeyStore(publicKey, keystore);
-        if (trust) {
-            return true;
-        } else {
-            //
-            // Now search the truststore for the transmitted public key (direct trust)
-            //
-            trust = findPublicKeyInKeyStore(publicKey, cacerts);
-            if (trust) {
-                return true;
-            }
+        List<?> l = path.getCertificates();
+        X509Certificate[] certs = new X509Certificate[l.size()];
+        int i = 0;
+        for (Iterator<?> iterator = l.iterator(); iterator.hasNext(); ) {
+            certs[i++] = (X509Certificate) iterator.next();
         }
-        return false;
+        return certs;
     }
 
-    /**
-     * Find the Public Key in a keystore.
-     */
-    private boolean findPublicKeyInKeyStore(PublicKey publicKey, KeyStore keyStoreToSearch) {
-        try {
-            for (Enumeration<String> e = keyStoreToSearch.aliases(); e.hasMoreElements(); ) {
-                String alias = e.nextElement();
-                Certificate[] certs = keyStoreToSearch.getCertificateChain(alias);
-                Certificate cert;
-                if (certs == null || certs.length == 0) {
-                    // no cert chain, so lets check if getCertificate gives us a result.
-                    cert = keyStoreToSearch.getCertificate(alias);
-                    if (cert == null) {
-                        continue;
-                    }
-                } else {
-                    cert = certs[0];
-                }
-                if (!(cert instanceof X509Certificate)) {
-                    continue;
-                }
-                X509Certificate x509cert = (X509Certificate) cert;
-                if (publicKey.equals(x509cert.getPublicKey())) {
-                    return true;
-                }
-            }
-        } catch (KeyStoreException e) {
-            return false;
+    protected Object createBCX509Name(String s) {
+        if (BC_509CLASS_CONS != null) {
+             try {
+                 return BC_509CLASS_CONS.newInstance(new Object[] {s});
+             } catch (Exception e) {
+                 //ignore
+             }
         }
-        return false;
+        return new X500Principal(s);
     }
-}
\ No newline at end of file
+    
+}

Added: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoType.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoType.java?rev=1241502&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoType.java (added)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/CryptoType.java Tue Feb  7 15:51:14 2012
@@ -0,0 +1,155 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.swssf.xmlsec.crypto;
+
+import java.math.BigInteger;
+
+/**
+ * This class represents a way of passing information to the Crypto.getX509Certificates() method.
+ * The TYPE enum describes which method to use to retrieve the Certificate(s). The corresponding
+ * get accessor must be set accordingly. 
+ */
+public class CryptoType {
+    
+    /**
+     * TYPE.ISSUER_SERIAL - A certificate (chain) is located by the issuer name and serial number
+     * TYPE.THUMBPRINT_SHA1 - A certificate (chain) is located by the SHA1 of the (root) cert
+     * TYPE.SKI_BYTES - A certificate (chain) is located by the SKI bytes of the (root) cert
+     * TYPE.SUBJECT_DN - A certificate (chain) is located by the Subject DN of the (root) cert
+     * TYPE.ALIAS - A certificate (chain) is located by an alias. This alias is implementation
+     * specific, for example - it could be a java KeyStore alias.
+     */
+    public enum TYPE {
+        ISSUER_SERIAL, THUMBPRINT_SHA1, SKI_BYTES, SUBJECT_DN, ALIAS
+    };
+    
+    private TYPE type;
+    private String issuer;
+    private BigInteger serial;
+    private byte[] bytes;
+    private String subjectDN;
+    private String alias;
+    
+    /**
+     * Default constructor
+     */
+    public CryptoType() {
+        //
+    }
+    
+    /**
+     * Constructor with a TYPE argument
+     * @param type describes which method to use to retrieve a certificate (chain) 
+     */
+    public CryptoType(TYPE type) {
+        this.type = type;
+    }
+    
+    /**
+     * Set the type.
+     * @param type describes which method to use to retrieve a certificate (chain) 
+     */
+    public void setType(TYPE type) {
+        this.type = type;
+    }
+    
+    /**
+     * Get the type
+     * @return which method to use to retrieve a certificate (chain) 
+     */
+    public TYPE getType() {
+        return type;
+    }
+    
+    /**
+     * Set the Issuer String, and Serial number of the cert (chain) to retrieve.
+     * @param issuer the issuer String
+     * @param serial the serial number
+     */
+    public void setIssuerSerial(String issuer, BigInteger serial) {
+        this.issuer = issuer;
+        this.serial = serial;
+    }
+    
+    /**
+     * Get the issuer String.
+     * @return the issuer String
+     */
+    public String getIssuer() {
+        return issuer;
+    }
+    
+    /**
+     * Get the serial number
+     * @return the serial number
+     */
+    public BigInteger getSerial() {
+        return serial;
+    }
+    
+    /**
+     * Set the byte[], which could be the SHA1 thumbprint, or SKI bytes of the cert.
+     * @param bytes an array of bytes 
+     */
+    public void setBytes(byte[] bytes) {
+        this.bytes = bytes;
+    }
+    
+    /**
+     * Get the array of bytes, which could be the SHA1 thumbprint, or SKI bytes of the cert.
+     * @return an array of bytes
+     */
+    public byte[] getBytes() {
+        return bytes;
+    }
+    
+    /**
+     * Set the Subject DN of the cert (chain) to locate
+     * @param subjectDN the Subject DN of the cert (chain) to locate
+     */
+    public void setSubjectDN(String subjectDN) {
+        this.subjectDN = subjectDN;
+    }
+    
+    /**
+     * Get the Subject DN of the cert (chain) to locate
+     * @return the Subject DN of the cert (chain) to locate
+     */
+    public String getSubjectDN() {
+        return subjectDN;
+    }
+    
+    /**
+     * Set the alias of the cert (chain) to locate.
+     * @param alias the alias of the cert (chain) to locate.
+     */
+    public void setAlias(String alias) {
+        this.alias = alias;
+    }
+    
+    /**
+     * Get the alias of the cert (chain) to locate.
+     * @return the alias of the cert (chain) to locate.
+     */
+    public String getAlias() {
+        return alias;
+    }
+    
+}

Added: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/DERDecoder.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/DERDecoder.java?rev=1241502&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/DERDecoder.java (added)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/DERDecoder.java Tue Feb  7 15:51:14 2012
@@ -0,0 +1,226 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.swssf.xmlsec.crypto;
+
+import java.math.BigInteger;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.swssf.xmlsec.ext.XMLSecurityException;
+
+/**
+ * Provides the means to navigate through a DER-encoded byte array, to help
+ * in decoding the contents.
+ * <p>
+ * It maintains a "current position" in the array that advances with each
+ * operation, providing a simple means to handle the type-length-value
+ * encoding of DER. For example
+ * <pre>
+ *   decoder.expect(TYPE);
+ *   int length = decoder.getLength();
+ *   byte[] value = decoder.getBytes(len);
+ * </pre>
+ */
+public class DERDecoder {
+    private static Log log = LogFactory.getLog(DERDecoder.class);
+
+    /** DER type identifier for a bit string value */
+    public static final byte TYPE_BIT_STRING = 0x03;
+    /** DER type identifier for a octet string value */
+    public static final byte TYPE_OCTET_STRING = 0x04;
+    /** DER type identifier for a sequence value */
+    public static final byte TYPE_SEQUENCE = 0x30;
+
+    private byte[] arr;
+    private int pos;
+
+    /**
+     * Construct a DERDecoder for the given byte array.
+     *
+     * @param derEncoded the DER-encoded array to decode.
+     * @throws XMLSecurityException if the given array is null.
+     */
+    public DERDecoder(byte[] derEncoded) throws XMLSecurityException {
+        if (derEncoded == null) {
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Invalid DER string" }
+            );
+        }
+        arr = derEncoded;
+        reset();
+    }
+
+
+    /**
+     * Reset the current position to the start of the array.
+     */
+    public void reset() {
+        pos = 0;
+    }
+
+    /**
+     * Advance the current position by the given number of bytes.
+     *
+     * @param length the number of bytes to skip.
+     * @throws XMLSecurityException if length is negative.
+     */
+    public void skip(int length) throws XMLSecurityException {
+        if (length < 0) {
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Unsupported DER format" }
+            );
+        }
+        pos += length;
+    }
+
+    /**
+     * Confirm that the byte at the current position matches the given value.
+     *
+     * @param val the expected next byte.
+     * @throws XMLSecurityException
+     *         if the current position is at the end of the array, or if the
+     *         byte at the current position doesn't match the expected value.
+     */
+    public void expect(int val) throws XMLSecurityException {
+        expect((byte)(val & 0xFF));
+    }
+
+    /**
+     * Confirm that the byte at the current position matches the given value.
+     *
+     * @param val the expected next byte.
+     * @throws XMLSecurityException
+     *         if the current position is at the end of the array, or if the
+     *         byte at the current position doesn't match the expected value.
+     */
+    public void expect(byte val) throws XMLSecurityException {
+        if (!test(val)) {
+            log.debug("DER mismatch: expected " + val + ", got " + arr[pos]);
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Invalid DER format" }
+            );
+        }
+        pos++;
+    }
+
+    /**
+     * Test if the byte at the current position matches the given value.
+     *
+     * @param val the value to test for a match with the current byte.
+     * @return true if the byte at the current position matches the given value.
+     * @throws XMLSecurityException if the current position is at the end of
+     *                             the array.
+     */
+    public boolean test(byte val) throws XMLSecurityException {
+        if (pos >= arr.length) {
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Invalid DER format" }
+            );
+        }
+        return (arr[pos] == val);
+    }
+
+    /**
+     * Get the DER length at the current position.
+     * <p>
+     * DER length is encoded as
+     * <ul>
+     * <li>If the first byte is 0x00 to 0x7F, it describes the actual length.
+     * <li>If the first byte is 0x80 + n with 0<n<0x7F, the actual length is
+     * described in the following 'n' bytes.
+     * <li>The length value 0x80, used only in constructed types, is
+     * defined as "indefinite length".
+     * </ul>
+     *
+     * @return the length, -1 for indefinite length.
+     * @throws XMLSecurityException
+     *         if the current position is at the end of the array or there is
+     *         an incomplete length specification.
+     */
+    public int getLength() throws XMLSecurityException {
+        if (pos >= arr.length) {
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Invalid DER format" }
+            );
+        }
+        int len;
+        if ((arr[pos] & 0xFF) <= 0x7F) {
+            len = arr[pos++];
+        } else if (arr[pos] == 0x80) {
+            len = -1;
+            pos++;
+        } else {
+            int nbytes = arr[pos++] & 0x7F;
+            if (pos + nbytes > arr.length) {
+                throw new XMLSecurityException(
+                        XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                        "noSKIHandling",
+                        new Object[] { "Invalid DER format" }
+                );
+            }
+            byte[] lenBytes = new byte[nbytes];
+            System.arraycopy(arr, pos, lenBytes, 0, lenBytes.length);
+            len = new BigInteger(1, lenBytes).intValue();
+            pos += nbytes;
+        }
+        return len;
+    }
+
+    /**
+     * Return an array of bytes from the current position.
+     *
+     * @param length the number of bytes to return.
+     * @return an array of the requested number of bytes from the current
+     *         position.
+     * @throws XMLSecurityException
+     *         if the current position is at the end of the array, or the
+     *         length is negative.
+     */
+    public byte[] getBytes(int length) throws XMLSecurityException {
+        if (pos + length > arr.length) {
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Invalid DER format" }
+             );
+        } else if (length < 0) {
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Unsupported DER format" }
+            );
+        }
+        byte[] value = new byte[length];
+        System.arraycopy(arr, pos, value, 0, length);
+        pos += length;
+        return value;
+    }
+    
+}

Added: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Loader.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Loader.java?rev=1241502&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Loader.java (added)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Loader.java Tue Feb  7 15:51:14 2012
@@ -0,0 +1,245 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.swssf.xmlsec.crypto;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Load resources (or images) from various sources.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class Loader {
+    private static org.apache.commons.logging.Log log = 
+        org.apache.commons.logging.LogFactory.getLog(Loader.class);
+
+    /**
+     * This method will search for <code>resource</code> in different
+     * places. The search order is as follows:
+     * <ol>
+     * <p><li>Search for <code>resource</code> using the thread context
+     * class loader under Java2.
+     * <p><li>Try one last time with
+     * <code>ClassLoader.getSystemResource(resource)</code>, that is is
+     * using the system class loader in JDK 1.2 and virtual machine's
+     * built-in class loader in JDK 1.1.
+     * </ol>
+     * <p/>
+     *
+     * @param resource
+     * @return TODO
+     */
+    public static URL getResource(String resource) {
+        ClassLoader classLoader = null;
+        URL url = null;
+        try {
+            classLoader = getTCL();
+            if (classLoader != null) {
+                log.debug("Trying to find [" + resource + "] using " + classLoader + " class loader.");
+                url = classLoader.getResource(resource);
+                if (url != null) {
+                    return url;
+                }
+            }
+        } catch (Throwable t) {
+            log.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
+        }
+    
+        // Last ditch attempt: get the resource from the class path. It
+        // may be the case that clazz was loaded by the Extension class
+        // loader which the parent of the system class loader. Hence the
+        // code below.
+        log.debug("Trying to find [" + resource + "] using ClassLoader.getSystemResource().");
+        return ClassLoader.getSystemResource(resource);
+    }
+    
+
+    /**
+     * This method will search for <code>resource</code> in different
+     * places. The search order is as follows:
+     * <ol>
+     * <p><li>Search for <code>resource</code> using the supplied class loader. 
+     * If that fails, search for <code>resource</code> using the thread context
+     * class loader.
+     * <p><li>Try one last time with
+     * <code>ClassLoader.getSystemResource(resource)</code>, that is is
+     * using the system class loader in JDK 1.2 and virtual machine's
+     * built-in class loader in JDK 1.1.
+     * </ol>
+     * <p/>
+     *
+     * @param resource
+     * @return TODO
+     */
+    public static URL getResource(ClassLoader loader, String resource) {
+        URL url = null;
+        try {
+            if (loader != null) {
+                log.debug("Trying to find [" + resource + "] using " + loader + " class loader.");
+                url = loader.getResource(resource);
+                if (url != null) {
+                    return url;
+                }
+            }
+        } catch (Throwable t) {
+            log.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
+        }
+        return getResource(resource);
+    }
+
+    /**
+     * Get the Thread context class loader.
+     * <p/>
+     *
+     * @return the Thread context class loader
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     */
+    public static ClassLoader getTCL() throws IllegalAccessException, InvocationTargetException {
+         return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+            public ClassLoader run() {
+                return Thread.currentThread().getContextClassLoader();
+            }
+         });
+    }
+    
+    /**
+     * Get the class loader of the class argument
+     * <p/>
+     *
+     * @return the class loader of the argument
+     */
+    public static ClassLoader getClassLoader(final Class<?> clazz) {
+        return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+            public ClassLoader run() {
+                return clazz.getClassLoader();
+            }
+         });
+    }
+
+    /**
+     * Try the specified classloader and then fall back to the loadClass
+     * <p/>
+     *
+     * @param loader
+     * @param clazz
+     * @return Class
+     * @throws ClassNotFoundException
+     */
+    public static Class<?> loadClass(ClassLoader loader, String clazz) throws ClassNotFoundException {
+        try {
+            if (loader != null) {
+                Class<?> c = loader.loadClass(clazz);
+                if (c != null) {
+                    return c;
+                }
+            }
+        } catch (Throwable e) {
+            log.warn(e.getMessage(), e);
+        }
+        return loadClass(clazz, true);
+    }
+
+    /**
+     * Try the specified classloader and then fall back to the loadClass
+     * <p/>
+     *
+     * @param loader
+     * @param clazz
+     * @param type
+     * @return Class
+     * @throws ClassNotFoundException
+     */
+    public static <T> Class<? extends T> loadClass(ClassLoader loader, 
+                                      String clazz,
+                                      Class<T> type) throws ClassNotFoundException {
+        try {
+            if (loader != null) {
+                Class<?> c = loader.loadClass(clazz);
+                if (c != null) {
+                    return c.asSubclass(type);
+                }
+            }
+        } catch (Throwable e) {
+            log.warn(e.getMessage(), e);
+        }
+        return loadClass(clazz, true, type);
+    }
+    /**
+     * If running under JDK 1.2 load the specified class using the
+     * <code>Thread</code> <code>contextClassLoader</code> if that
+     * fails try Class.forname.
+     * <p/>
+     *
+     * @param clazz
+     * @return TODO
+     * @throws ClassNotFoundException
+     */
+    public static Class<?> loadClass(String clazz) throws ClassNotFoundException {
+        return loadClass(clazz, true);
+    }
+    /**
+     * If running under JDK 1.2 load the specified class using the
+     * <code>Thread</code> <code>contextClassLoader</code> if that
+     * fails try Class.forname.
+     * <p/>
+     *
+     * @param clazz
+     * @param type  Type to cast it to
+     * @return TODO
+     * @throws ClassNotFoundException
+     */
+    public static <T> Class<? extends T> loadClass(String clazz, Class<T> type)
+        throws ClassNotFoundException {
+        return loadClass(clazz, true, type);
+    }
+    
+    public static <T> Class<? extends T> loadClass(String clazz, 
+                                                   boolean warn,
+                                                   Class<T> type) throws ClassNotFoundException {
+        return loadClass(clazz, warn).asSubclass(type);
+    }
+    public static Class<?> loadClass(String clazz, boolean warn) throws ClassNotFoundException {
+        try {
+            ClassLoader tcl = getTCL(); 
+            
+            if (tcl != null) {
+                Class<?> c = tcl.loadClass(clazz);
+                if (c != null) {
+                    return c;
+                }
+            }
+        } catch (Throwable e) {
+            if (warn) {
+                log.warn(e.getMessage(), e);
+            } else {
+                log.debug(e.getMessage(), e);
+            }
+        }
+        // we reached here because tcl was null or because of a
+        // security exception, or because clazz could not be loaded...
+        // In any case we now try one more time
+        return Class.forName(clazz);
+    }
+}

Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Merlin.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Merlin.java?rev=1241502&r1=1241501&r2=1241502&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Merlin.java (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/Merlin.java Tue Feb  7 15:51:14 2012
@@ -18,22 +18,16 @@
  */
 package org.swssf.xmlsec.crypto;
 
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.swssf.xmlsec.config.ConfigurationProperties;
 
-/**
- * class lent from apache wss4j
- */
-
-/**
- * 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 class Merlin extends CryptoBase {
+public class Merlin extends MerlinBase {
 
     private static final Log log = LogFactory.getLog(Merlin.class.getName());
 
@@ -44,9 +38,33 @@ public class Merlin extends CryptoBase {
      */
     public Merlin() {
         super();
+        
+        if (truststore == null) {
+            InputStream cacertsIs = null;
+
+            try {
+                String cacertsPath = System.getProperty("java.home") + "/lib/security/cacerts";
+                cacertsIs = new FileInputStream(cacertsPath);
+                String cacertsPasswd = ConfigurationProperties.getProperty("CACertKeyStorePassword");
+
+                truststore = KeyStore.getInstance(KeyStore.getDefaultType());
+                truststore.load(cacertsIs, cacertsPasswd.toCharArray());
+                loadCACerts = true;
+            } catch (Exception e) {
+                log.warn("CA certs could not be loaded: " + e.getMessage());
+            } finally {
+                if (cacertsIs != null) {
+                    try {
+                        cacertsIs.close();
+                    } catch (IOException e) {
+                        //ignore
+                    }
+                }
+            }
+        }
     }
 
-    protected String getCryptoProvider() {
+    public String getCryptoProvider() {
         return ConfigurationProperties.getProperty("CertProvider");
     }
 



Mime
View raw message