Search in sources :

Example 1 with JSSEKeyManager

use of org.apache.tomcat.util.net.jsse.JSSEKeyManager in project tomcat by apache.

the class SSLUtilBase method getKeyManagers.

@Override
public KeyManager[] getKeyManagers() throws Exception {
    String keyAlias = certificate.getCertificateKeyAlias();
    String algorithm = sslHostConfig.getKeyManagerAlgorithm();
    String keyPass = certificate.getCertificateKeyPassword();
    // defaults vary between JSSE and OpenSSL.
    if (keyPass == null) {
        keyPass = certificate.getCertificateKeystorePassword();
    }
    KeyStore ks = certificate.getCertificateKeystore();
    KeyStore ksUsed = ks;
    /*
         * Use an in memory key store where possible.
         * For PEM format keys and certificates, it allows them to be imported
         * into the expected format.
         * For Java key stores with PKCS8 encoded keys (e.g. JKS files), it
         * enables Tomcat to handle the case where multiple keys exist in the
         * key store, each with a different password. The KeyManagerFactory
         * can't handle that so using an in memory key store with just the
         * required key works around that.
         * Other keys stores (hardware, MS, etc.) will be used as is.
         */
    char[] keyPassArray = keyPass.toCharArray();
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
    if (kmf.getProvider().getInfo().indexOf("FIPS") != -1) {
        // FIPS doesn't like ANY wrapping nor key manipulation.
        if (keyAlias != null) {
            log.warn(sm.getString("sslUtilBase.aliasIgnored", keyAlias));
        }
        kmf.init(ksUsed, keyPassArray);
        return kmf.getKeyManagers();
    }
    if (ks == null) {
        if (certificate.getCertificateFile() == null) {
            throw new IOException(sm.getString("sslUtilBase.noCertFile"));
        }
        PEMFile privateKeyFile = new PEMFile(certificate.getCertificateKeyFile() != null ? certificate.getCertificateKeyFile() : certificate.getCertificateFile(), keyPass);
        PEMFile certificateFile = new PEMFile(certificate.getCertificateFile());
        Collection<Certificate> chain = new ArrayList<>(certificateFile.getCertificates());
        if (certificate.getCertificateChainFile() != null) {
            PEMFile certificateChainFile = new PEMFile(certificate.getCertificateChainFile());
            chain.addAll(certificateChainFile.getCertificates());
        }
        if (keyAlias == null) {
            keyAlias = "tomcat";
        }
        // Switch to in-memory key store
        ksUsed = KeyStore.getInstance("JKS");
        ksUsed.load(null, null);
        ksUsed.setKeyEntry(keyAlias, privateKeyFile.getPrivateKey(), keyPass.toCharArray(), chain.toArray(new Certificate[0]));
    } else {
        if (keyAlias != null && !ks.isKeyEntry(keyAlias)) {
            throw new IOException(sm.getString("sslUtilBase.alias_no_key_entry", keyAlias));
        } else if (keyAlias == null) {
            Enumeration<String> aliases = ks.aliases();
            if (!aliases.hasMoreElements()) {
                throw new IOException(sm.getString("sslUtilBase.noKeys"));
            }
            while (aliases.hasMoreElements() && keyAlias == null) {
                keyAlias = aliases.nextElement();
                if (!ks.isKeyEntry(keyAlias)) {
                    keyAlias = null;
                }
            }
            if (keyAlias == null) {
                throw new IOException(sm.getString("sslUtilBase.alias_no_key_entry", (Object) null));
            }
        }
        Key k = ks.getKey(keyAlias, keyPassArray);
        if (k != null && !"DKS".equalsIgnoreCase(certificate.getCertificateKeystoreType()) && "PKCS#8".equalsIgnoreCase(k.getFormat())) {
            // Switch to in-memory key store
            String provider = certificate.getCertificateKeystoreProvider();
            if (provider == null) {
                ksUsed = KeyStore.getInstance(certificate.getCertificateKeystoreType());
            } else {
                ksUsed = KeyStore.getInstance(certificate.getCertificateKeystoreType(), provider);
            }
            ksUsed.load(null, null);
            ksUsed.setKeyEntry(keyAlias, k, keyPassArray, ks.getCertificateChain(keyAlias));
        }
    // Non-PKCS#8 key stores will use the original key store
    }
    kmf.init(ksUsed, keyPassArray);
    KeyManager[] kms = kmf.getKeyManagers();
    // have a single key so don't need filtering
    if (kms != null && ksUsed == ks) {
        String alias = keyAlias;
        // JKS keystores always convert the alias name to lower case
        if ("JKS".equals(certificate.getCertificateKeystoreType())) {
            alias = alias.toLowerCase(Locale.ENGLISH);
        }
        for (int i = 0; i < kms.length; i++) {
            kms[i] = new JSSEKeyManager((X509KeyManager) kms[i], alias);
        }
    }
    return kms;
}
Also used : Enumeration(java.util.Enumeration) ArrayList(java.util.ArrayList) IOException(java.io.IOException) KeyStore(java.security.KeyStore) JSSEKeyManager(org.apache.tomcat.util.net.jsse.JSSEKeyManager) KeyManagerFactory(javax.net.ssl.KeyManagerFactory) X509KeyManager(javax.net.ssl.X509KeyManager) PEMFile(org.apache.tomcat.util.net.jsse.PEMFile) X509KeyManager(javax.net.ssl.X509KeyManager) JSSEKeyManager(org.apache.tomcat.util.net.jsse.JSSEKeyManager) KeyManager(javax.net.ssl.KeyManager) Key(java.security.Key) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Aggregations

IOException (java.io.IOException)1 Key (java.security.Key)1 KeyStore (java.security.KeyStore)1 Certificate (java.security.cert.Certificate)1 X509Certificate (java.security.cert.X509Certificate)1 ArrayList (java.util.ArrayList)1 Enumeration (java.util.Enumeration)1 KeyManager (javax.net.ssl.KeyManager)1 KeyManagerFactory (javax.net.ssl.KeyManagerFactory)1 X509KeyManager (javax.net.ssl.X509KeyManager)1 JSSEKeyManager (org.apache.tomcat.util.net.jsse.JSSEKeyManager)1 PEMFile (org.apache.tomcat.util.net.jsse.PEMFile)1