summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp44
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp7
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp5
-rw-r--r--src/network/ssl/qsslsocket_qt.cpp1
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp24
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h1
7 files changed, 52 insertions, 32 deletions
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index e81e5582f4..8566d78aef 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -157,32 +157,36 @@ SSL* QSslContext::createSsl()
for (int a = 0; a < protocols.count(); ++a) {
if (protocols.at(a).size() > 255) {
qCWarning(lcSsl) << "TLS NPN extension" << protocols.at(a)
- << "is too long and will be truncated to 255 characters.";
- protocols[a] = protocols.at(a).left(255);
+ << "is too long and will be ignored.";
+ continue;
+ } else if (protocols.at(a).isEmpty()) {
+ continue;
}
m_supportedNPNVersions.append(protocols.at(a).size()).append(protocols.at(a));
}
- m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
- m_npnContext.len = m_supportedNPNVersions.count();
- m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
+ if (m_supportedNPNVersions.size()) {
+ m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
+ m_npnContext.len = m_supportedNPNVersions.count();
+ m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
- // Callback's type has a parameter 'const unsigned char ** out'
- // since it was introduced in 1.0.2. Internally, OpenSSL's own code
- // (tests/examples) cast it to unsigned char * (since it's 'out').
- // We just re-use our NPN callback and cast here:
- typedef int (*alpn_callback_t) (SSL *, const unsigned char **, unsigned char *,
- const unsigned char *, unsigned int, void *);
- // With ALPN callback is for a server side only, for a client m_npnContext.status
- // will stay in NextProtocolNegotiationNone.
- q_SSL_CTX_set_alpn_select_cb(ctx, alpn_callback_t(next_proto_cb), &m_npnContext);
- // Client:
- q_SSL_set_alpn_protos(ssl, m_npnContext.data, m_npnContext.len);
- }
+ if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
+ // Callback's type has a parameter 'const unsigned char ** out'
+ // since it was introduced in 1.0.2. Internally, OpenSSL's own code
+ // (tests/examples) cast it to unsigned char * (since it's 'out').
+ // We just re-use our NPN callback and cast here:
+ typedef int (*alpn_callback_t) (SSL *, const unsigned char **, unsigned char *,
+ const unsigned char *, unsigned int, void *);
+ // With ALPN callback is for a server side only, for a client m_npnContext.status
+ // will stay in NextProtocolNegotiationNone.
+ q_SSL_CTX_set_alpn_select_cb(ctx, alpn_callback_t(next_proto_cb), &m_npnContext);
+ // Client:
+ q_SSL_set_alpn_protos(ssl, m_npnContext.data, m_npnContext.len);
+ }
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
- // And in case our peer does not support ALPN, but supports NPN:
- q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
+ // And in case our peer does not support ALPN, but supports NPN:
+ q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
+ }
}
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ca6c58117d..e302aa1761 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1512,7 +1512,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 1725937bc2..e0e065679d 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -928,6 +928,13 @@ bool QSslSocketBackendPrivate::initSslContext()
QCFType<CFMutableArrayRef> cfNames(CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks));
if (cfNames) {
for (const QByteArray &name : protocolNames) {
+ if (name.size() > 255) {
+ qCWarning(lcSsl) << "TLS ALPN extension" << name
+ << "is too long and will be ignored.";
+ continue;
+ } else if (name.isEmpty()) {
+ continue;
+ }
QCFString cfName(QString::fromLatin1(name).toCFString());
CFArrayAppendValue(cfNames, cfName);
}
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
index 28be4f2e79..1d935c5217 100644
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ b/src/network/ssl/qsslsocket_openssl11.cpp
@@ -143,13 +143,12 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
if (!s_loadRootCertsOnDemand)
setDefaultCaCertificates(systemCaCertificates());
#ifdef Q_OS_WIN
- //Enabled for fetching additional root certs from windows update on windows 6+
+ //Enabled for fetching additional root certs from windows update on windows.
//This flag is set false by setDefaultCaCertificates() indicating the app uses
//its own cert bundle rather than the system one.
//Same logic that disables the unix on demand cert loading.
//Unlike unix, we do preload the certificates from the cert store.
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::WindowsVista)
- s_loadRootCertsOnDemand = true;
+ s_loadRootCertsOnDemand = true;
#endif
}
diff --git a/src/network/ssl/qsslsocket_qt.cpp b/src/network/ssl/qsslsocket_qt.cpp
index b0fb60ea76..9ff9a66c05 100644
--- a/src/network/ssl/qsslsocket_qt.cpp
+++ b/src/network/ssl/qsslsocket_qt.cpp
@@ -72,6 +72,7 @@ static QAsn1Element _q_PKCS7_data(const QByteArray &data)
Some test vectors:
http://www.drh-consultancy.demon.co.uk/test.txt
+ \internal
*/
static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QString &passPhrase, int n, int r)
{
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index c254659a33..d7fb080b49 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -408,13 +408,17 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
for (QByteArray proto : nextAllowedProtocols) {
if (proto.size() > 255) {
qCWarning(lcSsl) << "TLS ALPN extension" << proto
- << "is too long and will be truncated to 255 characters.";
- proto = proto.left(255);
+ << "is too long and will be ignored.";
+ continue;
+ } else if (proto.isEmpty()) {
+ continue;
}
protocolString += char(proto.length()) + proto;
}
return protocolString;
}();
+ if (names.isEmpty())
+ return alpnString;
const quint16 namesSize = names.size();
const quint32 alpnId = SecApplicationProtocolNegotiationExt_ALPN;
@@ -824,12 +828,17 @@ bool QSslSocketBackendPrivate::acceptContext()
&expiry // ptsTimeStamp
);
+ if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ // Need more data
+ return true;
+ }
+
if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
// inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
// be stored.
intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer));
- } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
+ } else { /* No 'extra' data, message not incomplete */
intermediateBuffer.clear();
}
@@ -1065,7 +1074,6 @@ bool QSslSocketBackendPrivate::verifyHandshake()
}
schannelState = SchannelState::Done;
- peerCertVerified = true;
return true;
}
@@ -1148,7 +1156,6 @@ void QSslSocketBackendPrivate::reset()
connectionEncrypted = false;
shutdown = false;
- peerCertVerified = false;
renegotiating = false;
}
@@ -1311,7 +1318,9 @@ void QSslSocketBackendPrivate::transmit()
#endif
intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
}
- } else if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ }
+
+ if (status == SEC_E_INCOMPLETE_MESSAGE) {
// Need more data before we can decrypt.. to the buffer it goes!
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
@@ -1356,6 +1365,7 @@ void QSslSocketBackendPrivate::transmit()
#endif
schannelState = SchannelState::Renegotiate;
renegotiating = true;
+
// We need to call 'continueHandshake' or else there's no guarantee it ever gets called
continueHandshake();
break;
@@ -1521,7 +1531,7 @@ void QSslSocketBackendPrivate::continueHandshake()
case SchannelState::VerifyHandshake:
// if we're in shutdown or renegotiating then we might not need to verify
// (since we already did)
- if (!peerCertVerified && !verifyHandshake()) {
+ if (!verifyHandshake()) {
shutdown = true; // Skip sending shutdown alert
q->abort(); // We don't want to send buffered data
disconnectFromHost();
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
index 9879e2fc60..6ab200e1f9 100644
--- a/src/network/ssl/qsslsocket_schannel_p.h
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -147,7 +147,6 @@ private:
ULONG contextAttributes = 0;
bool renegotiating = false;
- bool peerCertVerified = false;
};
QT_END_NAMESPACE