use of jdk.incubator.foreign.MemorySegment in project tomcat by apache.
the class OpenSSLContext method openSSLCallbackAlpnSelectProto.
// int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned char *outlen,
// const unsigned char *in, unsigned int inlen, void *arg)
public static int openSSLCallbackAlpnSelectProto(MemoryAddress ssl, MemoryAddress out, MemoryAddress outlen, MemoryAddress in, int inlen, MemoryAddress arg) {
ContextState state = getState(arg);
if (state == null) {
log.warn(sm.getString("context.noSSL", Long.valueOf(arg.toRawLongValue())));
return SSL_TLSEXT_ERR_NOACK();
}
// However, the Java 17 API forces use of a scope later on, so create one for everything
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
byte[] advertisedBytes = in.asSegment(inlen, scope).toByteArray();
for (byte[] negotiableProtocolBytes : state.negotiableProtocols) {
for (int i = 0; i <= advertisedBytes.length - negotiableProtocolBytes.length; i++) {
if (advertisedBytes[i] == negotiableProtocolBytes[0]) {
for (int j = 0; j < negotiableProtocolBytes.length; j++) {
if (advertisedBytes[i + j] == negotiableProtocolBytes[j]) {
if (j == negotiableProtocolBytes.length - 1) {
MemorySegment outSegment = out.asSegment(CLinker.C_POINTER.byteSize(), scope);
MemorySegment outlenSegment = outlen.asSegment(CLinker.C_CHAR.byteSize(), scope);
// Match
MemoryAccess.setAddress(outSegment, in.addOffset(i));
MemoryAccess.setByte(outlenSegment, (byte) negotiableProtocolBytes.length);
return SSL_TLSEXT_ERR_OK();
}
} else {
break;
}
}
}
}
}
return SSL_TLSEXT_ERR_NOACK();
}
}
use of jdk.incubator.foreign.MemorySegment in project tomcat by apache.
the class OpenSSLContext method addCertificate.
private void addCertificate(SSLHostConfigCertificate certificate) throws Exception {
var allocator = SegmentAllocator.ofScope(state.contextScope);
int index = getCertificateIndex(certificate);
// Load Server key and certificate
if (certificate.getCertificateFile() != null) {
// Set certificate
// SSLContext.setCertificate(state.ctx,
// SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()),
// SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()),
// certificate.getCertificateKeyPassword(), getCertificateIndex(certificate));
var certificateFileNative = CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), state.contextScope);
var certificateKeyFileNative = (certificate.getCertificateKeyFile() == null) ? certificateFileNative : CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()), state.contextScope);
MemoryAddress bio;
MemoryAddress cert = MemoryAddress.NULL;
MemoryAddress key = MemoryAddress.NULL;
if (certificate.getCertificateFile().endsWith(".pkcs12")) {
// Load pkcs12
bio = BIO_new(BIO_s_file());
// (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
BIO_free(bio);
log.error(sm.getString("openssl.errorLoadingCertificate", "[0]:" + certificate.getCertificateFile()));
return;
}
MemoryAddress p12 = d2i_PKCS12_bio(bio, MemoryAddress.NULL);
BIO_free(bio);
if (MemoryAddress.NULL.equals(p12)) {
log.error(sm.getString("openssl.errorLoadingCertificate", "[1]:" + certificate.getCertificateFile()));
return;
}
MemoryAddress passwordAddress = MemoryAddress.NULL;
int passwordLength = 0;
String callbackPassword = certificate.getCertificateKeyPassword();
if (callbackPassword != null && callbackPassword.length() > 0) {
MemorySegment password = CLinker.toCString(callbackPassword, state.contextScope);
passwordAddress = password.address();
passwordLength = (int) (password.byteSize() - 1);
}
if (PKCS12_verify_mac(p12, passwordAddress, passwordLength) <= 0) {
// Bad password
log.error(sm.getString("openssl.errorLoadingCertificate", "[2]:" + certificate.getCertificateFile()));
PKCS12_free(p12);
return;
}
MemorySegment certPointer = allocator.allocate(CLinker.C_POINTER);
MemorySegment keyPointer = allocator.allocate(CLinker.C_POINTER);
if (PKCS12_parse(p12, passwordAddress, keyPointer, certPointer, MemoryAddress.NULL) <= 0) {
log.error(sm.getString("openssl.errorLoadingCertificate", "[3]:" + certificate.getCertificateFile()));
PKCS12_free(p12);
return;
}
PKCS12_free(p12);
cert = MemoryAccess.getAddress(certPointer);
key = MemoryAccess.getAddress(keyPointer);
} else {
// Load key
bio = BIO_new(BIO_s_file());
// (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateKeyFileNative) <= 0) {
BIO_free(bio);
log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
return;
}
key = MemoryAddress.NULL;
for (int i = 0; i < 3; i++) {
try {
callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
key = PEM_read_bio_PrivateKey(bio, MemoryAddress.NULL, openSSLCallbackPassword, MemoryAddress.NULL);
} finally {
callbackPasswordTheadLocal.set(null);
}
if (!MemoryAddress.NULL.equals(key)) {
break;
}
BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemoryAddress.NULL);
}
BIO_free(bio);
if (MemoryAddress.NULL.equals(key)) {
if (!MemoryAddress.NULL.equals(OpenSSLLifecycleListener.enginePointer)) {
key = ENGINE_load_private_key(OpenSSLLifecycleListener.enginePointer, certificateKeyFileNative, MemoryAddress.NULL, MemoryAddress.NULL);
}
}
if (MemoryAddress.NULL.equals(key)) {
log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
return;
}
// Load certificate
bio = BIO_new(BIO_s_file());
if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
BIO_free(bio);
log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
return;
}
try {
callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
cert = PEM_read_bio_X509_AUX(bio, MemoryAddress.NULL, openSSLCallbackPassword, MemoryAddress.NULL);
} finally {
callbackPasswordTheadLocal.set(null);
}
if (MemoryAddress.NULL.equals(cert) && /*int ERR_GET_REASON(unsigned long errcode) {
* if (ERR_SYSTEM_ERROR(errcode))
* return errcode & ERR_SYSTEM_MASK;
* return errcode & ERR_REASON_MASK;
*}
*# define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0)
*# define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1)
*# define ERR_SYSTEM_MASK ((unsigned int)INT_MAX)
*# define ERR_REASON_MASK 0X7FFFFF
*/
((ERR_peek_last_error() & 0X7FFFFF) == PEM_R_NO_START_LINE())) {
ERR_clear_error();
BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemoryAddress.NULL);
cert = d2i_X509_bio(bio, MemoryAddress.NULL);
}
BIO_free(bio);
if (MemoryAddress.NULL.equals(cert)) {
log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
return;
}
}
if (SSL_CTX_use_certificate(state.sslCtx, cert) <= 0) {
logLastError(allocator, "openssl.errorLoadingCertificate");
return;
}
if (SSL_CTX_use_PrivateKey(state.sslCtx, key) <= 0) {
logLastError(allocator, "openssl.errorLoadingPrivateKey");
return;
}
if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
logLastError(allocator, "openssl.errorPrivateKeyCheck");
return;
}
// Try to read DH parameters from the (first) SSLCertificateFile
if (index == SSL_AIDX_RSA) {
bio = BIO_new_file(certificateFileNative, CLinker.toCString("r", state.contextScope));
var dh = PEM_read_bio_DHparams(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
BIO_free(bio);
// SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh))
if (!MemoryAddress.NULL.equals(dh)) {
SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0, dh);
DH_free(dh);
}
}
// Similarly, try to read the ECDH curve name from SSLCertificateFile...
bio = BIO_new_file(certificateFileNative, CLinker.toCString("r", state.contextScope));
var ecparams = PEM_read_bio_ECPKParameters(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
BIO_free(bio);
if (!MemoryAddress.NULL.equals(ecparams)) {
int nid = EC_GROUP_get_curve_name(ecparams);
var eckey = EC_KEY_new_by_curve_name(nid);
// # define SSL_CTX_set_tmp_ecdh(sslCtx,ecdh) \
// SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh))
SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_ECDH(), 0, eckey);
EC_KEY_free(eckey);
EC_GROUP_free(ecparams);
}
// Set callback for DH parameters
MemoryAddress openSSLCallbackTmpDH = CLinker.getInstance().upcallStub(openSSLCallbackTmpDHHandle, openSSLCallbackTmpDHFunctionDescriptor, state.contextScope);
SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
// Set certificate chain file
if (certificate.getCertificateChainFile() != null) {
var certificateChainFileNative = CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), state.contextScope);
// SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
if (SSL_CTX_use_certificate_chain_file(state.sslCtx, certificateChainFileNative) <= 0) {
log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateChainFile()));
}
}
// Set revocation
// SSLContext.setCARevocation(state.ctx,
// SSLHostConfig.adjustRelativePath(
// sslHostConfig.getCertificateRevocationListFile()),
// SSLHostConfig.adjustRelativePath(
// sslHostConfig.getCertificateRevocationListPath()));
MemoryAddress certificateStore = SSL_CTX_get_cert_store(state.sslCtx);
if (sslHostConfig.getCertificateRevocationListFile() != null) {
MemoryAddress x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_file());
var certificateRevocationListFileNative = CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()), state.contextScope);
// X509_LOOKUP_ctrl(lookup,X509_L_FILE_LOAD,file,type,NULL)
if (X509_LOOKUP_ctrl(x509Lookup, X509_L_FILE_LOAD(), certificateRevocationListFileNative, X509_FILETYPE_PEM(), MemoryAddress.NULL) <= 0) {
log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListFile()));
}
}
if (sslHostConfig.getCertificateRevocationListPath() != null) {
MemoryAddress x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_hash_dir());
var certificateRevocationListPathNative = CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()), state.contextScope);
// X509_LOOKUP_ctrl(lookup,X509_L_ADD_DIR,path,type,NULL)
if (X509_LOOKUP_ctrl(x509Lookup, X509_L_ADD_DIR(), certificateRevocationListPathNative, X509_FILETYPE_PEM(), MemoryAddress.NULL) <= 0) {
log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListPath()));
}
}
X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK() | X509_V_FLAG_CRL_CHECK_ALL());
} else {
String alias = certificate.getCertificateKeyAlias();
X509KeyManager x509KeyManager = certificate.getCertificateKeyManager();
if (alias == null) {
alias = "tomcat";
}
X509Certificate[] chain = x509KeyManager.getCertificateChain(alias);
if (chain == null) {
alias = findAlias(x509KeyManager, certificate);
chain = x509KeyManager.getCertificateChain(alias);
}
PrivateKey key = x509KeyManager.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(state.ctx, chain[0].getEncoded(),
// sb.toString().getBytes(StandardCharsets.US_ASCII),
// getCertificateIndex(certificate));
var rawCertificate = allocator.allocateArray(CLinker.C_CHAR, chain[0].getEncoded());
var rawCertificatePointer = allocator.allocate(CLinker.C_POINTER, rawCertificate);
var rawKey = allocator.allocateArray(CLinker.C_CHAR, sb.toString().getBytes(StandardCharsets.US_ASCII));
var x509cert = d2i_X509(MemoryAddress.NULL, rawCertificatePointer, rawCertificate.byteSize());
if (MemoryAddress.NULL.equals(x509cert)) {
logLastError(allocator, "openssl.errorLoadingCertificate");
return;
}
var bio = BIO_new(BIO_s_mem());
BIO_write(bio, rawKey.address(), (int) rawKey.byteSize());
MemoryAddress privateKeyAddress = PEM_read_bio_PrivateKey(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
BIO_free(bio);
if (MemoryAddress.NULL.equals(privateKeyAddress)) {
logLastError(allocator, "openssl.errorLoadingPrivateKey");
return;
}
if (SSL_CTX_use_certificate(state.sslCtx, x509cert) <= 0) {
logLastError(allocator, "openssl.errorLoadingCertificate");
return;
}
if (SSL_CTX_use_PrivateKey(state.sslCtx, privateKeyAddress) <= 0) {
logLastError(allocator, "openssl.errorLoadingPrivateKey");
return;
}
if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
logLastError(allocator, "openssl.errorPrivateKeyCheck");
return;
}
// Set callback for DH parameters
MemoryAddress openSSLCallbackTmpDH = CLinker.getInstance().upcallStub(openSSLCallbackTmpDHHandle, openSSLCallbackTmpDHFunctionDescriptor, state.contextScope);
SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
for (int i = 1; i < chain.length; i++) {
// SSLContext.addChainCertificateRaw(state.ctx, chain[i].getEncoded());
var rawCertificateChain = allocator.allocateArray(CLinker.C_CHAR, chain[i].getEncoded());
var rawCertificateChainPointer = allocator.allocate(CLinker.C_POINTER, rawCertificateChain);
var x509certChain = d2i_X509(MemoryAddress.NULL, rawCertificateChainPointer, rawCertificateChain.byteSize());
if (MemoryAddress.NULL.equals(x509certChain)) {
logLastError(allocator, "openssl.errorLoadingCertificate");
return;
}
// # define SSL_CTX_add0_chain_cert(sslCtx,x509) SSL_CTX_ctrl(sslCtx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
if (SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_CHAIN_CERT(), 0, x509certChain) <= 0) {
logLastError(allocator, "openssl.errorAddingCertificate");
return;
}
}
}
}
use of jdk.incubator.foreign.MemorySegment in project tomcat by apache.
the class OpenSSLContext method openSSLCallbackPassword.
public static int openSSLCallbackPassword(MemoryAddress buf, int bufsiz, int verify, MemoryAddress cb) {
if (log.isDebugEnabled()) {
log.debug("Return password for certificate");
}
String callbackPassword = callbackPasswordTheadLocal.get();
if (callbackPassword != null && callbackPassword.length() > 0) {
try (var scope = ResourceScope.newConfinedScope()) {
MemorySegment callbackPasswordNative = CLinker.toCString(callbackPassword, scope);
if (callbackPasswordNative.byteSize() > bufsiz) {
// The password is too long
log.error(sm.getString("openssl.passwordTooLong"));
} else {
MemorySegment bufSegment = buf.asSegment(bufsiz, scope);
bufSegment.copyFrom(callbackPasswordNative);
return (int) callbackPasswordNative.byteSize();
}
}
}
return 0;
}
use of jdk.incubator.foreign.MemorySegment 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()) {
SSL_CTX_set_options(state.sslCtx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
} else {
SSL_CTX_clear_options(state.sslCtx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
}
// client's)
if (sslHostConfig.getHonorCipherOrder()) {
SSL_CTX_set_options(state.sslCtx, SSL_OP_CIPHER_SERVER_PREFERENCE());
} else {
SSL_CTX_clear_options(state.sslCtx, SSL_OP_CIPHER_SERVER_PREFERENCE());
}
// Disable compression if requested
if (sslHostConfig.getDisableCompression()) {
SSL_CTX_set_options(state.sslCtx, SSL_OP_NO_COMPRESSION());
} else {
SSL_CTX_clear_options(state.sslCtx, SSL_OP_NO_COMPRESSION());
}
// Disable TLS Session Tickets (RFC4507) to protect perfect forward secrecy
if (sslHostConfig.getDisableSessionTickets()) {
SSL_CTX_set_options(state.sslCtx, SSL_OP_NO_TICKET());
} else {
SSL_CTX_clear_options(state.sslCtx, SSL_OP_NO_TICKET());
}
// List the ciphers that the client is permitted to negotiate
if (SSL_CTX_set_cipher_list(state.sslCtx, CLinker.toCString(sslHostConfig.getCiphers(), state.contextScope)) <= 0) {
log.warn(sm.getString("engine.failedCipherSuite", sslHostConfig.getCiphers()));
}
if (certificate.getCertificateFile() == null) {
certificate.setCertificateKeyManager(OpenSSLUtil.chooseKeyManager(kms));
}
addCertificate(certificate);
// Client certificate verification
int value = 0;
switch(sslHostConfig.getCertificateVerification()) {
case NONE:
value = SSL_VERIFY_NONE();
break;
case OPTIONAL:
value = SSL_VERIFY_PEER();
break;
case OPTIONAL_NO_CA:
value = OPTIONAL_NO_CA;
break;
case REQUIRED:
value = SSL_VERIFY_FAIL_IF_NO_PEER_CERT();
break;
}
// SSLContext.setVerify(state.ctx, value, sslHostConfig.getCertificateVerificationDepth());
if (SSL_CTX_set_default_verify_paths(state.sslCtx) > 0) {
var store = SSL_CTX_get_cert_store(state.sslCtx);
X509_STORE_set_flags(store, 0);
}
// Set int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) callback
MemoryAddress openSSLCallbackVerify = CLinker.getInstance().upcallStub(openSSLCallbackVerifyHandle, openSSLCallbackVerifyFunctionDescriptor, state.contextScope);
// Leave this just in case but in Tomcat this is always set again by the engine
SSL_CTX_set_verify(state.sslCtx, value, openSSLCallbackVerify);
// Trust and certificate verification
var allocator = SegmentAllocator.ofScope(state.contextScope);
if (tms != null) {
// Client certificate verification based on custom trust managers
state.x509TrustManager = chooseTrustManager(tms);
MemoryAddress openSSLCallbackCertVerify = CLinker.getInstance().upcallStub(openSSLCallbackCertVerifyHandle, openSSLCallbackCertVerifyFunctionDescriptor, state.contextScope);
SSL_CTX_set_cert_verify_callback(state.sslCtx, openSSLCallbackCertVerify, state.sslCtx);
// an acceptable certificate
for (X509Certificate caCert : state.x509TrustManager.getAcceptedIssuers()) {
// SSLContext.addClientCACertificateRaw(state.ctx, caCert.getEncoded());
var rawCACertificate = allocator.allocateArray(CLinker.C_CHAR, caCert.getEncoded());
var rawCACertificatePointer = allocator.allocate(CLinker.C_POINTER, rawCACertificate);
var x509CACert = d2i_X509(MemoryAddress.NULL, rawCACertificatePointer, rawCACertificate.byteSize());
if (MemoryAddress.NULL.equals(x509CACert)) {
logLastError(allocator, "openssl.errorLoadingCertificate");
} else if (SSL_CTX_add_client_CA(state.sslCtx, x509CACert) <= 0) {
logLastError(allocator, "openssl.errorAddingCertificate");
} else if (log.isDebugEnabled()) {
log.debug(sm.getString("openssl.addedClientCaCert", caCert.toString()));
}
}
} else {
// Client certificate verification based on trusted CA files and dirs
// SSLContext.setCACertificate(state.ctx,
// SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()),
// SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()));
MemorySegment caCertificateFileNative = sslHostConfig.getCaCertificateFile() != null ? CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()), state.contextScope) : null;
MemorySegment caCertificatePathNative = sslHostConfig.getCaCertificatePath() != null ? CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()), state.contextScope) : null;
if (SSL_CTX_load_verify_locations(state.sslCtx, caCertificateFileNative == null ? MemoryAddress.NULL : caCertificateFileNative, caCertificatePathNative == null ? MemoryAddress.NULL : caCertificatePathNative) <= 0) {
logLastError(allocator, "openssl.errorConfiguringLocations");
} else {
var caCerts = SSL_CTX_get_client_CA_list(state.sslCtx);
if (MemoryAddress.NULL.equals(caCerts)) {
caCerts = SSL_load_client_CA_file(caCertificateFileNative);
if (!MemoryAddress.NULL.equals(caCerts)) {
SSL_CTX_set_client_CA_list(state.sslCtx, caCerts);
}
} else {
if (SSL_add_file_cert_subjects_to_stack(caCerts, caCertificateFileNative) <= 0) {
caCerts = MemoryAddress.NULL;
}
}
if (MemoryAddress.NULL.equals(caCerts)) {
log.warn(sm.getString("openssl.noCACerts"));
}
}
}
if (state.negotiableProtocols != null && state.negotiableProtocols.size() > 0) {
// int openSSLCallbackAlpnSelectProto(MemoryAddress ssl, MemoryAddress out, MemoryAddress outlen,
// MemoryAddress in, int inlen, MemoryAddress arg
MemoryAddress openSSLCallbackAlpnSelectProto = CLinker.getInstance().upcallStub(openSSLCallbackAlpnSelectProtoHandle, openSSLCallbackAlpnSelectProtoFunctionDescriptor, state.contextScope);
SSL_CTX_set_alpn_select_cb(state.sslCtx, openSSLCallbackAlpnSelectProto, state.sslCtx);
// Skip NPN (annoying and likely not useful anymore)
// SSLContext.setNpnProtos(state.ctx, protocolsArray, SSL.SSL_SELECTOR_FAILURE_NO_ADVERTISE);
}
// Apply OpenSSLConfCmd if used
OpenSSLConf openSslConf = sslHostConfig.getOpenSslConf();
if (openSslConf != null && !MemoryAddress.NULL.equals(state.confCtx)) {
// Check OpenSSLConfCmd if used
if (log.isDebugEnabled()) {
log.debug(sm.getString("openssl.checkConf"));
}
try {
if (!checkConf(openSslConf)) {
log.error(sm.getString("openssl.errCheckConf"));
throw new Exception(sm.getString("openssl.errCheckConf"));
}
} catch (Exception e) {
throw new Exception(sm.getString("openssl.errCheckConf"), e);
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("openssl.applyConf"));
}
try {
if (!applyConf(openSslConf)) {
log.error(sm.getString("openssl.errApplyConf"));
throw new SSLException(sm.getString("openssl.errApplyConf"));
}
} catch (Exception e) {
throw new SSLException(sm.getString("openssl.errApplyConf"), e);
}
// Reconfigure the enabled protocols
long opts = SSL_CTX_get_options(state.sslCtx);
List<String> enabled = new ArrayList<>();
// Seems like there is no way to explicitly disable SSLv2Hello
// in OpenSSL so it is always enabled
enabled.add(Constants.SSL_PROTO_SSLv2Hello);
if ((opts & SSL_OP_NO_TLSv1()) == 0) {
enabled.add(Constants.SSL_PROTO_TLSv1);
}
if ((opts & SSL_OP_NO_TLSv1_1()) == 0) {
enabled.add(Constants.SSL_PROTO_TLSv1_1);
}
if ((opts & SSL_OP_NO_TLSv1_2()) == 0) {
enabled.add(Constants.SSL_PROTO_TLSv1_2);
}
if ((opts & SSL_OP_NO_TLSv1_3()) == 0) {
enabled.add(Constants.SSL_PROTO_TLSv1_3);
}
if ((opts & SSL_OP_NO_SSLv2()) == 0) {
enabled.add(Constants.SSL_PROTO_SSLv2);
}
if ((opts & SSL_OP_NO_SSLv3()) == 0) {
enabled.add(Constants.SSL_PROTO_SSLv3);
}
sslHostConfig.setEnabledProtocols(enabled.toArray(new String[0]));
// Reconfigure the enabled ciphers
sslHostConfig.setEnabledCiphers(getCiphers(state.sslCtx));
}
sessionContext = new OpenSSLSessionContext(this);
// If client authentication is being used, OpenSSL requires that
// this is set so always set it in case an app is configured to
// require it
sessionContext.setSessionIdContext(DEFAULT_SESSION_ID_CONTEXT);
sslHostConfig.setOpenSslContext(state.sslCtx.toRawLongValue());
initialized = true;
} catch (Exception e) {
log.warn(sm.getString("openssl.errorSSLCtxInit"), e);
destroy();
}
}
use of jdk.incubator.foreign.MemorySegment in project tomcat by apache.
the class OpenSSLContext method openSSLCallbackCertVerify.
public static int openSSLCallbackCertVerify(MemoryAddress x509_ctx, MemoryAddress param) {
if (log.isDebugEnabled()) {
log.debug("Certificate verification");
}
if (MemoryAddress.NULL.equals(param)) {
return 0;
}
ContextState state = getState(param);
if (state == null) {
log.warn(sm.getString("context.noSSL", Long.valueOf(param.toRawLongValue())));
return 0;
}
MemoryAddress ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
MemoryAddress /*STACK_OF(X509)*/
sk = X509_STORE_CTX_get0_untrusted(x509_ctx);
int len = OPENSSL_sk_num(sk);
byte[][] certificateChain = new byte[len][];
try (var scope = ResourceScope.newConfinedScope()) {
var allocator = SegmentAllocator.ofScope(scope);
for (int i = 0; i < len; i++) {
MemoryAddress /*(X509*)*/
x509 = OPENSSL_sk_value(sk, i);
MemorySegment bufPointer = allocator.allocate(CLinker.C_POINTER, MemoryAddress.NULL);
int length = i2d_X509(x509, bufPointer);
if (length < 0) {
certificateChain[i] = new byte[0];
continue;
}
MemoryAddress buf = MemoryAccess.getAddress(bufPointer);
certificateChain[i] = buf.asSegment(length, scope).toByteArray();
// OPENSSL_free macro
CRYPTO_free(buf, MemoryAddress.NULL, 0);
}
MemoryAddress cipher = SSL_get_current_cipher(ssl);
String authMethod = (MemoryAddress.NULL.equals(cipher)) ? "UNKNOWN" : getCipherAuthenticationMethod(SSL_CIPHER_get_auth_nid(cipher), SSL_CIPHER_get_kx_nid(cipher));
X509Certificate[] peerCerts = certificates(certificateChain);
try {
state.x509TrustManager.checkClientTrusted(peerCerts, authMethod);
return 1;
} catch (Exception e) {
log.debug(sm.getString("openssl.certificateVerificationFailed"), e);
}
}
return 0;
}
Aggregations