Skip to content

Commit f60eafc

Browse files
committed
Refactor TLS 1.3 cipher suite configuration support
Align SSL and SSLContext implementations
1 parent 7855ef1 commit f60eafc

3 files changed

Lines changed: 126 additions & 40 deletions

File tree

native/src/ssl.c

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,32 +1120,87 @@ TCN_IMPLEMENT_CALL(jobjectArray, SSL, getCiphers)(TCN_STDARGS, jlong ssl)
11201120
}
11211121

11221122
TCN_IMPLEMENT_CALL(jboolean, SSL, setCipherSuites)(TCN_STDARGS, jlong ssl,
1123-
jstring ciphers)
1123+
jstring cipherList)
11241124
{
1125-
jboolean rv = JNI_TRUE;
11261125
SSL *ssl_ = J2P(ssl, SSL *);
1127-
TCN_ALLOC_CSTRING(ciphers);
1128-
1129-
UNREFERENCED_STDARGS;
1126+
TCN_ALLOC_CSTRING(cipherList);
1127+
jboolean rv = JNI_TRUE;
1128+
#ifndef HAVE_EXPORT_CIPHERS
1129+
size_t len;
1130+
char *buf;
1131+
#endif
1132+
UNREFERENCED(o);
11301133

11311134
if (ssl_ == NULL) {
1132-
TCN_FREE_CSTRING(ciphers);
1135+
TCN_FREE_CSTRING(cipherList);
11331136
tcn_ThrowException(e, "ssl is null");
11341137
return JNI_FALSE;
11351138
}
11361139

1140+
if (!J2S(cipherList)) {
1141+
rv = JNI_FALSE;
1142+
goto free_cipherList;
1143+
}
1144+
1145+
#ifndef HAVE_EXPORT_CIPHERS
1146+
/*
1147+
* Always disable NULL and export ciphers,
1148+
* no matter what was given in the config.
1149+
*/
1150+
len = strlen(J2S(cipherList)) + strlen(SSL_CIPHERS_ALWAYS_DISABLED) + 1;
1151+
buf = malloc(len * sizeof(char *));
1152+
if (buf == NULL) {
1153+
rv = JNI_FALSE;
1154+
goto free_cipherList;
1155+
}
1156+
memcpy(buf, SSL_CIPHERS_ALWAYS_DISABLED, strlen(SSL_CIPHERS_ALWAYS_DISABLED));
1157+
memcpy(buf + strlen(SSL_CIPHERS_ALWAYS_DISABLED), J2S(cipherList), strlen(J2S(cipherList)));
1158+
buf[len - 1] = '\0';
1159+
if (!SSL_set_cipher_list(ssl_, buf)) {
1160+
#else
1161+
if (!SSL_set_cipher_list(ssl_, J2S(cipherList))) {
1162+
#endif
1163+
char err[TCN_OPENSSL_ERROR_STRING_LENGTH];
1164+
ERR_error_string_n(SSL_ERR_get(), err, TCN_OPENSSL_ERROR_STRING_LENGTH);
1165+
tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err);
1166+
rv = JNI_FALSE;
1167+
}
1168+
#ifndef HAVE_EXPORT_CIPHERS
1169+
free(buf);
1170+
#endif
1171+
free_cipherList:
1172+
TCN_FREE_CSTRING(cipherList);
1173+
return rv;
1174+
}
1175+
1176+
TCN_IMPLEMENT_CALL(jboolean, SSL, setCipherSuitesEx)(TCN_STDARGS, jlong ssl,
1177+
jstring cipherSuites)
1178+
{
1179+
SSL *ssl_ = J2P(ssl, SSL *);
1180+
TCN_ALLOC_CSTRING(cipherSuites);
1181+
jboolean rv = JNI_TRUE;
11371182
UNREFERENCED(o);
1138-
if (!J2S(ciphers)) {
1139-
TCN_FREE_CSTRING(ciphers);
1183+
1184+
if (ssl_ == NULL) {
1185+
TCN_FREE_CSTRING(cipherSuites);
1186+
tcn_ThrowException(e, "ssl is null");
11401187
return JNI_FALSE;
11411188
}
1142-
if (!SSL_set_cipher_list(ssl_, J2S(ciphers))) {
1189+
1190+
if (!J2S(cipherSuites)) {
1191+
rv = JNI_FALSE;
1192+
goto free_cipherSuites;
1193+
}
1194+
1195+
if (!SSL_set_ciphersuites(ssl_, J2S(cipherSuites))) {
11431196
char err[TCN_OPENSSL_ERROR_STRING_LENGTH];
11441197
ERR_error_string_n(SSL_ERR_get(), err, TCN_OPENSSL_ERROR_STRING_LENGTH);
1145-
tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err);
1198+
tcn_Throw(e, "Unable to configure permitted SSL cipher suites (%s)", err);
11461199
rv = JNI_FALSE;
11471200
}
1148-
TCN_FREE_CSTRING(ciphers);
1201+
1202+
free_cipherSuites:
1203+
TCN_FREE_CSTRING(cipherSuites);
11491204
return rv;
11501205
}
11511206

native/src/sslcontext.c

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -513,54 +513,46 @@ TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx,
513513
}
514514

