Provide new code paths for OpenSSL v3

With OpenSSL v3 it would be possible to compile-out functions,
directly working with entities like RSA, DSA, DH and EC_KEY.
For this you have to define OPENSSL_API_COMPAT >= 0x30000000L.
This would break QSslKey and QSslContext.
To mitigate this potential problem, we switch to the 'generic'
API, that works with EVP_PKEY instead. All functionality
will be preserved, except inability of QSslKey::handle()
to get pointers to RSA, DSA, DH or EC_KEY.

Fixes: QTBUG-95122
Pick-to: 6.2
Change-Id: Ic85b48502421c4330cf4877b52850539c855fa74
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Timur Pocheptsov 2021-07-23 11:50:35 +02:00
parent 25fff849e8
commit 4c0f81490b
5 changed files with 275 additions and 157 deletions

View File

@ -46,6 +46,7 @@
#include "qsslsocket_openssl_symbols_p.h"
#include "qsslcontext_openssl_p.h"
#include "qtlsbackend_openssl_p.h"
#include "qtlskey_openssl_p.h"
#include "qopenssl_p.h"
#include <QtNetwork/private/qssl_p.h>
@ -626,6 +627,13 @@ QT_WARNING_POP
if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
} else {
#ifdef OPENSSL_NO_DEPRECATED_3_0
auto qtKey = QTlsBackend::backend<QTlsPrivate::TlsKeyOpenSSL>(configuration.d->privateKey);
Q_ASSERT(qtKey);
sslContext->pkey = qtKey->genericKey;
Q_ASSERT(sslContext->pkey);
q_EVP_PKEY_up_ref(sslContext->pkey);
#else
// Load private key
sslContext->pkey = q_EVP_PKEY_new();
// before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
@ -638,7 +646,8 @@ QT_WARNING_POP
#ifndef OPENSSL_NO_EC
else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
#endif
#endif // OPENSSL_NO_EC
#endif // OPENSSL_NO_DEPRECATED_3_0
}
auto pkey = sslContext->pkey;
if (configuration.d->privateKey.algorithm() == QSsl::Opaque)

View File

