summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp6
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp2
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp4
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h2
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp16
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp4
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp20
-rw-r--r--src/network/kernel/qdnslookup.cpp14
-rw-r--r--src/network/kernel/qdnslookup_winrt.cpp30
-rw-r--r--src/network/kernel/qhostinfo_winrt.cpp43
-rw-r--r--src/network/kernel/qnetworkinterface_winrt.cpp28
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp17
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp20
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h6
-rw-r--r--src/network/ssl/qsslcertificate.cpp36
-rw-r--r--src/network/ssl/qsslcertificate.h6
-rw-r--r--src/network/ssl/qsslconfiguration.cpp13
-rw-r--r--src/network/ssl/qsslconfiguration.h1
-rw-r--r--src/network/ssl/qsslconfiguration_p.h4
-rw-r--r--src/network/ssl/qsslkey.cpp32
-rw-r--r--src/network/ssl/qsslkey.h1
-rw-r--r--src/network/ssl/qsslkey_p.h1
-rw-r--r--src/network/ssl/qsslsocket.cpp42
-rw-r--r--src/network/ssl/qsslsocket.h3
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp101
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h5
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp16
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h10
-rw-r--r--src/network/ssl/qsslsocket_p.h3
29 files changed, 367 insertions, 119 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 360f9722c7..7ff6bffed3 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -1203,7 +1203,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16
: QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt, connectionType)), parent)
{
Q_D(QHttpNetworkConnection);
- d->networkSession = networkSession;
+ d->networkSession = qMove(networkSession);
d->init();
}
@@ -1215,7 +1215,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS
connectionType)), parent)
{
Q_D(QHttpNetworkConnection);
- d->networkSession = networkSession;
+ d->networkSession = qMove(networkSession);
d->init();
}
#else
@@ -1339,7 +1339,7 @@ QSharedPointer<QSslContext> QHttpNetworkConnection::sslContext()
void QHttpNetworkConnection::setSslContext(QSharedPointer<QSslContext> context)
{
Q_D(QHttpNetworkConnection);
- d->sslContext = context;
+ d->sslContext = qMove(context);
}
void QHttpNetworkConnection::ignoreSslErrors(int channel)
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 76107d3110..8743989dec 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -188,7 +188,7 @@ public:
QHttpNetworkConnection::ConnectionType connectionType,
QSharedPointer<QNetworkSession> networkSession)
: QHttpNetworkConnection(hostName, port, encrypt, connectionType, /*parent=*/0,
- networkSession)
+ qMove(networkSession))
#endif
{
setExpires(true);
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index b4aaca0851..acaba33dee 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -130,9 +130,9 @@ QStringList QNetworkAccessManagerPrivate::backendSupportedSchemes() const
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
if (reply->outgoingDataBuffer)
- uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer));
+ uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingDataBuffer);
else if (reply->outgoingData) {
- uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingData));
+ uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingData);
} else {
return 0;
}
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 9528330aae..bd5a6faeef 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -92,7 +92,7 @@ public:
initializeSession(true),
#endif
cookieJarCreated(false),
- authenticationManager(new QNetworkAccessAuthenticationManager)
+ authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create())
{ }
~QNetworkAccessManagerPrivate();
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 56105a544b..3ac8b8f56f 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -194,7 +194,7 @@ QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manage
if (d->synchronous && outgoingData) {
// The synchronous HTTP is a corner case, we will put all upload data in one big QByteArray in the outgoingDataBuffer.
// Yes, this is not the most efficient thing to do, but on the other hand synchronous XHR needs to die anyway.
- d->outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer());
+ d->outgoingDataBuffer = QSharedPointer<QRingBuffer>::create();
qint64 previousDataSize = 0;
do {
previousDataSize = d->outgoingDataBuffer->size();
@@ -277,6 +277,10 @@ void QNetworkReplyHttpImpl::abort()
// call finished which will emit signals
// FIXME shouldn't this be emitted Queued?
d->error(OperationCanceledError, tr("Operation canceled"));
+
+ // If state is WaitingForSession, calling finished has no effect
+ if (d->state == QNetworkReplyHttpImplPrivate::WaitingForSession)
+ d->state = QNetworkReplyHttpImplPrivate::Working;
d->finished();
}
@@ -440,8 +444,8 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate()
, downloadBufferReadPosition(0)
, downloadBufferCurrentSize(0)
, downloadZerocopyBuffer(0)
- , pendingDownloadDataEmissions(new QAtomicInt())
- , pendingDownloadProgressEmissions(new QAtomicInt())
+ , pendingDownloadDataEmissions(QSharedPointer<QAtomicInt>::create())
+ , pendingDownloadProgressEmissions(QSharedPointer<QAtomicInt>::create())
#ifndef QT_NO_SSL
, pendingIgnoreAllSslErrors(false)
#endif
@@ -1724,7 +1728,7 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData()
if (!outgoingDataBuffer) {
// first call, create our buffer
- outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer());
+ outgoingDataBuffer = QSharedPointer<QRingBuffer>::create();
QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData()));
QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished()));
@@ -1853,9 +1857,9 @@ QNonContiguousByteDevice* QNetworkReplyHttpImplPrivate::createUploadByteDevice()
Q_Q(QNetworkReplyHttpImpl);
if (outgoingDataBuffer)
- uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(outgoingDataBuffer));
+ uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(outgoingDataBuffer);
else if (outgoingData) {
- uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(outgoingData));
+ uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(outgoingData);
} else {
return 0;
}
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index f51b85cba0..616019ea41 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -248,7 +248,7 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData()
if (!outgoingDataBuffer) {
// first call, create our buffer
- outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer());
+ outgoingDataBuffer = QSharedPointer<QRingBuffer>::create();
QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData()));
QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished()));
@@ -367,7 +367,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const
// The synchronous HTTP is a corner case, we will put all upload data in one big QByteArray in the outgoingDataBuffer.
// Yes, this is not the most efficient thing to do, but on the other hand synchronous XHR needs to die anyway.
if (synchronousHttpAttribute.toBool() && outgoingData) {
- outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer());
+ outgoingDataBuffer = QSharedPointer<QRingBuffer>::create();
qint64 previousDataSize = 0;
do {
previousDataSize = outgoingDataBuffer->size();
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index 32a804e9f4..ab703981ee 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -506,25 +506,7 @@ QByteArray QSpdyProtocolHandler::composeHeader(const QHttpNetworkRequest &reques
#endif
uncompressedHeader.append(headerField(":version", "HTTP/1.1"));
- QHostAddress add; // ### unify with the host parsing from QHttpNetworkConnection
- QByteArray host;
- QString hostName = m_connection->hostName();
- if (add.setAddress(hostName)) {
- if (add.protocol() == QAbstractSocket::IPv6Protocol)
- host = "[" + hostName.toLatin1() + "]"; //format the ipv6 in the standard way
- else
- host = hostName.toLatin1();
-
- } else {
- host = QUrl::toAce(hostName);
- }
-
- int port = request.url().port();
- if (port != -1) {
- host += ':';
- host += QByteArray::number(port);
- }
- uncompressedHeader.append(headerField(":host", host));
+ uncompressedHeader.append(headerField(":host", request.url().authority(QUrl::FullyEncoded | QUrl::RemoveUserInfo).toLatin1()));
uncompressedHeader.append(headerField(":scheme", request.url().scheme().toLatin1()));
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index e111a190cb..b7e6bad0a7 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -283,9 +283,21 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, QObject *parent)
/*!
\fn QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent)
- \internal
+ \since 5.4
+ Constructs a QDnsLookup object for the given \a type, \a name and
+ \a nameserver and sets \a parent as the parent object.
*/
+QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent)
+ : QObject(*new QDnsLookupPrivate, parent)
+{
+ Q_D(QDnsLookup);
+ qRegisterMetaType<QDnsLookupReply>();
+ d->name = name;
+ d->type = type;
+ d->nameserver = nameserver;
+}
+
/*!
Destroys the QDnsLookup object.
diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp
index e2a5ba2f37..52a8c3a530 100644
--- a/src/network/kernel/qdnslookup_winrt.cpp
+++ b/src/network/kernel/qdnslookup_winrt.cpp
@@ -81,31 +81,28 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
return;
}
- IHostNameFactory *hostnameFactory;
-
- HStringReference classId(RuntimeClass_Windows_Networking_HostName);
- if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) {
+ ComPtr<IHostNameFactory> hostnameFactory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
+ IID_PPV_ARGS(&hostnameFactory));
+ if (FAILED(hr)) {
reply->error = QDnsLookup::ResolverError;
reply->errorString = QLatin1String("Could not obtain hostname factory");
return;
}
- IHostName *host;
+ ComPtr<IHostName> host;
HStringReference hostNameRef((const wchar_t*)aceHostname.utf16());
hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
- hostnameFactory->Release();
- IDatagramSocketStatics *datagramSocketStatics;
+ ComPtr<IDatagramSocketStatics> datagramSocketStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
- IAsyncOperation<IVectorView<EndpointPair*> *> *op;
- datagramSocketStatics->GetEndpointPairsAsync(host,
+ ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op;
+ datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
HString::MakeReference(L"0").Get(),
&op);
- datagramSocketStatics->Release();
- host->Release();
- IVectorView<EndpointPair*> *endpointPairs = 0;
- HRESULT hr = op->GetResults(&endpointPairs);
+ ComPtr<IVectorView<EndpointPair *>> endpointPairs;
+ hr = op->GetResults(&endpointPairs);
int waitCount = 0;
while (hr == E_ILLEGAL_METHOD_CALL) {
WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
@@ -113,7 +110,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
if (++waitCount > 1200) // Wait for 1 minute max
return;
}
- op->Release();
if (!endpointPairs)
return;
@@ -123,11 +119,10 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
// endpoint pairs might contain duplicates so we temporarily store addresses in a QSet
QSet<QHostAddress> addresses;
for (unsigned int i = 0; i < size; ++i) {
- IEndpointPair *endpointpair;
+ ComPtr<IEndpointPair> endpointpair;
endpointPairs->GetAt(i, &endpointpair);
- IHostName *remoteHost;
+ ComPtr<IHostName> remoteHost;
endpointpair->get_RemoteHostName(&remoteHost);
- endpointpair->Release();
HostNameType type;
remoteHost->get_Type(&type);
if (type == HostNameType_Bluetooth || type == HostNameType_DomainName
@@ -138,7 +133,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
HString name;
remoteHost->get_CanonicalName(name.GetAddressOf());
- remoteHost->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
addresses.insert(QHostAddress(QString::fromWCharArray(rawString, length)));
diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp
index e02cd98e08..26f6585c32 100644
--- a/src/network/kernel/qhostinfo_winrt.cpp
+++ b/src/network/kernel/qhostinfo_winrt.cpp
@@ -80,29 +80,25 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
- IHostNameFactory *hostnameFactory;
+ ComPtr<IHostNameFactory> hostnameFactory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
+ IID_PPV_ARGS(&hostnameFactory));
+ Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
- HStringReference classId(RuntimeClass_Windows_Networking_HostName);
- if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory)))
- Q_ASSERT_X(false, "QHostInfoAgent", "Could not obtain hostname factory.");
-
- IHostName *host;
+ ComPtr<IHostName> host;
HStringReference hostNameRef((const wchar_t*)hostName.utf16());
hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
- hostnameFactory->Release();
- IDatagramSocketStatics *datagramSocketStatics;
+ ComPtr<IDatagramSocketStatics> datagramSocketStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
- IAsyncOperation<IVectorView<EndpointPair*> *> *op;
- datagramSocketStatics->GetEndpointPairsAsync(host,
+ ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op;
+ datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
HString::MakeReference(L"0").Get(),
&op);
- datagramSocketStatics->Release();
- host->Release();
- IVectorView<EndpointPair*> *endpointPairs = 0;
- HRESULT hr = op->GetResults(&endpointPairs);
+ ComPtr<IVectorView<EndpointPair *>> endpointPairs;
+ hr = op->GetResults(&endpointPairs);
int waitCount = 0;
while (hr == E_ILLEGAL_METHOD_CALL) {
WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
@@ -110,7 +106,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
if (++waitCount > 1200) // Wait for 1 minute max
return results;
}
- op->Release();
if (!endpointPairs)
return results;
@@ -119,11 +114,10 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
endpointPairs->get_Size(&size);
QList<QHostAddress> addresses;
for (unsigned int i = 0; i < size; ++i) {
- IEndpointPair *endpointpair;
+ ComPtr<IEndpointPair> endpointpair;
endpointPairs->GetAt(i, &endpointpair);
- IHostName *remoteHost;
+ ComPtr<IHostName> remoteHost;
endpointpair->get_RemoteHostName(&remoteHost);
- endpointpair->Release();
if (!remoteHost)
continue;
HostNameType type;
@@ -133,7 +127,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
HString name;
remoteHost->get_CanonicalName(name.GetAddressOf());
- remoteHost->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
QHostAddress addr;
@@ -148,12 +141,11 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
QString QHostInfo::localHostName()
{
- INetworkInformationStatics *statics;
+ ComPtr<INetworkInformationStatics> statics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
- IVectorView<HostName*> *hostNames = 0;
+ ComPtr<IVectorView<HostName *>> hostNames;
statics->GetHostNames(&hostNames);
- statics->Release();
if (!hostNames)
return QString();
@@ -163,7 +155,7 @@ QString QHostInfo::localHostName()
return QString();
for (unsigned int i = 0; i < size; ++i) {
- IHostName *hostName;
+ ComPtr<IHostName> hostName;
hostNames->GetAt(i, &hostName);
HostNameType type;
hostName->get_Type(&type);
@@ -172,18 +164,15 @@ QString QHostInfo::localHostName()
HString name;
hostName->get_CanonicalName(name.GetAddressOf());
- hostName->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
return QString::fromWCharArray(rawString, length);
}
- IHostName *firstHost;
+ ComPtr<IHostName> firstHost;
hostNames->GetAt(0, &firstHost);
- hostNames->Release();
HString name;
firstHost->get_CanonicalName(name.GetAddressOf());
- firstHost->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
return QString::fromWCharArray(rawString, length);
diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp
index 48a96928a8..c8547411eb 100644
--- a/src/network/kernel/qnetworkinterface_winrt.cpp
+++ b/src/network/kernel/qnetworkinterface_winrt.cpp
@@ -73,12 +73,11 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
QList<HostNameInfo> hostList;
- INetworkInformationStatics *hostNameStatics;
+ ComPtr<INetworkInformationStatics> hostNameStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics);
- IVectorView<HostName*> *hostNames = 0;
+ ComPtr<IVectorView<HostName *>> hostNames;
hostNameStatics->GetHostNames(&hostNames);
- hostNameStatics->Release();
if (!hostNames)
return interfaces;
@@ -86,7 +85,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
hostNames->get_Size(&hostNameCount);
for (unsigned i = 0; i < hostNameCount; ++i) {
HostNameInfo hostInfo;
- IHostName *hostName;
+ ComPtr<IHostName> hostName;
hostNames->GetAt(i, &hostName);
HostNameType type;
@@ -94,20 +93,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (type == HostNameType_DomainName)
continue;
- IIPInformation *ipInformation;
+ ComPtr<IIPInformation> ipInformation;
hostName->get_IPInformation(&ipInformation);
- INetworkAdapter *currentAdapter;
+ ComPtr<INetworkAdapter> currentAdapter;
ipInformation->get_NetworkAdapter(&currentAdapter);
currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId);
- currentAdapter->Release();
- IReference<unsigned char> *prefixLengthReference;
+ ComPtr<IReference<unsigned char>> prefixLengthReference;
ipInformation->get_PrefixLength(&prefixLengthReference);
- ipInformation->Release();
prefixLengthReference->get_Value(&hostInfo.prefixLength);
- prefixLengthReference->Release();
// invalid prefixes
if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32)
@@ -116,20 +112,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
HString name;
hostName->get_CanonicalName(name.GetAddressOf());
- hostName->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
hostInfo.address = QString::fromWCharArray(rawString, length);
hostList << hostInfo;
}
- hostNames->Release();
INetworkInformationStatics *networkInfoStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics);
- IVectorView<ConnectionProfile *> *connectionProfiles = 0;
+ ComPtr<IVectorView<ConnectionProfile *>> connectionProfiles;
networkInfoStatics->GetConnectionProfiles(&connectionProfiles);
- networkInfoStatics->Release();
if (!connectionProfiles)
return interfaces;
@@ -139,7 +132,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
interfaces << iface;
- IConnectionProfile *profile;
+ ComPtr<IConnectionProfile> profile;
connectionProfiles->GetAt(i, &profile);
NetworkConnectivityLevel connectivityLevel;
@@ -147,16 +140,14 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (connectivityLevel != NetworkConnectivityLevel_None)
iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
- INetworkAdapter *adapter;
+ ComPtr<INetworkAdapter> adapter;
profile->get_NetworkAdapter(&adapter);
- profile->Release();
UINT32 type;
adapter->get_IanaInterfaceType(&type);
if (type == 23)
iface->flags |= QNetworkInterface::IsPointToPoint;
GUID id;
adapter->get_NetworkAdapterId(&id);
- adapter->Release();
OLECHAR adapterName[39]={0};
StringFromGUID2(id, adapterName, 39);
iface->name = QString::fromWCharArray(adapterName);
@@ -179,7 +170,6 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
--i;
}
}
- connectionProfiles->Release();
return interfaces;
}
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 65244ce9cf..472e0cb98c 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -365,7 +365,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port)
{
#ifdef QNATIVESOCKETENGINE_DEBUG
- qDebug("QNativeSocketEnginePrivate::nativeConnect() : %lli", socketDescriptor);
+ qDebug() << "QNativeSocketEnginePrivate::nativeConnect() " << socketDescriptor;
#endif
struct sockaddr_in sockAddrIPv4;
@@ -405,6 +405,9 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16
}
int connectResult = qt_safe_connect(socketDescriptor, sockAddrPtr, sockAddrSize);
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ int ecopy = errno;
+#endif
if (connectResult == -1) {
switch (errno) {
case EISCONN:
@@ -456,7 +459,7 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16
qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
addr.toString().toLatin1().constData(), port,
socketState == QAbstractSocket::ConnectingState
- ? "Connection in progress" : socketErrorString.toLatin1().constData());
+ ? "Connection in progress" : strerror(ecopy));
#endif
return false;
}
@@ -524,6 +527,9 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16
}
if (bindResult < 0) {
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ int ecopy = errno;
+#endif
switch(errno) {
case EADDRINUSE:
setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString);
@@ -543,7 +549,7 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",
- address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData());
+ address.toString().toLatin1().constData(), port, strerror(ecopy));
#endif
return false;
@@ -563,6 +569,9 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16
bool QNativeSocketEnginePrivate::nativeListen(int backlog)
{
if (qt_safe_listen(socketDescriptor, backlog) < 0) {
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ int ecopy = errno;
+#endif
switch (errno) {
case EADDRINUSE:
setError(QAbstractSocket::AddressInUseError,
@@ -574,7 +583,7 @@ bool QNativeSocketEnginePrivate::nativeListen(int backlog)
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)",
- backlog, socketErrorString.toLatin1().constData());
+ backlog, strerror(ecopy));
#endif
return false;
}
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index 1646940cb8..ab6c2a6590 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -477,16 +477,15 @@ void QNativeSocketEngine::close()
{
Q_D(QNativeSocketEngine);
if (d->socketDescriptor != -1) {
- IClosable *socket = 0;
+ ComPtr<IClosable> socket;
if (d->socketType == QAbstractSocket::TcpSocket && d->tcp)
- d->tcp->QueryInterface(IID_PPV_ARGS(&socket));
+ d->tcp.As(&socket);
else if (d->socketType == QAbstractSocket::UdpSocket && d->udp)
- d->udp->QueryInterface(IID_PPV_ARGS(&socket));
+ d->udp.As(&socket);
if (socket) {
d->closingDown = true;
socket->Close();
- socket->Release();
d->socketDescriptor = -1;
}
d->socketDescriptor = -1;
@@ -624,11 +623,10 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress
*addr = returnAddress;
*port = returnPort;
arg = d->pendingDatagrams.takeFirst();
+ arg->Release();
// TODO: fill data
Q_UNUSED(data);
- arg->Release();
- delete arg;
--i;
return maxlen;
}
@@ -833,8 +831,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
SocketHandler *handler = gSocketHandler();
switch (socketType) {
case QAbstractSocket::TcpSocket: {
- if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(),
- reinterpret_cast<IInspectable **>(&tcp)))) {
+ HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &tcp);
+ if (FAILED(hr)) {
qWarning("Failed to create StreamSocket instance");
return false;
}
@@ -842,8 +840,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
return true;
}
case QAbstractSocket::UdpSocket: {
- if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(),
- reinterpret_cast<IInspectable **>(&udp)))) {
+ HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &udp);
+ if (FAILED(hr)) {
qWarning("Failed to create stream socket");
return false;
}
@@ -1256,7 +1254,7 @@ HRESULT QNativeSocketEnginePrivate::handleWriteCompleted(IAsyncOperationWithProg
HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args)
{
Q_Q(QNativeSocketEngine);
- Q_UNUSED(socket)
+ Q_UNUSED(socket);
pendingDatagrams.append(args);
emit q->readReady();
diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h
index ec2e1b3ad4..bf23faeb45 100644
--- a/src/network/socket/qnativesocketengine_winrt_p.h
+++ b/src/network/socket/qnativesocketengine_winrt_p.h
@@ -193,10 +193,8 @@ public:
bool checkProxy(const QHostAddress &address);
bool fetchConnectionParameters();
private:
- union {
- ABI::Windows::Networking::Sockets::IStreamSocket *tcp;
- ABI::Windows::Networking::Sockets::IDatagramSocket *udp;
- };
+ Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocket> tcp;
+ Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IDatagramSocket> udp;
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener;
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> readBuffer;
QBuffer readBytes;
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 3b7fa4da09..11ea711f30 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -265,6 +265,22 @@ bool QSslCertificate::isBlacklisted() const
}
/*!
+ \since 5.4
+ Returns \c true if this certificate is self signed; otherwise
+ returns \c false.
+
+ A certificate is considered self-signed its issuer and subject
+ are identical.
+*/
+bool QSslCertificate::isSelfSigned() const
+{
+ if (!d->x509)
+ return false;
+
+ return (q_X509_check_issued(d->x509, d->x509) == X509_V_OK);
+}
+
+/*!
Clears the contents of this certificate, making it a null
certificate.
@@ -963,6 +979,26 @@ QList<QSslError> QSslCertificate::verify(QList<QSslCertificate> certificateChain
return QSslSocketBackendPrivate::verify(certificateChain, hostName);
}
+/*!
+ \since 5.4
+
+ Imports a PKCS#12 (pfx) file from the specified \a device. A PKCS#12
+ file is a bundle that can contain a number of certificates and keys.
+ This method reads a single \a key, its \a certificate and any
+ associated \a caCertificates from the bundle. If a \a passPhrase is
+ specified then this will be used to decrypt the bundle. Returns
+ \c true if the PKCS#12 file was successfully loaded.
+
+ \note The \a device must be open and ready to be read from.
+ */
+bool QSslCertificate::importPKCS12(QIODevice *device,
+ QSslKey *key, QSslCertificate *certificate,
+ QList<QSslCertificate> *caCertificates,
+ const QByteArray &passPhrase)
+{
+ return QSslSocketBackendPrivate::importPKCS12(device, key, certificate, caCertificates, passPhrase);
+}
+
void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat format)
{
if (!data.isEmpty()) {
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 988071eb9d..2217eb7fb9 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -105,6 +105,7 @@ public:
}
#endif
bool isBlacklisted() const;
+ bool isSelfSigned() const;
void clear();
// Certificate info
@@ -141,6 +142,11 @@ public:
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName = QString());
+ static bool importPKCS12(QIODevice *device,
+ QSslKey *key, QSslCertificate *cert,
+ QList<QSslCertificate> *caCertificates=0,
+ const QByteArray &passPhrase=QByteArray());
+
Qt::HANDLE handle() const;
private:
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 14881931af..64b75f98ec 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -208,6 +208,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->localCertificateChain == other.d->localCertificateChain &&
d->privateKey == other.d->privateKey &&
d->sessionCipher == other.d->sessionCipher &&
+ d->sessionProtocol == other.d->sessionProtocol &&
d->ciphers == other.d->ciphers &&
d->caCertificates == other.d->caCertificates &&
d->protocol == other.d->protocol &&
@@ -512,6 +513,18 @@ QSslCipher QSslConfiguration::sessionCipher() const
}
/*!
+ Returns the socket's SSL/TLS protocol or UnknownProtocol if the
+ connection isn't encrypted. The socket's protocol for the session
+ is set during the handshake phase.
+
+ \sa protocol(), setProtocol()
+*/
+QSsl::SslProtocol QSslConfiguration::sessionProtocol() const
+{
+ return d->sessionProtocol;
+}
+
+/*!
Returns the \l {QSslKey} {SSL key} assigned to this connection or
a null key if none has been assigned yet.
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 587187ca06..4c5799bf28 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -109,6 +109,7 @@ public:
QSslCertificate peerCertificate() const;
QList<QSslCertificate> peerCertificateChain() const;
QSslCipher sessionCipher() const;
+ QSsl::SslProtocol sessionProtocol() const;
// Private keys, for server sockets
QSslKey privateKey() const;
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index d183c3335c..29bd4053ad 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -81,7 +81,8 @@ class QSslConfigurationPrivate: public QSharedData
{
public:
QSslConfigurationPrivate()
- : protocol(QSsl::SecureProtocols),
+ : sessionProtocol(QSsl::UnknownProtocol),
+ protocol(QSsl::SecureProtocols),
peerVerifyMode(QSslSocket::AutoVerifyPeer),
peerVerifyDepth(0),
allowRootCertOnDemandLoading(true),
@@ -98,6 +99,7 @@ public:
QSslKey privateKey;
QSslCipher sessionCipher;
+ QSsl::SslProtocol sessionProtocol;
QList<QSslCipher> ciphers;
QList<QSslCertificate> caCertificates;
diff --git a/src/network/ssl/qsslkey.cpp b/src/network/ssl/qsslkey.cpp
index 95eed6e4b3..b43e28589f 100644
--- a/src/network/ssl/qsslkey.cpp
+++ b/src/network/ssl/qsslkey.cpp
@@ -96,6 +96,38 @@ void QSslKeyPrivate::clear(bool deep)
}
}
+bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
+{
+ if (pkey->type == EVP_PKEY_RSA) {
+ isNull = false;
+ algorithm = QSsl::Rsa;
+ type = QSsl::PrivateKey;
+
+ rsa = q_RSA_new();
+ memcpy(rsa, q_EVP_PKEY_get1_RSA(pkey), sizeof(RSA));
+
+ return true;
+ }
+ else if (pkey->type == EVP_PKEY_DSA) {
+ isNull = false;
+ algorithm = QSsl::Dsa;
+ type = QSsl::PrivateKey;
+
+ dsa = q_DSA_new();
+ memcpy(rsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA));
+
+ return true;
+ }
+ else {
+ // Unknown key type. This could be handled as opaque, but then
+ // we'd eventually leak memory since we wouldn't be able to free
+ // the underlying EVP_PKEY structure. For now, we won't support
+ // this.
+ }
+
+ return false;
+}
+
/*!
\internal
diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h
index 145d4a28f1..59063e2e57 100644
--- a/src/network/ssl/qsslkey.h
+++ b/src/network/ssl/qsslkey.h
@@ -95,6 +95,7 @@ public:
private:
QExplicitlySharedDataPointer<QSslKeyPrivate> d;
friend class QSslCertificate;
+ friend class QSslSocketBackendPrivate;
};
Q_DECLARE_SHARED(QSslKey)
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index 54d12d76fb..658be85621 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -79,6 +79,7 @@ public:
void clear(bool deep = true);
+ bool fromEVP_PKEY(EVP_PKEY *pkey);
void decodePem(const QByteArray &pem, const QByteArray &passPhrase,
bool deepClear = true);
QByteArray pemHeader() const;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 90f6e25b97..8fd9114b2e 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -880,6 +880,7 @@ QSslConfiguration QSslSocket::sslConfiguration() const
QSslConfigurationPrivate *copy = new QSslConfigurationPrivate(d->configuration);
copy->ref.store(0); // the QSslConfiguration constructor refs up
copy->sessionCipher = d->sessionCipher();
+ copy->sessionProtocol = d->sessionProtocol();
return QSslConfiguration(copy);
}
@@ -1075,6 +1076,20 @@ QSslCipher QSslSocket::sessionCipher() const
}
/*!
+ Returns the socket's SSL/TLS protocol or UnknownProtocol if the
+ connection isn't encrypted. The socket's protocol for the session
+ is set during the handshake phase.
+
+ \sa protocol(), setProtocol()
+*/
+QSsl::SslProtocol QSslSocket::sessionProtocol() const
+{
+ Q_D(const QSslSocket);
+ return d->sessionProtocol();
+}
+
+
+/*!
Sets the socket's private \l {QSslKey} {key} to \a key. The
private key and the local \l {QSslCertificate} {certificate} are
used by clients and servers that must prove their identity to
@@ -1667,6 +1682,32 @@ QString QSslSocket::sslLibraryVersionString()
}
/*!
+ \since 5.4
+ Returns the version number of the SSL library in use at compile
+ time. If no SSL support is available then this will return an
+ undefined value.
+
+ \sa sslLibraryVersionNumber()
+*/
+long QSslSocket::sslLibraryBuildVersionNumber()
+{
+ return QSslSocketPrivate::sslLibraryBuildVersionNumber();
+}
+
+/*!
+ \since 5.4
+ Returns the version string of the SSL library in use at compile
+ time. If no SSL support is available then this will return an
+ empty value.
+
+ \sa sslLibraryVersionString()
+*/
+QString QSslSocket::sslLibraryBuildVersionString()
+{
+ return QSslSocketPrivate::sslLibraryBuildVersionString();
+}
+
+/*!
Starts a delayed SSL handshake for a client connection. This
function can be called when the socket is in the \l ConnectedState
but still in the \l UnencryptedMode. If it is not yet connected,
@@ -2098,6 +2139,7 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
ptr->localCertificateChain = global->localCertificateChain;
ptr->privateKey = global->privateKey;
ptr->sessionCipher = global->sessionCipher;
+ ptr->sessionProtocol = global->sessionProtocol;
ptr->ciphers = global->ciphers;
ptr->caCertificates = global->caCertificates;
ptr->protocol = global->protocol;
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index d89933efda..9cc5e02de3 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -140,6 +140,7 @@ public:
QSslCertificate peerCertificate() const;
QList<QSslCertificate> peerCertificateChain() const;
QSslCipher sessionCipher() const;
+ QSsl::SslProtocol sessionProtocol() const;
// Private keys, for server sockets.
void setPrivateKey(const QSslKey &key);
@@ -182,6 +183,8 @@ public:
static bool supportsSsl();
static long sslLibraryVersionNumber();
static QString sslLibraryVersionString();
+ static long sslLibraryBuildVersionNumber();
+ static QString sslLibraryBuildVersionString();
void ignoreSslErrors(const QList<QSslError> &errors);
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 0315749cb3..f869039687 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -62,6 +62,7 @@
#include "qsslsocket.h"
#include "qsslcertificate_p.h"
#include "qsslcipher_p.h"
+#include "qsslkey_p.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
@@ -585,6 +586,16 @@ QString QSslSocketPrivate::sslLibraryVersionString()
return QString::fromLatin1(versionString);
}
+long QSslSocketPrivate::sslLibraryBuildVersionNumber()
+{
+ return OPENSSL_VERSION_NUMBER;
+}
+
+QString QSslSocketPrivate::sslLibraryBuildVersionString()
+{
+ return QLatin1String(OPENSSL_VERSION_TEXT);
+}
+
/*!
\internal
@@ -1429,6 +1440,28 @@ QSslCipher QSslSocketBackendPrivate::sessionCipher() const
return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher();
}
+QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const
+{
+ if (!ssl)
+ return QSsl::UnknownProtocol;
+ int ver = q_SSL_version(ssl);
+
+ switch (ver) {
+ case 0x2:
+ return QSsl::SslV2;
+ case 0x300:
+ return QSsl::SslV3;
+ case 0x301:
+ return QSsl::TlsV1_0;
+ case 0x302:
+ return QSsl::TlsV1_1;
+ case 0x303:
+ return QSsl::TlsV1_2;
+ }
+
+ return QSsl::UnknownProtocol;
+}
+
void QSslSocketBackendPrivate::continueHandshake()
{
Q_Q(QSslSocket);
@@ -1703,4 +1736,72 @@ QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certifi
return errors;
}
+bool QSslSocketBackendPrivate::importPKCS12(QIODevice *device,
+ QSslKey *key, QSslCertificate *cert,
+ QList<QSslCertificate> *caCertificates,
+ const QByteArray &passPhrase)
+{
+ if (!supportsSsl())
+ return false;
+
+ // These are required
+ Q_ASSERT(device);
+ Q_ASSERT(key);
+ Q_ASSERT(cert);
+
+ // Read the file into a BIO
+ QByteArray pkcs12data = device->readAll();
+ if (pkcs12data.size() == 0)
+ return false;
+
+ BIO *bio = q_BIO_new_mem_buf(const_cast<char *>(pkcs12data.constData()), pkcs12data.size());
+
+ // Create the PKCS#12 object
+ PKCS12 *p12 = q_d2i_PKCS12_bio(bio, 0);
+ if (!p12) {
+ qWarning("Unable to read PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0));
+ q_BIO_free(bio);
+ return false;
+ }
+
+ // Extract the data
+ EVP_PKEY *pkey;
+ X509 *x509;
+ STACK_OF(X509) *ca = 0;
+
+ if (!q_PKCS12_parse(p12, passPhrase.constData(), &pkey, &x509, &ca)) {
+ qWarning("Unable to parse PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0));
+ q_PKCS12_free(p12);
+ q_BIO_free(bio);
+ return false;
+ }
+
+ // Convert to Qt types
+ if (!key->d->fromEVP_PKEY(pkey)) {
+ qWarning("Unable to convert private key");
+ q_sk_pop_free(reinterpret_cast<STACK *>(ca), reinterpret_cast<void(*)(void*)>(q_sk_free));
+ q_X509_free(x509);
+ q_EVP_PKEY_free(pkey);
+ q_PKCS12_free(p12);
+ q_BIO_free(bio);
+
+ return false;
+ }
+
+ *cert = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
+
+ if (caCertificates)
+ *caCertificates = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(ca);
+
+ // Clean up
+ q_sk_pop_free(reinterpret_cast<STACK *>(ca), reinterpret_cast<void(*)(void*)>(q_sk_free));
+ q_X509_free(x509);
+ q_EVP_PKEY_free(pkey);
+ q_PKCS12_free(p12);
+ q_BIO_free(bio);
+
+ return true;
+}
+
+
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index c8b23e6cad..f4f2fe842c 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -131,6 +131,7 @@ public:
void disconnectFromHost();
void disconnected();
QSslCipher sessionCipher() const;
+ QSsl::SslProtocol sessionProtocol() const;
void continueHandshake();
bool checkSslErrors();
#ifdef Q_OS_WIN
@@ -145,6 +146,10 @@ public:
Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName);
static QString getErrorsFromOpenSsl();
+ static bool importPKCS12(QIODevice *device,
+ QSslKey *key, QSslCertificate *cert,
+ QList<QSslCertificate> *caCertificates,
+ const QByteArray &passPhrase);
};
#ifdef Q_OS_WIN
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index d4a4117b8b..ca692510c1 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -146,6 +146,7 @@ DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
+DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
#if OPENSSL_VERSION_NUMBER < 0x00908000L
DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, unsigned char **b, b, long c, c, return 0, return)
@@ -186,6 +187,7 @@ DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, retur
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
+DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
@@ -239,6 +241,7 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, retu
#else
DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
#endif
+DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return)
DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return)
@@ -316,6 +319,7 @@ DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0
#else
DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, return)
#endif
+DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return)
DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
@@ -368,6 +372,11 @@ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM
DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return)
DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG)
+DEFINEFUNC5(int, PKCS12_parse, PKCS12 *p12, p12, const char *pass, pass, EVP_PKEY **pkey, pkey, \
+ X509 **cert, cert, STACK_OF(X509) **ca, ca, return 1, return);
+DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return 0, return);
+DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
+
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
&& !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
@@ -686,6 +695,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(CRYPTO_num_locks)
RESOLVEFUNC(CRYPTO_set_id_callback)
RESOLVEFUNC(CRYPTO_set_locking_callback)
+ RESOLVEFUNC(DSA_new)
RESOLVEFUNC(DSA_free)
RESOLVEFUNC(ERR_error_string)
RESOLVEFUNC(ERR_get_error)
@@ -718,6 +728,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
RESOLVEFUNC(RAND_seed)
RESOLVEFUNC(RAND_status)
+ RESOLVEFUNC(RSA_new)
RESOLVEFUNC(RSA_free)
RESOLVEFUNC(sk_new_null)
RESOLVEFUNC(sk_push)
@@ -746,6 +757,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_free)
RESOLVEFUNC(SSL_get_ciphers)
RESOLVEFUNC(SSL_get_current_cipher)
+ RESOLVEFUNC(SSL_version)
RESOLVEFUNC(SSL_get_error)
RESOLVEFUNC(SSL_get_peer_cert_chain)
RESOLVEFUNC(SSL_get_peer_certificate)
@@ -819,6 +831,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(BASIC_CONSTRAINTS_free)
RESOLVEFUNC(AUTHORITY_KEYID_free)
RESOLVEFUNC(ASN1_STRING_print)
+ RESOLVEFUNC(X509_check_issued)
RESOLVEFUNC(X509_get_issuer_name)
RESOLVEFUNC(X509_get_subject_name)
RESOLVEFUNC(X509_verify_cert)
@@ -847,6 +860,9 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(BN_bin2bn)
RESOLVEFUNC(EC_KEY_new_by_curve_name)
RESOLVEFUNC(EC_KEY_free)
+ RESOLVEFUNC(PKCS12_parse)
+ RESOLVEFUNC(d2i_PKCS12_bio)
+ RESOLVEFUNC(PKCS12_free)
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 0f3d2673c2..34c0040e56 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -233,6 +233,7 @@ int q_CRYPTO_num_locks();
void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
void q_CRYPTO_set_id_callback(unsigned long (*a)());
void q_CRYPTO_free(void *a);
+DSA *q_DSA_new();
void q_DSA_free(DSA *a);
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
// 0.9.8 broke SC and BC by changing this function's signature.
@@ -277,6 +278,7 @@ int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b);
void q_RAND_seed(const void *a, int b);
int q_RAND_status();
+RSA *q_RSA_new();
void q_RSA_free(RSA *a);
int q_sk_num(STACK *a);
void q_sk_pop_free(STACK *a, void (*b)(void *));
@@ -330,6 +332,7 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
#else
SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
#endif
+int q_SSL_version(const SSL *a);
int q_SSL_get_error(SSL *a, int b);
STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
X509 *q_SSL_get_peer_certificate(SSL *a);
@@ -407,6 +410,7 @@ int q_ASN1_STRING_print(BIO *a, const ASN1_STRING *b);
#else
int q_ASN1_STRING_print(BIO *a, ASN1_STRING *b);
#endif
+int q_X509_check_issued(X509 *a, X509 *b);
X509_NAME *q_X509_get_issuer_name(X509 *a);
X509_NAME *q_X509_get_subject_name(X509 *a);
int q_X509_verify_cert(X509_STORE_CTX *ctx);
@@ -439,6 +443,12 @@ EC_KEY *q_EC_KEY_new_by_curve_name(int nid);
void q_EC_KEY_free(EC_KEY *ecdh);
#define q_SSL_CTX_set_tmp_ecdh(ctx, ecdh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_ECDH, 0, (char *)ecdh)
+// PKCS#12 support
+int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
+PKCS12 *q_d2i_PKCS12_bio(BIO *bio, PKCS12 **pkcs12);
+void q_PKCS12_free(PKCS12 *pkcs12);
+
+
#define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
#define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
#ifdef SSLEAY_MACROS
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 6281753225..0033a46d98 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -129,6 +129,8 @@ public:
static bool supportsSsl();
static long sslLibraryVersionNumber();
static QString sslLibraryVersionString();
+ static long sslLibraryBuildVersionNumber();
+ static QString sslLibraryBuildVersionString();
static void ensureInitialized();
static void deinitialize();
static QList<QSslCipher> defaultCiphers();
@@ -190,6 +192,7 @@ public:
virtual void disconnectFromHost() = 0;
virtual void disconnected() = 0;
virtual QSslCipher sessionCipher() const = 0;
+ virtual QSsl::SslProtocol sessionProtocol() const = 0;
virtual void continueHandshake() = 0;
Q_AUTOTEST_EXPORT static bool rootCertOnDemandLoadingSupported();