Fix crash when reading a PKCS12 file with no private key
The only reason our code wants PKCS12 files is for a private key, but a valid file needn't contain one; and reading a file without lead to a crash in QSslKeyPrivate::fromEVP_PKEY(). So check for missing key and fail the load, since the file is useless to us. Also ensure the caller's pkey is initialized, as we aren't promised that PKCS12_parse() will set it when there is no private key. Add a test for this case (it crashes without the fix) and update the instructions for how to generate test data to cover it also. (Corrected the wording there, too; at the interactive prompt, "providing no password" really provides an empty password.) Task-number: QTBUG-62335 Change-Id: I617508b903f6d9dee40d539b7136b0be8bc2c747 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
d7db2b4359
commit
b9557296cb
@ -84,6 +84,9 @@ void QSslKeyPrivate::clear(bool deep)
|
|||||||
|
|
||||||
bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
|
bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
|
||||||
{
|
{
|
||||||
|
if (pkey == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (pkey->type == EVP_PKEY_RSA) {
|
if (pkey->type == EVP_PKEY_RSA) {
|
||||||
isNull = false;
|
isNull = false;
|
||||||
algorithm = QSsl::Rsa;
|
algorithm = QSsl::Rsa;
|
||||||
|
@ -1805,7 +1805,7 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract the data
|
// Extract the data
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey = nullptr;
|
||||||
X509 *x509;
|
X509 *x509;
|
||||||
STACK_OF(X509) *ca = 0;
|
STACK_OF(X509) *ca = 0;
|
||||||
|
|
||||||
|
@ -1,8 +1,19 @@
|
|||||||
The PKCS#12 bundle was created by running the following on
|
The PKCS#12 bundle was created by running the following in an
|
||||||
in the qsslsocket/certs directory:
|
interactive shell in ../../qsslsocket/certs/:
|
||||||
|
|
||||||
openssl pkcs12 -export -in leaf.crt -inkey leaf.key \
|
openssl pkcs12 -export -in leaf.crt \
|
||||||
-out leaf.p12 \
|
-inkey leaf.key -out leaf.p12 \
|
||||||
-certfile inter.crt -CAfile ca.crt
|
-certfile inter.crt -CAfile ca.crt
|
||||||
|
|
||||||
No password was provided.
|
An empty password was provided (twice). The pkcs.crt and pkcs.key
|
||||||
|
files were then copied here and leaf.p12 was moved here.
|
||||||
|
|
||||||
|
|
||||||
|
The test-case with no private key (in a valid PKCS12 file) was created
|
||||||
|
similarly but with the command adjusted to:
|
||||||
|
|
||||||
|
openssl pkcs12 -export -in leaf.crt \
|
||||||
|
-nokeys -out leaf-nokey.p12 \
|
||||||
|
-certfile inter.crt -CAfile ca.crt
|
||||||
|
|
||||||
|
The file leaf-nokey.p12 was then moved here.
|
||||||
|
BIN
tests/auto/network/ssl/qsslcertificate/pkcs12/leaf-nokey.p12
Normal file
BIN
tests/auto/network/ssl/qsslcertificate/pkcs12/leaf-nokey.p12
Normal file
Binary file not shown.
@ -1308,6 +1308,7 @@ void tst_QSslCertificate::version()
|
|||||||
|
|
||||||
void tst_QSslCertificate::pkcs12()
|
void tst_QSslCertificate::pkcs12()
|
||||||
{
|
{
|
||||||
|
// See pkcs12/README for how to generate the PKCS12 files used here.
|
||||||
if (!QSslSocket::supportsSsl()) {
|
if (!QSslSocket::supportsSsl()) {
|
||||||
qWarning("SSL not supported, skipping test");
|
qWarning("SSL not supported, skipping test");
|
||||||
return;
|
return;
|
||||||
@ -1349,6 +1350,15 @@ void tst_QSslCertificate::pkcs12()
|
|||||||
QVERIFY(!caCerts.isEmpty());
|
QVERIFY(!caCerts.isEmpty());
|
||||||
QCOMPARE(caCerts.first(), caCert.first());
|
QCOMPARE(caCerts.first(), caCert.first());
|
||||||
QCOMPARE(caCerts, caCert);
|
QCOMPARE(caCerts, caCert);
|
||||||
|
|
||||||
|
// QTBUG-62335 - Fail (found no private key) but don't crash:
|
||||||
|
QFile nocert(testDataDir + QLatin1String("/pkcs12/leaf-nokey.p12"));
|
||||||
|
ok = nocert.open(QIODevice::ReadOnly);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "Unable to convert private key");
|
||||||
|
ok = QSslCertificate::importPkcs12(&nocert, &key, &cert, &caCerts);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
nocert.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // QT_NO_SSL
|
#endif // QT_NO_SSL
|
||||||
|
Loading…
x
Reference in New Issue
Block a user