]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream: Add accessors for additional SSL protocol details
authorAki Tuomi <aki.tuomi@dovecot.fi>
Mon, 11 Dec 2017 09:00:41 +0000 (11:00 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 13 Mar 2018 12:09:40 +0000 (14:09 +0200)
This is needed in order to send these details as fields to auth process

src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-ssl-private.h
src/lib-ssl-iostream/iostream-ssl.c
src/lib-ssl-iostream/iostream-ssl.h

index f0eb2203d2c4203c68cc8aa863f21d2abd1e57e7..8dd0541af83efd147c635426f389768c4cbab8b8 100644 (file)
@@ -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)
index 430dbc5f7374f415a5287698908781b66d791602..2f6f50a1e6c39052dfaa042c5fe2cd5323201905 100644 (file)
@@ -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);
index da9184c4c4e81b7a7e406ee14bfdd24b9f5f4580..b9cf2c760628221b3352d164c7efc129a3513c51 100644 (file)
@@ -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);
+}
index 049c62d71af171d7c743b94f3a3f92bf9d7864cd..53058532f33eed750c8c7c68d12a1ed55a669985 100644 (file)
@@ -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,