diff options
Diffstat (limited to 'src/openvpn/ssl_openssl.c')
-rw-r--r-- | src/openvpn/ssl_openssl.c | 128 |
1 files changed, 86 insertions, 42 deletions
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 5ba7440..31d94f2 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> - * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -335,6 +335,12 @@ tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) sslopt |= SSL_OP_CIPHER_SERVER_PREFERENCE; #endif sslopt |= SSL_OP_NO_COMPRESSION; + /* Disable TLS renegotiations. OpenVPN's renegotiation creates new SSL + * session and does not depend on this feature. And TLS renegotiations have + * been problematic in the past */ +#ifdef SSL_OP_NO_RENEGOTIATION + sslopt |= SSL_OP_NO_RENEGOTIATION; +#endif SSL_CTX_set_options(ctx->ctx, sslopt); @@ -2040,6 +2046,80 @@ key_state_read_plaintext(struct key_state_ssl *ks_ssl, struct buffer *buf, return ret; } +/** + * Print human readable information about the certifcate into buf + * @param cert the certificate being used + * @param buf output buffer + * @param buflen output buffer length + */ +static void +print_cert_details(X509 *cert, char *buf, size_t buflen) +{ + const char *curve = ""; + const char *type = "(error getting type)"; + EVP_PKEY *pkey = X509_get_pubkey(cert); + + if (pkey == NULL) + { + buf[0] = 0; + return; + } + + int typeid = EVP_PKEY_id(pkey); + +#ifndef OPENSSL_NO_EC + if (typeid == EVP_PKEY_EC && EVP_PKEY_get0_EC_KEY(pkey) != NULL) + { + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + const EC_GROUP *group = EC_KEY_get0_group(ec); + + int nid = EC_GROUP_get_curve_name(group); + if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL) + { + curve = "(error getting curve name)"; + } + } +#endif + if (EVP_PKEY_id(pkey) != 0) + { + int typeid = EVP_PKEY_id(pkey); + type = OBJ_nid2sn(typeid); + + /* OpenSSL reports rsaEncryption, dsaEncryption and + * id-ecPublicKey, map these values to nicer ones */ + if (typeid == EVP_PKEY_RSA) + { + type = "RSA"; + } + else if (typeid == EVP_PKEY_DSA) + { + type = "DSA"; + } + else if (typeid == EVP_PKEY_EC) + { + /* EC gets the curve appended after the type */ + type = "EC, curve "; + } + else if (type == NULL) + { + type = "unknown type"; + } + } + + char sig[128] = { 0 }; + int signature_nid = X509_get_signature_nid(cert); + if (signature_nid != 0) + { + openvpn_snprintf(sig, sizeof(sig), ", signature: %s", + OBJ_nid2sn(signature_nid)); + } + + openvpn_snprintf(buf, buflen, ", peer certificate: %d bit %s%s%s", + EVP_PKEY_bits(pkey), type, curve, sig); + + EVP_PKEY_free(pkey); +} + /* ************************************** * * Information functions @@ -2051,7 +2131,6 @@ void print_details(struct key_state_ssl *ks_ssl, const char *prefix) { const SSL_CIPHER *ciph; - X509 *cert; char s1[256]; char s2[256]; @@ -2062,48 +2141,13 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) SSL_get_version(ks_ssl->ssl), SSL_CIPHER_get_version(ciph), SSL_CIPHER_get_name(ciph)); - cert = SSL_get_peer_certificate(ks_ssl->ssl); - if (cert != NULL) - { - EVP_PKEY *pkey = X509_get_pubkey(cert); - if (pkey != NULL) - { - if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) && (EVP_PKEY_get0_RSA(pkey) != NULL)) - { - RSA *rsa = EVP_PKEY_get0_RSA(pkey); - openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", - RSA_bits(rsa)); - } - else if ((EVP_PKEY_id(pkey) == EVP_PKEY_DSA) && (EVP_PKEY_get0_DSA(pkey) != NULL)) - { - DSA *dsa = EVP_PKEY_get0_DSA(pkey); - openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", - DSA_bits(dsa)); - } -#ifndef OPENSSL_NO_EC - else if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && (EVP_PKEY_get0_EC_KEY(pkey) != NULL)) - { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - const EC_GROUP *group = EC_KEY_get0_group(ec); - const char *curve; + X509 *cert = SSL_get_peer_certificate(ks_ssl->ssl); - int nid = EC_GROUP_get_curve_name(group); - if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL) - { - curve = "Error getting curve name"; - } - - openvpn_snprintf(s2, sizeof(s2), ", %d bit EC, curve: %s", - EC_GROUP_order_bits(group), curve); - - } -#endif - EVP_PKEY_free(pkey); - } + if (cert) + { + print_cert_details(cert, s2, sizeof(s2)); X509_free(cert); } - /* The SSL API does not allow us to look at temporary RSA/DH keys, - * otherwise we should print their lengths too */ msg(D_HANDSHAKE, "%s%s", s1, s2); } |