-
Suggestion
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
None
If a PKCS #12 (.p12) file only contains the CA certificate chain (i.e. no private key, no end-entity certificate), then QSslCertificate::importPkcs12 currently aborts early simply because it can't find the key (example: https://github.com/qt/qtbase/blob/v6.9.1/src/plugins/tls/openssl/qx509_openssl.cpp#L823-L827 )
Consequently, the CA certificate chain doesn't get read, even though the certificates are there.
Suggestion
We should provide a way to read the CA certificate chain, regardless of the result of reading the private key
Quick workaround for OpenSSL
Simply moving the key conversion code to the end of X509CertificateOpenSSL::importPkcs12 will allow us to retrieve the CA certificate chain via QSslCertificate::importPkcs12, even though it returns false
--- src/plugins/tls/openssl/qx509_openssl.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/tls/openssl/qx509_openssl.cpp b/src/plugins/tls/openssl/qx509_openssl.cpp index 21c81b105de..2a9647cc87b 100644 --- a/src/plugins/tls/openssl/qx509_openssl.cpp +++ b/src/plugins/tls/openssl/qx509_openssl.cpp @@ -820,17 +820,16 @@ bool X509CertificateOpenSSL::importPkcs12(QIODevice *device, QSslKey *key, QSslC }); // Convert to Qt types - auto *tlsKey = QTlsBackend::backend<TlsKeyOpenSSL>(*key); - if (!tlsKey || !tlsKey->fromEVP_PKEY(pkey)) { - qCWarning(lcTlsBackend, "Unable to convert private key"); - return false; - } - *cert = certificateFromX509(x509); if (caCertificates) *caCertificates = stackOfX509ToQSslCertificates(ca); + auto *tlsKey = QTlsBackend::backend<TlsKeyOpenSSL>(*key); + if (!tlsKey || !tlsKey->fromEVP_PKEY(pkey)) { + qCWarning(lcTlsBackend, "Unable to convert private key"); + return false; + } return true; } --