summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qtls_st.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qtls_st.cpp')
-rw-r--r--src/network/ssl/qtls_st.cpp118
1 files changed, 61 insertions, 57 deletions
diff --git a/src/network/ssl/qtls_st.cpp b/src/network/ssl/qtls_st.cpp
index 602f1ef409..e4f5c71c02 100644
--- a/src/network/ssl/qtls_st.cpp
+++ b/src/network/ssl/qtls_st.cpp
@@ -346,7 +346,7 @@ void TlsCryptographSecureTransport::continueHandshake()
Q_ASSERT(q);
Q_ASSERT(d);
d->setEncrypted(true);
-#ifdef QSSLSOCKET_DEBU
+#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << d->plainTcpSocket() << "connection encrypted";
#endif
@@ -355,12 +355,12 @@ void TlsCryptographSecureTransport::continueHandshake()
// a callback during handshake. We can only set our list of preferred protocols
// (and send it during handshake) and then receive what our peer has sent to us.
// And here we can finally try to find a match (if any).
- auto &configuration = d->privateConfiguration();
+ const auto &configuration = q->sslConfiguration();
if (__builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
- const auto &requestedProtocols = configuration.nextAllowedProtocols;
+ const auto &requestedProtocols = configuration.allowedNextProtocols();
if (const int requestedCount = requestedProtocols.size()) {
- configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
- configuration.nextNegotiatedProtocol.clear();
+ QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNone);
+ QTlsBackend::setNegotiatedProtocol(d, {});
QCFType<CFArrayRef> cfArray;
const OSStatus result = SSLCopyALPNProtocols(context, &cfArray);
@@ -374,12 +374,12 @@ void TlsCryptographSecureTransport::continueHandshake()
const auto requestedName = QString::fromLatin1(requestedProtocols[i]);
for (int j = 0; j < size; ++j) {
if (requestedName == peerProtocols[j]) {
- configuration.nextNegotiatedProtocol = requestedName.toLatin1();
- configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
+ QTlsBackend::setNegotiatedProtocol(d, requestedName.toLatin1());
+ QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNegotiated);
break;
}
}
- if (configuration.nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNegotiated)
+ if (configuration.nextProtocolNegotiationStatus() == QSslConfiguration::NextProtocolNegotiationNegotiated)
break;
}
}
@@ -678,9 +678,9 @@ bool TlsCryptographSecureTransport::initSslContext()
SSLSetConnection(context, this);
- auto &configuration = d->privateConfiguration();
+ const auto &configuration = q->sslConfiguration();
if (mode == QSslSocket::SslServerMode
- && !configuration.localCertificateChain.isEmpty()) {
+ && !configuration.localCertificateChain().isEmpty()) {
QString errorDescription;
QAbstractSocket::SocketError errorCode = QAbstractSocket::UnknownSocketError;
if (!setSessionCertificate(errorDescription, errorCode)) {
@@ -698,7 +698,7 @@ bool TlsCryptographSecureTransport::initSslContext()
#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13_4, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
if (__builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
- const auto protocolNames = configuration.nextAllowedProtocols;
+ const auto protocolNames = configuration.allowedNextProtocols();
QCFType<CFMutableArrayRef> cfNames(CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks));
if (cfNames) {
for (const QByteArray &name : protocolNames) {
@@ -748,7 +748,7 @@ bool TlsCryptographSecureTransport::initSslContext()
}
//
} else {
- if (configuration.peerVerifyMode != QSslSocket::VerifyNone) {
+ if (configuration.peerVerifyMode() != QSslSocket::VerifyNone) {
// kAlwaysAuthenticate - always fails even if we set break on client auth.
OSStatus err = SSLSetClientSideAuthenticate(context, kTryAuthenticate);
if (err == errSecSuccess) {
@@ -769,9 +769,9 @@ bool TlsCryptographSecureTransport::initSslContext()
SSLSetDiffieHellmanParams(context, dhparam, sizeof(dhparam));
#endif
}
- if (configuration.ciphers.size() > 0) {
+ if (configuration.ciphers().size() > 0) {
QVector<SSLCipherSuite> cfCiphers;
- for (const QSslCipher &cipher : configuration.ciphers) {
+ for (const QSslCipher &cipher : configuration.ciphers()) {
if (auto sslCipher = TlsCryptographSecureTransport::SSLCipherSuite_from_QSslCipher(cipher))
cfCiphers << sslCipher;
}
@@ -798,7 +798,7 @@ bool TlsCryptographSecureTransport::setSessionCertificate(QString &errorDescript
Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)");
Q_ASSERT(d);
- const auto &configuration = d->privateConfiguration();
+ const auto &configuration = q->sslConfiguration();
#ifdef QSSLSOCKET_DEBUG
auto *plainSocket = d->plainTcpSocket();
@@ -806,12 +806,12 @@ bool TlsCryptographSecureTransport::setSessionCertificate(QString &errorDescript
QSslCertificate localCertificate;
- if (!configuration.localCertificateChain.isEmpty())
- localCertificate = configuration.localCertificateChain.at(0);
+ if (!configuration.localCertificateChain().isEmpty())
+ localCertificate = configuration.localCertificateChain().at(0);
if (!localCertificate.isNull()) {
// Require a private key as well.
- if (configuration.privateKey.isNull()) {
+ if (configuration.privateKey().isNull()) {
errorCode = QAbstractSocket::SslInvalidUserDataError;
errorDescription = QStringLiteral("Cannot provide a certificate with no key");
return false;
@@ -819,8 +819,8 @@ bool TlsCryptographSecureTransport::setSessionCertificate(QString &errorDescript
// import certificates and key
const QString passPhrase(QString::fromLatin1("foobar"));
- QCFType<CFDataRef> pkcs12 = _q_makePkcs12(configuration.localCertificateChain,
- configuration.privateKey, passPhrase).toCFData();
+ QCFType<CFDataRef> pkcs12 = _q_makePkcs12(configuration.localCertificateChain(),
+ configuration.privateKey(), passPhrase).toCFData();
QCFType<CFStringRef> password = passPhrase.toCFString();
const void *keys[2] = { kSecImportExportPassphrase };
const void *values[2] = { password };
@@ -904,14 +904,15 @@ bool TlsCryptographSecureTransport::setSessionCertificate(QString &errorDescript
bool TlsCryptographSecureTransport::setSessionProtocol()
{
Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)");
+ Q_ASSERT(q);
Q_ASSERT(d);
// SecureTransport has kTLSProtocol13 constant and also, kTLSProtocolMaxSupported.
// Calling SSLSetProtocolVersionMax/Min with any of these two constants results
// in errInvalidParam and a failure to set the protocol version. This means
// no TLS 1.3 on macOS and iOS.
- const auto &configuration = d->privateConfiguration();
+ const auto &configuration = q->sslConfiguration();
auto *plainSocket = d->plainTcpSocket();
- switch (configuration.protocol) {
+ switch (configuration.protocol()) {
case QSsl::TlsV1_3:
case QSsl::TlsV1_3OrLater:
qCWarning(lcTlsBackend) << plainSocket << "SecureTransport does not support TLS 1.3";
@@ -921,48 +922,48 @@ bool TlsCryptographSecureTransport::setSessionProtocol()
OSStatus err = errSecSuccess;
- if (configuration.protocol == QSsl::TlsV1_0) {
+ if (configuration.protocol() == QSsl::TlsV1_0) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1.0";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol1);
- } else if (configuration.protocol == QSsl::TlsV1_1) {
+ } else if (configuration.protocol() == QSsl::TlsV1_1) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1.1";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol11);
- } else if (configuration.protocol == QSsl::TlsV1_2) {
+ } else if (configuration.protocol() == QSsl::TlsV1_2) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::AnyProtocol) {
+ } else if (configuration.protocol() == QSsl::AnyProtocol) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : any";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- } else if (configuration.protocol == QSsl::SecureProtocols) {
+ } else if (configuration.protocol() == QSsl::SecureProtocols) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- } else if (configuration.protocol == QSsl::TlsV1_0OrLater) {
+ } else if (configuration.protocol() == QSsl::TlsV1_0OrLater) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- } else if (configuration.protocol == QSsl::TlsV1_1OrLater) {
+ } else if (configuration.protocol() == QSsl::TlsV1_1OrLater) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1.1 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
- } else if (configuration.protocol == QSsl::TlsV1_2OrLater) {
+ } else if (configuration.protocol() == QSsl::TlsV1_2OrLater) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcTlsBackend) << plainSocket << "requesting : TLSv1.2";
#endif
@@ -979,9 +980,10 @@ bool TlsCryptographSecureTransport::setSessionProtocol()
bool TlsCryptographSecureTransport::canIgnoreTrustVerificationFailure() const
{
+ Q_ASSERT(q);
Q_ASSERT(d);
- const auto &configuration = d->privateConfiguration();
- const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode;
+ const auto &configuration = q->sslConfiguration();
+ const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode();
return d->tlsMode() == QSslSocket::SslServerMode
&& (verifyMode == QSslSocket::QueryPeer
|| verifyMode == QSslSocket::AutoVerifyPeer
@@ -990,24 +992,24 @@ bool TlsCryptographSecureTransport::canIgnoreTrustVerificationFailure() const
bool TlsCryptographSecureTransport::verifySessionProtocol() const
{
- Q_ASSERT(d);
+ Q_ASSERT(q);
- const auto &configuration = d->privateConfiguration();
+ const auto &configuration = q->sslConfiguration();
bool protocolOk = false;
- if (configuration.protocol == QSsl::AnyProtocol)
+ if (configuration.protocol() == QSsl::AnyProtocol)
protocolOk = true;
- else if (configuration.protocol == QSsl::SecureProtocols)
+ else if (configuration.protocol() == QSsl::SecureProtocols)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
- else if (configuration.protocol == QSsl::TlsV1_0OrLater)
+ else if (configuration.protocol() == QSsl::TlsV1_0OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
- else if (configuration.protocol == QSsl::TlsV1_1OrLater)
+ else if (configuration.protocol() == QSsl::TlsV1_1OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_1);
- else if (configuration.protocol == QSsl::TlsV1_2OrLater)
+ else if (configuration.protocol() == QSsl::TlsV1_2OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_2);
- else if (configuration.protocol == QSsl::TlsV1_3OrLater)
+ else if (configuration.protocol() == QSsl::TlsV1_3OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_3OrLater);
else
- protocolOk = (sessionProtocol() == configuration.protocol);
+ protocolOk = (sessionProtocol() == configuration.protocol());
return protocolOk;
}
@@ -1017,9 +1019,8 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
Q_ASSERT(q);
Q_ASSERT(d);
- auto &configuration = d->privateConfiguration();
const auto mode = d->tlsMode();
- const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode;
+ const QSslSocket::PeerVerifyMode verifyMode = q->peerVerifyMode();
const bool canIgnoreVerify = canIgnoreTrustVerificationFailure();
Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)");
@@ -1060,21 +1061,22 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
return false;
}
- configuration.peerCertificate.clear();
- configuration.peerCertificateChain.clear();
+ QTlsBackend::clearPeerCertificates(d);
+ QList<QSslCertificate> peerCertificateChain;
const CFIndex certCount = SecTrustGetCertificateCount(trust);
for (CFIndex i = 0; i < certCount; ++i) {
SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, i);
QCFType<CFDataRef> derData = SecCertificateCopyData(cert);
- configuration.peerCertificateChain << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
+ peerCertificateChain << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
}
+ QTlsBackend::storePeerCertificateChain(d, peerCertificateChain);
- if (configuration.peerCertificateChain.size())
- configuration.peerCertificate = configuration.peerCertificateChain.at(0);
+ if (peerCertificateChain.size())
+ QTlsBackend::storePeerCertificate(d, peerCertificateChain.at(0));
// Check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer):
- for (const QSslCertificate &cert : qAsConst(configuration.peerCertificateChain)) {
+ for (const QSslCertificate &cert : qAsConst(peerCertificateChain)) {
if (QSslCertificatePrivate::isBlacklisted(cert) && !canIgnoreVerify) {
const QSslError error(QSslError::CertificateBlacklisted, cert);
errors << error;
@@ -1090,15 +1092,16 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
// Check the peer certificate itself. First try the subject's common name
// (CN) as a wildcard, then try all alternate subject name DNS entries the
// same way.
- if (!configuration.peerCertificate.isNull()) {
+ const auto &peerCertificate = q->peerCertificate();
+ if (!peerCertificate.isNull()) {
// but only if we're a client connecting to a server
// if we're the server, don't check CN
const QString verificationPeerName = d->verificationName();
if (mode == QSslSocket::SslClientMode) {
const QString peerName(verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
- if (!isMatchingHostname(configuration.peerCertificate, peerName) && !canIgnoreVerify) {
+ if (!isMatchingHostname(peerCertificate, peerName) && !canIgnoreVerify) {
// No matches in common names or alternate names.
- const QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
+ const QSslError error(QSslError::HostNameMismatch, peerCertificate);
errors << error;
emit q->peerVerifyError(error);
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1119,7 +1122,8 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
// verify certificate chain
QCFType<CFMutableArrayRef> certArray = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks);
- for (const QSslCertificate &cert : qAsConst(configuration.caCertificates)) {
+ const auto &caCertificates = q->sslConfiguration().caCertificates();
+ for (const QSslCertificate &cert : caCertificates) {
QCFType<CFDataRef> certData = cert.toDer().toCFData();
if (QCFType<SecCertificateRef> secRef = SecCertificateCreateWithData(nullptr, certData))
CFArrayAppendValue(certArray, secRef);
@@ -1165,7 +1169,7 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
break;
default:
if (!canIgnoreVerify) {
- const QSslError error(QSslError::CertificateUntrusted, configuration.peerCertificate);
+ const QSslError error(QSslError::CertificateUntrusted, peerCertificate);
errors << error;
emit q->peerVerifyError(error);
}
@@ -1199,9 +1203,9 @@ bool TlsCryptographSecureTransport::checkSslErrors()
emit q->sslErrors(sslErrors);
const auto mode = d->tlsMode();
- const auto &configuration = d->privateConfiguration();
- const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
- || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
+ const auto &configuration = q->sslConfiguration();
+ const bool doVerifyPeer = configuration.peerVerifyMode() == QSslSocket::VerifyPeer
+ || (configuration.peerVerifyMode() == QSslSocket::AutoVerifyPeer
&& mode == QSslSocket::SslClientMode);
const bool doEmitSslError = !d->verifyErrorsHaveBeenIgnored();
// check whether we need to emit an SSL handshake error