Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions openssl-dynamic/src/main/c/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2670,36 +2670,35 @@ TCN_IMPLEMENT_CALL(void, SSL, setRenegotiateMode)(TCN_STDARGS, jlong ssl, jint m
}

TCN_IMPLEMENT_CALL(void, SSL, addCredential)(TCN_STDARGS, jlong ssl, jlong cred) {
if (!check_credential_api(e)) return;
SSL *ssl_ = J2P(ssl, SSL *);
TCN_CHECK_NULL(ssl_, ssl, /* void */);

#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* credential = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(credential, credential, /* void */);

int result = SSL_add1_credential(ssl_, credential);
if (result == 0) {
tcn_Throw(e, "Failed to add credential to SSL");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL API is only supported by BoringSSL");
#endif // OPENSSL_IS_BORINGSSL
#endif
}

TCN_IMPLEMENT_CALL(jlong, SSL, getSelectedCredential)(TCN_STDARGS, jlong ssl) {
if (!check_credential_api(e)) return 0;
SSL *ssl_ = J2P(ssl, SSL *);
TCN_CHECK_NULL(ssl_, ssl, 0);

#ifdef OPENSSL_IS_BORINGSSL
const SSL_CREDENTIAL* credential = SSL_get0_selected_credential(ssl_);
if (credential == NULL) {
return 0;
}
return (jlong)(intptr_t)credential;
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL API is only supported by BoringSSL");
return 0;
#endif // OPENSSL_IS_BORINGSSL
return 0; // Unreachable - check_credential_api throws
#endif
}

// JNI Method Registration Table Begin
Expand Down
38 changes: 38 additions & 0 deletions openssl-dynamic/src/main/c/ssl_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,4 +518,42 @@ enum ssl_verify_result_t tcn_SSL_cert_custom_verify(SSL* ssl, uint8_t *out_alert
#define tcn_SSL_set1_curves(s, glist, glistlen) SSL_ctrl(s, SSL_CTRL_SET_GROUPS, glistlen,(char *)(glist))
#endif // defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)

// SSL_CREDENTIAL API runtime detection for FIPS compatibility
#ifdef OPENSSL_IS_BORINGSSL
// Use weak symbols to detect if SSL_CREDENTIAL API is available at runtime
// FIPS BoringSSL builds (fips-20230428 and earlier) don't have these symbols
__attribute__((weak)) extern SSL_CREDENTIAL* SSL_CREDENTIAL_new_x509(void);
__attribute__((weak)) extern SSL_CREDENTIAL* SSL_CREDENTIAL_new_delegated(void);
__attribute__((weak)) extern void SSL_CREDENTIAL_free(SSL_CREDENTIAL*);
__attribute__((weak)) extern void SSL_CREDENTIAL_up_ref(SSL_CREDENTIAL*);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_private_key(SSL_CREDENTIAL*, EVP_PKEY*);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_cert_chain(SSL_CREDENTIAL*, CRYPTO_BUFFER *const*, size_t);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_trust_anchor_id(SSL_CREDENTIAL*, const uint8_t*, size_t);
__attribute__((weak)) extern void SSL_CREDENTIAL_set_must_match_issuer(SSL_CREDENTIAL*, int);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_ocsp_response(SSL_CREDENTIAL*, CRYPTO_BUFFER*);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_signed_cert_timestamp_list(SSL_CREDENTIAL*, CRYPTO_BUFFER*);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_certificate_properties(SSL_CREDENTIAL*, CRYPTO_BUFFER*);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_signing_algorithm_prefs(SSL_CREDENTIAL*, const uint16_t*, size_t);
__attribute__((weak)) extern int SSL_CREDENTIAL_set1_delegated_credential(SSL_CREDENTIAL*, CRYPTO_BUFFER*);
__attribute__((weak)) extern int SSL_add1_credential(SSL*, SSL_CREDENTIAL*);
__attribute__((weak)) extern int SSL_CTX_add1_credential(SSL_CTX*, SSL_CREDENTIAL*);
__attribute__((weak)) extern const SSL_CREDENTIAL* SSL_get0_selected_credential(const SSL*);

// Check if credential API is available and throw if not
// Returns 1 if available, 0 if not (with exception thrown)
static inline int check_credential_api(JNIEnv* e) {
if (SSL_CREDENTIAL_new_x509 == NULL) {
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL API not available.");
return 0;
}
return 1;
}

#else
__attribute__((unused)) static inline int check_credential_api(JNIEnv* e) {
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL API not available.");
return 0;
}
#endif // OPENSSL_IS_BORINGSSL

#endif /* SSL_PRIVATE_H */
5 changes: 2 additions & 3 deletions openssl-dynamic/src/main/c/sslcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -2945,6 +2945,7 @@ TCN_IMPLEMENT_CALL(jint, SSLContext, addCertificateCompressionAlgorithm0)(TCN_ST
}

TCN_IMPLEMENT_CALL(void, SSLContext, addCredential)(TCN_STDARGS, jlong ctx, jlong cred) {
if (!check_credential_api(e)) return;
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
TCN_CHECK_NULL(c, ctx, /* void */);

Expand All @@ -2956,9 +2957,7 @@ TCN_IMPLEMENT_CALL(void, SSLContext, addCredential)(TCN_STDARGS, jlong ctx, jlon
if (result == 0) {
tcn_Throw(e, "Failed to add credential to SSL_CTX");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL API is only supported by BoringSSL");
#endif // OPENSSL_IS_BORINGSSL
#endif
}

// JNI Method Registration Table Begin
Expand Down
41 changes: 15 additions & 26 deletions openssl-dynamic/src/main/c/sslcredential.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,39 +43,38 @@ static void throw_openssl_error(JNIEnv* env, const char* msg) {

// Core SSL_CREDENTIAL functions
TCN_IMPLEMENT_CALL(jlong, SSLCredential, newX509)(TCN_STDARGS) {
if (!check_credential_api(e)) return 0;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* cred = SSL_CREDENTIAL_new_x509();
TCN_CHECK_NULL(cred, credential, 0);
return (jlong)(intptr_t)cred;
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_new_x509 is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
return 0;
return 0; // Unreachable - check_credential_api throws
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, upRef)(TCN_STDARGS, jlong cred) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
SSL_CREDENTIAL_up_ref(c);
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_up_ref is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, free)(TCN_STDARGS, jlong cred) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
if (c != NULL) {
SSL_CREDENTIAL_free(c);
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_free is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

// SSL_CREDENTIAL configuration methods
TCN_IMPLEMENT_CALL(void, SSLCredential, setPrivateKey)(TCN_STDARGS, jlong cred, jlong key) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
EVP_PKEY* pkey = (EVP_PKEY*)(intptr_t)key;
Expand All @@ -86,12 +85,11 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setPrivateKey)(TCN_STDARGS, jlong cred,
if (SSL_CREDENTIAL_set1_private_key(c, pkey) == 0) {
throw_openssl_error(e, "Failed to set private key");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_private_key is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setCertChain)(TCN_STDARGS, jlong cred, jlongArray certs) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand Down Expand Up @@ -125,12 +123,11 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setCertChain)(TCN_STDARGS, jlong cred, j
if (result == 0) {
throw_openssl_error(e, "Failed to set certificate chain");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_cert_chain is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setOcspResponse)(TCN_STDARGS, jlong cred, jbyteArray ocsp) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand All @@ -156,12 +153,11 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setOcspResponse)(TCN_STDARGS, jlong cred
if (result == 0) {
throw_openssl_error(e, "Failed to set OCSP response");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_ocsp_response is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setSigningAlgorithmPrefs)(TCN_STDARGS, jlong cred, jintArray prefs) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand Down Expand Up @@ -194,12 +190,11 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setSigningAlgorithmPrefs)(TCN_STDARGS, j
if (result == 0) {
throw_openssl_error(e, "Failed to set signing algorithm preferences");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_signing_algorithm_prefs is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setCertificateProperties)(TCN_STDARGS, jlong cred, jbyteArray cert_props) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand All @@ -225,12 +220,11 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setCertificateProperties)(TCN_STDARGS, j
if (result == 0) {
throw_openssl_error(e, "Failed to set certificate properties");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_certificate_properties is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setSignedCertTimestampList)(TCN_STDARGS, jlong cred, jbyteArray sct_list) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand All @@ -256,23 +250,21 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setSignedCertTimestampList)(TCN_STDARGS,
if (result == 0) {
throw_openssl_error(e, "Failed to set signed certificate timestamp list");
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_signed_cert_timestamp_list is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setMustMatchIssuer)(TCN_STDARGS, jlong cred, jboolean match) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
SSL_CREDENTIAL_set_must_match_issuer(c, match == JNI_TRUE ? 1 : 0);
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set_must_match_issuer is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

// Trust anchor configuration
TCN_IMPLEMENT_CALL(void, SSLCredential, setTrustAnchorId)(TCN_STDARGS, jlong cred, jbyteArray id) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand All @@ -294,13 +286,12 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setTrustAnchorId)(TCN_STDARGS, jlong cre
throw_openssl_error(e, "Failed to set trust anchor ID");
return;
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_trust_anchor_id is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

// Delegated credentials
TCN_IMPLEMENT_CALL(jlong, SSLCredential, newDelegated)(TCN_STDARGS) {
if (!check_credential_api(e)) return 0;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* credential = SSL_CREDENTIAL_new_delegated();
if (credential == NULL) {
Expand All @@ -309,12 +300,12 @@ TCN_IMPLEMENT_CALL(jlong, SSLCredential, newDelegated)(TCN_STDARGS) {
}
return (jlong)(intptr_t)credential;
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_new_delegated is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
return 0;
return 0; // Unreachable - check_credential_api throws
#endif
}

TCN_IMPLEMENT_CALL(void, SSLCredential, setDelegatedCredential)(TCN_STDARGS, jlong cred, jbyteArray dc) {
if (!check_credential_api(e)) return;
#ifdef OPENSSL_IS_BORINGSSL
SSL_CREDENTIAL* c = (SSL_CREDENTIAL*)(intptr_t)cred;
TCN_CHECK_NULL(c, credential, /* void */);
Expand All @@ -341,8 +332,6 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setDelegatedCredential)(TCN_STDARGS, jlo
throw_openssl_error(e, "Failed to set delegated credential");
return;
}
#else
tcn_ThrowUnsupportedOperationException(e, "SSL_CREDENTIAL_set1_delegated_credential is not supported. SSL_CREDENTIAL API is a BoringSSL-specific feature.");
#endif
}

Expand Down
Loading