From 181c617200e369d35076f0731cb2d979c02c3c57 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 31 Mar 2022 09:28:19 +0300 Subject: [PATCH] Set minimum supported OpenSSL version 1.1.1 and update to OpenSSL 1.1.1n (#1060) IB-7345 Signed-off-by: Raul Metsma --- .github/workflows/build.yml | 2 +- client/CryptoDoc.cpp | 26 ++++++------- client/QSigner.cpp | 47 +---------------------- client/SslCertificate.cpp | 65 +++++++++++--------------------- common | 2 +- prepare_osx_build_environment.sh | 2 +- 6 files changed, 37 insertions(+), 107 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3883ae9e7..52b5cb134 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -193,7 +193,7 @@ jobs: uses: lukka/run-vcpkg@v7 with: vcpkgArguments: openssl - vcpkgGitCommitId: b25cb779e5783531cc66562e224079b376055939 + vcpkgGitCommitId: a69b65229b3956b7f45abd81671b7330114bcaad vcpkgTriplet: ${{ matrix.arch }}-windows - name: Install Qt uses: jurplel/install-qt-action@v2 diff --git a/client/CryptoDoc.cpp b/client/CryptoDoc.cpp index 683a29c65..0d7969c53 100644 --- a/client/CryptoDoc.cpp +++ b/client/CryptoDoc.cpp @@ -64,11 +64,11 @@ using namespace ria::qdigidoc4; using puchar = uchar *; using pcuchar = const uchar *; -#define SCOPE(TYPE, VAR, DATA) std::unique_ptr VAR(DATA, TYPE##_free) +#define SCOPE(TYPE, DATA) std::unique_ptr(DATA, TYPE##_free) Q_LOGGING_CATEGORY(CRYPTO,"CRYPTO") -class CryptoDoc::Private: public QThread +class CryptoDoc::Private final: public QThread { Q_OBJECT public: @@ -214,11 +214,7 @@ QByteArray CryptoDoc::Private::crypto(const EVP_CIPHER *cipher, const QByteArray if(encrypt) { #ifdef WIN32 -#if OPENSSL_VERSION_NUMBER >= 0x10101000L RAND_poll(); -#else - RAND_screen(); -#endif #else RAND_load_file("/dev/urandom", 1024); #endif @@ -240,7 +236,7 @@ QByteArray CryptoDoc::Private::crypto(const EVP_CIPHER *cipher, const QByteArray _data = data.mid(iv.size(), data.size() - iv.size() - tag.size()); } - SCOPE(EVP_CIPHER_CTX, ctx, EVP_CIPHER_CTX_new()); + auto ctx = SCOPE(EVP_CIPHER_CTX, EVP_CIPHER_CTX_new()); if(opensslError(EVP_CipherInit(ctx.get(), cipher, pcuchar(key.constData()), pcuchar(iv.constData()), encrypt) <= 0)) return {}; @@ -640,20 +636,20 @@ void CryptoDoc::Private::writeCDoc(QIODevice *cdoc, const QByteArray &transportK { QByteArray derCert = k.cert.toDer(); pcuchar pp = pcuchar(derCert.data()); - SCOPE(X509, peerCert, d2i_X509(nullptr, &pp, derCert.size())); - SCOPE(EVP_PKEY, peerPKey, X509_get_pubkey(peerCert.get())); - SCOPE(EC_KEY, peerECKey, EVP_PKEY_get1_EC_KEY(peerPKey.get())); - int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(peerECKey.get())); - SCOPE(EC_KEY, priv, EC_KEY_new_by_curve_name(curve)); - SCOPE(EVP_PKEY, pkey, EVP_PKEY_new()); + auto peerCert = SCOPE(X509, d2i_X509(nullptr, &pp, derCert.size())); + EVP_PKEY *peerPKey = X509_get0_pubkey(peerCert.get()); + EC_KEY *peerECKey = EVP_PKEY_get0_EC_KEY(peerPKey); + int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(peerECKey)); + auto priv = SCOPE(EC_KEY, EC_KEY_new_by_curve_name(curve)); + auto pkey = SCOPE(EVP_PKEY, EVP_PKEY_new()); if (opensslError(EC_KEY_generate_key(priv.get()) <= 0) || opensslError(EVP_PKEY_set1_EC_KEY(pkey.get(), priv.get()) <= 0)) return; - SCOPE(EVP_PKEY_CTX, ctx, EVP_PKEY_CTX_new(pkey.get(), nullptr)); + auto ctx = SCOPE(EVP_PKEY_CTX, EVP_PKEY_CTX_new(pkey.get(), nullptr)); size_t sharedSecretLen = 0; if (opensslError(!ctx) || opensslError(EVP_PKEY_derive_init(ctx.get()) <= 0) || - opensslError(EVP_PKEY_derive_set_peer(ctx.get(), peerPKey.get()) <= 0) || + opensslError(EVP_PKEY_derive_set_peer(ctx.get(), peerPKey) <= 0) || opensslError(EVP_PKEY_derive(ctx.get(), nullptr, &sharedSecretLen) <= 0)) return; QByteArray sharedSecret(int(sharedSecretLen), 0); diff --git a/client/QSigner.cpp b/client/QSigner.cpp index f73593eaf..ae4b74b1e 100644 --- a/client/QSigner.cpp +++ b/client/QSigner.cpp @@ -42,20 +42,7 @@ Q_LOGGING_CATEGORY(SLog, "qdigidoc4.QSigner") -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if(!r || !s) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} -#endif - -class QSigner::Private +class QSigner::Private final { public: QSigner::ApiType api = QSigner::PKCS11; @@ -70,13 +57,8 @@ class QSigner::Private static ECDSA_SIG* ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - RSA_METHOD rsamethod = *RSA_get_default_method(); - ECDSA_METHOD *ecmethod = ECDSA_METHOD_new(nullptr); -#else RSA_METHOD *rsamethod = RSA_meth_dup(RSA_get_default_method()); EC_KEY_METHOD *ecmethod = EC_KEY_METHOD_new(EC_KEY_get_default_method()); -#endif }; QByteArray QSigner::Private::signData(int type, const QByteArray &digest, Private *d) @@ -98,11 +80,7 @@ int QSigner::Private::rsa_sign(int type, const unsigned char *m, unsigned int m_ ECDSA_SIG* QSigner::Private::ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM * /*inv*/, const BIGNUM * /*rp*/, EC_KEY *eckey) { -#if OPENSSL_VERSION_NUMBER < 0x10100000L - Private *d = (Private*)ECDSA_get_ex_data(eckey, 0); -#else Private *d = (Private*)EC_KEY_get_ex_data(eckey, 0); -#endif QByteArray result = signData(0, QByteArray::fromRawData((const char*)dgst, dgst_len), d); if(result.isEmpty()) return nullptr; @@ -123,14 +101,6 @@ QSigner::QSigner( ApiType api, QObject *parent ) : QThread(parent) , d(new Private) { -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - d->rsamethod.name = "QSmartCard"; - d->rsamethod.rsa_sign = Private::rsa_sign; - d->rsamethod.flags |= RSA_FLAG_SIGN_VER; - ECDSA_METHOD_set_name(d->ecmethod, const_cast("QSmartCard")); - ECDSA_METHOD_set_sign(d->ecmethod, Private::ecdsa_do_sign); - ECDSA_METHOD_set_app_data(d->ecmethod, d); -#else RSA_meth_set1_name(d->rsamethod, "QSmartCard"); RSA_meth_set_sign(d->rsamethod, Private::rsa_sign); using EC_KEY_sign = int (*)(int type, const unsigned char *dgst, int dlen, unsigned char *sig, @@ -140,7 +110,6 @@ QSigner::QSigner( ApiType api, QObject *parent ) EC_KEY_sign_setup sign_setup = nullptr; EC_KEY_METHOD_get_sign(d->ecmethod, &sign, &sign_setup, nullptr); EC_KEY_METHOD_set_sign(d->ecmethod, sign, sign_setup, Private::ecdsa_do_sign); -#endif d->api = api; d->smartcard = new QSmartCard(parent); @@ -155,12 +124,8 @@ QSigner::~QSigner() requestInterruption(); wait(); delete d->smartcard; -#if OPENSSL_VERSION_NUMBER >= 0x10100000L RSA_meth_free(d->rsamethod); EC_KEY_METHOD_free(d->ecmethod); -#else - ECDSA_METHOD_free(d->ecmethod); -#endif delete d; } @@ -306,23 +271,13 @@ QSslKey QSigner::key() const if (key.algorithm() == QSsl::Ec) { EC_KEY *ec = (EC_KEY*)key.handle(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L - ECDSA_set_ex_data(ec, 0, d); - ECDSA_set_method(ec, d->ecmethod); -#else EC_KEY_set_ex_data(ec, 0, d); EC_KEY_set_method(ec, d->ecmethod); -#endif } else { RSA *rsa = (RSA*)key.handle(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - RSA_set_method(rsa, &d->rsamethod); - rsa->flags |= RSA_FLAG_SIGN_VER; -#else RSA_set_method(rsa, d->rsamethod); -#endif RSA_set_app_data(rsa, d); } return key; diff --git a/client/SslCertificate.cpp b/client/SslCertificate.cpp index eb210f95f..4299f18bd 100644 --- a/client/SslCertificate.cpp +++ b/client/SslCertificate.cpp @@ -42,7 +42,7 @@ #include -#define SCOPE(TYPE, VAR, DATA) std::unique_ptr VAR(static_cast(DATA), TYPE##_free) +#define SCOPE(TYPE, DATA) std::unique_ptr(static_cast(DATA), TYPE##_free) #define toQByteArray(x) QByteArray((const char*)x->data, x->length) template static QByteArray i2dDer(Func func, Arg arg) @@ -59,27 +59,6 @@ static QByteArray i2dDer(Func func, Arg arg) return der; } -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if(n) *n = r->n; - if(e) *e = r->e; - if(d) *d = r->d; -} - -static void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) -{ - if(pub_key) *pub_key = d->pub_key; - if(priv_key) *priv_key = d->priv_key; -} - -static void X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg, const X509 *x) -{ - if(psig) *psig = x->signature; - if(palg) *palg = x->sig_alg; -} -#endif - uint qHash( const SslCertificate &cert ) { return qHash( cert.digest() ); } SslCertificate::SslCertificate() = default; @@ -105,7 +84,7 @@ QString SslCertificate::subjectInfo( QSslCertificate::SubjectInfo subject ) cons QMultiHash SslCertificate::authorityInfoAccess() const { QMultiHash result; - SCOPE(AUTHORITY_INFO_ACCESS, info, extension(NID_info_access)); + auto info = SCOPE(AUTHORITY_INFO_ACCESS, extension(NID_info_access)); if(!info) return result; for(int i = 0; i < sk_ACCESS_DESCRIPTION_num(info.get()); ++i) @@ -137,14 +116,14 @@ QMultiHash SslCertificate::authori QByteArray SslCertificate::authorityKeyIdentifier() const { - SCOPE(AUTHORITY_KEYID, id, extension(NID_authority_key_identifier)); + auto id = SCOPE(AUTHORITY_KEYID, extension(NID_authority_key_identifier)); return id && id->keyid ? toQByteArray(id->keyid) : QByteArray(); } QHash SslCertificate::enhancedKeyUsage() const { QHash list; - SCOPE(EXTENDED_KEY_USAGE, usage, extension(NID_ext_key_usage)); + auto usage = SCOPE(EXTENDED_KEY_USAGE, extension(NID_ext_key_usage)); if( !usage ) { list[All] = tr("All application policies"); @@ -193,7 +172,7 @@ QString SslCertificate::friendlyName() const bool SslCertificate::isCA() const { - SCOPE(BASIC_CONSTRAINTS, cons, extension(NID_basic_constraints)); + auto cons = SCOPE(BASIC_CONSTRAINTS, extension(NID_basic_constraints)); return cons && cons->ca > 0; } @@ -209,9 +188,9 @@ QString SslCertificate::keyName() const #ifndef OPENSSL_NO_ECDSA if(X509 *c = (X509*)handle()) { - SCOPE(EVP_PKEY, key, X509_get_pubkey(c)); - SCOPE(EC_KEY, ec, EVP_PKEY_get1_EC_KEY(key.get())); - int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec.get())); + EVP_PKEY *key = X509_get0_pubkey(c); + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(key); + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); ASN1_OBJECT *obj = OBJ_nid2obj(nid); QByteArray buff(50, 0); if(OBJ_obj2txt(buff.data(), buff.size(), obj, 0) > 0) @@ -230,7 +209,7 @@ Qt::HANDLE SslCertificate::extension( int nid ) const QHash SslCertificate::keyUsage() const { QHash list; - SCOPE(ASN1_BIT_STRING, keyusage, extension(NID_key_usage)); + auto keyusage = SCOPE(ASN1_BIT_STRING, extension(NID_key_usage)); if(!keyusage) return list; for( int n = 0; n < 9; ++n ) @@ -268,7 +247,7 @@ QString SslCertificate::personalCode() const QStringList SslCertificate::policies() const { - SCOPE(CERTIFICATEPOLICIES, cp, extension(NID_certificate_policies)); + auto cp = SCOPE(CERTIFICATEPOLICIES, extension(NID_certificate_policies)); QStringList list; if( !cp ) return list; @@ -300,7 +279,7 @@ QString SslCertificate::signatureAlgorithm() const QByteArray SslCertificate::subjectKeyIdentifier() const { - SCOPE(ASN1_OCTET_STRING, id, extension(NID_subject_key_identifier)); + auto id = SCOPE(ASN1_OCTET_STRING, extension(NID_subject_key_identifier)); return !id ? QByteArray() : toQByteArray(id); } @@ -411,7 +390,7 @@ SslCertificate::Validity SslCertificate::validateOnline() const return Unknown; // Build request - SCOPE(OCSP_REQUEST, ocspReq, OCSP_REQUEST_new()); + auto ocspReq = SCOPE(OCSP_REQUEST, OCSP_REQUEST_new()); if(!ocspReq) return Unknown; OCSP_CERTID *certId = OCSP_cert_to_id(nullptr, (X509*)handle(), (X509*)issuer.handle()); @@ -428,12 +407,12 @@ SslCertificate::Validity SslCertificate::validateOnline() const QByteArray respData = repl->readAll(); repl->deleteLater(); const unsigned char *p = (const unsigned char*)respData.constData(); - SCOPE(OCSP_RESPONSE, resp, d2i_OCSP_RESPONSE(nullptr, &p, respData.size())); + auto resp = SCOPE(OCSP_RESPONSE, d2i_OCSP_RESPONSE(nullptr, &p, respData.size())); if(!resp || OCSP_response_status(resp.get()) != OCSP_RESPONSE_STATUS_SUCCESSFUL) return Unknown; // Validate response - SCOPE(OCSP_BASICRESP, basic, OCSP_response_get1_basic(resp.get())); + auto basic = SCOPE(OCSP_BASICRESP, OCSP_response_get1_basic(resp.get())); if(!basic) return Unknown; //OCSP_TRUSTOTHER - enables OCSP_NOVERIFY @@ -452,7 +431,7 @@ SslCertificate::Validity SslCertificate::validateOnline() const -class PKCS12Certificate::Private: public QSharedData +class PKCS12Certificate::Private final: public QSharedData { public: void setLastError() @@ -542,7 +521,7 @@ PKCS12Certificate PKCS12Certificate::fromPath( const QString &path, const QStrin else if( !f.open( QFile::ReadOnly ) ) p12.d->error = PKCS12Certificate::FailedToRead; else - return PKCS12Certificate(&f, pin); + return {&f, pin}; return p12; } @@ -559,22 +538,22 @@ QSslKey PKCS12Certificate::fromEVP(Qt::HANDLE evp) const { case EVP_PKEY_RSA: { - SCOPE(RSA, rsa, EVP_PKEY_get1_RSA(key)); + RSA *rsa = EVP_PKEY_get0_RSA(key); alg = QSsl::Rsa; const BIGNUM *d = nullptr; - RSA_get0_key(rsa.get(), nullptr, nullptr, &d); + RSA_get0_key(rsa, nullptr, nullptr, &d); type = d ? QSsl::PrivateKey : QSsl::PublicKey; - len = d ? i2d_RSAPrivateKey(rsa.get(), &data) : i2d_RSAPublicKey(rsa.get(), &data); + len = d ? i2d_RSAPrivateKey(rsa, &data) : i2d_RSAPublicKey(rsa, &data); break; } case EVP_PKEY_DSA: { - SCOPE(DSA, dsa, EVP_PKEY_get1_DSA(key)); + DSA *dsa = EVP_PKEY_get0_DSA(key); alg = QSsl::Dsa; const BIGNUM *priv_key = nullptr; - DSA_get0_key(dsa.get(), nullptr, &priv_key); + DSA_get0_key(dsa, nullptr, &priv_key); type = priv_key ? QSsl::PrivateKey : QSsl::PublicKey; - len = priv_key ? i2d_DSAPrivateKey(dsa.get(), &data) : i2d_DSAPublicKey(dsa.get(), &data); + len = priv_key ? i2d_DSAPrivateKey(dsa, &data) : i2d_DSAPublicKey(dsa, &data); break; } default: break; diff --git a/common b/common index 33fe6d062..6be09d9da 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 33fe6d062fd7137001d0f0d073c9a6d05b09c925 +Subproject commit 6be09d9dab2bd000011269920032521cf311349a diff --git a/prepare_osx_build_environment.sh b/prepare_osx_build_environment.sh index e7cf3e88e..6f9d9b297 100755 --- a/prepare_osx_build_environment.sh +++ b/prepare_osx_build_environment.sh @@ -5,7 +5,7 @@ set -e ######### Versions of libraries/frameworks to be compiled QT_VER="5.12.12" -OPENSSL_VER="1.1.1m" +OPENSSL_VER="1.1.1n" OPENLDAP_VER="2.6.1" REBUILD=false BUILD_PATH=~/cmake_builds