summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp32
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h1
2 files changed, 21 insertions, 12 deletions
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index aecbebfd1fa..ebf36fc34a2 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1118,11 +1118,10 @@ bool QSslSocketBackendPrivate::startHandshake()
int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
const QList<QPair<int, int> > &lastErrors = _q_sslErrorList()->errors;
+ if (!lastErrors.isEmpty())
+ storePeerCertificates();
for (int i = 0; i < lastErrors.size(); ++i) {
const QPair<int, int> &currentError = lastErrors.at(i);
- // Initialize the peer certificate chain in order to find which certificate caused this error
- if (configuration.peerCertificateChain.isEmpty())
- configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.first,
configuration.peerCertificateChain.value(currentError.second)));
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1155,15 +1154,8 @@ bool QSslSocketBackendPrivate::startHandshake()
return false;
}
- // Store the peer certificate and chain. For clients, the peer certificate
- // chain includes the peer certificate; for servers, it doesn't. Both the
- // peer certificate and the chain may be empty if the peer didn't present
- // any certificate.
- if (configuration.peerCertificateChain.isEmpty())
- configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
- X509 *x509 = q_SSL_get_peer_certificate(ssl);
- configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
- q_X509_free(x509);
+ // store peer certificate chain
+ storePeerCertificates();
// Start translating errors.
QList<QSslError> errors;
@@ -1271,6 +1263,22 @@ bool QSslSocketBackendPrivate::startHandshake()
return true;
}
+void QSslSocketBackendPrivate::storePeerCertificates()
+{
+ // Store the peer certificate and chain. For clients, the peer certificate
+ // chain includes the peer certificate; for servers, it doesn't. Both the
+ // peer certificate and the chain may be empty if the peer didn't present
+ // any certificate.
+ X509 *x509 = q_SSL_get_peer_certificate(ssl);
+ configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
+ q_X509_free(x509);
+ if (configuration.peerCertificateChain.isEmpty()) {
+ configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
+ if (!configuration.peerCertificate.isNull() && mode == QSslSocket::SslServerMode)
+ configuration.peerCertificateChain.prepend(configuration.peerCertificate);
+ }
+}
+
bool QSslSocketBackendPrivate::checkSslErrors()
{
Q_Q(QSslSocket);
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 9564ef8566b..de2bfea8928 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -129,6 +129,7 @@ public:
QSsl::SslProtocol sessionProtocol() const Q_DECL_OVERRIDE;
void continueHandshake() Q_DECL_OVERRIDE;
bool checkSslErrors();
+ void storePeerCertificates();
unsigned int tlsPskClientCallback(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len);
#ifdef Q_OS_WIN
void fetchCaRootForCert(const QSslCertificate &cert);