ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1241502 [3/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
Added: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/MerlinBase.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/MerlinBase.java?rev=1241502&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/MerlinBase.java (added)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/MerlinBase.java Tue Feb  7 15:51:14 2012
@@ -0,0 +1,1069 @@
+/**
+ * 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.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;
+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.UnrecoverableKeyException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.swssf.xmlsec.ext.XMLSecurityException;
+
+/**
+ * A base Crypto implementation based on two Java KeyStore objects, one being the keystore, and one
+ * being the truststore.
+ */
+public class MerlinBase extends CryptoBase {
+    
+    private static final org.apache.commons.logging.Log log = 
+        org.apache.commons.logging.LogFactory.getLog(MerlinBase.class);
+    private static final boolean doDebug = log.isDebugEnabled();
+
+    protected static CertificateFactory certFact;
+    protected KeyStore keystore = null;
+    protected KeyStore truststore = null;
+    protected CertStore crlCertStore = null;
+    protected boolean loadCACerts = false;
+    
+    public MerlinBase() {
+        // Default constructor
+    }
+    
+    /**
+     * Load a KeyStore object as an InputStream, using the ClassLoader and location arguments
+     */
+    public static InputStream loadInputStream(ClassLoader loader, String location) 
+        throws XMLSecurityException, IOException {
+        InputStream is = null;
+        if (location != null) {
+            java.net.URL url = Loader.getResource(loader, location);
+            if (url != null) {
+                is = url.openStream();
+            }
+    
+            //
+            // If we don't find it, then look on the file system.
+            //
+            if (is == null) {
+                try {
+                    is = new FileInputStream(location);
+                } catch (Exception e) {
+                    if (doDebug) {
+                        log.debug(e.getMessage(), e);
+                    }
+                    throw new XMLSecurityException(
+                        XMLSecurityException.ErrorCode.FAILURE, "proxyNotFound", new Object[]{location}, e
+                    );
+                }
+            }
+        }
+        return is;
+    }
+    
+
+    /**
+     * Loads the keystore from an <code>InputStream </code>.
+     * <p/>
+     *
+     * @param input <code>InputStream</code> to read from
+     * @throws XMLSecurityException
+     */
+    public KeyStore load(InputStream input, String storepass, String provider, String type) 
+        throws XMLSecurityException {
+        KeyStore ks = null;
+        
+        try {
+            if (provider == null || provider.length() == 0) {
+                ks = KeyStore.getInstance(type);
+            } else {
+                ks = KeyStore.getInstance(type, provider);
+            }
+                    
+            ks.load(input, (storepass == null || storepass.length() == 0) 
+                ? new char[0] : storepass.toCharArray());
+        } catch (IOException e) {
+            if (doDebug) {
+                log.debug(e.getMessage(), e);
+            }
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "ioError00", e);
+        } catch (GeneralSecurityException e) {
+            if (doDebug) {
+                log.debug(e.getMessage(), e);
+            }
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "secError00", e);
+        } catch (Exception e) {
+            if (doDebug) {
+                log.debug(e.getMessage(), e);
+            }
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "error00", e);
+        }
+        return ks;
+    }
+    
+    //
+    // Accessor methods
+    //
+    
+    /**
+     * Gets the Keystore that was loaded
+     *
+     * @return the Keystore
+     */
+    public KeyStore getKeyStore() {
+        return keystore;
+    }
+    
+    /**
+     * Set the Keystore on this Crypto instance
+     *
+     * @param keyStore the Keystore to set
+     */
+    public void setKeyStore(KeyStore keyStore) {
+        keystore = keyStore;
+    }
+    
+    /**
+     * Gets the trust store that was loaded by the underlying implementation
+     *
+     * @return the trust store
+     */
+    public KeyStore getTrustStore() {
+        return truststore;
+    }
+    
+    /**
+     * Set the trust store on this Crypto instance
+     *
+     * @param trustStore the trust store to set
+     */
+    public void setTrustStore(KeyStore trustStore) {
+        truststore = trustStore;
+    }
+    
+    /**
+     * Set the CertStore from which to obtain a list of CRLs for Certificate Revocation
+     * checking.
+     * @param crlCertStore the CertStore from which to obtain a list of CRLs for Certificate 
+     * Revocation checking.
+     */
+    public void setCRLCertStore(CertStore crlCertStore) {
+        this.crlCertStore = crlCertStore;
+    }
+    
+    /**
+     * Get the CertStore from which to obtain a list of CRLs for Certificate Revocation
+     * checking.
+     * @return the CertStore from which to obtain a list of CRLs for Certificate 
+     * Revocation checking.
+     */
+    public CertStore getCRLCertStore() {
+        return crlCertStore;
+    }
+    
+    /**
+     * Singleton certificate factory for this Crypto instance.
+     * <p/>
+     *
+     * @return Returns a <code>CertificateFactory</code> to construct
+     *         X509 certificates
+     * @throws org.apache.ws.security.XMLSecurityException
+     */
+    @Override
+    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) {
+            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) {
+            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",
+                    null, e
+                );
+            } catch (NoSuchProviderException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "noSecProvider",
+                    null, e
+                );
+            }
+        }
+        return factory;
+    }
+    
+    private String mapKeystoreProviderToCertProvider(String s) {
+        if ("SunJSSE".equals(s)) {
+            return "SUN";
+        }
+        return s;
+    }
+    
+    /**
+     * 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.
+     *
+     * @return name of the default X509 certificate.
+     */
+    @Override
+    public String getDefaultX509Identifier() throws XMLSecurityException {
+        if (defaultAlias != null) {
+            return defaultAlias;
+        }
+        
+        if (keystore != null) {
+            try {
+                Enumeration<String> as = keystore.aliases();
+                if (as.hasMoreElements()) {
+                    String alias = as.nextElement();
+                    if (!as.hasMoreElements()) {
+                        defaultAlias = alias;
+                        return alias;
+                    }
+                }
+            } catch (KeyStoreException ex) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE, "keystore", null, ex
+                );
+            } 
+        }
+        return null;
+    }
+    
+    //
+    // Keystore-specific Crypto functionality methods
+    //
+
+    /**
+     * Get an X509Certificate (chain) corresponding to the CryptoType argument. The supported
+     * types are as follows:
+     * 
+     * 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, which for this implementation
+     * means an alias of the keystore or truststore.
+     */
+    public X509Certificate[] getX509Certificates(CryptoType cryptoType) throws XMLSecurityException {
+        if (cryptoType == null) {
+            return null;
+        }
+        CryptoType.TYPE type = cryptoType.getType();
+        X509Certificate[] certs = null;
+        switch (type) {
+        case ISSUER_SERIAL: {
+            certs = getX509Certificates(cryptoType.getIssuer(), cryptoType.getSerial());
+            break;
+        }
+        case THUMBPRINT_SHA1: {
+            certs = getX509Certificates(cryptoType.getBytes());
+            break;
+        }
+        case SKI_BYTES: {
+            certs = getX509CertificatesSKI(cryptoType.getBytes());
+            break;
+        }
+        case SUBJECT_DN: {
+            certs = getX509CertificatesSubjectDN(cryptoType.getSubjectDN());
+            break;
+        }
+        case ALIAS: {
+            certs = getX509Certificates(cryptoType.getAlias());
+            break;
+        }
+        }
+        return certs;
+    }
+
+    /**
+     * Get the implementation-specific identifier corresponding to the cert parameter. In this 
+     * case, the identifier corresponds to a KeyStore alias.
+     * @param cert The X509Certificate for which to search for an identifier
+     * @return the identifier corresponding to the cert parameter
+     * @throws XMLSecurityException
+     */
+    public String getX509Identifier(X509Certificate cert) throws XMLSecurityException {
+        String identifier = null;
+        
+        if (keystore != null) {
+            identifier = getIdentifier(cert, keystore);
+        }
+        
+        if (identifier == null && truststore != null) {
+            identifier = getIdentifier(cert, truststore);
+        }
+        
+        return identifier;
+    }
+    
+    /**
+     * Gets the private key corresponding to the identifier.
+     *
+     * @param identifier The implementation-specific identifier corresponding to the key
+     * @param password The password needed to get the key
+     * @return The private key
+     */
+    public PrivateKey getPrivateKey(
+        String identifier,
+        String password
+    ) throws XMLSecurityException {
+        if (keystore == null) {
+            throw new XMLSecurityException("The keystore is null");
+        }
+        try {
+            if (identifier == null || !keystore.isKeyEntry(identifier)) {
+                String msg = "Cannot find key for alias: [" + identifier + "]";
+                String logMsg = createKeyStoreErrorMessage(keystore);
+                log.error(msg + logMsg);
+                throw new XMLSecurityException(msg);
+            }
+            /*
+             * todo
+            if (password == null && privatePasswordSet) {
+                password = properties.getProperty(KEYSTORE_PRIVATE_PASSWORD);
+                if (password != null) {
+                    password = password.trim();
+                }
+            }
+            */
+            Key keyTmp = keystore.getKey(identifier, password == null 
+                                         ? new char[]{} : password.toCharArray());
+            if (!(keyTmp instanceof PrivateKey)) {
+                String msg = "Key is not a private key, alias: [" + identifier + "]";
+                String logMsg = createKeyStoreErrorMessage(keystore);
+                log.error(msg + logMsg);
+                throw new XMLSecurityException(msg);
+            }
+            return (PrivateKey) keyTmp;
+        } catch (KeyStoreException ex) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "noPrivateKey", new Object[]{ex.getMessage()}, ex
+            );
+        } catch (UnrecoverableKeyException ex) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "noPrivateKey", new Object[]{ex.getMessage()}, ex
+            );
+        } catch (NoSuchAlgorithmException ex) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "noPrivateKey", new Object[]{ex.getMessage()}, ex
+            );
+        }
+    }
+    
+    /**
+     * 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 XMLSecurityException
+     */
+    @Deprecated
+    public boolean verifyTrust(X509Certificate[] certs) throws XMLSecurityException {
+        return verifyTrust(certs, false);
+    }
+    
+    /**
+     * 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
+     * @param enableRevocation whether to enable CRL verification or not
+     * @return true if the certificate chain is valid, false otherwise
+     * @throws XMLSecurityException
+     */
+    public boolean verifyTrust(
+        X509Certificate[] certs, 
+        boolean enableRevocation
+    ) throws XMLSecurityException {
+        try {
+            // Generate cert path
+            List<X509Certificate> certList = Arrays.asList(certs);
+            CertPath path = getCertificateFactory().generateCertPath(certList);
+
+            Set<TrustAnchor> set = new HashSet<TrustAnchor>();
+            if (truststore != null) {
+                Enumeration<String> truststoreAliases = truststore.aliases();
+                while (truststoreAliases.hasMoreElements()) {
+                    String alias = truststoreAliases.nextElement();
+                    X509Certificate cert = 
+                        (X509Certificate) truststore.getCertificate(alias);
+                    if (cert != null) {
+                        TrustAnchor anchor = 
+                            new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
+                        set.add(anchor);
+                    }
+                }
+            }
+
+            //
+            // Add certificates from the keystore - only if there is no TrustStore, apart from
+            // the case that the truststore is the JDK CA certs. This behaviour is preserved
+            // for backwards compatibility reasons
+            //
+            if (keystore != null && (truststore == null || loadCACerts)) {
+                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);
+            param.setRevocationEnabled(enableRevocation);
+            if (enableRevocation && crlCertStore != null) {
+                param.addCertStore(crlCertStore);
+            }
+
+            // 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",
+                    new Object[] { e.getMessage() }, e
+                );
+        } catch (java.security.NoSuchAlgorithmException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE,
+                    "certpath", new Object[] { e.getMessage() },
+                    e
+                );
+        } catch (java.security.cert.CertificateException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE, "certpath", 
+                    new Object[] { e.getMessage() }, e
+                );
+        } catch (java.security.InvalidAlgorithmParameterException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
+                    new Object[] { e.getMessage() }, e
+                );
+        } catch (java.security.cert.CertPathValidatorException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
+                    new Object[] { e.getMessage() }, e
+                );
+        } catch (java.security.KeyStoreException e) {
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
+                    new Object[] { e.getMessage() }, e
+                );
+        } catch (NullPointerException e) {
+                // NPE thrown by JDK 1.7 for one of the test cases
+                throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.FAILURE, "certpath",
+                    new Object[] { e.getMessage() }, e
+                );
+        }
+    }
+    
+    /**
+     * Evaluate whether a given public key should be trusted.
+     * 
+     * @param publicKey The PublicKey to be evaluated
+     * @return whether the PublicKey parameter is trusted or not
+     */
+    public boolean verifyTrust(PublicKey publicKey) throws XMLSecurityException {
+        //
+        // If the public key is null, do not trust the signature
+        //
+        if (publicKey == null) {
+            return false;
+        }
+        
+        //
+        // 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, truststore);
+            if (trust) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) according to a given serial number and issuer string.
+     *
+     * @param issuer The Issuer String
+     * @param serialNumber The serial number of the certificate
+     * @return an X509 Certificate (chain) corresponding to the found certificate(s)
+     * @throws XMLSecurityException
+     */
+    private X509Certificate[] getX509Certificates(
+        String issuer, 
+        BigInteger serialNumber
+    ) throws XMLSecurityException {
+        //
+        // Convert the subject 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
+        //
+        Object issuerName = null;
+        try {
+            X500Principal issuerRDN = new X500Principal(issuer);
+            issuerName = createBCX509Name(issuerRDN.getName());
+        } catch (java.lang.IllegalArgumentException ex) {
+            issuerName = createBCX509Name(issuer);
+        }
+        Certificate[] certs = null;
+        if (keystore != null) {
+            certs = getCertificates(issuerName, serialNumber, keystore);
+        }
+
+        //If we can't find the issuer in the keystore then look at the truststore
+        if ((certs == null || certs.length == 0) && truststore != null) {
+            certs = getCertificates(issuerName, serialNumber, truststore);
+        }
+        
+        if ((certs == null || certs.length == 0)) {
+            return null;
+        }
+        
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) of the X500Principal argument in the supplied KeyStore 
+     * @param subjectRDN either an X500Principal or a BouncyCastle X509Name instance.
+     * @param store The KeyStore
+     * @return an X509 Certificate (chain)
+     * @throws XMLSecurityException
+     */
+    private Certificate[] getCertificates(
+        Object issuerRDN, 
+        BigInteger serialNumber, 
+        KeyStore store
+    ) throws XMLSecurityException {
+        try {
+            for (Enumeration<String> e = store.aliases(); e.hasMoreElements();) {
+                String alias = e.nextElement();
+                Certificate cert = null;
+                Certificate[] certs = store.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a result.
+                    cert = store.getCertificate(alias);
+                    if (cert == null) {
+                        continue;
+                    }
+                    certs = new Certificate[]{cert};
+                } else {
+                    cert = certs[0];
+                }
+                if (cert instanceof X509Certificate) {
+                    X509Certificate x509cert = (X509Certificate) cert;
+                    if (x509cert.getSerialNumber().compareTo(serialNumber) == 0) {
+                        Object certName = 
+                            createBCX509Name(x509cert.getIssuerX500Principal().getName());
+                        if (certName.equals(issuerRDN)) {
+                            return certs;
+                        }
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "keystore", null, e
+            );
+        }
+        return new Certificate[]{};
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) according to a given Thumbprint.
+     *
+     * @param thumbprint The SHA1 thumbprint info bytes
+     * @return the X509 Certificate (chain) that was found (can be null)
+     * @throws XMLSecurityException if problems during keystore handling or wrong certificate
+     */
+    private X509Certificate[] getX509Certificates(byte[] thumbprint) throws XMLSecurityException {
+        MessageDigest sha = null;
+        
+        try {
+            sha = MessageDigest.getInstance("SHA1");
+        } catch (NoSuchAlgorithmException e) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "noSHA1availabe", null, e
+            );
+        }
+        Certificate[] certs = null;
+        if (keystore != null) {
+            certs = getCertificates(thumbprint, keystore, sha);
+        }
+
+        //If we can't find the issuer in the keystore then look at the truststore
+        if ((certs == null || certs.length == 0) && truststore != null) {
+            certs = getCertificates(thumbprint, truststore, sha);
+        }
+        
+        if ((certs == null || certs.length == 0)) {
+            return null;
+        }
+        
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+
+    /**
+     * Get an X509 Certificate (chain) of the X500Principal argument in the supplied KeyStore 
+     * @param subjectRDN either an X500Principal or a BouncyCastle X509Name instance.
+     * @param store The KeyStore
+     * @return an X509 Certificate (chain)
+     * @throws XMLSecurityException
+     */
+    private Certificate[] getCertificates(
+        byte[] thumbprint, 
+        KeyStore store,
+        MessageDigest sha
+    ) throws XMLSecurityException {
+        try {
+            for (Enumeration<String> e = store.aliases(); e.hasMoreElements();) {
+                String alias = e.nextElement();
+                Certificate cert = null;
+                Certificate[] certs = store.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a result.
+                    cert = store.getCertificate(alias);
+                    if (cert == null) {
+                        continue;
+                    }
+                    certs = new Certificate[]{cert};
+                } else {
+                    cert = certs[0];
+                }
+                if (cert instanceof X509Certificate) {
+                    X509Certificate x509cert = (X509Certificate) cert;
+                    try {
+                        sha.update(x509cert.getEncoded());
+                    } catch (CertificateEncodingException ex) {
+                        throw new XMLSecurityException(
+                            XMLSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "encodeError",
+                            null, ex
+                        );
+                    }
+                    byte[] data = sha.digest();
+
+                    if (Arrays.equals(data, thumbprint)) {
+                        return certs;
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "keystore", null, e
+            );
+        }
+        return new Certificate[]{};
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) according to a given SubjectKeyIdentifier.
+     *
+     * @param skiBytes The SKI bytes
+     * @return the X509 certificate (chain) that was found (can be null)
+     */
+    private X509Certificate[] getX509CertificatesSKI(byte[] skiBytes) throws XMLSecurityException {
+        Certificate[] certs = null;
+        if (keystore != null) {
+            certs = getCertificates(skiBytes, keystore);
+        }
+
+        //If we can't find the issuer in the keystore then look at the truststore
+        if ((certs == null || certs.length == 0) && truststore != null) {
+            certs = getCertificates(skiBytes, truststore);
+        }
+        
+        if ((certs == null || certs.length == 0)) {
+            return null;
+        }
+        
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) of the X500Principal argument in the supplied KeyStore 
+     * @param subjectRDN either an X500Principal or a BouncyCastle X509Name instance.
+     * @param store The KeyStore
+     * @return an X509 Certificate (chain)
+     * @throws XMLSecurityException
+     */
+    private Certificate[] getCertificates(
+        byte[] skiBytes, 
+        KeyStore store
+    ) throws XMLSecurityException {
+        try {
+            for (Enumeration<String> e = store.aliases(); e.hasMoreElements();) {
+                String alias = e.nextElement();
+                Certificate cert = null;
+                Certificate[] certs = store.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a result.
+                    cert = store.getCertificate(alias);
+                    if (cert == null) {
+                        continue;
+                    }
+                    certs = new Certificate[]{cert};
+                } else {
+                    cert = certs[0];
+                }
+                if (cert instanceof X509Certificate) {
+                    X509Certificate x509cert = (X509Certificate) cert;
+                    byte[] data = getSKIBytesFromCert(x509cert);
+                    if (data.length == skiBytes.length && Arrays.equals(data, skiBytes)) {
+                        return certs;
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "keystore", null, e
+            );
+        }
+        return new Certificate[]{};
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) according to a given DN of the subject of the certificate
+     *
+     * @param subjectDN The DN of subject to look for
+     * @return An X509 Certificate (chain) with the same DN as given in the parameters
+     * @throws XMLSecurityException
+     */
+    private X509Certificate[] getX509CertificatesSubjectDN(String subjectDN) throws XMLSecurityException {
+        //
+        // Convert the subject 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
+        //
+        Object subject;
+        try {
+            X500Principal subjectRDN = new X500Principal(subjectDN);
+            subject = createBCX509Name(subjectRDN.getName());
+        } catch (java.lang.IllegalArgumentException ex) {
+            subject = createBCX509Name(subjectDN);
+        }
+        
+        Certificate[] certs = null;
+        if (keystore != null) {
+            certs = getCertificates(subject, keystore);
+        }
+
+        //If we can't find the issuer in the keystore then look at the truststore
+        if ((certs == null || certs.length == 0) && truststore != null) {
+            certs = getCertificates(subject, truststore);
+        }
+        
+        if ((certs == null || certs.length == 0)) {
+            return null;
+        }
+        
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) that correspond to the identifier. For this implementation,
+     * the identifier corresponds to the KeyStore alias.
+     * 
+     * @param identifier The identifier that corresponds to the returned certs
+     * @return an X509 Certificate (chain) that corresponds to the identifier
+     */
+    private X509Certificate[] getX509Certificates(String identifier) throws XMLSecurityException {
+        Certificate[] certs = null;
+        try {
+            if (keystore != null) {
+                // There's a chance that there can only be a set of trust stores
+                certs = keystore.getCertificateChain(identifier);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a result.
+                    Certificate cert = keystore.getCertificate(identifier);
+                    if (cert != null) {
+                        certs = new Certificate[]{cert};
+                    }
+                }
+            }
+
+            if (certs == null && truststore != null) {
+                // Now look into the trust stores
+                certs = truststore.getCertificateChain(identifier);
+                if (certs == null) {
+                    Certificate cert = truststore.getCertificate(identifier);
+                    if (cert != null) {
+                        certs = new Certificate[]{cert};
+                    }
+                }
+            }
+
+            if (certs == null) {
+                return null;
+            }
+        } catch (KeyStoreException e) {
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", null, e);
+        }
+
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+    
+    /**
+     * 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;
+        }
+        return false;
+    }
+    
+    /**
+     * Get an X509 Certificate (chain) of the X500Principal argument in the supplied KeyStore 
+     * @param subjectRDN either an X500Principal or a BouncyCastle X509Name instance.
+     * @param store The KeyStore
+     * @return an X509 Certificate (chain)
+     * @throws XMLSecurityException
+     */
+    private Certificate[] getCertificates(Object subjectRDN, KeyStore store) 
+        throws XMLSecurityException {
+        try {
+            for (Enumeration<String> e = store.aliases(); e.hasMoreElements();) {
+                String alias = e.nextElement();
+                Certificate cert = null;
+                Certificate[] certs = store.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a result.
+                    cert = store.getCertificate(alias);
+                    if (cert == null) {
+                        continue;
+                    }
+                    certs = new Certificate[]{cert};
+                } else {
+                    cert = certs[0];
+                }
+                if (cert instanceof X509Certificate) {
+                    X500Principal foundRDN = ((X509Certificate) cert).getSubjectX500Principal();
+                    Object certName = createBCX509Name(foundRDN.getName());
+
+                    if (subjectRDN.equals(certName)) {
+                        return certs;
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.FAILURE, "keystore", null, e
+            );
+        }
+        return new Certificate[]{};
+    }
+    
+    private 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;
+        }
+        String msg = " in keystore of type [" + keystore.getType()
+            + "] from provider [" + keystore.getProvider()
+            + "] with size [" + keystore.size() + "] and aliases: {"
+            + sb.toString() + "}";
+        return msg;
+    }
+    
+    /**
+     * Get an implementation-specific identifier that corresponds to the X509Certificate. In
+     * this case, the identifier is the KeyStore alias.
+     * @param cert The X509Certificate corresponding to the returned identifier
+     * @param store The KeyStore to search
+     * @return An implementation-specific identifier that corresponds to the X509Certificate
+     */
+    private String getIdentifier(X509Certificate cert, KeyStore store)
+        throws XMLSecurityException {
+        try {
+            for (Enumeration<String> e = store.aliases(); e.hasMoreElements();) {
+                String alias = e.nextElement();
+                
+                Certificate[] certs = store.getCertificateChain(alias);
+                Certificate retrievedCert = null;
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a  result.
+                    retrievedCert = store.getCertificate(alias);
+                    if (retrievedCert == null) {
+                        continue;
+                    }
+                } else {
+                    retrievedCert = certs[0];
+                }
+                if (!(retrievedCert instanceof X509Certificate)) {
+                    continue;
+                }
+                if (retrievedCert != null && retrievedCert.equals(cert)) {
+                    return alias;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, "keystore", null, e);
+        }
+        return null;
+    }
+    
+}