@ -150,9 +150,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
DEFINEFUNC2(void, OPENSSL_sk_pop_free, OPENSSL_STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
@ -195,7 +192,6 @@ DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
DEFINEFUNC(const char *, OpenSSL_version, int a, a, return nullptr, return)
DEFINEFUNC(unsigned long, SSL_SESSION_get_ticket_lifetime_hint, const SSL_SESSION *session, session, return 0, return)
DEFINEFUNC4(void, DH_get0_pqg, const DH *dh, dh, const BIGNUM **p, p, const BIGNUM **q, q, const BIGNUM **g, g, return, DUMMYARG)
DEFINEFUNC(int, DH_bits, DH *dh, dh, return 0, return)
#if QT_CONFIG(dtls)
DEFINEFUNC2(int, DTLSv1_listen, SSL *s, s, BIO_ADDR *c, c, return -1, return)
@ -259,10 +255,6 @@ DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
DEFINEFUNC2(BN_ULONG, BN_mod_word, const BIGNUM *a, a, BN_ULONG w, w, return static_cast<BN_ULONG>(-1), return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return nullptr, return)
DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return)
#endif
DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return nullptr, return)
@ -291,21 +283,7 @@ DEFINEFUNC(const EVP_CIPHER *, EVP_aes_192_cbc, DUMMYARG, DUMMYARG, return nullp
DEFINEFUNC(const EVP_CIPHER *, EVP_aes_256_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, void *r, r, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
#endif
DEFINEFUNC2(int, EVP_PKEY_cmp, const EVP_PKEY *a, a, const EVP_PKEY *b, b, return -1, return)
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(DH *, EVP_PKEY_get1_DH, EVP_PKEY *a, a, return nullptr, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return)
#endif
DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
@ -317,25 +295,11 @@ DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, retur
DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d, return -1, return)
DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return)
#endif // OPENSSL_NO_EC
DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_PrivateKey, BIO *a, a, EVP_PKEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_PrivateKey_traditional, BIO *a, a, EVP_PKEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_PUBKEY, BIO *a, a, EVP_PKEY *b, b, return 0, return)
DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
@ -378,8 +342,11 @@ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr,
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_get_bits, const EVP_PKEY *pkey, pkey, return -1, return)
DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
#else
DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
#endif // OPENSSL_VERSION_MAJOR >= 3
DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
@ -518,6 +485,53 @@ DEFINEFUNC5(int, PKCS12_parse, PKCS12 *p12, p12, const char *pass, pass, EVP_PKE
DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return nullptr, return);
DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
#ifndef OPENSSL_NO_DEPRECATED_3_0
DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
DEFINEFUNC(int, DH_bits, DH *dh, dh, return 0, return)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(DH *, EVP_PKEY_get1_DH, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC2(int, EVP_PKEY_cmp, const EVP_PKEY *a, a, const EVP_PKEY *b, b, return -1, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, void *r, r, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return nullptr, return)
DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return)
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return)
#endif // OPENSSL_NO_EC
#endif
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.ssl->resolve(#func))) \
&& !(_q_##func = _q_PTR_##func(libs.crypto->resolve(#func)))) \
@ -863,8 +877,6 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_CTX_new)
RESOLVEFUNC(EVP_PKEY_param_check)
RESOLVEFUNC(EVP_PKEY_CTX_free)
RESOLVEFUNC(EVP_PKEY_base_id)
RESOLVEFUNC(RSA_bits)
RESOLVEFUNC(OPENSSL_sk_new_null)
RESOLVEFUNC(OPENSSL_sk_push)
RESOLVEFUNC(OPENSSL_sk_free)
@ -915,8 +927,6 @@ bool q_resolveOpenSslSymbols()
}
RESOLVEFUNC(SSL_SESSION_get_ticket_lifetime_hint)
RESOLVEFUNC(DH_bits)
RESOLVEFUNC(DSA_bits)
#if QT_CONFIG(dtls)
RESOLVEFUNC(DTLSv1_listen)
@ -978,11 +988,6 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(BIO_clear_flags)
RESOLVEFUNC(BIO_set_ex_data)
RESOLVEFUNC(BIO_get_ex_data)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EC_KEY_get0_group)
RESOLVEFUNC(EC_GROUP_get_degree)
#endif
RESOLVEFUNC(BN_num_bits)
RESOLVEFUNC(BN_is_word)
RESOLVEFUNC(BN_mod_word)
@ -1013,25 +1018,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_aes_256_cbc)
#endif
RESOLVEFUNC(EVP_sha1)
RESOLVEFUNC(EVP_PKEY_assign)
RESOLVEFUNC(EVP_PKEY_set1_RSA)
RESOLVEFUNC(EVP_PKEY_set1_DSA)
RESOLVEFUNC(EVP_PKEY_set1_DH)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_set1_EC_KEY)
RESOLVEFUNC(EVP_PKEY_get1_EC_KEY)
RESOLVEFUNC(PEM_read_bio_ECPrivateKey)
RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
RESOLVEFUNC(PEM_read_bio_EC_PUBKEY)
RESOLVEFUNC(PEM_write_bio_EC_PUBKEY)
#endif // OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_cmp)
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
RESOLVEFUNC(EVP_PKEY_get1_DH)
RESOLVEFUNC(EVP_PKEY_new)
RESOLVEFUNC(EVP_PKEY_type)
RESOLVEFUNC(OBJ_nid2sn)
@ -1042,17 +1029,10 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OBJ_obj2txt)
RESOLVEFUNC(OBJ_obj2nid)
RESOLVEFUNC(PEM_read_bio_PrivateKey)
RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
RESOLVEFUNC(PEM_read_bio_DHparams)
RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_PrivateKey)
RESOLVEFUNC(PEM_write_bio_PrivateKey_traditional)
RESOLVEFUNC(PEM_read_bio_PUBKEY)
RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_PUBKEY)
RESOLVEFUNC(RAND_seed)
RESOLVEFUNC(RAND_status)
@ -1095,10 +1075,54 @@ bool q_resolveOpenSslSymbols()
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
RESOLVEFUNC(SSL_get1_peer_certificate)
RESOLVEFUNC(EVP_PKEY_get_bits)
RESOLVEFUNC(EVP_PKEY_get_base_id)
#else
RESOLVEFUNC(SSL_get_peer_certificate)
RESOLVEFUNC(EVP_PKEY_base_id)
#endif // OPENSSL_VERSION_MAJOR >= 3
#ifndef OPENSSL_NO_DEPRECATED_3_0
RESOLVEFUNC(EVP_PKEY_assign)
RESOLVEFUNC(EVP_PKEY_cmp)
RESOLVEFUNC(EVP_PKEY_set1_RSA)
RESOLVEFUNC(EVP_PKEY_set1_DSA)
RESOLVEFUNC(EVP_PKEY_set1_DH)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
RESOLVEFUNC(EVP_PKEY_get1_DH)
RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
RESOLVEFUNC(DH_bits)
RESOLVEFUNC(DSA_bits)
RESOLVEFUNC(RSA_bits)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_set1_EC_KEY)
RESOLVEFUNC(EVP_PKEY_get1_EC_KEY)
RESOLVEFUNC(PEM_read_bio_EC_PUBKEY)
RESOLVEFUNC(PEM_read_bio_ECPrivateKey)
RESOLVEFUNC(PEM_write_bio_EC_PUBKEY)
RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
RESOLVEFUNC(EC_KEY_get0_group)
RESOLVEFUNC(EC_GROUP_get_degree)
#endif // OPENSSL_NO_EC
#endif // OPENSSL_NO_DEPRECATED_3_0
RESOLVEFUNC(SSL_get_verify_result)
RESOLVEFUNC(SSL_new)
RESOLVEFUNC(SSL_get_SSL_CTX)

