summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp12
-rw-r--r--src/network/ssl/qasn1element_p.h2
-rw-r--r--src/network/ssl/qsslcertificate_qt.cpp4
-rw-r--r--src/network/ssl/qsslkey_qt.cpp67
-rw-r--r--src/network/ssl/qsslsocket.cpp1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp9
6 files changed, 83 insertions, 12 deletions
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index c1e837de7b..8ff6ee828d 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -465,15 +465,18 @@ QList<QBearerEngine *> QNetworkConfigurationManagerPrivate::engines() const
void QNetworkConfigurationManagerPrivate::startPolling()
{
QMutexLocker locker(&mutex);
-
- if(!pollTimer) {
+ if (!pollTimer) {
pollTimer = new QTimer(this);
- pollTimer->setInterval(10000);
+ bool ok;
+ int interval = qgetenv("QT_BEARER_POLL_TIMEOUT").toInt(&ok);
+ if (!ok)
+ interval = 10000;//default 10 seconds
+ pollTimer->setInterval(interval);
pollTimer->setSingleShot(true);
connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines()));
}
- if(pollTimer->isActive())
+ if (pollTimer->isActive())
return;
foreach (QBearerEngine *engine, sessionEngines) {
@@ -482,6 +485,7 @@ void QNetworkConfigurationManagerPrivate::startPolling()
break;
}
}
+ performAsyncConfigurationUpdate();
}
void QNetworkConfigurationManagerPrivate::pollEngines()
diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h
index 68acbe33ee..e58b974661 100644
--- a/src/network/ssl/qasn1element_p.h
+++ b/src/network/ssl/qasn1element_p.h
@@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE
#define RSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.113549.1.1.1")
#define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1")
+#define EC_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10045.2.1")
class Q_AUTOTEST_EXPORT QAsn1Element
{
@@ -80,6 +81,7 @@ public:
// context specific
Context0Type = 0xA0,
+ Context1Type = 0xA1,
Context3Type = 0xA3
};
diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp
index 2d1dd68198..a283078998 100644
--- a/src/network/ssl/qsslcertificate_qt.cpp
+++ b/src/network/ssl/qsslcertificate_qt.cpp
@@ -366,8 +366,10 @@ bool QSslCertificatePrivate::parse(const QByteArray &data)
const QByteArray oid = elem.toObjectId();
if (oid == RSA_ENCRYPTION_OID)
publicKeyAlgorithm = QSsl::Rsa;
- else if (oid == RSA_ENCRYPTION_OID)
+ else if (oid == DSA_ENCRYPTION_OID)
publicKeyAlgorithm = QSsl::Dsa;
+ else if (oid == EC_ENCRYPTION_OID)
+ publicKeyAlgorithm = QSsl::Ec;
else
publicKeyAlgorithm = QSsl::Opaque;
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 4f68912527..c4f8df86e2 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -59,6 +59,47 @@ static const quint8 bits_table[256] = {
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
+// OIDs of named curves allowed in TLS as per RFCs 4492 and 7027,
+// see also https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+
+typedef QMap<QByteArray, int> OidLengthMap;
+static OidLengthMap createOidMap()
+{
+ OidLengthMap oids;
+ oids.insert(oids.cend(), QByteArrayLiteral("1.2.840.10045.3.1.1"), 192); // secp192r1 a.k.a prime192v1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.2.840.10045.3.1.7"), 256); // secp256r1 a.k.a prime256v1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.1"), 193); // sect193r2
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.10"), 256); // secp256k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.16"), 283); // sect283k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.17"), 283); // sect283r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.26"), 233); // sect233k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.27"), 233); // sect233r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.3"), 239); // sect239k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.30"), 160); // secp160r2
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.31"), 192); // secp192k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.32"), 224); // secp224k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.33"), 224); // secp224r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.34"), 384); // secp384r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.35"), 521); // secp521r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.36"), 409); // sect409k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.37"), 409); // sect409r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.38"), 571); // sect571k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.39"), 571); // sect571r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.8"), 160); // secp160r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.9"), 160); // secp160k1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.11"), 384); // brainpoolP384r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.13"), 521); // brainpoolP512r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.7"), 256); // brainpoolP256r1
+ return oids;
+}
+Q_GLOBAL_STATIC_WITH_ARGS(OidLengthMap, oidLengthMap, (createOidMap()))
+
+static int curveBits(const QByteArray &oid)
+{
+ const int length = oidLengthMap->value(oid);
+ return length ? length : -1;
+}
+
static int numberOfBits(const QByteArray &modulus)
{
int bits = modulus.size() * 8;
@@ -146,6 +187,12 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(params[0].value());
+ } else if (algorithm == QSsl::Ec) {
+ if (infoItems[0].toObjectId() != EC_ENCRYPTION_OID)
+ return;
+ if (infoItems[1].type() != QAsn1Element::ObjectIdentifierType)
+ return;
+ keyLength = curveBits(infoItems[1].toObjectId());
}
} else {
@@ -154,17 +201,35 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
return;
// version
- if (items[0].type() != QAsn1Element::IntegerType || items[0].value().toHex() != "00")
+ if (items[0].type() != QAsn1Element::IntegerType)
return;
+ const QByteArray versionHex = items[0].value().toHex();
if (algorithm == QSsl::Rsa) {
+ if (versionHex != "00")
+ return;
if (items.size() != 9 || items[1].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(items[1].value());
} else if (algorithm == QSsl::Dsa) {
+ if (versionHex != "00")
+ return;
if (items.size() != 6 || items[1].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(items[1].value());
+ } else if (algorithm == QSsl::Ec) {
+ if (versionHex != "01")
+ return;
+ if (items.size() != 4
+ || items[1].type() != QAsn1Element::OctetStringType
+ || items[2].type() != QAsn1Element::Context0Type
+ || items[3].type() != QAsn1Element::Context1Type)
+ return;
+ QAsn1Element oidElem;
+ if (!oidElem.read(items[2].value())
+ || oidElem.type() != QAsn1Element::ObjectIdentifierType)
+ return;
+ keyLength = curveBits(oidElem.toObjectId());
}
}
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 58809e921a..092a414f99 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -500,6 +500,7 @@ bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state
bool retVal = d->plainSocket->setSocketDescriptor(socketDescriptor, state, openMode);
d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
setSocketError(d->plainSocket->error());
+ setErrorString(d->plainSocket->errorString());
setSocketState(state);
setOpenMode(openMode);
setLocalPort(d->plainSocket->localPort());
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 2b4c64e89f..a21317d0f2 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -377,12 +377,9 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
- if ((configuration.protocol == QSsl::TlsV1SslV3 ||
- configuration.protocol == QSsl::TlsV1_0 ||
- configuration.protocol == QSsl::TlsV1_1 ||
- configuration.protocol == QSsl::TlsV1_2 ||
- configuration.protocol == QSsl::SecureProtocols ||
- configuration.protocol == QSsl::AnyProtocol) &&
+ if (configuration.protocol != QSsl::SslV2 &&
+ configuration.protocol != QSsl::SslV3 &&
+ configuration.protocol != QSsl::UnknownProtocol &&
mode == QSslSocket::SslClientMode && q_SSLeay() >= 0x00090806fL) {
// Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;