Added: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/X509SubjectPublicKeyInfo.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/X509SubjectPublicKeyInfo.java?rev=1241502&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/X509SubjectPublicKeyInfo.java (added)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/crypto/X509SubjectPublicKeyInfo.java Tue Feb  7 15:51:14 2012
@@ -0,0 +1,108 @@
+/**
+ * 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.security.PublicKey;
+
+import org.swssf.xmlsec.ext.XMLSecurityException;
+
+/**
+ * Represents the X.509 SubjectPublicKeyInfo for a public key, as specified
+ * in RFC3280/5280:
+ * <pre>
+ * SubjectPublicKeyInfo  ::=  SEQUENCE  {
+ *       algorithm            AlgorithmIdentifier,
+ *       subjectPublicKey     BIT STRING  }
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *       algorithm               OBJECT IDENTIFIER,
+ *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
+ * </pre>
+ */
+public class X509SubjectPublicKeyInfo extends DERDecoder {
+
+    /**
+     * Construct a SubjectPublicKeyInfo for the given public key.
+     *
+     * @param key the public key.
+     * @throws XMLSecurityException if the public key encoding format is 
+     *                             not X.509 or the encoding is null.
+     */
+    public X509SubjectPublicKeyInfo(PublicKey key) throws XMLSecurityException {
+        super(key.getEncoded());
+        if (!("X.509".equalsIgnoreCase(key.getFormat()) 
+                || "X509".equalsIgnoreCase(key.getFormat()))) {
+            throw new XMLSecurityException(
+                XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                "noSKIHandling",
+                new Object[] { "Support for X.509-encoded public keys only" }
+            );
+        }
+    }
+
+    /**
+     * Construct a SubjectPublicKeyInfo for the given X.509-encoded public key.
+     *
+     * @param x509EncodedPublicKey the public key, in X.509 DER-encoding.
+     * @throws XMLSecurityException if the encoded public key is null.
+     */
+    public X509SubjectPublicKeyInfo(byte[] x509EncodedPublicKey) throws XMLSecurityException {
+        super(x509EncodedPublicKey);
+    }
+
+    /**
+     * Get the subjectPublicKey element of the SubjectPublicKeyInfo.
+     *
+     * @return the X.509-encoded subjectPublicKey bit string.
+     * @throws XMLSecurityException the DER-encoding is invalid.
+     */
+    public byte[] getSubjectPublicKey() throws XMLSecurityException {
+        reset();
+        expect(TYPE_SEQUENCE);    // SubjectPublicKeyInfo SEQUENCE
+        getLength();
+        // Could enforce the max length of this sequence, but not actually
+        // necessary for our purposes, so be forgiving and simply ignore.
+        expect(TYPE_SEQUENCE);    // algorithm AlgorithmIdentifier SEQUENCE
+        int algIDlen = getLength();
+        if (algIDlen < 0) {
+            // Unsupported indefinite-length
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Unsupported X.509 public key format" }
+            );
+        }
+        skip(algIDlen);           // AlgorithmIdentifier contents
+        expect(TYPE_BIT_STRING);  // subjectPublicKey BIT STRING
+        int keyLen = getLength()-1;
+        if (keyLen < 0) {
+            // Invalid BIT STRING length
+            throw new XMLSecurityException(
+                    XMLSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
+                    "noSKIHandling",
+                    new Object[] { "Invalid X.509 public key format" }
+            );
+        }
+        skip(1);   // number unused bits
+        // DER-encoding guarantees unused bits should be 0
+
+        return getBytes(keyLen);
+    }
+}

Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java?rev=1241502&r1=1241501&r2=1241502&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java Tue Feb  7 15:51:14 2012
@@ -19,7 +19,7 @@
 package org.swssf.xmlsec.ext;
 
 import org.swssf.xmlsec.crypto.Crypto;
