From 42530714760b3aab9857f74191f27e91e05c621c Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Sun, 5 Nov 2023 20:48:21 +0100 Subject: [PATCH] lib-ssl-iostream: Add ssl_iostream_get_protocol_version() --- src/lib-ssl-iostream/iostream-openssl.c | 27 +++++++++++++++++++++ src/lib-ssl-iostream/iostream-ssl-private.h | 2 ++ src/lib-ssl-iostream/iostream-ssl.c | 6 +++++ src/lib-ssl-iostream/iostream-ssl.h | 20 +++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c index 88885259bc..cdbd45c171 100644 --- a/src/lib-ssl-iostream/iostream-openssl.c +++ b/src/lib-ssl-iostream/iostream-openssl.c @@ -828,6 +828,32 @@ openssl_iostream_get_protocol_name(struct ssl_iostream *ssl_io) return SSL_get_version(ssl_io->ssl); } +static enum ssl_iostream_protocol_version +openssl_iostream_get_protocol_version(struct ssl_iostream *ssl_io) +{ + if (!ssl_io->handshaked) + return SSL_IOSTREAM_PROTOCOL_VERSION_UNKNOWN; + + int version = SSL_version(ssl_io->ssl); + + switch (version) { + case SSL3_VERSION: + return SSL_IOSTREAM_PROTOCOL_VERSION_SSL3; + case TLS1_VERSION: + return SSL_IOSTREAM_PROTOCOL_VERSION_TLS1; + case TLS1_1_VERSION: + return SSL_IOSTREAM_PROTOCOL_VERSION_TLS1_1; + case TLS1_2_VERSION: + return SSL_IOSTREAM_PROTOCOL_VERSION_TLS1_2; + case TLS1_3_VERSION: + return SSL_IOSTREAM_PROTOCOL_VERSION_TLS1_3; + default: + break; + } + i_assert(version > TLS1_3_VERSION); + return SSL_IOSTREAM_PROTOCOL_VERSION_NEW; +} + static const char * openssl_iostream_get_ja3(struct ssl_iostream *ssl_io) { @@ -881,6 +907,7 @@ static const struct iostream_ssl_vfuncs ssl_vfuncs = { .get_cipher = openssl_iostream_get_cipher, .get_pfs = openssl_iostream_get_pfs, .get_protocol_name = openssl_iostream_get_protocol_name, + .get_protocol_version = openssl_iostream_get_protocol_version, .get_ja3 = openssl_iostream_get_ja3, .get_application_protocol = openssl_iostream_get_application_protocol, diff --git a/src/lib-ssl-iostream/iostream-ssl-private.h b/src/lib-ssl-iostream/iostream-ssl-private.h index 0b55811edf..1f587d12a1 100644 --- a/src/lib-ssl-iostream/iostream-ssl-private.h +++ b/src/lib-ssl-iostream/iostream-ssl-private.h @@ -51,6 +51,8 @@ struct iostream_ssl_vfuncs { const char *(*get_cipher)(struct ssl_iostream *ssl_io, unsigned int *bits_r); const char *(*get_pfs)(struct ssl_iostream *ssl_io); const char *(*get_protocol_name)(struct ssl_iostream *ssl_io); + enum ssl_iostream_protocol_version + (*get_protocol_version)(struct ssl_iostream *ssl_io); const char *(*get_ja3)(struct ssl_iostream *ssl_io); const char *(*get_application_protocol)(struct ssl_iostream *ssl_io); diff --git a/src/lib-ssl-iostream/iostream-ssl.c b/src/lib-ssl-iostream/iostream-ssl.c index 7ad468c551..8cece98df6 100644 --- a/src/lib-ssl-iostream/iostream-ssl.c +++ b/src/lib-ssl-iostream/iostream-ssl.c @@ -404,6 +404,12 @@ const char *ssl_iostream_get_protocol_name(struct ssl_iostream *ssl_io) return ssl_vfuncs->get_protocol_name(ssl_io); } +enum ssl_iostream_protocol_version +ssl_iostream_get_protocol_version(struct ssl_iostream *ssl_io) +{ + return ssl_vfuncs->get_protocol_version(ssl_io); +} + const char *ssl_iostream_get_ja3(struct ssl_iostream *ssl_io) { return ssl_vfuncs->get_ja3(ssl_io); diff --git a/src/lib-ssl-iostream/iostream-ssl.h b/src/lib-ssl-iostream/iostream-ssl.h index 40e07c5493..1825037ba6 100644 --- a/src/lib-ssl-iostream/iostream-ssl.h +++ b/src/lib-ssl-iostream/iostream-ssl.h @@ -7,6 +7,23 @@ struct ssl_iostream; struct ssl_iostream_context; +enum ssl_iostream_protocol_version { + /* Version not yet known at this protocol stage */ + SSL_IOSTREAM_PROTOCOL_VERSION_UNKNOWN = 0, + /* SSLv3 protocol */ + SSL_IOSTREAM_PROTOCOL_VERSION_SSL3, + /* TLSv1.0 protocol */ + SSL_IOSTREAM_PROTOCOL_VERSION_TLS1, + /* TLSv1.1 protocol */ + SSL_IOSTREAM_PROTOCOL_VERSION_TLS1_1, + /* TLSv1.2 protocol */ + SSL_IOSTREAM_PROTOCOL_VERSION_TLS1_2, + /* TLSv1.3 protocol */ + SSL_IOSTREAM_PROTOCOL_VERSION_TLS1_3, + /* Protocol version newer than Dovecot recognizes. */ + SSL_IOSTREAM_PROTOCOL_VERSION_NEW, +}; + enum ssl_iostream_flags { /* Enable ssl_iostream_settings.allow_invalid_cert after context is already created. If the context already has @@ -217,6 +234,9 @@ const char *ssl_iostream_get_pfs(struct ssl_iostream *ssl_io); This returns values like SSLv3, TLSv1, TLSv1.1, TLSv1.2 */ const char *ssl_iostream_get_protocol_name(struct ssl_iostream *ssl_io); +/* Returns currently used SSL protocol version. */ +enum ssl_iostream_protocol_version +ssl_iostream_get_protocol_version(struct ssl_iostream *ssl_io); const char *ssl_iostream_get_last_error(struct ssl_iostream *ssl_io); -- 2.47.3