From 96b7834e98410ddaf46cfc8cd0d7cbcad20f14e7 Mon Sep 17 00:00:00 2001 From: Emmanuel Hocdet Date: Tue, 31 Oct 2017 15:46:07 +0100 Subject: [PATCH] MINOR: ssl: add ssl_sock_get_pkey_algo function ssl_sock_get_pkey_algo can be used to report pkey algorithm to log and ppv2 (RSA2048, EC256,...). Extract pkey information is not free in ssl api (lock/alloc/free): haproxy can use the pkey information computed in load_certificate. Store and use this information in a SSL ex_data when available, compute it if not (SSL multicert bundled and generated cert). --- include/proto/ssl_sock.h | 1 + src/ssl_sock.c | 68 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h index ef03de69d4..91456e2204 100644 --- a/include/proto/ssl_sock.h +++ b/include/proto/ssl_sock.h @@ -56,6 +56,7 @@ void ssl_sock_set_servername(struct connection *conn, const char *hostname); int ssl_sock_get_cert_used_sess(struct connection *conn); int ssl_sock_get_cert_used_conn(struct connection *conn); int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *out); +int ssl_sock_get_pkey_algo(struct connection *conn, struct chunk *out); unsigned int ssl_sock_get_verify_result(struct connection *conn); #if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err); diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 1f52f18682..555c7c4eca 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -262,6 +262,8 @@ struct ssl_capture { struct pool_head *pool_head_ssl_capture = NULL; static int ssl_capture_ptr_index = -1; +static int ssl_pkey_info_index = -1; + #if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0) struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference); #endif @@ -2059,6 +2061,11 @@ static struct { static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx) { + struct pkey_info *pkinfo; + + pkinfo = SSL_CTX_get_ex_data(ctx, ssl_pkey_info_index); + if (pkinfo) + SSL_set_ex_data(ssl, ssl_pkey_info_index, pkinfo); SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk); SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx))); SSL_set_SSL_CTX(ssl, ctx); @@ -2705,6 +2712,8 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_b sc->kinfo = kinfo; sc->order = order++; sc->neg = neg; + if (kinfo.sig != TLSEXT_signature_anonymous) + SSL_CTX_set_ex_data(ctx, ssl_pkey_info_index, &sc->kinfo); if (wild) ebst_insert(&s->sni_w_ctx, &sc->name); else @@ -5701,6 +5710,64 @@ static void ssl_sock_shutw(struct connection *conn, int clean) } } +/* used for ppv2 pkey alog (can be used for logging) */ +int ssl_sock_get_pkey_algo(struct connection *conn, struct chunk *out) +{ + struct pkey_info *pkinfo; + int bits = 0; + int sig = TLSEXT_signature_anonymous; + int len = -1; + + if (!ssl_sock_is_ssl(conn)) + return 0; + + pkinfo = SSL_get_ex_data(conn->xprt_ctx, ssl_pkey_info_index); + if (pkinfo) { + sig = pkinfo->sig; + bits = pkinfo->bits; + } else { + /* multicert and generated cert have no pkey info */ + X509 *crt; + EVP_PKEY *pkey; + crt = SSL_get_certificate(conn->xprt_ctx); + if (!crt) + return 0; + pkey = X509_get_pubkey(crt); + if (pkey) { + bits = EVP_PKEY_bits(pkey); + switch(EVP_PKEY_base_id(pkey)) { + case EVP_PKEY_RSA: + sig = TLSEXT_signature_rsa; + break; + case EVP_PKEY_EC: + sig = TLSEXT_signature_ecdsa; + break; + case EVP_PKEY_DSA: + sig = TLSEXT_signature_dsa; + break; + } + EVP_PKEY_free(pkey); + } + } + + switch(sig) { + case TLSEXT_signature_rsa: + len = chunk_printf(out, "RSA%d", bits); + break; + case TLSEXT_signature_ecdsa: + len = chunk_printf(out, "EC%d", bits); + break; + case TLSEXT_signature_dsa: + len = chunk_printf(out, "DSA%d", bits); + break; + default: + return 0; + } + if (len < 0) + return 0; + return 1; +} + /* used for logging/ppv2, may be changed for a sample fetch later */ const char *ssl_sock_get_cipher_name(struct connection *conn) { @@ -8813,6 +8880,7 @@ static void __ssl_sock_init(void) sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func); #endif ssl_capture_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_capture_free_func); + ssl_pkey_info_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); sample_register_fetches(&sample_fetch_keywords); acl_register_keywords(&acl_kws); bind_register_keywords(&bind_kws); -- 2.39.5