Search in sources :

Example 1 with CertificateVerifier

use of org.apache.tomcat.jni.CertificateVerifier in project tomcat by apache.

the class OpenSSLContext method init.

/**
     * Setup the SSL_CTX.
     *
     * @param kms Must contain a KeyManager of the type
     *            {@code OpenSSLKeyManager}
     * @param tms Must contain a TrustManager of the type
     *            {@code X509TrustManager}
     * @param sr Is not used for this implementation.
     */
@Override
public synchronized void init(KeyManager[] kms, TrustManager[] tms, SecureRandom sr) {
    if (initialized) {
        log.warn(sm.getString("openssl.doubleInit"));
        return;
    }
    try {
        if (sslHostConfig.getInsecureRenegotiation()) {
            SSLContext.setOptions(ctx, SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
        } else {
            SSLContext.clearOptions(ctx, SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
        }
        // client's)
        if (sslHostConfig.getHonorCipherOrder()) {
            SSLContext.setOptions(ctx, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
        } else {
            SSLContext.clearOptions(ctx, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
        }
        // Disable compression if requested
        if (sslHostConfig.getDisableCompression()) {
            SSLContext.setOptions(ctx, SSL.SSL_OP_NO_COMPRESSION);
        } else {
            SSLContext.clearOptions(ctx, SSL.SSL_OP_NO_COMPRESSION);
        }
        // Disable TLS Session Tickets (RFC4507) to protect perfect forward secrecy
        if (sslHostConfig.getDisableSessionTickets()) {
            SSLContext.setOptions(ctx, SSL.SSL_OP_NO_TICKET);
        } else {
            SSLContext.clearOptions(ctx, SSL.SSL_OP_NO_TICKET);
        }
        // Set session cache size, if specified
        if (sslHostConfig.getSessionCacheSize() > 0) {
            SSLContext.setSessionCacheSize(ctx, sslHostConfig.getSessionCacheSize());
        } else {
            // Get the default session cache size using SSLContext.setSessionCacheSize()
            long sessionCacheSize = SSLContext.setSessionCacheSize(ctx, 20480);
            // Revert the session cache size to the default value.
            SSLContext.setSessionCacheSize(ctx, sessionCacheSize);
        }
        // Set session timeout, if specified
        if (sslHostConfig.getSessionTimeout() > 0) {
            SSLContext.setSessionCacheTimeout(ctx, sslHostConfig.getSessionTimeout());
        } else {
            // Get the default session timeout using SSLContext.setSessionCacheTimeout()
            long sessionTimeout = SSLContext.setSessionCacheTimeout(ctx, 300);
            // Revert the session timeout to the default value.
            SSLContext.setSessionCacheTimeout(ctx, sessionTimeout);
        }
        // List the ciphers that the client is permitted to negotiate
        String opensslCipherConfig = sslHostConfig.getCiphers();
        this.jsseCipherNames = OpenSSLCipherConfigurationParser.parseExpression(opensslCipherConfig);
        SSLContext.setCipherSuite(ctx, opensslCipherConfig);
        // Load Server key and certificate
        if (certificate.getCertificateFile() != null) {
            // Set certificate
            SSLContext.setCertificate(ctx, SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()), certificate.getCertificateKeyPassword(), SSL.SSL_AIDX_RSA);
            // Set certificate chain file
            SSLContext.setCertificateChainFile(ctx, SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
            // Support Client Certificates
            SSLContext.setCACertificate(ctx, SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()), SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()));
            // Set revocation
            SSLContext.setCARevocation(ctx, SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()), SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()));
        } else {
            X509KeyManager keyManager = chooseKeyManager(kms);
            String alias = certificate.getCertificateKeyAlias();
            if (alias == null) {
                alias = "tomcat";
            }
            X509Certificate[] chain = keyManager.getCertificateChain(alias);
            if (chain == null) {
                alias = findAlias(keyManager, certificate);
                chain = keyManager.getCertificateChain(alias);
            }
            PrivateKey key = keyManager.getPrivateKey(alias);
            StringBuilder sb = new StringBuilder(BEGIN_KEY);
            sb.append(Base64.getMimeEncoder(64, new byte[] { '\n' }).encodeToString(key.getEncoded()));
            sb.append(END_KEY);
            SSLContext.setCertificateRaw(ctx, chain[0].getEncoded(), sb.toString().getBytes(StandardCharsets.US_ASCII), SSL.SSL_AIDX_RSA);
            for (int i = 1; i < chain.length; i++) {
                SSLContext.addChainCertificateRaw(ctx, chain[i].getEncoded());
            }
        }
        // Client certificate verification
        int value = 0;
        switch(sslHostConfig.getCertificateVerification()) {
            case NONE:
                value = SSL.SSL_CVERIFY_NONE;
                break;
            case OPTIONAL:
                value = SSL.SSL_CVERIFY_OPTIONAL;
                break;
            case OPTIONAL_NO_CA:
                value = SSL.SSL_CVERIFY_OPTIONAL_NO_CA;
                break;
            case REQUIRED:
                value = SSL.SSL_CVERIFY_REQUIRE;
                break;
        }
        SSLContext.setVerify(ctx, value, sslHostConfig.getCertificateVerificationDepth());
        if (tms != null) {
            final X509TrustManager manager = chooseTrustManager(tms);
            SSLContext.setCertVerifyCallback(ctx, new CertificateVerifier() {

                @Override
                public boolean verify(long ssl, byte[][] chain, String auth) {
                    X509Certificate[] peerCerts = certificates(chain);
                    try {
                        manager.checkClientTrusted(peerCerts, auth);
                        return true;
                    } catch (Exception e) {
                        log.debug(sm.getString("openssl.certificateVerificationFailed"), e);
                    }
                    return false;
                }
            });
        }
        if (negotiableProtocols != null && negotiableProtocols.size() > 0) {
            ArrayList<String> protocols = new ArrayList<>();
            protocols.addAll(negotiableProtocols);
            protocols.add("http/1.1");
            String[] protocolsArray = protocols.toArray(new String[0]);
            SSLContext.setAlpnProtos(ctx, protocolsArray, SSL.SSL_SELECTOR_FAILURE_NO_ADVERTISE);
            SSLContext.setNpnProtos(ctx, protocolsArray, SSL.SSL_SELECTOR_FAILURE_NO_ADVERTISE);
        }
        sessionContext = new OpenSSLSessionContext(ctx);
        sslHostConfig.setOpenSslContext(Long.valueOf(ctx));
        initialized = true;
    } catch (Exception e) {
        log.warn(sm.getString("openssl.errorSSLCtxInit"), e);
        destroy();
    }
}
Also used : PrivateKey(java.security.PrivateKey) ArrayList(java.util.ArrayList) X509Certificate(java.security.cert.X509Certificate) AbstractEndpoint(org.apache.tomcat.util.net.AbstractEndpoint) CertificateException(java.security.cert.CertificateException) SSLException(javax.net.ssl.SSLException) X509TrustManager(javax.net.ssl.X509TrustManager) CertificateVerifier(org.apache.tomcat.jni.CertificateVerifier) X509KeyManager(javax.net.ssl.X509KeyManager)

Aggregations

PrivateKey (java.security.PrivateKey)1 CertificateException (java.security.cert.CertificateException)1 X509Certificate (java.security.cert.X509Certificate)1 ArrayList (java.util.ArrayList)1 SSLException (javax.net.ssl.SSLException)1 X509KeyManager (javax.net.ssl.X509KeyManager)1 X509TrustManager (javax.net.ssl.X509TrustManager)1 CertificateVerifier (org.apache.tomcat.jni.CertificateVerifier)1 AbstractEndpoint (org.apache.tomcat.util.net.AbstractEndpoint)1