View File

@ -232,14 +232,11 @@ const unsigned char * q_ASN1_STRING_get0_data(const ASN1_STRING *x);
BIO *q_BIO_new(const BIO_METHOD *a);
const BIO_METHOD *q_BIO_s_mem();
int q_DSA_bits(DSA *a);
int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
int q_EVP_PKEY_up_ref(EVP_PKEY *a);
EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
int q_RSA_bits(RSA *a);
int q_OPENSSL_sk_num(OPENSSL_STACK *a);
void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
OPENSSL_STACK *q_OPENSSL_sk_new_null();
@ -266,7 +263,6 @@ int q_X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
void *q_X509_STORE_get_ex_data(X509_STORE *r, int idx);
STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
int q_DH_bits(DH *dh);
# define q_SSL_load_error_strings() q_OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
@ -380,11 +376,6 @@ int q_BN_num_bits(const BIGNUM *a);
int q_BN_is_word(BIGNUM *a, BN_ULONG w);
BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w);
#ifndef OPENSSL_NO_EC
const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k);
int q_EC_GROUP_get_degree(const EC_GROUP* g);
#endif // OPENSSL_NO_EC
DSA *q_DSA_new();
void q_DSA_free(DSA *a);
X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c);
@ -417,23 +408,8 @@ const EVP_CIPHER *q_EVP_aes_256_cbc();
#endif // OPENSSL_NO_AES
const EVP_MD *q_EVP_sha1();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, void *r);
int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
#ifndef OPENSSL_NO_EC
int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
#endif
int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a);
#ifndef OPENSSL_NO_EC
EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a);
#endif
int q_EVP_PKEY_type(int a);
EVP_PKEY *q_EVP_PKEY_new();
int q_i2d_X509(X509 *a, unsigned char **b);
@ -446,29 +422,13 @@ int q_OBJ_obj2txt(char *buf, int buf_len, ASN1_OBJECT *obj, int no_name);
int q_OBJ_obj2nid(const ASN1_OBJECT *a);
#define q_EVP_get_digestbynid(a) q_EVP_get_digestbyname(q_OBJ_nid2sn(a))
EVP_PKEY *q_PEM_read_bio_PrivateKey(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
DSA *q_PEM_read_bio_DSAPrivateKey(BIO *a, DSA **b, pem_password_cb *c, void *d);
RSA *q_PEM_read_bio_RSAPrivateKey(BIO *a, RSA **b, pem_password_cb *c, void *d);
#ifndef OPENSSL_NO_EC
EC_KEY *q_PEM_read_bio_ECPrivateKey(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
#endif // OPENSSL_NO_EC
DH *q_PEM_read_bio_DHparams(BIO *a, DH **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_PrivateKey(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_PrivateKey_traditional(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
EVP_PKEY *q_PEM_read_bio_PUBKEY(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d);
RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b);
int q_PEM_write_bio_PUBKEY(BIO *a, EVP_PKEY *b);
void q_RAND_seed(const void *a, int b);
@ -621,10 +581,6 @@ void q_GENERAL_NAME_free(GENERAL_NAME *a);
#define q_sk_SSL_CIPHER_value(st, i) q_SKM_sk_value(SSL_CIPHER, (st), (i))
#define q_SSL_CTX_add_extra_chain_cert(ctx,x509) \
q_SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
#define q_EVP_PKEY_assign_RSA(pkey,rsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
(char *)(rsa))
#define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
(char *)(dsa))
#define q_OpenSSL_add_all_algorithms() q_OPENSSL_add_all_algorithms_conf()
#if OPENSSL_VERSION_MAJOR < 3
@ -754,10 +710,70 @@ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
X509 *q_SSL_get1_peer_certificate(SSL *a);
#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
int q_EVP_PKEY_get_bits(const EVP_PKEY *pkey);
int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
#else
X509 *q_SSL_get_peer_certificate(SSL *a);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
#endif // OPENSSL_VERSION_MAJOR >= 3
#ifndef OPENSSL_NO_DEPRECATED_3_0
DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d);
RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d);
DSA *q_PEM_read_bio_DSAPrivateKey(BIO *a, DSA **b, pem_password_cb *c, void *d);
RSA *q_PEM_read_bio_RSAPrivateKey(BIO *a, RSA **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b);
int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a);
int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
int q_DH_bits(DH *dh);
int q_RSA_bits(RSA *a);
int q_DSA_bits(DSA *a);
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, void *r);
int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
#ifndef OPENSSL_NO_EC
EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
EC_KEY *q_PEM_read_bio_ECPrivateKey(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a);
int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k);
int q_EC_GROUP_get_degree(const EC_GROUP* g);
#define q_EVP_PKEY_assign_RSA(pkey,rsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
(char *)(rsa))
#define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
(char *)(dsa))
#endif // OPENSSL_NO_EC
#endif // OPENSSL_NO_DEPRECATED_3_0
QT_END_NAMESPACE
#endif

