Date: Thu, 28 Feb 2019 13:47:40 +0000 (UTC) From: Raphael Kubo da Costa <rakuco@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-branches@freebsd.org Subject: svn commit: r494150 - in branches/2019Q1/devel/qca: . files Message-ID: <201902281347.x1SDletZ058011@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rakuco Date: Thu Feb 28 13:47:39 2019 New Revision: 494150 URL: https://svnweb.freebsd.org/changeset/ports/494150 Log: MFH: r494079 Replace OpenSSL 1.1.0 with upstream ones The patches from bug 228902 and added in r481850 are not entirely compatible with older OpenSSL versions, to the point that the qca-ossl plugin refuses to load at all on FreeBSD 11.2, for example (see bug 232784 and its duplicates). Fix it by replacing our patches with backports from upstream the same way OpenSUSE does it (the OpenSSL 1.1.0 upstream patch was authored by SUSE): * Revert an upstream commit made only to the 2.1 branch disabling a few ciphers in the unit tests. * Backport a change to the master branch that never made it to the 2.1 branch disabling the ciphers mentioned above as well as a few other ones, so that we can backport the actual change adding support for OpenSSL 1.1.0 more clealy. * Backport the actual OpenSSL 1.1.0 support commit, with a few conflicts resolved due to the lack of a commit adding suport for AES GCM and AES CCM in the 2.1 branch. The patch was actually obtained from OpenSUSE's repositories, since they had to resolve the same conflict as well. The port built fine on 11.2-i386, an old 12-CURRENT snapshot on amd64 as well as 13-CURRENT on amd64, and all unit tests are passing except for some PGP ones that are unrelated. With the patches we have in the tree, a lot of unit tests failed on 11.2 due to the qca-ossl plugin failing to load. PR: 228902 PR: 232784 Reviewed by: tcberner Differential Revision: https://reviews.freebsd.org/D19347 Approved by: ports-secteam (joneum) Added: branches/2019Q1/devel/qca/files/patch-openssl110_01 - copied unchanged from r494079, head/devel/qca/files/patch-openssl110_01 branches/2019Q1/devel/qca/files/patch-openssl110_02 - copied unchanged from r494079, head/devel/qca/files/patch-openssl110_02 branches/2019Q1/devel/qca/files/patch-openssl110_03 - copied unchanged from r494079, head/devel/qca/files/patch-openssl110_03 Deleted: branches/2019Q1/devel/qca/files/patch-plugins_qca-ossl_libcrypto-compat.c branches/2019Q1/devel/qca/files/patch-plugins_qca-ossl_libcrypto-compat.h branches/2019Q1/devel/qca/files/patch-plugins_qca-ossl_qca-ossl.cpp Modified: branches/2019Q1/devel/qca/Makefile Directory Properties: branches/2019Q1/ (props changed) Modified: branches/2019Q1/devel/qca/Makefile ============================================================================== --- branches/2019Q1/devel/qca/Makefile Thu Feb 28 12:39:29 2019 (r494149) +++ branches/2019Q1/devel/qca/Makefile Thu Feb 28 13:47:39 2019 (r494150) @@ -3,7 +3,7 @@ PORTNAME= qca PORTVERSION= 2.1.3 -PORTREVISION= 4 +PORTREVISION= 6 CATEGORIES= devel MASTER_SITES= KDE/stable/qca/${PORTVERSION}/src PKGNAMESUFFIX= -${FLAVOR} Copied: branches/2019Q1/devel/qca/files/patch-openssl110_01 (from r494079, head/devel/qca/files/patch-openssl110_01) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2019Q1/devel/qca/files/patch-openssl110_01 Thu Feb 28 13:47:39 2019 (r494150, copy of r494079, head/devel/qca/files/patch-openssl110_01) @@ -0,0 +1,44 @@ +Revert a change to the 2.1 branch that conflicts with a more extensive one from +the master branch (159e144abf, "Disable missed openssl cipher suites"). That +one is more extensive and is necessary for a clean backport of the upstream +change adding support for OpenSSL 1.1.0. +--- +From ecec3886ac73a5cfc8eb1f5929171afb89b204c3 Mon Sep 17 00:00:00 2001 +From: Raphael Kubo da Costa <rakuco@FreeBSD.org> +Date: Mon, 25 Feb 2019 13:31:51 +0100 +Subject: [PATCH 1/2] Revert "tlsunittest: disable some ciphers" + +This reverts commit 89800d4341a3346cee53bc28e18d9a3972e33378. +--- + unittest/tls/tlsunittest.cpp | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/unittest/tls/tlsunittest.cpp b/unittest/tls/tlsunittest.cpp +index fb8fa10..74c0b18 100644 +--- unittest/tls/tlsunittest.cpp ++++ unittest/tls/tlsunittest.cpp +@@ -69,9 +69,7 @@ void TLSUnitTest::testCipherList() + QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("TLS_RSA_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_SHA") ); +- +- // Fedora 22 has no TLS_RSA_WITH_RC4_128_MD5 +- // QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_MD5") ); ++ QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_MD5") ); + + // Fedora 20 openssl has no this cipher suites. + // I just believe that F20 has the most strict patent rules +@@ -98,9 +96,7 @@ void TLSUnitTest::testCipherList() + QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("SSL_RSA_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_SHA") ); +- +- // Fedora 22 has no SSL_RSA_WITH_RC4_128_MD5 +- // QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_MD5") ); ++ QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_MD5") ); + + // QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_DES_CBC_SHA") ); + // QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_DES_CBC_SHA") ); +-- +2.20.1 + Copied: branches/2019Q1/devel/qca/files/patch-openssl110_02 (from r494079, head/devel/qca/files/patch-openssl110_02) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2019Q1/devel/qca/files/patch-openssl110_02 Thu Feb 28 13:47:39 2019 (r494150, copy of r494079, head/devel/qca/files/patch-openssl110_02) @@ -0,0 +1,47 @@ +This change is part of the master branch but was never integrated into the 2.1 +branch, which only has a similar but less extensive commit mentioning Fedora 22. + +This backport is necessary for a clean cherry-pick of the change adding support +for OpenSSL 1.1.0 upstream. +--- +From 802180b9611e816b12b58c279824106514941d53 Mon Sep 17 00:00:00 2001 +From: Ivan Romanov <drizt@land.ru> +Date: Sat, 30 Sep 2017 15:45:59 +0500 +Subject: [PATCH 2/2] Disable missed openssl cipher suites + +Fedora 26 has no them. +--- + unittest/tls/tlsunittest.cpp | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/unittest/tls/tlsunittest.cpp b/unittest/tls/tlsunittest.cpp +index 74c0b18..38caf2d 100644 +--- unittest/tls/tlsunittest.cpp ++++ unittest/tls/tlsunittest.cpp +@@ -68,8 +68,12 @@ void TLSUnitTest::testCipherList() + QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("TLS_RSA_WITH_AES_128_CBC_SHA") ); +- QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_SHA") ); +- QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_MD5") ); ++ ++ // Fedora 26 openssl has no this cipher suites. ++ // QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_SHA") ); ++ // QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_MD5") ); ++ // QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_SHA") ); ++ // QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_MD5") ); + + // Fedora 20 openssl has no this cipher suites. + // I just believe that F20 has the most strict patent rules +@@ -95,8 +99,6 @@ void TLSUnitTest::testCipherList() + QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_AES_128_CBC_SHA") ); + QVERIFY( cipherList.contains("SSL_RSA_WITH_AES_128_CBC_SHA") ); +- QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_SHA") ); +- QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_MD5") ); + + // QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_DES_CBC_SHA") ); + // QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_DES_CBC_SHA") ); +-- +2.20.1 + Copied: branches/2019Q1/devel/qca/files/patch-openssl110_03 (from r494079, head/devel/qca/files/patch-openssl110_03) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2019Q1/devel/qca/files/patch-openssl110_03 Thu Feb 28 13:47:39 2019 (r494150, copy of r494079, head/devel/qca/files/patch-openssl110_03) @@ -0,0 +1,1802 @@ +The upstream commit is d58e20ee65, "Add support for OpenSSL 1.1.0" by +the same author below. This is a backport for a commit that only +landed in QCA's master branch. + +Instead of backporting the vanilla commit from upstream, grab the +OpenSUSE version created by the same author of the upstream change: it +resolves some conflicts due to the fact that the upstream commit was +applied on top of commit 57878ff44 ("Add support for AES GCM and AES +CCM modes"), which is not present in the 2.1 branch that version 2.1.3 +is based on. +--- +From 32bab34def80e08ca0b0d3a75f521369a8ee9ff0 Mon Sep 17 00:00:00 2001 +From: Fabian Vogt <fabian@ritter-vogt.de> +Date: Sat, 16 Dec 2017 22:29:40 +0100 +Subject: [PATCH 3/3] Add support for OpenSSL 1.1.0 + +Test Plan: +Ran the testsuite with OpenSSL 1.1.0g and 1.0.2j, all passed. +Using this code with kdeconnect and okteta successfully on my system now. + +Reviewers: iromanov + +Differential Revision: https://phabricator.kde.org/D9416 +--- + plugins/qca-ossl/ossl110-compat.h | 283 ++++++++++++++++++ + plugins/qca-ossl/qca-ossl.cpp | 587 +++++++++++++++++++++++++------------- + unittest/tls/tlsunittest.cpp | 35 +-- + 3 files changed, 687 insertions(+), 218 deletions(-) + create mode 100644 plugins/qca-ossl/ossl110-compat.h + +diff --git a/plugins/qca-ossl/ossl110-compat.h b/plugins/qca-ossl/ossl110-compat.h +new file mode 100644 +index 0000000..ec15475 +--- /dev/null ++++ plugins/qca-ossl/ossl110-compat.h +@@ -0,0 +1,283 @@ ++/* ++ * Copyright (C) 2017 Gabriel Souza Franco <gabrielfrancosouza@gmail.com> ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ++ * ++ */ ++ ++#ifndef OSSL110COMPAT_H ++#define OSSL110COMPAT_H ++ ++#include <openssl/evp.h> ++#include <openssl/hmac.h> ++#include <openssl/rsa.h> ++#include <openssl/dsa.h> ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#define RSA_F_RSA_METH_DUP 161 ++ ++static void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) ++{ ++ if (pr) ++ *pr = sig->r; ++ if (ps) ++ *ps = sig->s; ++} ++ ++static int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) ++{ ++ if (!sig) return 0; ++ sig->r = r; ++ sig->s = s; ++ return 1; ++} ++ ++static void DSA_get0_pqg(const DSA *dsa, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) ++{ ++ if (p) ++ *p = dsa->p; ++ if (q) ++ *q = dsa->q; ++ if (g) ++ *g = dsa->g; ++} ++ ++static int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ if (!dsa) return 0; ++ dsa->p = p; ++ dsa->q = q; ++ dsa->g = g; ++ return 1; ++} ++ ++static void RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) ++{ ++ if (n) ++ *n = rsa->n; ++ if (e) ++ *e = rsa->e; ++ if (d) ++ *d = rsa->d; ++} ++ ++static int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) ++{ ++ if (!rsa) return 0; ++ rsa->n = n; ++ rsa->e = e; ++ rsa->d = d; ++ return 1; ++} ++ ++static void RSA_get0_factors(const RSA *rsa, const BIGNUM **p, const BIGNUM **q) ++{ ++ if (p) ++ *p = rsa->p; ++ if (q) ++ *q = rsa->q; ++} ++ ++static int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) ++{ ++ if (!rsa) return 0; ++ rsa->p = p; ++ rsa->q = q; ++ return 1; ++} ++ ++static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) ++{ ++ if (p) ++ *p = dh->p; ++ if (q) ++ *q = dh->q; ++ if (g) ++ *g = dh->g; ++} ++ ++static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ if (!dh) return 0; ++ dh->p = p; ++ dh->q = q; ++ dh->g = g; ++ return 1; ++} ++ ++static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) ++{ ++ if (pub_key) ++ *pub_key = dh->pub_key; ++ if (priv_key) ++ *priv_key = dh->priv_key; ++} ++ ++static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ if (!dh) return 0; ++ dh->pub_key = pub_key; ++ dh->priv_key = priv_key; ++ return 1; ++} ++ ++static void DSA_get0_key(const DSA *dsa, const BIGNUM **pub_key, const BIGNUM **priv_key) ++{ ++ if (pub_key) ++ *pub_key = dsa->pub_key; ++ if (priv_key) ++ *priv_key = dsa->priv_key; ++} ++ ++static int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ if (!dsa) return 0; ++ dsa->pub_key = pub_key; ++ dsa->priv_key = priv_key; ++ return 1; ++} ++ ++static void X509_SIG_getm(const X509_SIG *sig, X509_ALGOR **palg, ASN1_OCTET_STRING **pdigest) ++{ ++ if (palg) ++ *palg = sig->algor; ++ if (pdigest) ++ *pdigest = sig->digest; ++} ++ ++static void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, const X509_ALGOR **palg) ++{ ++ if (psig) ++ *psig = req->signature; ++ if (palg) ++ *palg = req->sig_alg; ++} ++ ++static void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, const X509_ALGOR **palg) ++{ ++ if (psig) ++ *psig = crl->signature; ++ if (palg) ++ *palg = crl->sig_alg; ++} ++ ++static RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) ++{ ++ if (!meth) ++ return NULL; ++ ++ RSA_METHOD *_meth = (RSA_METHOD *) OPENSSL_malloc(sizeof(*_meth)); ++ ++ if (!_meth) ++ { ++ RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE); ++ return NULL; ++ } ++ ++ memcpy(_meth, meth, sizeof(*_meth)); ++ _meth->name = strdup(meth->name); ++ if (!_meth->name) { ++ OPENSSL_free(_meth); ++ RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE); ++ return NULL; ++ } ++ ++ return _meth; ++} ++ ++static int RSA_meth_set_priv_enc(RSA_METHOD *rsa, int (*priv_enc) (int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding)) ++{ ++ if (!rsa) return 0; ++ rsa->rsa_priv_enc = priv_enc; ++ return 1; ++} ++ ++static int RSA_meth_set_priv_dec(RSA_METHOD *rsa, int (*priv_dec) (int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding)) ++{ ++ if (!rsa) return 0; ++ rsa->rsa_priv_dec = priv_dec; ++ return 1; ++} ++ ++static int RSA_meth_set_sign(RSA_METHOD *meth, int (*sign) (int type, const unsigned char *m, ++ unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa)) ++{ ++ if (!meth) return 0; ++ meth->rsa_sign = sign; ++ return 1; ++} ++ ++static int RSA_meth_set_verify(RSA_METHOD *meth, int (*verify) (int dtype, const unsigned char *m, ++ unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)) ++{ ++ if (!meth) return 0; ++ meth->rsa_verify = verify; ++ return 1; ++} ++ ++static int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) ++{ ++ if (!meth) return 0; ++ meth->finish = finish; ++ return 1; ++} ++ ++static HMAC_CTX *HMAC_CTX_new() ++{ ++ HMAC_CTX *ctx = (HMAC_CTX *) OPENSSL_malloc(sizeof(HMAC_CTX)); ++ if (ctx) ++ HMAC_CTX_init(ctx); ++ return ctx; ++} ++ ++static void HMAC_CTX_free(HMAC_CTX *ctx) ++{ ++ if (!ctx) ++ return; ++ HMAC_CTX_cleanup(ctx); ++ EVP_MD_CTX_cleanup(&ctx->i_ctx); ++ EVP_MD_CTX_cleanup(&ctx->o_ctx); ++ EVP_MD_CTX_cleanup(&ctx->md_ctx); ++ OPENSSL_free(ctx); ++} ++ ++#define ASN1_STRING_get0_data(...) (const unsigned char*)ASN1_STRING_data(__VA_ARGS__) ++ ++#define EVP_MD_CTX_new(...) EVP_MD_CTX_create(__VA_ARGS__) ++#define EVP_MD_CTX_free(...) EVP_MD_CTX_destroy(__VA_ARGS__) ++ ++#define EVP_PKEY_up_ref(pkey) CRYPTO_add(&(pkey)->references, 1, CRYPTO_LOCK_EVP_PKEY) ++#define X509_up_ref(cert) CRYPTO_add(&(cert)->references, 1, CRYPTO_LOCK_X509) ++#define X509_CRL_up_ref(crl) CRYPTO_add(&(crl)->references, 1, CRYPTO_LOCK_X509_CRL) ++ ++#define EVP_PKEY_id(pky) (pky)->type ++#define EVP_PKEY_get0_DSA(pky) (pky)->pkey.dsa ++#define EVP_PKEY_get0_RSA(pky) (pky)->pkey.rsa ++#define EVP_PKEY_get0_DH(pky) (pky)->pkey.dh ++ ++#define X509_CRL_get0_lastUpdate X509_CRL_get_lastUpdate ++#define X509_CRL_get0_nextUpdate X509_CRL_get_nextUpdate ++ ++#define X509_REQ_get_signature_nid(req) OBJ_obj2nid((req)->sig_alg->algorithm) ++#define X509_CRL_get_signature_nid(crl) OBJ_obj2nid((crl)->sig_alg->algorithm) ++ ++#define X509_REVOKED_get0_serialNumber(rev) (rev)->serialNumber ++#define X509_REVOKED_get0_revocationDate(rev) (rev)->revocationDate ++ ++#endif // OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++#endif // OSSL110COMPAT_H +diff --git a/plugins/qca-ossl/qca-ossl.cpp b/plugins/qca-ossl/qca-ossl.cpp +index f0b9431..3bbbfdc 100644 +--- plugins/qca-ossl/qca-ossl.cpp ++++ plugins/qca-ossl/qca-ossl.cpp +@@ -1,6 +1,7 @@ + /* + * Copyright (C) 2004-2007 Justin Karneges <justin@affinix.com> + * Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net> ++ * Copyright (C) 2017 Fabian Vogt <fabian@ritter-vogt.de> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -38,6 +39,8 @@ + #include <openssl/pkcs12.h> + #include <openssl/ssl.h> + ++#include "ossl110-compat.h" ++ + #ifndef OSSL_097 + // comment this out if you'd rather use openssl 0.9.6 + #define OSSL_097 +@@ -52,6 +55,16 @@ + ((_STACK*) (1 ? p : (type*)0)) + #endif + ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ #define OSSL_110 ++#endif ++ ++// OpenSSL 1.1.0 compatibility macros ++#ifdef OSSL_110 ++#define M_ASN1_IA5STRING_new() ASN1_IA5STRING_new() ++#define RSA_F_RSA_EAY_PRIVATE_DECRYPT RSA_F_RSA_OSSL_PRIVATE_DECRYPT ++#endif ++ + using namespace QCA; + + namespace opensslQCAPlugin { +@@ -93,7 +106,7 @@ static QByteArray bio2ba(BIO *b) + return buf; + } + +-static BigInteger bn2bi(BIGNUM *n) ++static BigInteger bn2bi(const BIGNUM *n) + { + SecureArray buf(BN_num_bytes(n) + 1); + buf[0] = 0; // positive +@@ -109,7 +122,7 @@ static BIGNUM *bi2bn(const BigInteger &n) + + // take lowest bytes of BIGNUM to fit + // pad with high byte zeroes to fit +-static SecureArray bn2fixedbuf(BIGNUM *n, int size) ++static SecureArray bn2fixedbuf(const BIGNUM *n, int size) + { + SecureArray buf(BN_num_bytes(n)); + BN_bn2bin(n, (unsigned char *)buf.data()); +@@ -127,8 +140,11 @@ static SecureArray dsasig_der_to_raw(const SecureArray &in) + const unsigned char *inp = (const unsigned char *)in.data(); + d2i_DSA_SIG(&sig, &inp, in.size()); + +- SecureArray part_r = bn2fixedbuf(sig->r, 20); +- SecureArray part_s = bn2fixedbuf(sig->s, 20); ++ const BIGNUM *bnr, *bns; ++ DSA_SIG_get0(sig, &bnr, &bns); ++ ++ SecureArray part_r = bn2fixedbuf(bnr, 20); ++ SecureArray part_s = bn2fixedbuf(bns, 20); + SecureArray result; + result.append(part_r); + result.append(part_s); +@@ -143,12 +159,16 @@ static SecureArray dsasig_raw_to_der(const SecureArray &in) + return SecureArray(); + + DSA_SIG *sig = DSA_SIG_new(); +- SecureArray part_r(20); +- SecureArray part_s(20); ++ SecureArray part_r(20); BIGNUM *bnr; ++ SecureArray part_s(20); BIGNUM *bns; + memcpy(part_r.data(), in.data(), 20); + memcpy(part_s.data(), in.data() + 20, 20); +- sig->r = BN_bin2bn((const unsigned char *)part_r.data(), part_r.size(), NULL); +- sig->s = BN_bin2bn((const unsigned char *)part_s.data(), part_s.size(), NULL); ++ bnr = BN_bin2bn((const unsigned char *)part_r.data(), part_r.size(), NULL); ++ bns = BN_bin2bn((const unsigned char *)part_s.data(), part_s.size(), NULL); ++ ++ if(DSA_SIG_set0(sig, bnr, bns) == 0) ++ return SecureArray(); ++ // Not documented what happens in the failure case, free bnr and bns? + + int len = i2d_DSA_SIG(sig, NULL); + SecureArray result(len); +@@ -1004,29 +1024,39 @@ public: + opensslHashContext(const EVP_MD *algorithm, Provider *p, const QString &type) : HashContext(p, type) + { + m_algorithm = algorithm; +- EVP_DigestInit( &m_context, m_algorithm ); ++ m_context = EVP_MD_CTX_new(); ++ EVP_DigestInit( m_context, m_algorithm ); ++ } ++ ++ opensslHashContext(const opensslHashContext &other) ++ : HashContext(other) ++ { ++ m_algorithm = other.m_algorithm; ++ m_context = EVP_MD_CTX_new(); ++ EVP_MD_CTX_copy_ex(m_context, other.m_context); + } + + ~opensslHashContext() + { +- EVP_MD_CTX_cleanup(&m_context); ++ EVP_MD_CTX_free(m_context); + } + + void clear() + { +- EVP_MD_CTX_cleanup(&m_context); +- EVP_DigestInit( &m_context, m_algorithm ); ++ EVP_MD_CTX_free(m_context); ++ m_context = EVP_MD_CTX_new(); ++ EVP_DigestInit( m_context, m_algorithm ); + } + + void update(const MemoryRegion &a) + { +- EVP_DigestUpdate( &m_context, (unsigned char*)a.data(), a.size() ); ++ EVP_DigestUpdate( m_context, (unsigned char*)a.data(), a.size() ); + } + + MemoryRegion final() + { + SecureArray a( EVP_MD_size( m_algorithm ) ); +- EVP_DigestFinal( &m_context, (unsigned char*)a.data(), 0 ); ++ EVP_DigestFinal( m_context, (unsigned char*)a.data(), 0 ); + return a; + } + +@@ -1037,7 +1067,7 @@ public: + + protected: + const EVP_MD *m_algorithm; +- EVP_MD_CTX m_context; ++ EVP_MD_CTX *m_context; + }; + + +@@ -1047,7 +1077,21 @@ public: + opensslPbkdf1Context(const EVP_MD *algorithm, Provider *p, const QString &type) : KDFContext(p, type) + { + m_algorithm = algorithm; +- EVP_DigestInit( &m_context, m_algorithm ); ++ m_context = EVP_MD_CTX_new(); ++ EVP_DigestInit( m_context, m_algorithm ); ++ } ++ ++ opensslPbkdf1Context(const opensslPbkdf1Context &other) ++ : KDFContext(other) ++ { ++ m_algorithm = other.m_algorithm; ++ m_context = EVP_MD_CTX_new(); ++ EVP_MD_CTX_copy(m_context, other.m_context); ++ } ++ ++ ~opensslPbkdf1Context() ++ { ++ EVP_MD_CTX_free(m_context); + } + + Provider::Context *clone() const +@@ -1081,16 +1125,16 @@ public: + DK = Tc<0..dkLen-1> + */ + // calculate T_1 +- EVP_DigestUpdate( &m_context, (unsigned char*)secret.data(), secret.size() ); +- EVP_DigestUpdate( &m_context, (unsigned char*)salt.data(), salt.size() ); ++ EVP_DigestUpdate( m_context, (unsigned char*)secret.data(), secret.size() ); ++ EVP_DigestUpdate( m_context, (unsigned char*)salt.data(), salt.size() ); + SecureArray a( EVP_MD_size( m_algorithm ) ); +- EVP_DigestFinal( &m_context, (unsigned char*)a.data(), 0 ); ++ EVP_DigestFinal( m_context, (unsigned char*)a.data(), 0 ); + + // calculate T_2 up to T_c + for ( unsigned int i = 2; i <= iterationCount; ++i ) { +- EVP_DigestInit( &m_context, m_algorithm ); +- EVP_DigestUpdate( &m_context, (unsigned char*)a.data(), a.size() ); +- EVP_DigestFinal( &m_context, (unsigned char*)a.data(), 0 ); ++ EVP_DigestInit( m_context, m_algorithm ); ++ EVP_DigestUpdate( m_context, (unsigned char*)a.data(), a.size() ); ++ EVP_DigestFinal( m_context, (unsigned char*)a.data(), 0 ); + } + + // shrink a to become DK, of the required length +@@ -1136,19 +1180,19 @@ public: + DK = Tc<0..dkLen-1> + */ + // calculate T_1 +- EVP_DigestUpdate( &m_context, (unsigned char*)secret.data(), secret.size() ); +- EVP_DigestUpdate( &m_context, (unsigned char*)salt.data(), salt.size() ); ++ EVP_DigestUpdate( m_context, (unsigned char*)secret.data(), secret.size() ); ++ EVP_DigestUpdate( m_context, (unsigned char*)salt.data(), salt.size() ); + SecureArray a( EVP_MD_size( m_algorithm ) ); +- EVP_DigestFinal( &m_context, (unsigned char*)a.data(), 0 ); ++ EVP_DigestFinal( m_context, (unsigned char*)a.data(), 0 ); + + // calculate T_2 up to T_c + *iterationCount = 2 - 1; // <- Have to remove 1, unless it computes one + timer.start(); // ^ time more than the base function + // ^ with the same iterationCount + while (timer.elapsed() < msecInterval) { +- EVP_DigestInit( &m_context, m_algorithm ); +- EVP_DigestUpdate( &m_context, (unsigned char*)a.data(), a.size() ); +- EVP_DigestFinal( &m_context, (unsigned char*)a.data(), 0 ); ++ EVP_DigestInit( m_context, m_algorithm ); ++ EVP_DigestUpdate( m_context, (unsigned char*)a.data(), a.size() ); ++ EVP_DigestFinal( m_context, (unsigned char*)a.data(), 0 ); + ++(*iterationCount); + } + +@@ -1163,7 +1207,7 @@ public: + + protected: + const EVP_MD *m_algorithm; +- EVP_MD_CTX m_context; ++ EVP_MD_CTX *m_context; + }; + + class opensslPbkdf2Context : public KDFContext +@@ -1231,12 +1275,28 @@ public: + opensslHMACContext(const EVP_MD *algorithm, Provider *p, const QString &type) : MACContext(p, type) + { + m_algorithm = algorithm; +- HMAC_CTX_init( &m_context ); ++ m_context = HMAC_CTX_new(); ++#ifndef OSSL_110 ++ HMAC_CTX_init( m_context ); ++#endif ++ } ++ ++ opensslHMACContext(const opensslHMACContext &other) ++ : MACContext(other) ++ { ++ m_algorithm = other.m_algorithm; ++ m_context = HMAC_CTX_new(); ++ HMAC_CTX_copy(m_context, other.m_context); ++ } ++ ++ ~opensslHMACContext() ++ { ++ HMAC_CTX_free(m_context); + } + + void setup(const SymmetricKey &key) + { +- HMAC_Init_ex( &m_context, key.data(), key.size(), m_algorithm, 0 ); ++ HMAC_Init_ex( m_context, key.data(), key.size(), m_algorithm, 0 ); + } + + KeyLength keyLength() const +@@ -1246,14 +1306,18 @@ public: + + void update(const MemoryRegion &a) + { +- HMAC_Update( &m_context, (unsigned char *)a.data(), a.size() ); ++ HMAC_Update( m_context, (unsigned char *)a.data(), a.size() ); + } + + void final(MemoryRegion *out) + { + SecureArray sa( EVP_MD_size( m_algorithm ), 0 ); +- HMAC_Final(&m_context, (unsigned char *)sa.data(), 0 ); +- HMAC_CTX_cleanup(&m_context); ++ HMAC_Final(m_context, (unsigned char *)sa.data(), 0 ); ++#ifdef OSSL_110 ++ HMAC_CTX_reset(m_context); ++#else ++ HMAC_CTX_cleanup(m_context); ++#endif + *out = sa; + } + +@@ -1263,7 +1327,7 @@ public: + } + + protected: +- HMAC_CTX m_context; ++ HMAC_CTX *m_context; + const EVP_MD *m_algorithm; + }; + +@@ -1277,7 +1341,7 @@ class EVPKey + public: + enum State { Idle, SignActive, SignError, VerifyActive, VerifyError }; + EVP_PKEY *pkey; +- EVP_MD_CTX mdctx; ++ EVP_MD_CTX *mdctx; + State state; + bool raw_type; + SecureArray raw; +@@ -1287,19 +1351,23 @@ public: + pkey = 0; + raw_type = false; + state = Idle; ++ mdctx = EVP_MD_CTX_new(); + } + + EVPKey(const EVPKey &from) + { + pkey = from.pkey; +- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); ++ EVP_PKEY_up_ref(pkey); + raw_type = false; + state = Idle; ++ mdctx = EVP_MD_CTX_new(); ++ EVP_MD_CTX_copy(mdctx, from.mdctx); + } + + ~EVPKey() + { + reset(); ++ EVP_MD_CTX_free(mdctx); + } + + void reset() +@@ -1322,8 +1390,8 @@ public: + else + { + raw_type = false; +- EVP_MD_CTX_init(&mdctx); +- if(!EVP_SignInit_ex(&mdctx, type, NULL)) ++ EVP_MD_CTX_init(mdctx); ++ if(!EVP_SignInit_ex(mdctx, type, NULL)) + state = SignError; + } + } +@@ -1339,8 +1407,8 @@ public: + else + { + raw_type = false; +- EVP_MD_CTX_init(&mdctx); +- if(!EVP_VerifyInit_ex(&mdctx, type, NULL)) ++ EVP_MD_CTX_init(mdctx); ++ if(!EVP_VerifyInit_ex(mdctx, type, NULL)) + state = VerifyError; + } + } +@@ -1352,7 +1420,7 @@ public: + if (raw_type) + raw += in; + else +- if(!EVP_SignUpdate(&mdctx, in.data(), (unsigned int)in.size())) ++ if(!EVP_SignUpdate(mdctx, in.data(), (unsigned int)in.size())) + state = SignError; + } + else if(state == VerifyActive) +@@ -1360,7 +1428,7 @@ public: + if (raw_type) + raw += in; + else +- if(!EVP_VerifyUpdate(&mdctx, in.data(), (unsigned int)in.size())) ++ if(!EVP_VerifyUpdate(mdctx, in.data(), (unsigned int)in.size())) + state = VerifyError; + } + } +@@ -1373,17 +1441,20 @@ public: + unsigned int len = out.size(); + if (raw_type) + { +- if (pkey->type == EVP_PKEY_RSA) ++ int type = EVP_PKEY_id(pkey); ++ ++ if (type == EVP_PKEY_RSA) + { ++ RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if(RSA_private_encrypt (raw.size(), (unsigned char *)raw.data(), +- (unsigned char *)out.data(), pkey->pkey.rsa, ++ (unsigned char *)out.data(), rsa, + RSA_PKCS1_PADDING) == -1) { + + state = SignError; + return SecureArray (); + } + } +- else if (pkey->type == EVP_PKEY_DSA) ++ else if (type == EVP_PKEY_DSA) + { + state = SignError; + return SecureArray (); +@@ -1395,7 +1466,7 @@ public: + } + } + else { +- if(!EVP_SignFinal(&mdctx, (unsigned char *)out.data(), &len, pkey)) ++ if(!EVP_SignFinal(mdctx, (unsigned char *)out.data(), &len, pkey)) + { + state = SignError; + return SecureArray(); +@@ -1418,16 +1489,19 @@ public: + SecureArray out(EVP_PKEY_size(pkey)); + int len = 0; + +- if (pkey->type == EVP_PKEY_RSA) { ++ int type = EVP_PKEY_id(pkey); ++ ++ if (type == EVP_PKEY_RSA) { ++ RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if((len = RSA_public_decrypt (sig.size(), (unsigned char *)sig.data(), +- (unsigned char *)out.data (), pkey->pkey.rsa, ++ (unsigned char *)out.data (), rsa, + RSA_PKCS1_PADDING)) == -1) { + + state = VerifyError; + return false; + } + } +- else if (pkey->type == EVP_PKEY_DSA) ++ else if (type == EVP_PKEY_DSA) + { + state = VerifyError; + return false; +@@ -1447,7 +1521,7 @@ public: + } + else + { +- if(EVP_VerifyFinal(&mdctx, (unsigned char *)sig.data(), (unsigned int)sig.size(), pkey) != 1) ++ if(EVP_VerifyFinal(mdctx, (unsigned char *)sig.data(), (unsigned int)sig.size(), pkey) != 1) + { + state = VerifyError; + return false; +@@ -1561,9 +1635,11 @@ static bool make_dlgroup(const QByteArray &seed, int bits, int counter, DLParams + return false; + if(ret_counter != counter) + return false; +- params->p = bn2bi(dsa->p); +- params->q = bn2bi(dsa->q); +- params->g = bn2bi(dsa->g); ++ const BIGNUM *bnp, *bnq, *bng; ++ DSA_get0_pqg(dsa, &bnp, &bnq, &bng); ++ params->p = bn2bi(bnp); ++ params->q = bn2bi(bnq); ++ params->g = bn2bi(bng); + DSA_free(dsa); + return true; + } +@@ -1826,10 +1902,11 @@ public: + return; + + // extract the public key into DER format +- int len = i2d_RSAPublicKey(evp.pkey->pkey.rsa, NULL); ++ RSA *rsa_pkey = EVP_PKEY_get0_RSA(evp.pkey); ++ int len = i2d_RSAPublicKey(rsa_pkey, NULL); + SecureArray result(len); + unsigned char *p = (unsigned char *)result.data(); +- i2d_RSAPublicKey(evp.pkey->pkey.rsa, &p); ++ i2d_RSAPublicKey(rsa_pkey, &p); + p = (unsigned char *)result.data(); + + // put the DER public key back into openssl +@@ -1852,7 +1929,7 @@ public: + + virtual int maximumEncryptSize(EncryptionAlgorithm alg) const + { +- RSA *rsa = evp.pkey->pkey.rsa; ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); + int size = 0; + switch(alg) + { +@@ -1867,7 +1944,7 @@ public: + + virtual SecureArray encrypt(const SecureArray &in, EncryptionAlgorithm alg) + { +- RSA *rsa = evp.pkey->pkey.rsa; ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); + SecureArray buf = in; + int max = maximumEncryptSize(alg); + +@@ -1900,7 +1977,7 @@ public: + + virtual bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) + { +- RSA *rsa = evp.pkey->pkey.rsa; ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); + SecureArray result(RSA_size(rsa)); + int pad; + +@@ -2021,14 +2098,10 @@ public: + evp.reset(); + + RSA *rsa = RSA_new(); +- rsa->n = bi2bn(n); +- rsa->e = bi2bn(e); +- rsa->p = bi2bn(p); +- rsa->q = bi2bn(q); +- rsa->d = bi2bn(d); +- +- if(!rsa->n || !rsa->e || !rsa->p || !rsa->q || !rsa->d) ++ if(RSA_set0_key(rsa, bi2bn(n), bi2bn(e), bi2bn(d)) == 0 ++ || RSA_set0_factors(rsa, bi2bn(p), bi2bn(q)) == 0) + { ++ // Free BIGNUMS? + RSA_free(rsa); + return; + } +@@ -2036,7 +2109,7 @@ public: + // When private key has no Public Exponent (e) or Private Exponent (d) + // need to disable blinding. Otherwise decryption will be broken. + // http://www.mail-archive.com/openssl-users@openssl.org/msg63530.html +- if(BN_is_zero(rsa->e) || BN_is_zero(rsa->d)) ++ if(e == BigInteger(0) || d == BigInteger(0)) + RSA_blinding_off(rsa); + + evp.pkey = EVP_PKEY_new(); +@@ -2049,10 +2122,7 @@ public: + evp.reset(); + + RSA *rsa = RSA_new(); +- rsa->n = bi2bn(n); +- rsa->e = bi2bn(e); +- +- if(!rsa->n || !rsa->e) ++ if(RSA_set0_key(rsa, bi2bn(n), bi2bn(e), NULL) == 0) + { + RSA_free(rsa); + return; +@@ -2065,27 +2135,42 @@ public: + + virtual BigInteger n() const + { +- return bn2bi(evp.pkey->pkey.rsa->n); ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); ++ const BIGNUM *bnn; ++ RSA_get0_key(rsa, &bnn, NULL, NULL); ++ return bn2bi(bnn); + } + + virtual BigInteger e() const + { +- return bn2bi(evp.pkey->pkey.rsa->e); ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); ++ const BIGNUM *bne; ++ RSA_get0_key(rsa, NULL, &bne, NULL); ++ return bn2bi(bne); + } + + virtual BigInteger p() const + { +- return bn2bi(evp.pkey->pkey.rsa->p); ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); ++ const BIGNUM *bnp; ++ RSA_get0_factors(rsa, &bnp, NULL); ++ return bn2bi(bnp); + } + + virtual BigInteger q() const + { +- return bn2bi(evp.pkey->pkey.rsa->q); ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); ++ const BIGNUM *bnq; ++ RSA_get0_factors(rsa, NULL, &bnq); ++ return bn2bi(bnq); + } + + virtual BigInteger d() const + { +- return bn2bi(evp.pkey->pkey.rsa->d); ++ RSA *rsa = EVP_PKEY_get0_RSA(evp.pkey); ++ const BIGNUM *bnd; ++ RSA_get0_key(rsa, NULL, NULL, &bnd); ++ return bn2bi(bnd); + } + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902281347.x1SDletZ058011>