-import org.swssf.xmlsec.crypto.CryptoBase;
+import org.swssf.xmlsec.crypto.MerlinBase;
 
 import javax.security.auth.callback.CallbackHandler;
 import java.net.URL;
@@ -57,7 +57,7 @@ public class XMLSecurityProperties {
         return inputProcessorList;
     }
 
-    private Class<? extends CryptoBase> decryptionCryptoClass;
+    private Class<? extends MerlinBase> decryptionCryptoClass;
     private KeyStore decryptionKeyStore;
     private CallbackHandler callbackHandler;
 
@@ -88,7 +88,7 @@ public class XMLSecurityProperties {
      *
      * @return
      */
-    public Class<? extends CryptoBase> getDecryptionCryptoClass() {
+    public Class<? extends MerlinBase> getDecryptionCryptoClass() {
         if (decryptionCryptoClass != null) {
             return decryptionCryptoClass;
         }
@@ -101,7 +101,7 @@ public class XMLSecurityProperties {
      *
      * @param decryptionCryptoClass
      */
-    public void setDecryptionCryptoClass(Class<? extends CryptoBase> decryptionCryptoClass) {
+    public void setDecryptionCryptoClass(Class<? extends MerlinBase> decryptionCryptoClass) {
         this.decryptionCryptoClass = decryptionCryptoClass;
     }
 
@@ -124,10 +124,10 @@ public class XMLSecurityProperties {
             return cachedDecryptionCrypto;
         }
 
-        Class<? extends CryptoBase> decryptionCryptoClass = this.getDecryptionCryptoClass();
+        Class<? extends MerlinBase> decryptionCryptoClass = this.getDecryptionCryptoClass();
 
         try {
-            CryptoBase decryptionCrypto = decryptionCryptoClass.newInstance();
+            MerlinBase decryptionCrypto = decryptionCryptoClass.newInstance();
             decryptionCrypto.setKeyStore(this.getDecryptionKeyStore());
             cachedDecryptionCrypto = decryptionCrypto;
             cachedDecryptionKeyStore = this.getDecryptionKeyStore();
@@ -157,7 +157,7 @@ public class XMLSecurityProperties {
 
     private XMLSecurityConstants.Action[] outAction;
 
-    private Class<? extends CryptoBase> encryptionCryptoClass;
+    private Class<? extends MerlinBase> encryptionCryptoClass;
     private KeyStore encryptionKeyStore;
     private String encryptionUser;
     private X509Certificate encryptionUseThisCertificate;
@@ -192,7 +192,7 @@ public class XMLSecurityProperties {
      *
      * @return
      */
-    public Class<? extends CryptoBase> getEncryptionCryptoClass() {
+    public Class<? extends MerlinBase> getEncryptionCryptoClass() {
         if (encryptionCryptoClass != null) {
             return encryptionCryptoClass;
         }
@@ -205,7 +205,7 @@ public class XMLSecurityProperties {
      *
      * @param encryptionCryptoClass
      */
-    public void setEncryptionCryptoClass(Class<? extends CryptoBase> encryptionCryptoClass) {
+    public void setEncryptionCryptoClass(Class<? extends MerlinBase> encryptionCryptoClass) {
         this.encryptionCryptoClass = encryptionCryptoClass;
     }
 
@@ -228,10 +228,10 @@ public class XMLSecurityProperties {
             return cachedEncryptionCrypto;
         }
 
-        Class<? extends CryptoBase> encryptionCryptoClass = this.getEncryptionCryptoClass();
+        Class<? extends MerlinBase> encryptionCryptoClass = this.getEncryptionCryptoClass();
 
         try {
-            CryptoBase encryptionCrypto = encryptionCryptoClass.newInstance();
+            MerlinBase encryptionCrypto = encryptionCryptoClass.newInstance();
             encryptionCrypto.setKeyStore(this.getEncryptionKeyStore());
             cachedEncryptionCrypto = encryptionCrypto;
             cachedEncryptionKeyStore = this.getEncryptionKeyStore();
@@ -326,7 +326,7 @@ public class XMLSecurityProperties {
     private String signatureAlgorithm;
     private String signatureDigestAlgorithm;
     private String signatureCanonicalizationAlgorithm;
-    private Class<? extends CryptoBase> signatureCryptoClass;
+    private Class<? extends MerlinBase> signatureCryptoClass;
     private KeyStore signatureKeyStore;
     private String signatureUser;
     private boolean useSingleCert = true;
@@ -373,7 +373,7 @@ public class XMLSecurityProperties {
         this.signatureKeyStore = keyStore;
     }
 
-    public Class<? extends CryptoBase> getSignatureCryptoClass() {
+    public Class<? extends MerlinBase> getSignatureCryptoClass() {
         if (signatureCryptoClass != null) {
             return signatureCryptoClass;
         }
@@ -381,7 +381,7 @@ public class XMLSecurityProperties {
         return signatureCryptoClass;
     }
 
-    public void setSignatureCryptoClass(Class<? extends CryptoBase> signatureCryptoClass) {
+    public void setSignatureCryptoClass(Class<? extends MerlinBase> signatureCryptoClass) {
         this.signatureCryptoClass = signatureCryptoClass;
     }
 
@@ -398,10 +398,10 @@ public class XMLSecurityProperties {
             return cachedSignatureCrypto;
         }
 
-        Class<? extends CryptoBase> signatureCryptoClass = this.getSignatureCryptoClass();
+        Class<? extends MerlinBase> signatureCryptoClass = this.getSignatureCryptoClass();
 
         try {
-            CryptoBase signatureCrypto = signatureCryptoClass.newInstance();
+            MerlinBase signatureCrypto = signatureCryptoClass.newInstance();
             signatureCrypto.setKeyStore(this.getSignatureKeyStore());
             cachedSignatureCrypto = signatureCrypto;
             cachedSignatureKeyStore = this.getSignatureKeyStore();
@@ -445,7 +445,7 @@ public class XMLSecurityProperties {
         this.signatureCanonicalizationAlgorithm = signatureCanonicalizationAlgorithm;
     }
 
-    private Class<? extends CryptoBase> signatureVerificationCryptoClass;
+    private Class<? extends MerlinBase> signatureVerificationCryptoClass;
     private KeyStore signatureVerificationKeyStore;
 
     public KeyStore getSignatureVerificationKeyStore() {
@@ -458,7 +458,7 @@ public class XMLSecurityProperties {
         this.signatureVerificationKeyStore = keyStore;
     }
 
-    public Class<? extends CryptoBase> getSignatureVerificationCryptoClass() {
+    public Class<? extends MerlinBase> getSignatureVerificationCryptoClass() {
         if (signatureVerificationCryptoClass != null) {
             return signatureVerificationCryptoClass;
         }
@@ -466,7 +466,7 @@ public class XMLSecurityProperties {
         return signatureVerificationCryptoClass;
     }
 
-    public void setSignatureVerificationCryptoClass(Class<? extends CryptoBase> signatureVerificationCryptoClass) {
+    public void setSignatureVerificationCryptoClass(Class<? extends MerlinBase> signatureVerificationCryptoClass) {
         this.signatureVerificationCryptoClass = signatureVerificationCryptoClass;
     }
 
@@ -483,10 +483,10 @@ public class XMLSecurityProperties {
             return cachedSignatureVerificationCrypto;
         }
 
-        Class<? extends CryptoBase> signatureVerificationCryptoClass = this.getSignatureVerificationCryptoClass();
+        Class<? extends MerlinBase> signatureVerificationCryptoClass = this.getSignatureVerificationCryptoClass();
 
         try {
-            CryptoBase signatureVerificationCrypto = signatureVerificationCryptoClass.newInstance();
+            MerlinBase signatureVerificationCrypto = signatureVerificationCryptoClass.newInstance();
             signatureVerificationCrypto.setKeyStore(this.getSignatureVerificationKeyStore());
             cachedSignatureVerificationCrypto = signatureVerificationCrypto;
             cachedSignatureVerificationKeyStore = this.getSignatureVerificationKeyStore();

Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java?rev=1241502&r1=1241501&r2=1241502&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java Tue Feb  7 15:51:14 2012
@@ -18,18 +18,24 @@
  */
 package org.swssf.xmlsec.impl.processor.input;
 
-import org.apache.commons.codec.binary.Base64OutputStream;
-import org.swssf.binding.xmldsig.KeyInfoType;
-import org.swssf.binding.xmlenc.EncryptedDataType;
-import org.swssf.binding.xmlenc.ReferenceList;
-import org.swssf.binding.xmlenc.ReferenceType;
-import org.swssf.xmlsec.config.JCEAlgorithmMapper;
-import org.swssf.xmlsec.ext.*;
-import org.swssf.xmlsec.impl.XMLSecurityEventReader;
-import org.swssf.xmlsec.impl.securityToken.SecurityTokenFactory;
-import org.swssf.xmlsec.impl.util.IVSplittingOutputStream;
-import org.swssf.xmlsec.impl.util.ReplaceableOuputStream;
-import org.xmlsecurity.ns.configuration.AlgorithmType;
+import java.io.BufferedWriter;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
 
 import javax.crypto.Cipher;
 import javax.crypto.CipherOutputStream;
@@ -45,11 +51,30 @@ import javax.xml.stream.XMLStreamExcepti
 import javax.xml.stream.events.Attribute;
 import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
-import java.io.*;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.util.*;
+
+import org.apache.commons.codec.binary.Base64OutputStream;
+import org.swssf.binding.xmldsig.KeyInfoType;
+import org.swssf.binding.xmlenc.EncryptedDataType;
+import org.swssf.binding.xmlenc.ReferenceList;
+import org.swssf.binding.xmlenc.ReferenceType;
+import org.swssf.xmlsec.config.JCEAlgorithmMapper;
+import org.swssf.xmlsec.ext.AbstractInputProcessor;
+import org.swssf.xmlsec.ext.ComparableAttribute;
+import org.swssf.xmlsec.ext.ComparableNamespace;
+import org.swssf.xmlsec.ext.InputProcessorChain;
+import org.swssf.xmlsec.ext.SecurePart;
+import org.swssf.xmlsec.ext.SecurityContext;
+import org.swssf.xmlsec.ext.SecurityToken;
+import org.swssf.xmlsec.ext.UncheckedXMLSecurityException;
+import org.swssf.xmlsec.ext.XMLEventNS;
+import org.swssf.xmlsec.ext.XMLSecurityConstants;
+import org.swssf.xmlsec.ext.XMLSecurityException;
+import org.swssf.xmlsec.ext.XMLSecurityProperties;
+import org.swssf.xmlsec.ext.XMLSecurityUtils;
+import org.swssf.xmlsec.impl.XMLSecurityEventReader;
+import org.swssf.xmlsec.impl.util.IVSplittingOutputStream;
+import org.swssf.xmlsec.impl.util.ReplaceableOuputStream;
+import org.xmlsecurity.ns.configuration.AlgorithmType;
 
 /**
  * Processor for decryption of EncryptedData XML structures
@@ -69,6 +94,10 @@ public abstract class AbstractDecryptInp
 
     private ArrayDeque<XMLEvent> tmpXmlEventList = new ArrayDeque<XMLEvent>();
 
+    public AbstractDecryptInputProcessor(XMLSecurityProperties securityProperties) {
+        super(securityProperties);
+    }
+    
     public AbstractDecryptInputProcessor(ReferenceList referenceList, XMLSecurityProperties securityProperties) {
         super(securityProperties);
         this.referenceList = referenceList;
@@ -152,7 +181,7 @@ public abstract class AbstractDecryptInp
             //check if the current start-element has the name EncryptedData and an Id attribute
             if (startElement.getName().equals(XMLSecurityConstants.TAG_xenc_EncryptedData)) {
                 ReferenceType referenceType = matchesReferenceId(startElement);
-                if (referenceType != null) {
+                if (referenceType != null || referenceList == null) {
                     //duplicate id's are forbidden
                     if (processedReferences.contains(referenceType)) {
                         throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, "duplicateId");
@@ -226,11 +255,15 @@ public abstract class AbstractDecryptInp
                     final String algorithmURI = encryptedDataType.getEncryptionMethod().getAlgorithm();
 
                     //retrieve the securityToken which must be used for decryption
-                    SecurityToken securityToken = SecurityTokenFactory.newInstance().getSecurityToken(
-                            keyInfoType, getSecurityProperties().getDecryptionCrypto(),
-                            getSecurityProperties().getCallbackHandler(), inputProcessorChain.getSecurityContext(), this);
-
-                    handleSecurityToken(securityToken, inputProcessorChain.getSecurityContext(), encryptedDataType);
+                    SecurityToken securityToken = 
+                            findSecurityToken(keyInfoType, getSecurityProperties(), 
+                                    inputProcessorChain.getSecurityContext(), this);
+                    if (securityToken != null) {
+                        handleSecurityToken(
+                            securityToken, inputProcessorChain.getSecurityContext(), encryptedDataType
+                        );
+                    }
+                    
                     //only fire here ContentEncryptedElementEvents
                     //the other ones will be fired later, because we don't know the encrypted element name yet
                     if (SecurePart.Modifier.Content.getModifier().equals(encryptedDataType.getType())) {
@@ -323,6 +356,10 @@ public abstract class AbstractDecryptInp
             boolean encryptedHeader, List<ComparableNamespace>[] comparableNamespaceList,
             List<ComparableAttribute>[] comparableAttributeList, EncryptedDataType currentEncryptedDataType, SecurityToken securityToken);
 
+    protected abstract SecurityToken findSecurityToken(
+            KeyInfoType keyInfoType, XMLSecurityProperties securityProperties,
+            SecurityContext securityContext, Object processor) throws XMLSecurityException;
+    
     protected abstract void handleSecurityToken(
             SecurityToken securityToken, SecurityContext securityContext, EncryptedDataType encryptedDataType) throws XMLSecurityException;
 
@@ -350,12 +387,14 @@ public abstract class AbstractDecryptInp
     @Override
     public void doFinal(InputProcessorChain inputProcessorChain) throws XMLStreamException, XMLSecurityException {
         //here we check if all references where processed.
-        List<JAXBElement<ReferenceType>> references = referenceList.getDataReferenceOrKeyReference();
-        Iterator<JAXBElement<ReferenceType>> referenceTypeIterator = references.iterator();
-        while (referenceTypeIterator.hasNext()) {
-            ReferenceType referenceType = referenceTypeIterator.next().getValue();
-            if (!processedReferences.contains(referenceType)) {
-                throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, "unprocessedEncryptionReferences");
+        if (referenceList != null) {
+            List<JAXBElement<ReferenceType>> references = referenceList.getDataReferenceOrKeyReference();
+            Iterator<JAXBElement<ReferenceType>> referenceTypeIterator = references.iterator();
+            while (referenceTypeIterator.hasNext()) {
+                ReferenceType referenceType = referenceTypeIterator.next().getValue();
+                if (!processedReferences.contains(referenceType)) {
+                    throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, "unprocessedEncryptionReferences");
+                }
             }
         }
         inputProcessorChain.doFinal();

Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/messages/errors.properties
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/messages/errors.properties?rev=1241502&r1=1241501&r2=1241502&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/messages/errors.properties (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/messages/errors.properties Tue Feb  7 15:51:14 2012
@@ -121,3 +121,8 @@ unexpectedXMLEvent = "Unexpected event: 
 notASOAPMessage = Request is not a valid SOAP Message
 digestVerificationFailed = Digest verification failed for URI {0}
 unsupportedSecurityToken = Unsupported SecurityToken {0}
+
+proxyNotFound = Proxy file ({0}) not found.
+ioError00 = Failed to load credentials.
+secError00 = Failed to load credentials.
+error00 = Failed to load credentials.



Mime
View raw message