View File

@ -85,6 +85,16 @@ void TlsKeyOpenSSL::decodePem(KeyType type, KeyAlgorithm algorithm, const QByteA
void *phrase = const_cast<char *>(passPhrase.data());
#ifdef OPENSSL_NO_DEPRECATED_3_0
if (type == QSsl::PublicKey)
genericKey = q_PEM_read_bio_PUBKEY(bio, nullptr, nullptr, phrase);
else
genericKey = q_PEM_read_bio_PrivateKey(bio, nullptr, nullptr, phrase);
keyIsNull = !genericKey;
if (keyIsNull)
QTlsBackendOpenSSL::logAndClearErrorQueue();
#else
if (algorithm == QSsl::Rsa) {
RSA *result = (type == QSsl::PublicKey)
? q_PEM_read_bio_RSA_PUBKEY(bio, &rsa, nullptr, phrase)
@ -113,8 +123,10 @@ void TlsKeyOpenSSL::decodePem(KeyType type, KeyAlgorithm algorithm, const QByteA
: q_PEM_read_bio_ECPrivateKey(bio, &ec, nullptr, phrase);
if (ec && ec == result)
keyIsNull = false;
#endif
#endif // OPENSSL_NO_EC
}
#endif // OPENSSL_NO_DEPRECATED_3_0
}
QByteArray TlsKeyOpenSSL::derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const
@ -183,6 +195,7 @@ void TlsKeyOpenSSL::clear(bool deep)
{
keyIsNull = true;
#ifndef OPENSSL_NO_DEPRECATED_3_0
if (algorithm() == QSsl::Rsa && rsa) {
if (deep)
q_RSA_free(rsa);
@ -205,18 +218,30 @@ void TlsKeyOpenSSL::clear(bool deep)
ec = nullptr;
}
#endif
#endif // OPENSSL_NO_DEPRECATED_3_0
if (algorithm() == QSsl::Opaque && opaque) {
if (deep)
q_EVP_PKEY_free(opaque);
opaque = nullptr;
}
if (genericKey) {
// None of the above cleared it. genericKey is either
// initialised by PEM read operation, or from X509, and
// we are the owners and not sharing. So we free it.
q_EVP_PKEY_free(genericKey);
genericKey = nullptr;
}
}
Qt::HANDLE TlsKeyOpenSSL::handle() const
{
switch (keyAlgorithm) {
case QSsl::Opaque:
if (keyAlgorithm == QSsl::Opaque)
return Qt::HANDLE(opaque);
#ifndef OPENSSL_NO_DEPRECATED_3_0
switch (keyAlgorithm) {
case QSsl::Rsa:
return Qt::HANDLE(rsa);
case QSsl::Dsa:
@ -230,6 +255,11 @@ Qt::HANDLE TlsKeyOpenSSL::handle() const
default:
return Qt::HANDLE(nullptr);
}
#else
qCWarning(lcTlsBackend,
"This version of OpenSSL disabled direct manipulation with RSA/DSA/DH/EC_KEY structures, consider using QSsl::Opaque instead.");
return Qt::HANDLE(nullptr);
#endif
}
int TlsKeyOpenSSL::length() const
@ -237,6 +267,7 @@ int TlsKeyOpenSSL::length() const
if (isNull() || algorithm() == QSsl::Opaque)
return -1;
#ifndef OPENSSL_NO_DEPRECATED_3_0
switch (algorithm()) {
case QSsl::Rsa:
return q_RSA_bits(rsa);
@ -251,6 +282,10 @@ int TlsKeyOpenSSL::length() const
default:
return -1;
}
#else // OPENSSL_NO_DEPRECATED_3_0
Q_ASSERT(genericKey);
return q_EVP_PKEY_get_bits(genericKey);
#endif // OPENSSL_NO_DEPRECATED_3_0
}
QByteArray TlsKeyOpenSSL::toPem(const QByteArray &passPhrase) const
@ -273,54 +308,61 @@ QByteArray TlsKeyOpenSSL::toPem(const QByteArray &passPhrase) const
const auto bioRaii = qScopeGuard([bio]{q_BIO_free(bio);});
bool fail = false;
#ifndef OPENSSL_NO_DEPRECATED_3_0
#define write_pubkey(alg, key) q_PEM_write_bio_##alg##_PUBKEY(bio, key)
#define write_privatekey(alg, key) \
q_PEM_write_bio_##alg##PrivateKey(bio, key, cipher, (uchar *)passPhrase.data(), \
passPhrase.size(), nullptr, nullptr)
#else
#define write_pubkey(alg, key) q_PEM_write_bio_PUBKEY(bio, genericKey)
#define write_privatekey(alg, key) \
q_PEM_write_bio_PrivateKey_traditional(bio, genericKey, cipher, (uchar *)passPhrase.data(), passPhrase.size(), nullptr, nullptr)
#endif // OPENSSL_NO_DEPRECATED_3_0
bool fail = false;
if (algorithm() == QSsl::Rsa) {
if (type() == QSsl::PublicKey) {
if (!q_PEM_write_bio_RSA_PUBKEY(bio, rsa))
if (!write_pubkey(RSA, rsa))
fail = true;
} else {
if (!q_PEM_write_bio_RSAPrivateKey(
bio, rsa, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
} else if (!write_privatekey(RSA, rsa)) {
fail = true;
}
} else if (algorithm() == QSsl::Dsa) {
if (type() == QSsl::PublicKey) {
if (!q_PEM_write_bio_DSA_PUBKEY(bio, dsa))
if (!write_pubkey(DSA, dsa))
fail = true;
} else {
if (!q_PEM_write_bio_DSAPrivateKey(
bio, dsa, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
} else if (!write_privatekey(DSA, dsa)) {
fail = true;
}
} else if (algorithm() == QSsl::Dh) {
#ifdef OPENSSL_NO_DEPRECATED_3_0
EVP_PKEY *result = genericKey;
#else
EVP_PKEY *result = q_EVP_PKEY_new();
const auto guard = qScopeGuard([result]{if (result) q_EVP_PKEY_free(result);});
if (!result || !q_EVP_PKEY_set1_DH(result, dh)) {
fail = true;
} else if (type() == QSsl::PublicKey) {
} else
#endif
if (type() == QSsl::PublicKey) {
if (!q_PEM_write_bio_PUBKEY(bio, result))
fail = true;
} else if (!q_PEM_write_bio_PrivateKey(
bio, result, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
} else if (!q_PEM_write_bio_PrivateKey(bio, result, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
q_EVP_PKEY_free(result);
#ifndef OPENSSL_NO_EC
} else if (algorithm() == QSsl::Ec) {
if (type() == QSsl::PublicKey) {
if (!q_PEM_write_bio_EC_PUBKEY(bio, ec))
if (!write_pubkey(EC, ec))
fail = true;
} else {
if (!q_PEM_write_bio_ECPrivateKey(
bio, ec, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
if (!write_privatekey(EC, ec))
fail = true;
}
}
#endif
} else {
@ -333,6 +375,8 @@ QByteArray TlsKeyOpenSSL::toPem(const QByteArray &passPhrase) const
const long size = q_BIO_get_mem_data(bio, &data);
if (size > 0 && data)
pem = QByteArray(data, size);
} else {
QTlsBackendOpenSSL::logAndClearErrorQueue();
}
return pem;
@ -357,34 +401,37 @@ bool TlsKeyOpenSSL::fromEVP_PKEY(EVP_PKEY *pkey)
if (!pkey)
return false;
#ifndef OPENSSL_NO_DEPRECATED_3_0
#define get_key(key, alg) key = q_EVP_PKEY_get1_##alg(pkey)
#else
#define get_key(key, alg) q_EVP_PKEY_up_ref(pkey); genericKey = pkey;
#endif
switch (q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey))) {
case EVP_PKEY_RSA:
keyIsNull = false;
keyAlgorithm = QSsl::Rsa;
keyType = QSsl::PrivateKey;
rsa = q_EVP_PKEY_get1_RSA(pkey);
get_key(rsa, RSA);
return true;
case EVP_PKEY_DSA:
keyIsNull = false;
keyAlgorithm = QSsl::Dsa;
keyType = QSsl::PrivateKey;
dsa = q_EVP_PKEY_get1_DSA(pkey);
get_key(dsa, DSA);
return true;
case EVP_PKEY_DH:
keyIsNull = false;
keyAlgorithm = QSsl::Dh;
keyType = QSsl::PrivateKey;
dh = q_EVP_PKEY_get1_DH(pkey);
get_key(dh, DH);
return true;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
keyIsNull = false;
keyAlgorithm = QSsl::Ec;
keyType = QSsl::PrivateKey;
ec = q_EVP_PKEY_get1_EC_KEY(pkey);
get_key(ec, EC_KEY);
return true;
#endif
default:;
@ -484,21 +531,31 @@ TlsKeyOpenSSL *TlsKeyOpenSSL::publicKeyFromX509(X509 *x)
tlsKey->keyType = QSsl::PublicKey;
#ifndef OPENSSL_NO_DEPRECATED_3_0
#define get_pubkey(keyName, alg) tlsKey->keyName = q_EVP_PKEY_get1_##alg(pkey)
#else
#define get_pubkey(a, b) tlsKey->genericKey = pkey
#endif
EVP_PKEY *pkey = q_X509_get_pubkey(x);
Q_ASSERT(pkey);
const int keyType = q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey));
if (keyType == EVP_PKEY_RSA) {
tlsKey->rsa = q_EVP_PKEY_get1_RSA(pkey);
get_pubkey(rsa, RSA);
tlsKey->keyAlgorithm = QSsl::Rsa;
tlsKey->keyIsNull = false;
} else if (keyType == EVP_PKEY_DSA) {
tlsKey->dsa = q_EVP_PKEY_get1_DSA(pkey);
get_pubkey(dsa, DSA);
tlsKey->keyAlgorithm = QSsl::Dsa;
tlsKey->keyIsNull = false;
#ifndef OPENSSL_NO_EC
} else if (keyType == EVP_PKEY_EC) {
tlsKey->ec = q_EVP_PKEY_get1_EC_KEY(pkey);
get_pubkey(ec, EC_KEY);
tlsKey->keyAlgorithm = QSsl::Ec;
tlsKey->keyIsNull = false;
#endif
@ -508,7 +565,10 @@ TlsKeyOpenSSL *TlsKeyOpenSSL::publicKeyFromX509(X509 *x)
// error? (key is null)
}
#ifndef OPENSSL_NO_DEPRECATED_3_0
q_EVP_PKEY_free(pkey);
#endif
return keyRaii.release();
}

View File

@ -67,6 +67,14 @@
#include <openssl/dsa.h>
#include <openssl/dh.h>
#ifdef OPENSSL_NO_DEPRECATED_3_0
typedef struct evp_pkey_st EVP_PKEY;
typedef struct dsa_st DSA;
typedef struct rsa_st RSA;
typedef struct dh_st DH;
typedef struct ec_key_st EC_KEY;
#endif // OPENSSL_NO_DEPRECATED_3_0
QT_BEGIN_NAMESPACE
QT_REQUIRE_CONFIG(ssl);
@ -115,6 +123,7 @@ public:
#ifndef OPENSSL_NO_EC
EC_KEY *ec;
#endif
EVP_PKEY *genericKey;
};
bool fromEVP_PKEY(EVP_PKEY *pkey);