From a3dfceefc2c729243b71270e3f503fa2dd57ec8d Mon Sep 17 00:00:00 2001 From: Alexander Zakharov Date: Wed, 21 Jun 2017 15:28:31 +0300 Subject: [PATCH] Workaround for key caching in OpenSSL > 1.1.0 Since v.1.1.0 the key caching has been added to OpenSSL. After X.509 had been parsed there is no point in changing of key algorithm as the key had already been decoded and cached result will be returned anyway. (check crypto/x509/x_pubkey.c: X509_PUBKEY_get0()) --- ssl.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/ssl.c b/ssl.c index c248449..45d8ee4 100644 --- a/ssl.c +++ b/ssl.c @@ -161,6 +161,11 @@ rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len) int nid; int ret; + const unsigned char *p; + int pklen; + + RSA *rsa = NULL; + /* By some reason, Microsoft sets the OID of the Public RSA key to the oid for "MD5 with RSA Encryption" instead of "RSA Encryption" @@ -194,10 +199,35 @@ rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len) if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption)) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L logger(Protocol, Debug, - "rdssl_cert_to_key(), re-setting algorithm type to RSA in server certificate"); + "rdssl_cert_to_key(), re-setting algorithm type to RSA in server certificate"); X509_PUBKEY_set0_param(key, OBJ_nid2obj(NID_rsaEncryption), 0, NULL, NULL, 0); +#else + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, key)) { + logger(Protocol, Error, + "rdssl_cert_to_key(), failed to get algorithm used for public key"); + rdssl_log_ssl_errors("rdssl_cert_to_key()"); + + return NULL; + } + + if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { + logger(Protocol, Error, + "rdssl_cert_to_key(), failed to extract public key from certificate"); + rdssl_log_ssl_errors("rdssl_cert_to_key()"); + + return NULL; + } + + lkey = RSAPublicKey_dup(rsa); + *key_len = RSA_size(lkey); + return lkey; +#endif + } + epk = X509_get_pubkey(cert); if (NULL == epk) { @@ -256,7 +286,7 @@ rdssl_rkey_get_exp_mod(RDSSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, e = rkey->e; n = rkey->n; #else - RSA_get0_key(rkey, &e, &n, NULL); + RSA_get0_key(rkey, &n, &e, NULL); #endif if ((BN_num_bytes(e) > (int) max_exp_len) || (BN_num_bytes(n) > (int) max_mod_len))