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();
}
}
Aggregations