From: Aki Tuomi Date: Mon, 11 Dec 2017 09:00:41 +0000 (+0200) Subject: lib-ssl-iostream: Add accessors for additional SSL protocol details X-Git-Tag: 2.3.1~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8230e3df4b59d79f77fbd5dd37a5da3d4660e08f;p=thirdparty%2Fdovecot%2Fcore.git lib-ssl-iostream: Add accessors for additional SSL protocol details This is needed in order to send these details as fields to auth process --- diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c index f0eb2203d2..8dd0541af8 100644 --- a/src/lib-ssl-iostream/iostream-openssl.c +++ b/src/lib-ssl-iostream/iostream-openssl.c @@ -822,6 +822,46 @@ openssl_iostream_get_last_error(struct ssl_iostream *ssl_io) return ssl_io->last_error; } +static const char * +openssl_iostream_get_cipher(struct ssl_iostream *ssl_io, unsigned int *bits_r) +{ + if (!ssl_io->handshaked) + return NULL; + + const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_io->ssl); + *bits_r = SSL_CIPHER_get_bits(cipher, NULL); + return SSL_CIPHER_get_name(cipher); +} + +static const char * +openssl_iostream_get_pfs(struct ssl_iostream *ssl_io) +{ + if (!ssl_io->handshaked) + return NULL; + + const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_io->ssl); +#if defined(HAVE_SSL_CIPHER_get_kx_nid) + int nid = SSL_CIPHER_get_kx_nid(cipher); + return OBJ_nid2sn(nid); +#else + char buf[128]; + const char *desc, *ptr; + if ((desc = SSL_CIPHER_description(cipher, buf, sizeof(buf)))==NULL || + (ptr = strstr(desc, "Kx=")) == NULL) + return ""; + return t_strcut(ptr+3, ' '); +#endif +} + +static const char * +openssl_iostream_get_protocol_name(struct ssl_iostream *ssl_io) +{ + if (!ssl_io->handshaked) + return NULL; + return SSL_get_version(ssl_io->ssl); +} + + static const struct iostream_ssl_vfuncs ssl_vfuncs = { .global_init = openssl_iostream_global_init, .context_init_client = openssl_iostream_context_init_client, @@ -849,6 +889,9 @@ static const struct iostream_ssl_vfuncs ssl_vfuncs = { .get_compression = openssl_iostream_get_compression, .get_security_string = openssl_iostream_get_security_string, .get_last_error = openssl_iostream_get_last_error, + .get_cipher = openssl_iostream_get_cipher, + .get_pfs = openssl_iostream_get_pfs, + .get_protocol_name = openssl_iostream_get_protocol_name, }; void ssl_iostream_openssl_init(void) diff --git a/src/lib-ssl-iostream/iostream-ssl-private.h b/src/lib-ssl-iostream/iostream-ssl-private.h index 430dbc5f73..2f6f50a1e6 100644 --- a/src/lib-ssl-iostream/iostream-ssl-private.h +++ b/src/lib-ssl-iostream/iostream-ssl-private.h @@ -44,6 +44,9 @@ struct iostream_ssl_vfuncs { const char *(*get_compression)(struct ssl_iostream *ssl_io); const char *(*get_security_string)(struct ssl_iostream *ssl_io); const char *(*get_last_error)(struct ssl_iostream *ssl_io); + 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); }; void iostream_ssl_module_init(const struct iostream_ssl_vfuncs *vfuncs); diff --git a/src/lib-ssl-iostream/iostream-ssl.c b/src/lib-ssl-iostream/iostream-ssl.c index da9184c4c4..b9cf2c7606 100644 --- a/src/lib-ssl-iostream/iostream-ssl.c +++ b/src/lib-ssl-iostream/iostream-ssl.c @@ -330,3 +330,19 @@ void ssl_iostream_settings_drop_stream_only(struct ssl_iostream_settings *set) set->verbose_invalid_cert = FALSE; set->allow_invalid_cert = FALSE; } + +const char *ssl_iostream_get_cipher(struct ssl_iostream *ssl_io, + unsigned int *bits_r) +{ + return ssl_vfuncs->get_cipher(ssl_io, bits_r); +} + +const char *ssl_iostream_get_pfs(struct ssl_iostream *ssl_io) +{ + return ssl_vfuncs->get_pfs(ssl_io); +} + +const char *ssl_iostream_get_protocol_name(struct ssl_iostream *ssl_io) +{ + return ssl_vfuncs->get_protocol_name(ssl_io); +} diff --git a/src/lib-ssl-iostream/iostream-ssl.h b/src/lib-ssl-iostream/iostream-ssl.h index 049c62d71a..53058532f3 100644 --- a/src/lib-ssl-iostream/iostream-ssl.h +++ b/src/lib-ssl-iostream/iostream-ssl.h @@ -109,6 +109,26 @@ const char *ssl_iostream_get_peer_name(struct ssl_iostream *ssl_io); const char *ssl_iostream_get_compression(struct ssl_iostream *ssl_io); const char *ssl_iostream_get_server_name(struct ssl_iostream *ssl_io); const char *ssl_iostream_get_security_string(struct ssl_iostream *ssl_io); +/* Returns SSL context's current used cipher algorithm. Returns NULL + if SSL handshake has not been performed. + + This returns values like 'AESGCM' +*/ +const char *ssl_iostream_get_cipher(struct ssl_iostream *ssl_io, + unsigned int *bits_r); +/* Returns currently used forward secrecy algorithm, if available. + Returns NULL if handshake not done yet, empty string if missing. + + This returns values like 'DH', 'ECDH' etc.. +*/ +const char *ssl_iostream_get_pfs(struct ssl_iostream *ssl_io); +/* Returns currently used SSL protocol name. Returns NULL if handshake + has not yet been made. + + This returns values like SSLv3, TLSv1, TLSv1.1, TLSv1.2 +*/ +const char *ssl_iostream_get_protocol_name(struct ssl_iostream *ssl_io); + const char *ssl_iostream_get_last_error(struct ssl_iostream *ssl_io); int ssl_iostream_context_init_client(const struct ssl_iostream_settings *set,