Skip to content

Commit f5854e2

Browse files
Hiroshi Hatakeedsiper
Hiroshi Hatake
authored andcommittedMar 27, 2025·
openssl: implement TLS version bounds and cipher config
Adds support for parsing TLS protocol versions and disabling specific ones using SSL options. Also enables cipher selection via `SSL_CTX_set_cipher_list()`. Signed-off-by: Eduardo Silva <[email protected]>
1 parent cb13897 commit f5854e2

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed
 

‎src/tls/openssl.c

+118
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,122 @@ static void *tls_context_create(int verify,
651651
return NULL;
652652
}
653653

654+
#if !defined(TLS1_3_VERSION)
655+
# define TLS1_3_VERSION 0x0304
656+
#endif
657+
658+
struct tls_proto_def {
659+
char *name;
660+
int ver;
661+
};
662+
663+
struct tls_proto_options {
664+
int ver;
665+
int no_opt;
666+
};
667+
668+
static int parse_proto_version(const char *proto_ver)
669+
{
670+
int i;
671+
struct tls_proto_def defs[] = {
672+
{ "SSLv2", SSL2_VERSION },
673+
{ "SSLv3", SSL3_VERSION },
674+
{ "TLSv1", TLS1_VERSION },
675+
{ "TLSv1.1", TLS1_1_VERSION },
676+
{ "TLSv1.2", TLS1_2_VERSION },
677+
#if defined(TLS1_3_VERSION)
678+
{ "TLSv1.3", TLS1_3_VERSION },
679+
#endif
680+
{ NULL, 0 },
681+
};
682+
683+
if (proto_ver == NULL) {
684+
return 0;
685+
}
686+
687+
for (i = 0; i < sizeof(defs) / sizeof(struct tls_proto_def); i++) {
688+
if (strncasecmp(defs[i].name, proto_ver, strlen(proto_ver)) == 0) {
689+
return defs[i].ver;
690+
}
691+
}
692+
693+
return -1;
694+
}
695+
696+
#if defined(TLS1_3_VERSION)
697+
#define DEFAULT_MAX_VERSION TLS1_3_VERSION
698+
#else
699+
#define DEFAULT_MAX_VERSION TLS1_2_VERSION
700+
#endif
701+
702+
static int tls_set_minmax_proto(struct flb_tls *tls,
703+
const char *min_version,
704+
const char *max_version)
705+
{
706+
int i;
707+
unsigned long sum = 0, opts = 0;
708+
int min = TLS1_1_VERSION;
709+
int max = DEFAULT_MAX_VERSION;
710+
int val = -1;
711+
struct tls_context *ctx = tls->ctx;
712+
713+
struct tls_proto_options tls_options[] = {
714+
{ SSL2_VERSION, SSL_OP_NO_SSLv2 },
715+
{ SSL3_VERSION, SSL_OP_NO_SSLv3 },
716+
{ TLS1_VERSION, SSL_OP_NO_TLSv1 },
717+
{ TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
718+
{ TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
719+
#if defined(TLS1_3_VERSION) && defined(SSL_OP_NO_TLSv1_3)
720+
{ TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
721+
#endif
722+
};
723+
724+
if (!ctx) {
725+
return -1;
726+
}
727+
728+
val = parse_proto_version(min_version);
729+
if (val >= 0) {
730+
min = val;
731+
}
732+
733+
val = parse_proto_version(max_version);
734+
if (val >= 0) {
735+
max = val;
736+
}
737+
738+
pthread_mutex_lock(&ctx->mutex);
739+
740+
for (i = 0; i < sizeof(tls_options) / sizeof(struct tls_proto_options); i++) {
741+
sum |= tls_options[i].no_opt;
742+
if ((min && min > tls_options[i].ver) ||
743+
(max && max < tls_options[i].ver)) {
744+
opts |= tls_options[i].no_opt;
745+
}
746+
}
747+
SSL_CTX_clear_options(ctx->ctx, sum);
748+
SSL_CTX_set_options(ctx->ctx, opts);
749+
750+
pthread_mutex_unlock(&ctx->mutex);
751+
752+
return 0;
753+
}
754+
755+
static int tls_set_ciphers(struct flb_tls *tls, const char *ciphers)
756+
{
757+
struct tls_context *ctx = tls->ctx;
758+
759+
pthread_mutex_lock(&ctx->mutex);
760+
761+
if (!SSL_CTX_set_cipher_list(ctx->ctx, ciphers)) {
762+
return -1;
763+
}
764+
765+
pthread_mutex_unlock(&ctx->mutex);
766+
767+
return 0;
768+
}
769+
654770
static void *tls_session_create(struct flb_tls *tls,
655771
int fd)
656772
{
@@ -1043,6 +1159,8 @@ static struct flb_tls_backend tls_openssl = {
10431159
.context_destroy = tls_context_destroy,
10441160
.context_alpn_set = tls_context_alpn_set,
10451161
.session_alpn_get = tls_session_alpn_get,
1162+
.set_minmax_proto = tls_set_minmax_proto,
1163+
.set_ciphers = tls_set_ciphers,
10461164
.session_create = tls_session_create,
10471165
.session_destroy = tls_session_destroy,
10481166
.net_read = tls_net_read,

0 commit comments

Comments
 (0)
Please sign in to comment.