0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 12:02:28 +02:00

Cleanup print_details and add signature/ED certificate print

This commit cleans up the logic in the function a bit. It also makes it
more clear the the details printed in the second part of the message are
details about the peer certificate and not the TLS connection as such.
Also print the signature algorithm as this might help to identify
peer certificate that still use SHA1.

The new format with for TLS 1.3 and an EC certificate.

Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, peer
certificate: 384 bit EC, curve secp384r1, signature: ecdsa-with-SHA256

Using the more generic OpenSSL functions also allows use to correctly
print details about ED certificates:

Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, peer
certificate: 253 bit ED25519, signature: ED25519

Patch v2: Cleanup multiple calls to EVP_PKEY_id, minor code restructuring

Patch v3: Always initialise sig.

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20210326175750.4772-1-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg21861.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Arne Schwabe 2021-03-26 18:57:50 +01:00 committed by Gert Doering
parent 467b16dc65
commit ca57070630

View File

@ -2001,6 +2001,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
@ -2012,7 +2086,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];
@ -2023,48 +2096,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)
if (cert)
{
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);
}
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);
}