515515
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx,
516-
jstring ciphers)
516+
jstring cipherList)
517517
{
518518
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
519-
TCN_ALLOC_CSTRING(ciphers);
519+
TCN_ALLOC_CSTRING(cipherList);
520520
jboolean rv = JNI_TRUE;
521-
int minProtoVer = 0;
522-
int maxProtoVer = 0;
523-
int ciphersSet = 0;
524521
#ifndef HAVE_EXPORT_CIPHERS
525522
size_t len;
526523
char *buf;
527524
#endif
528-
529525
UNREFERENCED(o);
530-
TCN_ASSERT(ctx != 0);
531-
if (!J2S(ciphers))
526+
527+
if (c == NULL) {
528+
TCN_FREE_CSTRING(cipherList);
529+
tcn_ThrowException(e, "ssl context is null");
532530
return JNI_FALSE;
531+
}
533532

534-
minProtoVer = SSL_CTX_get_min_proto_version(c->ctx);
535-
maxProtoVer = SSL_CTX_get_max_proto_version(c->ctx);
533+
if (!J2S(cipherList)) {
534+
rv = JNI_FALSE;
535+
goto free_cipherList;
536+
}
536537

537538
#ifndef HAVE_EXPORT_CIPHERS
538539
/*
539540
* Always disable NULL and export ciphers,
540541
* no matter what was given in the config.
541542
*/
542-
len = strlen(J2S(ciphers)) + strlen(SSL_CIPHERS_ALWAYS_DISABLED) + 1;
543+
len = strlen(J2S(cipherList)) + strlen(SSL_CIPHERS_ALWAYS_DISABLED) + 1;
543544
buf = malloc(len * sizeof(char *));
544-
if (buf == NULL)
545-
return JNI_FALSE;
545+
if (buf == NULL) {
546+
rv = JNI_FALSE;
547+
goto free_cipherList;
548+
}
546549
memcpy(buf, SSL_CIPHERS_ALWAYS_DISABLED, strlen(SSL_CIPHERS_ALWAYS_DISABLED));
547-
memcpy(buf + strlen(SSL_CIPHERS_ALWAYS_DISABLED), J2S(ciphers), strlen(J2S(ciphers)));
550+
memcpy(buf + strlen(SSL_CIPHERS_ALWAYS_DISABLED), J2S(cipherList), strlen(J2S(cipherList)));
548551
buf[len - 1] = '\0';
552+
if (!SSL_CTX_set_cipher_list(c->ctx, buf)) {
549553
#else
550-
buf = (char*)J2S(ciphers);
554+
if (!SSL_CTX_set_cipher_list(c->ctx, J2S(cipherList))) {
551555
#endif
552-
/* OpenSSL will ignore any unknown cipher, but TLS 1.3 requires a call to SSL_CTX_set_ciphersuites */
553-
if (minProtoVer <= TLS1_2_VERSION) {
554-
if (SSL_CTX_set_cipher_list(c->ctx, buf)) {
555-
ciphersSet = 1;
556-
}
557-
}
558-
if (maxProtoVer >= TLS1_3_VERSION) {
559-
if (SSL_CTX_set_ciphersuites(c->ctx, buf)) {
560-
ciphersSet = 1;
561-
}
562-
}
563-
if (!ciphersSet) {
564556
char err[TCN_OPENSSL_ERROR_STRING_LENGTH];
565557
ERR_error_string_n(SSL_ERR_get(), err, TCN_OPENSSL_ERROR_STRING_LENGTH);
566558
tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err);
@@ -569,7 +561,39 @@ TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx,
569561
#ifndef HAVE_EXPORT_CIPHERS
570562
free(buf);
571563
#endif
572-
TCN_FREE_CSTRING(ciphers);
564+
free_cipherList:
565+
TCN_FREE_CSTRING(cipherList);
566+
return rv;
567+
}
568+
569+
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuitesEx)(TCN_STDARGS, jlong ctx,
570+
jstring cipherSuites)
571+
{
572+
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
573+
TCN_ALLOC_CSTRING(cipherSuites);
574+
jboolean rv = JNI_TRUE;
575+
UNREFERENCED(o);
576+
577+
if (c == NULL) {
578+
TCN_FREE_CSTRING(cipherSuites);
579+
tcn_ThrowException(e, "ssl context is null");
580+
return JNI_FALSE;
581+
}
582+
583+
if (!J2S(cipherSuites)) {
584+
rv = JNI_FALSE;
585+
goto free_cipherSuites;
586+
}
587+
588+
if (SSL_CTX_set_ciphersuites(c->ctx, J2S(cipherSuites))) {
589+
char err[TCN_OPENSSL_ERROR_STRING_LENGTH];
590+
ERR_error_string_n(SSL_ERR_get(), err, TCN_OPENSSL_ERROR_STRING_LENGTH);
591+
tcn_Throw(e, "Unable to configure permitted SSL cipher suites (%s)", err);
592+
rv = JNI_FALSE;
593+
}
594+
595+
free_cipherSuites:
596+
TCN_FREE_CSTRING(cipherSuites);
573597
return rv;
574598
}
575599

xdocs/miscellaneous/changelog.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@
3232
</p>
3333
</section>
3434
<section name="Changes in 2.0.12">
35+
<changelog>
36+
<fix>
37+
Refactor the addition of TLS 1.3 cipher suite configuration to avoid a
38+
regression when running a version of Tomcat that pre-dates this change.
39+
(markt)
40+
</fix>
41+
</changelog>
3542
</section>
36-
<section name="Changes in 2.0.11">
43+
<section name="Changes in 2.0.11 (not released)">
3744
<changelog>
3845
<fix>
3946
Fix a reference to an uninitialized variable. (schultz)

0 commit comments

Comments
 (0)