@@ -37,12 +37,24 @@ static void throw_openssl_error(JNIEnv* env, const char* msg) {
3737 ERR_error_string_n (err , err_buf , sizeof (err_buf ));
3838 tcn_Throw (env , "%s: %s" , msg , err_buf );
3939}
40+
41+ static int tcn_SSL_CREDENTIAL_id_idx = -1 ;
42+
43+ typedef char tcn_SSL_CREDENTIAL_id_requires_64bit_pointers [sizeof (void * ) >= sizeof (jlong ) ? 1 : -1 ];
44+
45+ // The id is a scalar packed into the ex_data slot, so no free callback is needed.
46+ jlong tcn_SSL_CREDENTIAL_get_id (const SSL_CREDENTIAL * cred ) {
47+ if (cred == NULL || tcn_SSL_CREDENTIAL_id_idx < 0 ) {
48+ return 0 ;
49+ }
50+ return (jlong )(intptr_t ) SSL_CREDENTIAL_get_ex_data (cred , tcn_SSL_CREDENTIAL_id_idx );
51+ }
4052#endif
4153
4254
4355
4456// Core SSL_CREDENTIAL functions
45- TCN_IMPLEMENT_CALL (jlong , SSLCredential , newX509 )(TCN_STDARGS ) {
57+ TCN_IMPLEMENT_CALL (jlong , SSLCredential , newX509Native )(TCN_STDARGS ) {
4658#ifdef OPENSSL_IS_BORINGSSL
4759 SSL_CREDENTIAL * cred = SSL_CREDENTIAL_new_x509 ();
4860 TCN_CHECK_NULL (cred , credential , 0 );
@@ -74,6 +86,40 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, free)(TCN_STDARGS, jlong cred) {
7486#endif
7587}
7688
89+ TCN_IMPLEMENT_CALL (void , SSLCredential , setId0 )(TCN_STDARGS , jlong cred , jlong id ) {
90+ #ifdef OPENSSL_IS_BORINGSSL
91+ SSL_CREDENTIAL * c = (SSL_CREDENTIAL * )(intptr_t )cred ;
92+ TCN_CHECK_NULL (c , credential , /* void */ );
93+ if (id <= 0 ) {
94+ tcn_ThrowIllegalArgumentException (e , "credential id must be positive" );
95+ return ;
96+ }
97+ if (tcn_SSL_CREDENTIAL_get_id (c ) != 0 ) {
98+ jclass ise = (* e )-> FindClass (e , "java/lang/IllegalStateException" );
99+ if (ise != NULL ) {
100+ (* e )-> ThrowNew (e , ise , "credential already has an id" );
101+ }
102+ return ;
103+ }
104+ if (!SSL_CREDENTIAL_set_ex_data (c , tcn_SSL_CREDENTIAL_id_idx , (void * )(intptr_t ) id )) {
105+ throw_openssl_error (e , "Failed to set SSL_CREDENTIAL id" );
106+ }
107+ #else
108+ tcn_ThrowUnsupportedOperationException (e , "SSL_CREDENTIAL API not available." );
109+ #endif
110+ }
111+
112+ TCN_IMPLEMENT_CALL (jlong , SSLCredential , getId )(TCN_STDARGS , jlong cred ) {
113+ #ifdef OPENSSL_IS_BORINGSSL
114+ SSL_CREDENTIAL * c = (SSL_CREDENTIAL * )(intptr_t )cred ;
115+ TCN_CHECK_NULL (c , credential , 0 );
116+ return tcn_SSL_CREDENTIAL_get_id (c );
117+ #else
118+ tcn_ThrowUnsupportedOperationException (e , "SSL_CREDENTIAL API not available." );
119+ return 0 ;
120+ #endif
121+ }
122+
77123// SSL_CREDENTIAL configuration methods
78124TCN_IMPLEMENT_CALL (void , SSLCredential , setPrivateKey )(TCN_STDARGS , jlong cred , jlong key ) {
79125#ifdef OPENSSL_IS_BORINGSSL
@@ -294,7 +340,7 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setTrustAnchorId)(TCN_STDARGS, jlong cre
294340}
295341
296342// Delegated credentials
297- TCN_IMPLEMENT_CALL (jlong , SSLCredential , newDelegated )(TCN_STDARGS ) {
343+ TCN_IMPLEMENT_CALL (jlong , SSLCredential , newDelegatedNative )(TCN_STDARGS ) {
298344#ifdef OPENSSL_IS_BORINGSSL
299345 SSL_CREDENTIAL * credential = SSL_CREDENTIAL_new_delegated ();
300346 if (credential == NULL ) {
@@ -343,9 +389,11 @@ TCN_IMPLEMENT_CALL(void, SSLCredential, setDelegatedCredential)(TCN_STDARGS, jlo
343389// JNI Method Registration Table Begin
344390static const JNINativeMethod method_table [] = {
345391 // Core functions
346- { TCN_METHOD_TABLE_ENTRY (newX509 , ( )J , SSLCredential ) },
392+ { TCN_METHOD_TABLE_ENTRY (newX509Native , ( )J , SSLCredential ) },
347393 { TCN_METHOD_TABLE_ENTRY (upRef , (J )V , SSLCredential ) },
348394 { TCN_METHOD_TABLE_ENTRY (free , (J )V , SSLCredential ) },
395+ { TCN_METHOD_TABLE_ENTRY (setId0 , (JJ )V , SSLCredential ) },
396+ { TCN_METHOD_TABLE_ENTRY (getId , (J )J , SSLCredential ) },
349397
350398 // Configuration
351399 { TCN_METHOD_TABLE_ENTRY (setPrivateKey , (JJ )V , SSLCredential ) },
@@ -360,7 +408,7 @@ static const JNINativeMethod method_table[] = {
360408 { TCN_METHOD_TABLE_ENTRY (setTrustAnchorId , (J [B )V , SSLCredential ) },
361409
362410 // Delegated credentials
363- { TCN_METHOD_TABLE_ENTRY (newDelegated , ( )J , SSLCredential ) },
411+ { TCN_METHOD_TABLE_ENTRY (newDelegatedNative , ( )J , SSLCredential ) },
364412 { TCN_METHOD_TABLE_ENTRY (setDelegatedCredential , (J [B )V , SSLCredential ) }
365413};
366414
@@ -371,6 +419,12 @@ static const jint method_table_size = sizeof(method_table) / sizeof(method_table
371419// IMPORTANT: If you add any NETTY_JNI_UTIL_LOAD_CLASS or NETTY_JNI_UTIL_FIND_CLASS calls you also need to update
372420// Library to reflect that.
373421jint netty_internal_tcnative_SSLCredential_JNI_OnLoad (JNIEnv * env , const char * packagePrefix ) {
422+ #ifdef OPENSSL_IS_BORINGSSL
423+ tcn_SSL_CREDENTIAL_id_idx = SSL_CREDENTIAL_get_ex_new_index (0 , NULL , NULL , NULL , NULL );
424+ if (tcn_SSL_CREDENTIAL_id_idx < 0 ) {
425+ return JNI_ERR ;
426+ }
427+ #endif
374428 if (netty_jni_util_register_natives (env ,
375429 packagePrefix ,
376430 SSLCREDENTIAL_CLASSNAME ,
0 commit comments