From de83447830b0941216f922a37b6cd36e703197d4 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Wed, 13 Jul 2016 08:42:33 +0200 Subject: Add support for Diffie-Hellman keys to QSslKey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is necessary to provide details for the key too, when the server is using DHE-RSA-AESxxx-SHAxxx. Amends 7f77dc84fb434f33ffe96f6633792706b80fb0a3. Change-Id: I8ab15b6987c17c857f54bc368df3c6c1818f428c Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Qt CI Bot Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qasn1element_p.h | 1 + src/network/ssl/qssl.cpp | 3 +- src/network/ssl/qssl.h | 3 +- src/network/ssl/qsslkey_openssl.cpp | 46 ++++++++++++++++++--- src/network/ssl/qsslkey_p.cpp | 8 +++- src/network/ssl/qsslkey_p.h | 1 + src/network/ssl/qsslkey_qt.cpp | 32 ++++++++++++++ src/network/ssl/qsslsocket_openssl_symbols.cpp | 8 ++++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 5 +++ .../ssl/qsslsocket_opensslpre11_symbols_p.h | 1 + .../auto/network/ssl/qsslkey/keys/dh-pri-1024.der | Bin 0 -> 293 bytes .../auto/network/ssl/qsslkey/keys/dh-pri-1024.pem | 9 ++++ .../auto/network/ssl/qsslkey/keys/dh-pri-2048.der | Bin 0 -> 554 bytes .../auto/network/ssl/qsslkey/keys/dh-pri-2048.pem | 14 +++++++ tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der | Bin 0 -> 159 bytes tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem | 6 +++ .../auto/network/ssl/qsslkey/keys/dh-pub-1024.der | Bin 0 -> 291 bytes .../auto/network/ssl/qsslkey/keys/dh-pub-1024.pem | 9 ++++ .../auto/network/ssl/qsslkey/keys/dh-pub-2048.der | Bin 0 -> 552 bytes .../auto/network/ssl/qsslkey/keys/dh-pub-2048.pem | 14 +++++++ tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der | Bin 0 -> 157 bytes tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem | 6 +++ tests/auto/network/ssl/qsslkey/keys/genkeys.sh | 21 ++++++++++ tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp | 5 ++- 24 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h index 2068254a95..59d1f58482 100644 --- a/src/network/ssl/qasn1element_p.h +++ b/src/network/ssl/qasn1element_p.h @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE #define RSA_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.1.1") #define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1") #define EC_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10045.2.1") +#define DH_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.3.1") // These are mostly from the RFC for PKCS#5 // PKCS#5: https://tools.ietf.org/html/rfc8018#appendix-B diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 19d99bc489..ea2b73bad5 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -71,7 +71,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value Rsa The RSA algorithm. \value Dsa The DSA algorithm. - \value Ec The Elliptic Curve algorithm + \value Ec The Elliptic Curve algorithm. + \value Dh The Diffie-Hellman algorithm. \value Opaque A key that should be treated as a 'black box' by QSslKey. The opaque key facility allows applications to add support for facilities diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h index 60362cb410..5c25e4e105 100644 --- a/src/network/ssl/qssl.h +++ b/src/network/ssl/qssl.h @@ -62,7 +62,8 @@ namespace QSsl { Opaque, Rsa, Dsa, - Ec + Ec, + Dh, }; enum AlternativeNameEntryType { diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 9a43e67772..99c1a39c73 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -69,6 +69,11 @@ void QSslKeyPrivate::clear(bool deep) q_DSA_free(dsa); dsa = nullptr; } + if (algorithm == QSsl::Dh && dh) { + if (deep) + q_DH_free(dh); + dh = nullptr; + } #ifndef OPENSSL_NO_EC if (algorithm == QSsl::Ec && ec) { if (deep) @@ -105,6 +110,12 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) type = QSsl::PrivateKey; dsa = q_EVP_PKEY_get1_DSA(pkey); return true; + } else if (keyType == EVP_PKEY_DH) { + isNull = false; + algorithm = QSsl::Dh; + type = QSsl::PrivateKey; + dh = q_EVP_PKEY_get1_DH(pkey); + return true; } #ifndef OPENSSL_NO_EC else if (keyType == EVP_PKEY_EC) { @@ -160,6 +171,15 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra : q_PEM_read_bio_DSAPrivateKey(bio, &dsa, nullptr, phrase); if (dsa && dsa == result) isNull = false; + } else if (algorithm == QSsl::Dh) { + EVP_PKEY *result = (type == QSsl::PublicKey) + ? q_PEM_read_bio_PUBKEY(bio, nullptr, nullptr, phrase) + : q_PEM_read_bio_PrivateKey(bio, nullptr, nullptr, phrase); + if (result) + dh = q_EVP_PKEY_get1_DH(result); + if (dh) + isNull = false; + q_EVP_PKEY_free(result); #ifndef OPENSSL_NO_EC } else if (algorithm == QSsl::Ec) { EC_KEY *result = (type == QSsl::PublicKey) @@ -181,6 +201,7 @@ int QSslKeyPrivate::length() const switch (algorithm) { case QSsl::Rsa: return q_RSA_bits(rsa); case QSsl::Dsa: return q_DSA_bits(dsa); + case QSsl::Dh: return q_DH_bits(dh); #ifndef OPENSSL_NO_EC case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec)); #endif @@ -215,7 +236,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const fail = true; } else { if (!q_PEM_write_bio_RSAPrivateKey( - bio, rsa, cipher, const_cast((const uchar *)passPhrase.data()), + bio, rsa, cipher, (uchar *)passPhrase.data(), passPhrase.size(), nullptr, nullptr)) { fail = true; } @@ -226,20 +247,33 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const fail = true; } else { if (!q_PEM_write_bio_DSAPrivateKey( - bio, dsa, cipher, const_cast((const uchar *)passPhrase.data()), + bio, dsa, cipher, (uchar *)passPhrase.data(), passPhrase.size(), nullptr, nullptr)) { fail = true; } } + } else if (algorithm == QSsl::Dh) { + EVP_PKEY *result = q_EVP_PKEY_new(); + if (!result || !q_EVP_PKEY_set1_DH(result, dh)) { + fail = true; + } else 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)) { + 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)) fail = true; } else { - if (!q_PEM_write_bio_ECPrivateKey(bio, ec, cipher, - const_cast((const uchar *)passPhrase.data()), - passPhrase.size(), nullptr, nullptr)) { + if (!q_PEM_write_bio_ECPrivateKey( + bio, ec, cipher, (uchar *)passPhrase.data(), + passPhrase.size(), nullptr, nullptr)) { fail = true; } } @@ -267,6 +301,8 @@ Qt::HANDLE QSslKeyPrivate::handle() const return Qt::HANDLE(rsa); case QSsl::Dsa: return Qt::HANDLE(dsa); + case QSsl::Dh: + return Qt::HANDLE(dh); #ifndef OPENSSL_NO_EC case QSsl::Ec: return Qt::HANDLE(ec); diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp index 28e3e2efd8..b29b38beab 100644 --- a/src/network/ssl/qsslkey_p.cpp +++ b/src/network/ssl/qsslkey_p.cpp @@ -116,6 +116,8 @@ QByteArray QSslKeyPrivate::pemHeader() const return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----"); else if (algorithm == QSsl::Ec) return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----"); + else if (algorithm == QSsl::Dh) + return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----"); Q_UNREACHABLE(); return QByteArray(); @@ -141,6 +143,8 @@ QByteArray QSslKeyPrivate::pemFooter() const return QByteArrayLiteral("-----END DSA PRIVATE KEY-----"); else if (algorithm == QSsl::Ec) return QByteArrayLiteral("-----END EC PRIVATE KEY-----"); + else if (algorithm == QSsl::Dh) + return QByteArrayLiteral("-----END PRIVATE KEY-----"); Q_UNREACHABLE(); return QByteArray(); @@ -535,7 +539,9 @@ QDebug operator<<(QDebug debug, const QSslKey &key) debug << "QSslKey(" << (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey") << ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" : - (key.algorithm() == QSsl::Rsa ? "RSA" : ((key.algorithm() == QSsl::Dsa) ? "DSA" : "EC"))) + (key.algorithm() == QSsl::Rsa ? "RSA" : + (key.algorithm() == QSsl::Dsa ? "DSA" : + (key.algorithm() == QSsl::Dh ? "DH" : "EC")))) << ", " << key.length() << ')'; return debug; diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index 7ae2cc740b..310553cab2 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -116,6 +116,7 @@ public: EVP_PKEY *opaque; RSA *rsa; DSA *dsa; + DH *dh; #ifndef OPENSSL_NO_EC EC_KEY *ec; #endif diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp index a13275f3bb..5ebd8ac3bd 100644 --- a/src/network/ssl/qsslkey_qt.cpp +++ b/src/network/ssl/qsslkey_qt.cpp @@ -165,6 +165,7 @@ static int extractPkcs8KeyLength(const QVector &items, QSslKeyPriv switch (algorithm){ case QSsl::Rsa: return "RSA"; case QSsl::Dsa: return "DSA"; + case QSsl::Dh: return "DH"; case QSsl::Ec: return "EC"; case QSsl::Opaque: return "Opaque"; } @@ -217,6 +218,21 @@ static int extractPkcs8KeyLength(const QVector &items, QSslKeyPriv if (dsaInfo.size() != 3 || dsaInfo[0].type() != QAsn1Element::IntegerType) return -1; keyLength = numberOfBits(dsaInfo[0].value()); + } else if (value == DH_ENCRYPTION_OID) { + if (Q_UNLIKELY(that->algorithm != QSsl::Dh)) { + // As above for RSA. + qWarning() << "QSslKey: Found DH when asked to use" << getName(that->algorithm) + << "\nLoading will fail."; + return -1; + } + // DH's structure is documented here: + // https://www.cryptsoft.com/pkcs11doc/STANDARD/v201-95.pdf in section 11.9. + if (pkcs8Info[1].type() != QAsn1Element::SequenceType) + return -1; + const QVector dhInfo = pkcs8Info[1].toVector(); + if (dhInfo.size() < 2 || dhInfo.size() > 3 || dhInfo[0].type() != QAsn1Element::IntegerType) + return -1; + keyLength = numberOfBits(dhInfo[0].value()); } else { // in case of unexpected formats: qWarning() << "QSslKey: Unsupported PKCS#8 key algorithm:" << value @@ -268,6 +284,16 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType) return; keyLength = numberOfBits(params[0].value()); + } else if (algorithm == QSsl::Dh) { + if (infoItems[0].toObjectId() != DH_ENCRYPTION_OID) + return; + if (infoItems[1].type() != QAsn1Element::SequenceType) + return; + // key params + const QVector params = infoItems[1].toVector(); + if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType) + return; + keyLength = numberOfBits(params[0].value()); } else if (algorithm == QSsl::Ec) { if (infoItems[0].toObjectId() != EC_ENCRYPTION_OID) return; @@ -307,6 +333,12 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra if (items.size() != 6 || items[1].type() != QAsn1Element::IntegerType) return; keyLength = numberOfBits(items[1].value()); + } else if (algorithm == QSsl::Dh) { + if (versionHex != "00") + return; + if (items.size() < 5 || items.size() > 6 || items[1].type() != QAsn1Element::IntegerType) + return; + keyLength = numberOfBits(items[1].value()); } else if (algorithm == QSsl::Ec) { if (versionHex != "01") return; diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 781b3d6640..5ba2c40636 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -366,12 +366,14 @@ DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, 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 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 @@ -397,6 +399,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_p 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) #ifndef OPENSSL_NO_EC 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) #endif @@ -409,6 +412,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_pass #endif 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) #ifndef OPENSSL_NO_EC DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return) #endif @@ -1168,12 +1172,14 @@ bool q_resolveOpenSslSymbols() 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) #endif RESOLVEFUNC(EVP_PKEY_free) RESOLVEFUNC(EVP_PKEY_get1_DSA) RESOLVEFUNC(EVP_PKEY_get1_RSA) + RESOLVEFUNC(EVP_PKEY_get1_DH) #ifndef OPENSSL_NO_EC RESOLVEFUNC(EVP_PKEY_get1_EC_KEY) #endif @@ -1197,6 +1203,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(PEM_read_bio_DHparams) RESOLVEFUNC(PEM_write_bio_DSAPrivateKey) RESOLVEFUNC(PEM_write_bio_RSAPrivateKey) + RESOLVEFUNC(PEM_write_bio_PrivateKey) #ifndef OPENSSL_NO_EC RESOLVEFUNC(PEM_write_bio_ECPrivateKey) #endif @@ -1210,6 +1217,7 @@ bool q_resolveOpenSslSymbols() #endif RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY) RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY) + RESOLVEFUNC(PEM_write_bio_PUBKEY) #ifndef OPENSSL_NO_EC RESOLVEFUNC(PEM_write_bio_EC_PUBKEY) #endif diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index bfdfbf0efc..7e759d3825 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -278,12 +278,14 @@ const EVP_MD *q_EVP_sha1(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT 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 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 @@ -314,6 +316,8 @@ int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned 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); #ifndef OPENSSL_NO_EC 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); @@ -327,6 +331,7 @@ EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d #endif 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); #ifndef OPENSSL_NO_EC int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b); #endif diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h index b7bac5d2a2..daf46f485c 100644 --- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h +++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h @@ -218,6 +218,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); #define q_SSL_SESSION_get_ticket_lifetime_hint(s) ((s)->tlsext_tick_lifetime_hint) #define q_RSA_bits(rsa) q_BN_num_bits((rsa)->n) #define q_DSA_bits(dsa) q_BN_num_bits((dsa)->p) +#define q_DH_bits(dsa) q_BN_num_bits((dh)->p) #define q_X509_STORE_set_verify_cb(s,c) X509_STORE_set_verify_cb_func((s),(c)) char *q_CONF_get1_default_config_file(); diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der new file mode 100644 index 0000000000..687009e087 Binary files /dev/null and b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der differ diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem new file mode 100644 index 0000000000..233e0dfb37 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN PRIVATE KEY----- +MIIBIQIBADCBlQYJKoZIhvcNAQMBMIGHAoGBAIlk2YX0TJzfQ18ZzZroQoE5Nyjt +bWxWRxBriG/c+JWhBwttVDb6lzLN+GVJxXVPfc6JJmDORVRxdxAlMqu++2Vqpsnl +/H8xIXsxjuTcTjq8sXagGRa0LfeggkUD64tEhO4iZ8Q2TIdb3OHkAF0Sn+06b/0e +iIz323Kywq0CsspTAgECBIGDAoGAQCo39UHP4s2ZVH4nOmWgNlb4JsHPX4EzqDBr +ig46hvMLAFrILYnsCbqqD/+GNAUl1PV/nfEQoAk/HvtACqLFLG5/3jK2w6dVHGEo +JnVOGz9vZpWUx+SCslHJRFaeE+6AAbbvrTr0lci29Ta4IesHlamRsj+ZaUrVX6k/ +/9OTGAo= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der new file mode 100644 index 0000000000..e193f25f07 Binary files /dev/null and b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der differ diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem new file mode 100644 index 0000000000..32299b2b6c --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem @@ -0,0 +1,14 @@ +-----BEGIN PRIVATE KEY----- +MIICJgIBADCCARcGCSqGSIb3DQEDATCCAQgCggEBAJsiReJxBjkC7Hy99AJATusq +YsNQHhjoeTLPeHhsBuLtJK18Krk736V09efX6qeAEmvgMQbvbHqtrOaY3q6dut6C +UTGVW+oVg3d/Y8qakkanvEnIlliaTIyWIz0JMjO2prC6AuU/QEzZcQVUS6bxyn3D +iYFxCE6+7cJJpEH9HVbcrl+J6Ch6ax5rQGUyxpSMkmItLJx92upRxOnaxJMHR+ZF +OSdDPfrkINpEzahnhteLszddyLasnE0or6ZnXYLvKsT1Uu6QwDc4EO1FJHScoeep +zsK/VRcXzMpj/1Rl+F9E/AikCqHRrnvISt25wrK0Mwy854P2T7dJlBNewc6vE6MC +AQIEggEEAoIBAGIctO30MoZ9DiuKbOBpqM9rl2bNH/I46GGcfEiSsO/zOw2V9WFC +MxkjF0I1ilDfPY+Ag3bLB2n89DPcfXliYH9MFolehPTc1fWplhX3+ImdC6y95uXO +FV5xtcEQCbPktnUtkUdcAT5831p9lu1QJo+DzMPrQa7axMLj8heBAi4VqAi+8Q31 +dpGKuhCUlgs+pLENx1o0QY2kui6Z5uR0YhmA547lwBWA4XEv5OV9ExmxytiatvOv +PZKT1ID76LrL9bnnZvOEGczWLQvJ9VaaZSpoP+2QisRANWW4w57d+PIR1WR/FTSH +F6xocElUoTzuiSPzRz60aw/KkisImBBKERQ= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der new file mode 100644 index 0000000000..42ddbaaae2 Binary files /dev/null and b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der differ diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem new file mode 100644 index 0000000000..d2c3170b16 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGcAgEAMFMGCSqGSIb3DQEDATBGAkEAvXx0QxJvIGA2ig8Je55R2rmeO4Ta2Esj +ANLuyVIFRbtuLFsdhU+amUc8bs9RUQmkUNzS92jkpAfqtCv+mQ06EwIBAgRCAkBJ +rDM0BTevOPIHpJzMtSQhw3e7Dr38HUfTn8zF3uYi1RCxjkTUukmzRLPTf0aqPgpd +8dSldjG/11aZORl8/mXO +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der new file mode 100644 index 0000000000..2805a67633 Binary files /dev/null and b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der differ diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem new file mode 100644 index 0000000000..da4e327ac9 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBHzCBlQYJKoZIhvcNAQMBMIGHAoGBAIlk2YX0TJzfQ18ZzZroQoE5NyjtbWxW +RxBriG/c+JWhBwttVDb6lzLN+GVJxXVPfc6JJmDORVRxdxAlMqu++2Vqpsnl/H8x +IXsxjuTcTjq8sXagGRa0LfeggkUD64tEhO4iZ8Q2TIdb3OHkAF0Sn+06b/0eiIz3 +23Kywq0CsspTAgECA4GEAAKBgA8pxU1sMDvRWKpvJKNs3jNhZPQWFf4Tszu/cMcb +1qAQ/q0DRb41VvsUoMaCfef/plZleV4MG26owb574AJeC86wX5MbRDTPS4CzAn+I +an92AZl3vlYRQ2sSo3ktkyhw6LV1iewi08Ky7J4rqvG0Oo335QGEZlK1OgwBsyh0 +FKLe +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der new file mode 100644 index 0000000000..9e749d8a41 Binary files /dev/null and b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der differ diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem new file mode 100644 index 0000000000..f751157c87 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICJDCCARcGCSqGSIb3DQEDATCCAQgCggEBAJsiReJxBjkC7Hy99AJATusqYsNQ +HhjoeTLPeHhsBuLtJK18Krk736V09efX6qeAEmvgMQbvbHqtrOaY3q6dut6CUTGV +W+oVg3d/Y8qakkanvEnIlliaTIyWIz0JMjO2prC6AuU/QEzZcQVUS6bxyn3DiYFx +CE6+7cJJpEH9HVbcrl+J6Ch6ax5rQGUyxpSMkmItLJx92upRxOnaxJMHR+ZFOSdD +PfrkINpEzahnhteLszddyLasnE0or6ZnXYLvKsT1Uu6QwDc4EO1FJHScoeepzsK/ +VRcXzMpj/1Rl+F9E/AikCqHRrnvISt25wrK0Mwy854P2T7dJlBNewc6vE6MCAQID +ggEFAAKCAQAUeWRuqjl7F84USogxJOM1M4y8yKtBYY2KLs5iIVhzV4UZ+9+cMNZA +otLXJ/e8BH0diR0yk7tjxD6hjjqd+nyafIkJGPElDMnTbRPHg5zZYMmI5L/efdSm +OPbM7QsodrYH5aoF4c7hjMb/cttYVG2Yupsy4tfORuDbwL70upqOo6rkVq55eOGS +6pseEume/SD+7e3xIPJTkrMMzBFHG6H7bVHikT4O7yWV1iVzElj919yi+4Zy6TK8 +0hG6l31D5bsJpOduhHYZtN1yQpw+sGT6Yiepkjgt+1YkGFiiRs5vDl4DHeYHyAhL +oH9uKcm3q4lhaOeT5ml765g87qQD6+vr +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der new file mode 100644 index 0000000000..8a75babb6d Binary files /dev/null and b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der differ diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem new file mode 100644 index 0000000000..1f4e5c9a47 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGaMFMGCSqGSIb3DQEDATBGAkEAvXx0QxJvIGA2ig8Je55R2rmeO4Ta2EsjANLu +yVIFRbtuLFsdhU+amUc8bs9RUQmkUNzS92jkpAfqtCv+mQ06EwIBAgNDAAJARGBh +9FmRRZZAxBtXZmS8wIgDwWvjB63GQ+E1pDLtZPztvPQ2eqUjTgSuGKV5cDankAV1 +Pkj/IA0Xl+SuFhLLew== +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh index 6210b42ab4..0106953bff 100755 --- a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh +++ b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh @@ -88,6 +88,27 @@ do openssl ec -in ec-pri-$size-$curve.pem -pubout -out ec-pub-$size-$curve.der -outform DER done +#--- DH ---------------------------------------------------------------------------- +for size in 512 1024 2048 +do + echo -e "\ngenerating DH parameters to PEM file ..." + openssl dhparam -out dhpar-$size.pem $size + + echo -e "\ngenerating DH private key to PEM file ..." + openssl genpkey -paramfile dhpar-$size.pem -out dh-pri-$size.pem + + /bin/rm dhpar-$size.pem + + echo -e "\ngenerating DH private key to DER file ..." + openssl pkey -in dh-pri-$size.pem -out dh-pri-$size.der -outform DER + + echo -e "\ngenerating DH public key to PEM file ..." + openssl pkey -in dh-pri-$size.pem -pubout -out dh-pub-$size.pem + + echo -e "\ngenerating DH public key to DER file ..." + openssl pkey -in dh-pri-$size.pem -pubout -out dh-pub-$size.der -outform DER +done + #--- PKCS#8 ------------------------------------------------------------------------ # Note: We'll just grab some of the keys generated earlier and convert those # https://www.openssl.org/docs/manmaster/man1/pkcs8.html#PKCS-5-v1.5-and-PKCS-12-algorithms diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index ddfe52c5e4..a257becfd2 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -111,13 +111,14 @@ void tst_QSslKey::initTestCase() QDir dir(testDataDir + "keys"); const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); - QRegExp rx(QLatin1String("^(rsa|dsa|ec)-(pub|pri)-(\\d+)-?[\\w-]*\\.(pem|der)$")); + QRegExp rx(QLatin1String("^(rsa|dsa|dh|ec)-(pub|pri)-(\\d+)-?[\\w-]*\\.(pem|der)$")); for (const QFileInfo &fileInfo : fileInfoList) { if (rx.indexIn(fileInfo.fileName()) >= 0) { keyInfoList << KeyInfo( fileInfo, rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa : - (rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : QSsl::Ec), + rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : + rx.cap(1) == QLatin1String("dh") ? QSsl::Dh : QSsl::Ec, rx.cap(2) == QLatin1String("pub") ? QSsl::PublicKey : QSsl::PrivateKey, rx.cap(3).toInt(), rx.cap(4) == QLatin1String("pem") ? QSsl::Pem : QSsl::Der); -- cgit v1.2.3