summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/ssl/qsslkey_p.cpp16
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp4
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h10
-rw-r--r--tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp61
4 files changed, 78 insertions, 13 deletions
diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp
index 34f664093c..e66ec953a0 100644
--- a/src/network/ssl/qsslkey_p.cpp
+++ b/src/network/ssl/qsslkey_p.cpp
@@ -56,6 +56,9 @@
#include "qsslkey.h"
#include "qsslkey_p.h"
+#ifndef QT_NO_OPENSSL
+#include "qsslsocket_openssl_symbols_p.h"
+#endif
#include "qsslsocket.h"
#include "qsslsocket_p.h"
@@ -277,18 +280,23 @@ QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::Encoding
\a type specifies whether the key is public or private.
QSslKey will take ownership for this key and you must not
- free the key using the native library. The algorithm used
- when creating a key from a handle will always be QSsl::Opaque.
+ free the key using the native library.
*/
QSslKey::QSslKey(Qt::HANDLE handle, QSsl::KeyType type)
: d(new QSslKeyPrivate)
{
#ifndef QT_NO_OPENSSL
- d->opaque = reinterpret_cast<EVP_PKEY *>(handle);
+ EVP_PKEY *evpKey = reinterpret_cast<EVP_PKEY *>(handle);
+ if (!evpKey || !d->fromEVP_PKEY(evpKey)) {
+ d->opaque = evpKey;
+ d->algorithm = QSsl::Opaque;
+ } else {
+ q_EVP_PKEY_free(evpKey);
+ }
#else
d->opaque = handle;
-#endif
d->algorithm = QSsl::Opaque;
+#endif
d->type = type;
d->isNull = !d->opaque;
}
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index f75df0466f..88fed69d3a 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -206,6 +206,7 @@ DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
#else
+DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
#ifndef OPENSSL_NO_EC
@@ -218,6 +219,7 @@ DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CI
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
#endif
+DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
#ifndef OPENSSL_NO_EC
@@ -836,6 +838,7 @@ bool q_resolveOpenSslSymbols()
#ifdef SSLEAY_MACROS // ### verify
RESOLVEFUNC(PEM_ASN1_read_bio)
#else
+ RESOLVEFUNC(PEM_read_bio_PrivateKey)
RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
#ifndef OPENSSL_NO_EC
@@ -848,6 +851,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
#endif
#endif
+ RESOLVEFUNC(PEM_read_bio_PUBKEY)
RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
#ifndef OPENSSL_NO_EC
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index f912d8609b..508fdc2a4b 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -221,12 +221,12 @@ unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
int q_ASN1_STRING_length(ASN1_STRING *a);
int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b);
long q_BIO_ctrl(BIO *a, int b, long c, void *d);
-int q_BIO_free(BIO *a);
-BIO *q_BIO_new(BIO_METHOD *a);
+Q_AUTOTEST_EXPORT int q_BIO_free(BIO *a);
+Q_AUTOTEST_EXPORT BIO *q_BIO_new(BIO_METHOD *a);
BIO *q_BIO_new_mem_buf(void *a, int b);
int q_BIO_read(BIO *a, void *b, int c);
-BIO_METHOD *q_BIO_s_mem();
-int q_BIO_write(BIO *a, const void *b, int c);
+Q_AUTOTEST_EXPORT BIO_METHOD *q_BIO_s_mem();
+Q_AUTOTEST_EXPORT int q_BIO_write(BIO *a, const void *b, int c);
int q_BN_num_bits(const BIGNUM *a);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
int q_BN_is_word(BIGNUM *a, BN_ULONG w);
@@ -295,6 +295,7 @@ void *q_PEM_ASN1_read_bio(d2i_of_void *a, const char *b, BIO *c, void **d, pem_p
void *f);
// ### ditto for write
#else
+Q_AUTOTEST_EXPORT 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
@@ -310,6 +311,7 @@ int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigne
int e, pem_password_cb *f, void *g);
#endif
#endif
+Q_AUTOTEST_EXPORT 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);
#ifndef OPENSSL_NO_EC
diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
index 8afc71a216..0112af4ed7 100644
--- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
+++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
@@ -34,9 +34,14 @@
#include <QtNetwork/qhostaddress.h>
#include <QtNetwork/qnetworkproxy.h>
-#if !defined(QT_NO_SSL) && defined(QT_BUILD_INTERNAL)
-#include "private/qsslkey_p.h"
-#define TEST_CRYPTO
+#ifdef QT_BUILD_INTERNAL
+ #ifndef QT_NO_SSL
+ #include "private/qsslkey_p.h"
+ #define TEST_CRYPTO
+ #endif
+ #ifndef QT_NO_OPENSSL
+ #include "private/qsslsocket_openssl_symbols_p.h"
+ #endif
#endif
class tst_QSslKey : public QObject
@@ -58,7 +63,7 @@ class tst_QSslKey : public QObject
QList<KeyInfo> keyInfoList;
- void createPlainTestRows();
+ void createPlainTestRows(bool filter = false, QSsl::EncodingFormat format = QSsl::EncodingFormat::Pem);
public slots:
void initTestCase();
@@ -69,6 +74,10 @@ private slots:
void emptyConstructor();
void constructor_data();
void constructor();
+#ifndef QT_NO_OPENSSL
+ void constructorHandle_data();
+ void constructorHandle();
+#endif
void copyAndAssign_data();
void copyAndAssign();
void equalsOperator();
@@ -142,7 +151,7 @@ Q_DECLARE_METATYPE(QSsl::KeyAlgorithm)
Q_DECLARE_METATYPE(QSsl::KeyType)
Q_DECLARE_METATYPE(QSsl::EncodingFormat)
-void tst_QSslKey::createPlainTestRows()
+void tst_QSslKey::createPlainTestRows(bool filter, QSsl::EncodingFormat format)
{
QTest::addColumn<QString>("absFilePath");
QTest::addColumn<QSsl::KeyAlgorithm>("algorithm");
@@ -150,6 +159,9 @@ void tst_QSslKey::createPlainTestRows()
QTest::addColumn<int>("length");
QTest::addColumn<QSsl::EncodingFormat>("format");
foreach (KeyInfo keyInfo, keyInfoList) {
+ if (filter && keyInfo.format != format)
+ continue;
+
QTest::newRow(keyInfo.fileInfo.fileName().toLatin1())
<< keyInfo.fileInfo.absoluteFilePath() << keyInfo.algorithm << keyInfo.type
<< keyInfo.length << keyInfo.format;
@@ -176,6 +188,45 @@ void tst_QSslKey::constructor()
QVERIFY(!key.isNull());
}
+#ifndef QT_NO_OPENSSL
+
+void tst_QSslKey::constructorHandle_data()
+{
+ createPlainTestRows(true);
+}
+
+void tst_QSslKey::constructorHandle()
+{
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("This test requires -developer-build.");
+#else
+ if (!QSslSocket::supportsSsl())
+ return;
+
+ QFETCH(QString, absFilePath);
+ QFETCH(QSsl::KeyAlgorithm, algorithm);
+ QFETCH(QSsl::KeyType, type);
+ QFETCH(int, length);
+
+ QByteArray pem = readFile(absFilePath);
+ auto func = (type == QSsl::KeyType::PublicKey
+ ? q_PEM_read_bio_PUBKEY
+ : q_PEM_read_bio_PrivateKey);
+
+ BIO* bio = q_BIO_new(q_BIO_s_mem());
+ q_BIO_write(bio, pem.constData(), pem.length());
+ QSslKey key(func(bio, nullptr, nullptr, nullptr), type);
+ q_BIO_free(bio);
+
+ QVERIFY(!key.isNull());
+ QCOMPARE(key.algorithm(), algorithm);
+ QCOMPARE(key.type(), type);
+ QCOMPARE(key.length(), length);
+#endif
+}
+
+#endif
+
void tst_QSslKey::copyAndAssign_data()
{
createPlainTestRows();