Skip to content

Commit

Permalink
Set minimum supported OpenSSL version 1.1.1 and update to OpenSSL 1.1…
Browse files Browse the repository at this point in the history
….1n (open-eid#1060)

IB-7345

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma authored Mar 31, 2022
1 parent f9f6b7c commit 181c617
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 107 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 11 additions & 15 deletions client/CryptoDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ using namespace ria::qdigidoc4;
using puchar = uchar *;
using pcuchar = const uchar *;

#define SCOPE(TYPE, VAR, DATA) std::unique_ptr<TYPE,decltype(&TYPE##_free)> VAR(DATA, TYPE##_free)
#define SCOPE(TYPE, DATA) std::unique_ptr<TYPE,decltype(&TYPE##_free)>(DATA, TYPE##_free)

Q_LOGGING_CATEGORY(CRYPTO,"CRYPTO")

class CryptoDoc::Private: public QThread
class CryptoDoc::Private final: public QThread
{
Q_OBJECT
public:
Expand Down Expand Up @@ -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
Expand All @@ -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 {};

Expand Down Expand Up @@ -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);
Expand Down
47 changes: 1 addition & 46 deletions client/QSigner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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<char*>("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,
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
65 changes: 22 additions & 43 deletions client/SslCertificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

#include <memory>

#define SCOPE(TYPE, VAR, DATA) std::unique_ptr<TYPE,decltype(&TYPE##_free)> VAR(static_cast<TYPE*>(DATA), TYPE##_free)
#define SCOPE(TYPE, DATA) std::unique_ptr<TYPE,decltype(&TYPE##_free)>(static_cast<TYPE*>(DATA), TYPE##_free)
#define toQByteArray(x) QByteArray((const char*)x->data, x->length)
template <typename Func, typename Arg>
static QByteArray i2dDer(Func func, Arg arg)
Expand All @@ -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;
Expand All @@ -105,7 +84,7 @@ QString SslCertificate::subjectInfo( QSslCertificate::SubjectInfo subject ) cons
QMultiHash<SslCertificate::AuthorityInfoAccess, QString> SslCertificate::authorityInfoAccess() const
{
QMultiHash<AuthorityInfoAccess, QString> 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)
Expand Down Expand Up @@ -137,14 +116,14 @@ QMultiHash<SslCertificate::AuthorityInfoAccess, QString> 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,QString> SslCertificate::enhancedKeyUsage() const
{
QHash<EnhancedKeyUsage,QString> 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");
Expand Down Expand Up @@ -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;
}

Expand All @@ -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)
Expand All @@ -230,7 +209,7 @@ Qt::HANDLE SslCertificate::extension( int nid ) const
QHash<SslCertificate::KeyUsage,QString> SslCertificate::keyUsage() const
{
QHash<KeyUsage,QString> 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 )
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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());
Expand All @@ -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
Expand All @@ -452,7 +431,7 @@ SslCertificate::Validity SslCertificate::validateOnline() const



class PKCS12Certificate::Private: public QSharedData
class PKCS12Certificate::Private final: public QSharedData
{
public:
void setLastError()
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion common
Submodule common updated 1 files
+1 −1 CMakeLists.txt
2 changes: 1 addition & 1 deletion prepare_osx_build_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 181c617

Please sign in to comment.