drop SSL support

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-02-21 15:18:36 +02:00
parent 808d94b266
commit fba2c2132c
35 changed files with 19 additions and 7665 deletions

View file

@ -1133,13 +1133,6 @@ include/katie/QtNetwork/QNetworkInterface
include/katie/QtNetwork/QNetworkProxy
include/katie/QtNetwork/QNetworkProxyFactory
include/katie/QtNetwork/QNetworkProxyQuery
include/katie/QtNetwork/QSsl
include/katie/QtNetwork/QSslCertificate
include/katie/QtNetwork/QSslCipher
include/katie/QtNetwork/QSslConfiguration
include/katie/QtNetwork/QSslError
include/katie/QtNetwork/QSslKey
include/katie/QtNetwork/QSslSocket
include/katie/QtNetwork/QTcpServer
include/katie/QtNetwork/QTcpSocket
include/katie/QtNetwork/QUdpSocket
@ -1155,13 +1148,6 @@ include/katie/QtNetwork/qlocalserver.h
include/katie/QtNetwork/qlocalsocket.h
include/katie/QtNetwork/qnetworkinterface.h
include/katie/QtNetwork/qnetworkproxy.h
include/katie/QtNetwork/qssl.h
include/katie/QtNetwork/qsslcertificate.h
include/katie/QtNetwork/qsslcipher.h
include/katie/QtNetwork/qsslconfiguration.h
include/katie/QtNetwork/qsslerror.h
include/katie/QtNetwork/qsslkey.h
include/katie/QtNetwork/qsslsocket.h
include/katie/QtNetwork/qtcpserver.h
include/katie/QtNetwork/qtcpsocket.h
include/katie/QtNetwork/qudpsocket.h

View file

@ -1136,13 +1136,6 @@ include/katie/QtNetwork/QNetworkInterface
include/katie/QtNetwork/QNetworkProxy
include/katie/QtNetwork/QNetworkProxyFactory
include/katie/QtNetwork/QNetworkProxyQuery
include/katie/QtNetwork/QSsl
include/katie/QtNetwork/QSslCertificate
include/katie/QtNetwork/QSslCipher
include/katie/QtNetwork/QSslConfiguration
include/katie/QtNetwork/QSslError
include/katie/QtNetwork/QSslKey
include/katie/QtNetwork/QSslSocket
include/katie/QtNetwork/QTcpServer
include/katie/QtNetwork/QTcpSocket
include/katie/QtNetwork/QUdpSocket
@ -1158,13 +1151,6 @@ include/katie/QtNetwork/qlocalserver.h
include/katie/QtNetwork/qlocalsocket.h
include/katie/QtNetwork/qnetworkinterface.h
include/katie/QtNetwork/qnetworkproxy.h
include/katie/QtNetwork/qssl.h
include/katie/QtNetwork/qsslcertificate.h
include/katie/QtNetwork/qsslcipher.h
include/katie/QtNetwork/qsslconfiguration.h
include/katie/QtNetwork/qsslerror.h
include/katie/QtNetwork/qsslkey.h
include/katie/QtNetwork/qsslsocket.h
include/katie/QtNetwork/qtcpserver.h
include/katie/QtNetwork/qtcpsocket.h
include/katie/QtNetwork/qudpsocket.h

View file

@ -1142,13 +1142,6 @@ include/katie/QtNetwork/QNetworkInterface
include/katie/QtNetwork/QNetworkProxy
include/katie/QtNetwork/QNetworkProxyFactory
include/katie/QtNetwork/QNetworkProxyQuery
include/katie/QtNetwork/QSsl
include/katie/QtNetwork/QSslCertificate
include/katie/QtNetwork/QSslCipher
include/katie/QtNetwork/QSslConfiguration
include/katie/QtNetwork/QSslError
include/katie/QtNetwork/QSslKey
include/katie/QtNetwork/QSslSocket
include/katie/QtNetwork/QTcpServer
include/katie/QtNetwork/QTcpSocket
include/katie/QtNetwork/QUdpSocket
@ -1164,13 +1157,6 @@ include/katie/QtNetwork/qlocalserver.h
include/katie/QtNetwork/qlocalsocket.h
include/katie/QtNetwork/qnetworkinterface.h
include/katie/QtNetwork/qnetworkproxy.h
include/katie/QtNetwork/qssl.h
include/katie/QtNetwork/qsslcertificate.h
include/katie/QtNetwork/qsslcipher.h
include/katie/QtNetwork/qsslconfiguration.h
include/katie/QtNetwork/qsslerror.h
include/katie/QtNetwork/qsslkey.h
include/katie/QtNetwork/qsslsocket.h
include/katie/QtNetwork/qtcpserver.h
include/katie/QtNetwork/qtcpsocket.h
include/katie/QtNetwork/qudpsocket.h

View file

@ -508,13 +508,6 @@ classlist = [
"QSplitter",
"QSplitterHandle",
"QSpontaneKeyEvent",
"QSsl",
"QSslCertificate",
"QSslCipher",
"QSslConfiguration",
"QSslError",
"QSslKey",
"QSslSocket",
"QStack",
"QStackedLayout",
"QStackedWidget",

View file

@ -37,7 +37,6 @@
#include <QBuffer>
#include <QDebug>
#include "qobject_p.h"
#include <QSslError>
#define IMAGEREQUEST_MAX_REQUEST_COUNT 8
#define IMAGEREQUEST_MAX_REDIRECT_RECURSION 16

View file

@ -13,13 +13,6 @@ set(NETWORK_PUBLIC_HEADERS
QLocalSocket
QNetworkInterface
QNetworkProxy
QSsl
QSslCertificate
QSslCipher
QSslConfiguration
QSslError
QSslKey
QSslSocket
QTcpServer
QTcpSocket
QUdpSocket
@ -60,18 +53,6 @@ set(NETWORK_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/socket/qlocalsocket_p.h
${CMAKE_CURRENT_SOURCE_DIR}/socket/qnativesocketengine_p.h
${CMAKE_CURRENT_SOURCE_DIR}/socket/qnet_unix_p.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qssl.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslcertificate.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslcertificate_p.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslconfiguration.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslconfiguration_p.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslcipher.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslcipher_p.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslerror.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslkey.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslsocket.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslsocket_openssl_p.h
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslsocket_p.h
${CMAKE_CURRENT_SOURCE_DIR}/qnetworkcommon_p.h
)
@ -96,14 +77,6 @@ set(NETWORK_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/socket/qnativesocketengine_unix.cpp
${CMAKE_CURRENT_SOURCE_DIR}/socket/qlocalsocket_unix.cpp
${CMAKE_CURRENT_SOURCE_DIR}/socket/qlocalserver_unix.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qssl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslcertificate.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslconfiguration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslcipher.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslerror.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslkey.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslsocket.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ssl/qsslsocket_openssl.cpp
)
katie_generate_misc("${NETWORK_HEADERS}" QtNetwork)

View file

@ -95,7 +95,7 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
The Digest-MD5 authentication mechanism supports no outgoing options.
\sa QSslSocket
\sa QTcpSocket
*/

View file

@ -280,8 +280,6 @@
IPv6 support).
\value ProxyAuthenticationRequiredError The socket is using a proxy, and
the proxy requires authentication.
\value SslHandshakeFailedError The SSL/TLS handshake failed, so
the connection was closed (only used in QSslSocket) (This value was introduced in 4.4.)
\value UnfinishedSocketOperationError Used by QAbstractSocketEngine only,
The last operation attempted has not finished yet (still in progress in
the background). (This value was introduced in 4.4.)
@ -357,7 +355,6 @@
#include "qtimer.h"
#include "qelapsedtimer.h"
#include "qscopedvaluerollback.h"
#include "qsslsocket.h"
#include "qdebug.h"
#include "qthread_p.h"
#include "qcore_unix_p.h"
@ -1915,7 +1912,6 @@ bool QAbstractSocket::atEnd() const
\sa write(), waitForBytesWritten()
*/
// Note! docs copied to QSslSocket::flush()
bool QAbstractSocket::flush()
{
Q_D(QAbstractSocket);
@ -2545,9 +2541,6 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, QAbstractSocket::SocketError er
case QAbstractSocket::ProxyAuthenticationRequiredError:
debug << "QAbstractSocket::ProxyAuthenticationRequiredError";
break;
case QAbstractSocket::SslHandshakeFailedError:
debug << "QAbstractSocket::SslHandshakeFailedError";
break;
case QAbstractSocket::ProxyConnectionRefusedError:
debug << "QAbstractSocket::ProxyConnectionRefusedError";
break;

View file

@ -68,10 +68,9 @@ public:
UnsupportedSocketOperationError, /* 10 */
UnfinishedSocketOperationError,
ProxyAuthenticationRequiredError,
SslHandshakeFailedError,
ProxyConnectionRefusedError,
ProxyConnectionClosedError, /* 15 */
ProxyConnectionTimeoutError,
ProxyConnectionClosedError,
ProxyConnectionTimeoutError, /* 15 */
ProxyNotFoundError,
ProxyProtocolError,

View file

@ -1,139 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qsslkey.h"
QT_BEGIN_NAMESPACE
/*! \namespace QSsl
\brief The QSsl namespace declares enums common to all SSL classes in QtNetwork.
\since 4.3
\ingroup network
\ingroup ssl
\inmodule QtNetwork
*/
/*!
\enum QSsl::KeyType
Describes the two types of keys QSslKey supports.
\value PrivateKey A private key.
\value PublicKey A public key.
*/
/*!
\enum QSsl::KeyAlgorithm
Describes the different key algorithms supported by QSslKey.
\value Rsa The RSA algorithm.
\value Dsa The DSA algorithm.
\value Dh The DH algorithm.
*/
/*!
\enum QSsl::EncodingFormat
Describes supported encoding formats for certificates and keys.
\value Pem The PEM format.
\value Der The DER format.
*/
/*!
\enum QSsl::AlternateNameEntryType
Describes the key types for alternate name entries in QSslCertificate.
\value EmailEntry An email entry; the entry contains an email address that
the certificate is valid for.
\value DnsEntry A DNS host name entry; the entry contains a host name
entry that the certificate is valid for. The entry may contain wildcards.
\sa QSslCertificate::alternateSubjectNames()
*/
/*!
\enum QSsl::SslProtocol
Describes the protocol of the cipher.
\value SslV3 SSLv3
\value TlsV1 TLSv1
\value UnknownProtocol The cipher's protocol cannot be determined.
\value AnyProtocol The socket understands SSLv2, SSLv3, and TLSv1. This
value is used by QSslSocket only.
\value SecureProtocols The default option, using protocols known to be secure;
currently behaves like AnyProtocol.
Note: most servers using SSL understand both versions (2 and 3),
but it is recommended to use the latest version only for security
reasons. However, SSL and TLS are not compatible with each other:
if you get unexpected handshake failures, verify that you chose
the correct setting for your protocol.
*/
/*!
\enum QSsl::SslOption
Describes the options that can be used to control the details of
SSL behaviour. These options are generally used to turn features off
to work around buggy servers.
\value SslOptionDisableEmptyFragments Disables the insertion of empty
fragments into the data when using block ciphers. When enabled, this
prevents some attacks (such as the BEAST attack), however it is
incompatible with some servers.
\value SslOptionDisableSessionTickets Disables the SSL session ticket
extension. This can cause slower connection setup, however some servers
are not compatible with the extension.
\value SslOptionDisableCompression Disables the SSL compression
extension. When enabled, this allows the data being passed over SSL to
be compressed, however some servers are not compatible with this
extension.
\value SslOptionDisableServerNameIndication Disables the SSL server
name indication extension. When enabled, this tells the server the virtual
host being accessed allowing it to respond with the correct certificate.
\value SslOptionDisableLegacyRenegotiation Disables the older insecure
mechanism for renegotiating the connection parameters. When enabled, this
option can allow connections for legacy servers, but it introduces the
possibility that an attacker could inject plaintext into the SSL session.
By default, SslOptionDisableEmptyFragments is turned on since this causes
problems with a large number of servers. SslOptionDisableLegacyRenegotiation
is also turned on, since it introduces a security risk.
SslOptionDisableCompression is turned on to prevent the attack publicised by
CRIME. The other options are turned off.
Note: Availability of above options depends on the version of the SSL
backend in use.
*/
QT_END_NAMESPACE

View file

@ -1,77 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSL_H
#define QSSL_H
#include <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
namespace QSsl {
enum KeyType {
PrivateKey,
PublicKey
};
enum EncodingFormat {
Pem,
Der
};
enum KeyAlgorithm {
Rsa,
Dsa,
Dh
};
enum AlternateNameEntryType {
EmailEntry,
DnsEntry
};
enum SslProtocol {
SslV3,
TlsV1, // ### Qt 5: rename to TlsV1_0 or so
AnyProtocol,
SecureProtocols,
UnknownProtocol = -1
};
enum SslOption {
SslOptionDisableEmptyFragments = 0x01,
SslOptionDisableSessionTickets = 0x02,
SslOptionDisableCompression = 0x04,
SslOptionDisableServerNameIndication = 0x08,
SslOptionDisableLegacyRenegotiation = 0x10
};
Q_DECLARE_FLAGS(SslOptions, SslOption)
}
Q_DECLARE_OPERATORS_FOR_FLAGS(QSsl::SslOptions)
QT_END_NAMESPACE
#endif // QSSL_H

View file

@ -1,957 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QSslCertificate
\brief The QSslCertificate class provides a convenient API for an X509 certificate.
\since 4.3
\reentrant
\ingroup network
\ingroup ssl
\inmodule QtNetwork
QSslCertificate stores an X509 certificate, and is commonly used
to verify the identity and store information about the local host,
a remotely connected peer, or a trusted third party Certificate
Authority.
There are many ways to construct a QSslCertificate. The most
common way is to call QSslSocket::peerCertificate(), which returns
a QSslCertificate object, or QSslSocket::peerCertificateChain(),
which returns a list of them. You can also load certificates from
a DER (binary) or PEM (Base64) encoded bundle, typically stored as
one or more local files, or in a Qt Resource.
You can call isNull() to check if your certificate is null. By
default, QSslCertificate constructs a null certificate. To check
if the certificate is valid, call isValid(). A null certificate is
invalid, but an invalid certificate is not necessarily null. If
you want to reset all contents in a certificate, call clear().
After loading a certificate, you can find information about the
certificate, its subject, and its issuer, by calling one of the
many accessor functions, including version(), serialNumber(),
issuerInfo() and subjectInfo(). You can call effectiveDate() and
expiryDate() to check when the certificate starts being
effective and when it expires.
The publicKey() function returns the certificate
subject's public key as a QSslKey. You can call issuerInfo() or
subjectInfo() to get detailed information about the certificate
issuer and its subject.
Internally, QSslCertificate is stored as an X509 structure. You
can access this handle by calling handle(), but the results are
likely to not be portable.
\sa QSslSocket, QSslKey, QSslCipher, QSslError
*/
/*!
\enum QSslCertificate::SubjectInfo
Describes keys that you can pass to QSslCertificate::issuerInfo() or
QSslCertificate::subjectInfo() to get information about the certificate
issuer or subject.
\value Organization "O" The name of the organization.
\value CommonName "CN" The common name; most often this is used to store
the host name.
\value LocalityName "L" The locality.
\value OrganizationalUnitName "OU" The organizational unit name.
\value CountryName "C" The country.
\value StateOrProvinceName "ST" The state or province.
*/
#include "qsslsocket_openssl_p.h"
#include "qsslcertificate.h"
#include "qsslcertificate_p.h"
#include "qsslkey.h"
#include "qsslkey_p.h"
#include "qatomic.h"
#include "qdatetime.h"
#include "qdebug.h"
#include "qdir.h"
#include "qdiriterator.h"
#include "qfile.h"
#include "qmap.h"
#include "qmutex.h"
#include "qmutexpool_p.h"
#include "qstring.h"
#include "qstringlist.h"
#include "qcorecommon_p.h"
#include "qcore_unix_p.h"
QT_BEGIN_NAMESPACE
// forward declaration
static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name);
/*!
Constructs a QSslCertificate by reading \a format encoded data
from \a device and using the first certificate found. You can
later call isNull() to see if \a device contained a certificate,
and if this certificate was loaded successfully.
*/
QSslCertificate::QSslCertificate(QIODevice *device, QSsl::EncodingFormat format)
: d(new QSslCertificatePrivate)
{
QSslSocketPrivate::ensureInitialized();
if (device)
d->init(device->readAll(), format);
}
/*!
Constructs a QSslCertificate by parsing the \a format encoded
\a data and using the first available certificate found. You can
later call isNull() to see if \a data contained a certificate,
and if this certificate was loaded successfully.
*/
QSslCertificate::QSslCertificate(const QByteArray &data, QSsl::EncodingFormat format)
: d(new QSslCertificatePrivate)
{
QSslSocketPrivate::ensureInitialized();
d->init(data, format);
}
/*!
Constructs an identical copy of \a other.
*/
QSslCertificate::QSslCertificate(const QSslCertificate &other) : d(other.d)
{
}
/*!
Destroys the QSslCertificate.
*/
QSslCertificate::~QSslCertificate()
{
}
/*!
Copies the contents of \a other into this certificate, making the two
certificates identical.
*/
QSslCertificate &QSslCertificate::operator=(const QSslCertificate &other)
{
d = other.d;
return *this;
}
/*!
Returns true if this certificate is the same as \a other; otherwise
returns false.
*/
bool QSslCertificate::operator==(const QSslCertificate &other) const
{
if (d == other.d)
return true;
if (d->null && other.d->null)
return true;
if (d->x509 && other.d->x509)
return X509_cmp(d->x509, other.d->x509) == 0;
return false;
}
/*!
\fn bool QSslCertificate::operator!=(const QSslCertificate &other) const
Returns true if this certificate is not the same as \a other; otherwise
returns false.
*/
/*!
Returns true if this is a null certificate (i.e., a certificate
with no contents); otherwise returns false.
By default, QSslCertificate constructs a null certificate.
\sa isValid(), clear()
*/
bool QSslCertificate::isNull() const
{
return d->null;
}
/*!
Returns true if this certificate is valid; otherwise returns
false.
Note: Currently, this function checks that the current
data-time is within the date-time range during which the
certificate is considered valid, and checks that the
certificate is not in a blacklist of fraudulent certificates.
\sa isNull()
*/
bool QSslCertificate::isValid() const
{
const QDateTime currentTime = QDateTime::currentDateTime();
return currentTime >= d->notValidBefore &&
currentTime <= d->notValidAfter &&
! QSslCertificatePrivate::isBlacklisted(*this);
}
/*!
Clears the contents of this certificate, making it a null
certificate.
\sa isNull()
*/
void QSslCertificate::clear()
{
if (isNull())
return;
d = new QSslCertificatePrivate;
}
/*!
Returns the certificate's version string.
*/
QByteArray QSslCertificate::version() const
{
std::lock_guard<std::recursive_mutex> lock(*QRecursiveMutexPool::globalInstanceGet(d.data()));
if (d->versionString.isEmpty() && d->x509) {
d->versionString = QByteArray::number(qlonglong(X509_get_version(d->x509)) + 1);
}
return d->versionString;
}
/*!
Returns the certificate's serial number string in decimal format.
In case the serial number cannot be converted to decimal format
(i.e. if it is bigger than 4294967295, which means it does not fit into 4 bytes),
its hexadecimal version is returned.
*/
QByteArray QSslCertificate::serialNumber() const
{
std::lock_guard<std::recursive_mutex> lock(*QRecursiveMutexPool::globalInstanceGet(d.data()));
if (d->serialNumberString.isEmpty() && d->x509) {
const ASN1_INTEGER *serialNumber = X509_get0_serialNumber(d->x509);
// if we cannot convert to a long, just output the hexadecimal number
if (serialNumber->length > 4) {
QByteArray hexString;
hexString.reserve(serialNumber->length * 3);
for (int a = 0; a < serialNumber->length; ++a) {
hexString += QByteArray::number(serialNumber->data[a], 16).rightJustified(2, '0');
hexString += ':';
}
hexString.chop(1);
d->serialNumberString = hexString;
} else {
d->serialNumberString = QByteArray::number(qlonglong(ASN1_INTEGER_get(serialNumber)));
}
}
return d->serialNumberString;
}
/*!
Returns a cryptographic digest of this certificate. By default,
an MD5 digest will be generated, but you can also specify a
custom \a algorithm.
*/
QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) const
{
return QCryptographicHash::hash(toDer(), algorithm);
}
static QString _q_SubjectInfoToString(QSslCertificate::SubjectInfo info)
{
QString str;
switch (info) {
case QSslCertificate::Organization: str = QLatin1String("O"); break;
case QSslCertificate::CommonName: str = QLatin1String("CN"); break;
case QSslCertificate::LocalityName: str = QLatin1String("L"); break;
case QSslCertificate::OrganizationalUnitName: str = QLatin1String("OU"); break;
case QSslCertificate::CountryName: str = QLatin1String("C"); break;
case QSslCertificate::StateOrProvinceName: str = QLatin1String("ST"); break;
}
return str;
}
/*!
\fn QString QSslCertificate::issuerInfo(SubjectInfo subject) const
Returns the issuer information for the \a subject from the
certificate, or an empty string if there is no information for
\a subject in the certificate.
\sa subjectInfo()
*/
QString QSslCertificate::issuerInfo(SubjectInfo info) const
{
std::lock_guard<std::recursive_mutex> lock(*QRecursiveMutexPool::globalInstanceGet(d.data()));
// lazy init
if (d->issuerInfo.isEmpty() && d->x509)
d->issuerInfo =
_q_mapFromX509Name(X509_get_issuer_name(d->x509));
return d->issuerInfo.value(_q_SubjectInfoToString(info));
}
/*!
Returns the issuer information for \a tag from the certificate,
or an empty string if there is no information for \a tag in the
certificate.
\sa subjectInfo()
*/
QString QSslCertificate::issuerInfo(const QByteArray &tag) const
{
std::lock_guard<std::recursive_mutex> lock(*QRecursiveMutexPool::globalInstanceGet(d.data()));
// lazy init
if (d->issuerInfo.isEmpty() && d->x509)
d->issuerInfo =
_q_mapFromX509Name(X509_get_issuer_name(d->x509));
return d->issuerInfo.value(QString::fromLatin1(tag));
}
/*!
\fn QString QSslCertificate::subjectInfo(SubjectInfo subject) const
Returns the information for the \a subject, or an empty string if
there is no information for \a subject in the certificate.
\sa issuerInfo()
*/
QString QSslCertificate::subjectInfo(SubjectInfo info) const
{
std::lock_guard<std::recursive_mutex> lock(*QRecursiveMutexPool::globalInstanceGet(d.data()));
// lazy init
if (d->subjectInfo.isEmpty() && d->x509)
d->subjectInfo =
_q_mapFromX509Name(X509_get_subject_name(d->x509));
return d->subjectInfo.value(_q_SubjectInfoToString(info));
}
/*!
Returns the subject information for \a tag, or an empty string if
there is no information for \a tag in the certificate.
\sa issuerInfo()
*/
QString QSslCertificate::subjectInfo(const QByteArray &tag) const
{
std::lock_guard<std::recursive_mutex> lock(*QRecursiveMutexPool::globalInstanceGet(d.data()));
// lazy init
if (d->subjectInfo.isEmpty() && d->x509)
d->subjectInfo =
_q_mapFromX509Name(X509_get_subject_name(d->x509));
return d->subjectInfo.value(QString::fromLatin1(tag));
}
/*!
Returns the list of alternative subject names for this
certificate. The alternate subject names typically contain host
names, optionally with wildcards, that are valid for this
certificate.
These names are tested against the connected peer's host name, if
either the subject information for \l CommonName doesn't define a
valid host name, or the subject info name doesn't match the peer's
host name.
\sa subjectInfo()
*/
QMultiMap<QSsl::AlternateNameEntryType, QString> QSslCertificate::alternateSubjectNames() const
{
QMultiMap<QSsl::AlternateNameEntryType, QString> result;
if (!d->x509)
return result;
STACK_OF(GENERAL_NAME) *altNames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(d->x509, NID_subject_alt_name, 0, 0);
if (altNames) {
for (int i = 0; i < sk_GENERAL_NAME_num(altNames); ++i) {
const GENERAL_NAME *genName = sk_GENERAL_NAME_value(altNames, i);
if (genName->type != GEN_DNS && genName->type != GEN_EMAIL)
continue;
int len = ASN1_STRING_length(genName->d.ia5);
if (len < 0 || len >= 8192) {
// broken name
continue;
}
const char *altNameStr = reinterpret_cast<const char *>(ASN1_STRING_get0_data(genName->d.ia5));
const QString altName = QString::fromLatin1(altNameStr, len);
if (genName->type == GEN_DNS)
result.insert(QSsl::DnsEntry, altName);
else if (genName->type == GEN_EMAIL)
result.insert(QSsl::EmailEntry, altName);
}
sk_pop_free((OPENSSL_STACK*)altNames, reinterpret_cast<void(*)(void*)>(sk_free));
}
return result;
}
/*!
Returns the date-time that the certificate becomes valid, or an
empty QDateTime if this is a null certificate.
\sa expiryDate()
*/
QDateTime QSslCertificate::effectiveDate() const
{
return d->notValidBefore;
}
/*!
Returns the date-time that the certificate expires, or an empty
QDateTime if this is a null certificate.
\sa effectiveDate()
*/
QDateTime QSslCertificate::expiryDate() const
{
return d->notValidAfter;
}
/*!
Returns a pointer to the native certificate handle, if there is
one, or a null pointer otherwise.
You can use this handle, together with the native API, to access
extended information about the certificate.
\warning Use of this function has a high probability of being
non-portable, and its return value may vary from platform to
platform or change from minor release to minor release.
*/
Qt::HANDLE QSslCertificate::handle() const
{
return Qt::HANDLE(d->x509);
}
/*!
Returns the certificate subject's public key.
*/
QSslKey QSslCertificate::publicKey() const
{
if (!d->x509)
return QSslKey();
QSslKey key;
key.d->type = QSsl::PublicKey;
X509_PUBKEY *xkey = X509_get_X509_PUBKEY(d->x509);
EVP_PKEY *pkey = X509_PUBKEY_get(xkey);
Q_ASSERT(pkey);
const int key_id = EVP_PKEY_base_id(pkey);
if (key_id == EVP_PKEY_RSA) {
key.d->rsa = EVP_PKEY_get1_RSA(pkey);
key.d->algorithm = QSsl::Rsa;
key.d->isNull = false;
} else if (key_id == EVP_PKEY_DSA) {
key.d->dsa = EVP_PKEY_get1_DSA(pkey);
key.d->algorithm = QSsl::Dsa;
key.d->isNull = false;
} else if (key_id == EVP_PKEY_DH) {
key.d->dh = EVP_PKEY_get1_DH(pkey);
key.d->algorithm = QSsl::Dh;
key.d->isNull = false;
} else {
// error?
}
EVP_PKEY_free(pkey);
return key;
}
/*!
Returns this certificate converted to a PEM (Base64) encoded
representation.
*/
QByteArray QSslCertificate::toPem() const
{
if (!d->x509)
return QByteArray();
return d->QByteArray_from_X509(d->x509, QSsl::Pem);
}
/*!
Returns this certificate converted to a DER (binary) encoded
representation.
*/
QByteArray QSslCertificate::toDer() const
{
if (!d->x509)
return QByteArray();
return d->QByteArray_from_X509(d->x509, QSsl::Der);
}
/*!
Searches all files in the \a path for certificates encoded in the
specified \a format and returns them in a list. \e must be a file or a
pattern matching one or more files, as specified by \a syntax.
Example:
\snippet doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp 0
\sa fromData()
*/
QList<QSslCertificate> QSslCertificate::fromPath(const QString &path,
QSsl::EncodingFormat format,
QRegExp::PatternSyntax syntax)
{
// $, (,), *, +, ., ?, [, ,], ^, {, | and }.
int pos = -1;
if (syntax == QRegExp::Wildcard)
pos = path.indexOf(QRegExp(QLatin1String("[^\\][\\*\\?\\[\\]]")));
else if (syntax != QRegExp::FixedString)
pos = path.indexOf(QRegExp(QLatin1String("[^\\][\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\}\\|]")));
QString pathPrefix = path.left(pos); // == path if pos < 0
if (pos != -1)
pathPrefix = pathPrefix.left(pathPrefix.lastIndexOf(QLatin1Char('/')));
// Special case - if the prefix ends up being nothing, use "." instead and
// chop off the first two characters from the glob'ed paths.
int startIndex = 0;
if (pathPrefix.trimmed().isEmpty()) {
if(path.startsWith(QLatin1Char('/'))) {
pathPrefix = path.left(path.indexOf(QRegExp(QLatin1String("[\\*\\?\\[]"))));
pathPrefix = path.left(path.lastIndexOf(QLatin1Char('/')));
} else {
startIndex = 2;
pathPrefix = QLatin1String(".");
}
}
// The path is a file.
if (pos == -1 && QStatInfo(pathPrefix).isFile()) {
QFile file(pathPrefix);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
return QSslCertificate::fromData(file.readAll(),format);
return QList<QSslCertificate>();
}
// The path can be a file or directory.
QList<QSslCertificate> certs;
QRegExp pattern(path, Qt::CaseSensitive, syntax);
QDirIterator it(pathPrefix, QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
while (it.hasNext()) {
QString filePath = startIndex == 0 ? it.next() : it.next().mid(startIndex);
if (!pattern.exactMatch(filePath))
continue;
QFile file(filePath);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
certs += QSslCertificate::fromData(file.readAll(),format);
}
return certs;
}
/*!
Searches for and parses all certificates in \a device that are
encoded in the specified \a format and returns them in a list of
certificates.
\sa fromData()
*/
QList<QSslCertificate> QSslCertificate::fromDevice(QIODevice *device, QSsl::EncodingFormat format)
{
if (!device) {
qWarning("QSslCertificate::fromDevice: cannot read from a null device");
return QList<QSslCertificate>();
}
return fromData(device->readAll(), format);
}
/*!
Searches for and parses all certificates in \a data that are
encoded in the specified \a format and returns them in a list of
certificates.
\sa fromDevice()
*/
QList<QSslCertificate> QSslCertificate::fromData(const QByteArray &data, QSsl::EncodingFormat format)
{
return (format == QSsl::Pem)
? QSslCertificatePrivate::certificatesFromPem(data)
: QSslCertificatePrivate::certificatesFromDer(data);
}
void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat format)
{
if (!data.isEmpty()) {
QList<QSslCertificate> certs = (format == QSsl::Pem)
? certificatesFromPem(data, 1)
: certificatesFromDer(data, 1);
if (!certs.isEmpty()) {
*this = *certs.first().d;
if (x509)
x509 = X509_dup(x509);
}
}
}
#define BEGINCERTSTRING "-----BEGIN CERTIFICATE-----"
#define ENDCERTSTRING "-----END CERTIFICATE-----"
// ### refactor against QSsl::pemFromDer() etc. (to avoid redundant implementations)
QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format)
{
if (!x509) {
qWarning("QSslSocketBackendPrivate::X509_to_QByteArray: null X509");
return QByteArray();
}
// Use i2d_X509 to convert the X509 to an array.
int length = i2d_X509(x509, 0);
QByteArray array(length, Qt::Uninitialized);
char *data = array.data();
char **dataP = &data;
unsigned char **dataPu = (unsigned char **)dataP;
if (i2d_X509(x509, dataPu) < 0)
return QByteArray();
if (format == QSsl::Der)
return array;
// Convert to Base64 - wrap at 64 characters.
array = array.toBase64();
QByteArray tmp;
for (int i = 0; i <= array.size() - 64; i += 64) {
tmp += QByteArray::fromRawData(array.data() + i, 64);
tmp += '\n';
}
if (int remainder = array.size() % 64) {
tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder);
tmp += '\n';
}
return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n";
}
static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name)
{
QMap<QString, QString> info;
for (int i = 0; i < X509_NAME_entry_count(name); ++i) {
X509_NAME_ENTRY *e = X509_NAME_get_entry(name, i);
const char *obj = OBJ_nid2sn(OBJ_obj2nid(X509_NAME_ENTRY_get_object(e)));
unsigned char *data = 0;
int size = ASN1_STRING_to_UTF8(&data, X509_NAME_ENTRY_get_data(e));
info[QString::fromUtf8(obj)] = QString::fromUtf8((char*)data, size);
OPENSSL_free(data);
}
return info;
}
//==============================================================================
// contributed by Jay Case of Sarvega, Inc.; http://sarvega.com/
// Based on X509_cmp_time() for intitial buffer hacking.
//==============================================================================
QDateTime _q_getTimeFromASN1(const ASN1_TIME *aTime)
{
size_t lTimeLength = aTime->length;
char *pString = (char *) aTime->data;
if (aTime->type == V_ASN1_UTCTIME) {
QSTACKARRAY(char, lBuffer, 24);
char *pBuffer = lBuffer;
if ((lTimeLength < 11) || (lTimeLength > 17))
return QDateTime();
memcpy(pBuffer, pString, 10);
pBuffer += 10;
pString += 10;
if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
*pBuffer++ = '0';
*pBuffer++ = '0';
} else {
*pBuffer++ = *pString++;
*pBuffer++ = *pString++;
// Skip any fractional seconds...
if (*pString == '.') {
pString++;
while ((*pString >= '0') && (*pString <= '9'))
pString++;
}
}
*pBuffer++ = 'Z';
*pBuffer++ = '\0';
time_t lSecondsFromUCT;
if (*pString == 'Z') {
lSecondsFromUCT = 0;
} else {
if ((*pString != '+') && (*pString != '-'))
return QDateTime();
lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
lSecondsFromUCT *= 60;
if (*pString == '-')
lSecondsFromUCT = -lSecondsFromUCT;
}
tm lTime;
lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
if (lTime.tm_year < 50)
lTime.tm_year += 100; // RFC 2459
QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
QDateTime result(resDate, resTime, Qt::UTC);
result = result.addSecs(lSecondsFromUCT);
return result;
} else if (aTime->type == V_ASN1_GENERALIZEDTIME) {
if (lTimeLength < 15)
return QDateTime(); // hopefully never triggered
// generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2)
tm lTime;
lTime.tm_sec = ((pString[12] - '0') * 10) + (pString[13] - '0');
lTime.tm_min = ((pString[10] - '0') * 10) + (pString[11] - '0');
lTime.tm_hour = ((pString[8] - '0') * 10) + (pString[9] - '0');
lTime.tm_mday = ((pString[6] - '0') * 10) + (pString[7] - '0');
lTime.tm_mon = (((pString[4] - '0') * 10) + (pString[5] - '0'));
lTime.tm_year = ((pString[0] - '0') * 1000) + ((pString[1] - '0') * 100) +
((pString[2] - '0') * 10) + (pString[3] - '0');
QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday);
QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
QDateTime result(resDate, resTime, Qt::UTC);
return result;
} else {
qWarning("unsupported date format detected");
return QDateTime();
}
}
QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509)
{
QSslCertificate certificate;
if (!x509 || !QSslSocket::supportsSsl())
return certificate;
ASN1_TIME *nbef = X509_get_notBefore(x509);
ASN1_TIME *naft = X509_get_notAfter(x509);
certificate.d->notValidBefore = _q_getTimeFromASN1(nbef);
certificate.d->notValidAfter = _q_getTimeFromASN1(naft);
certificate.d->null = false;
certificate.d->x509 = X509_dup(x509);
return certificate;
}
static bool matchLineFeed(const QByteArray &pem, int *offset)
{
char ch = 0;
// ignore extra whitespace at the end of the line
while (*offset < pem.size() && (ch = pem.at(*offset)) == ' ')
++*offset;
if (ch == '\n') {
*offset += 1;
return true;
}
if (ch == '\r' && pem.size() > (*offset + 1) && pem.at(*offset + 1) == '\n') {
*offset += 2;
return true;
}
return false;
}
QList<QSslCertificate> QSslCertificatePrivate::certificatesFromPem(const QByteArray &pem, int count)
{
QList<QSslCertificate> certificates;
QSslSocketPrivate::ensureInitialized();
int offset = 0;
while (count == -1 || certificates.size() < count) {
int startPos = pem.indexOf(BEGINCERTSTRING, offset);
if (startPos == -1)
break;
startPos += sizeof(BEGINCERTSTRING) - 1;
if (!matchLineFeed(pem, &startPos))
break;
int endPos = pem.indexOf(ENDCERTSTRING, startPos);
if (endPos == -1)
break;
offset = endPos + sizeof(ENDCERTSTRING) - 1;
if (offset < pem.size() && !matchLineFeed(pem, &offset))
break;
QByteArray decoded = QByteArray::fromBase64(
QByteArray::fromRawData(pem.data() + startPos, endPos - startPos));
const unsigned char *data = reinterpret_cast<const unsigned char *>(decoded.constData());
if (X509 *x509 = d2i_X509(0, &data, decoded.size())) {
certificates << QSslCertificate_from_X509(x509);
X509_free(x509);
}
}
return certificates;
}
QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteArray &der, int count)
{
QList<QSslCertificate> certificates;
QSslSocketPrivate::ensureInitialized();
const unsigned char *data = reinterpret_cast<const unsigned char *>(der.constData());
int size = der.size();
while (count == -1 || certificates.size() < count) {
if (X509 *x509 = d2i_X509(0, &data, size)) {
certificates << QSslCertificate_from_X509(x509);
X509_free(x509);
} else {
break;
}
size -= ((char *)data - der.data());
}
return certificates;
}
// These certificates are known to be fraudulent and were created during the comodo
// compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html
static const struct certBlacklistTblData {
const char* const serial;
const char* name;
} certBlacklistTbl[] = {
{ "04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e", "mail.google.com" }, // Comodo
{ "f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06", "www.google.com" }, // Comodo
{ "d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3", "login.yahoo.com" }, // Comodo
{ "39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29", "login.yahoo.com" }, // Comodo
{ "3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71", "login.yahoo.com" }, // Comodo
{ "e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47", "login.skype.com" }, // Comodo
{ "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43", "addons.mozilla.org" }, // Comodo
{ "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0", "login.live.com" }, // Comodo
{ "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0", "global trustee" }, // Comodo
{ "05:e2:e6:a4:cd:09:ea:54:d6:65:b0:75:fe:22:a2:56", "*.google.com" }, // leaf certificate issued by DigiNotar
{ "0c:76:da:9c:91:0c:4e:2c:9e:fe:15:d0:58:93:3c:4c", "DigiNotar Root CA" }, // DigiNotar root
{ "f1:4a:13:f4:87:2b:56:dc:39:df:84:ca:7a:a1:06:49", "DigiNotar Services CA" }, // DigiNotar intermediate signed by DigiNotar Root
{ "36:16:71:55:43:42:1b:9d:e6:cb:a3:64:41:df:24:38", "DigiNotar Services 1024 CA" }, // DigiNotar intermediate signed by DigiNotar Root
{ "0a:82:bd:1e:14:4e:88:14:d7:5b:1a:55:27:be:bf:3e", "DigiNotar Root CA G2" }, // other DigiNotar Root CA
{ "a4:b6:ce:e3:2e:d3:35:46:26:3c:b3:55:3a:a8:92:21", "CertiID Enterprise Certificate Authority" }, // DigiNotar intermediate signed by "DigiNotar Root CA G2"
{ "5b:d5:60:9c:64:17:68:cf:21:0e:35:fd:fb:05:ad:41", "DigiNotar Qualified CA" }, // DigiNotar intermediate signed by DigiNotar Root
{ "1184640176", "DigiNotar Services 1024 CA" }, // DigiNotar intermediate cross-signed by Entrust
{ "120000525", "DigiNotar Cyber CA" }, // DigiNotar intermediate cross-signed by CyberTrust
{ "120000505", "DigiNotar Cyber CA" }, // DigiNotar intermediate cross-signed by CyberTrust
{ "120000515", "DigiNotar Cyber CA" }, // DigiNotar intermediate cross-signed by CyberTrust
{ "20015536", "DigiNotar PKIoverheid CA Overheid en Bedrijven" }, // DigiNotar intermediate cross-signed by the Dutch government
{ "20001983", "DigiNotar PKIoverheid CA Organisatie - G2" }, // DigiNotar intermediate cross-signed by the Dutch government
{ "d6:d0:29:77:f1:49:fd:1a:83:f2:b9:ea:94:8c:5c:b4", "DigiNotar Extended Validation CA" }, // DigiNotar intermediate signed by DigiNotar EV Root
{ "1e:7d:7a:53:3d:45:30:41:96:40:0f:71:48:1f:45:04", "DigiNotar Public CA 2025" }, // DigiNotar intermediate
// "(has not been seen in the wild so far)", "DigiNotar Public CA - G2", // DigiNotar intermediate
// "(has not been seen in the wild so far)", "Koninklijke Notariele Beroepsorganisatie CA", // compromised during DigiNotar breach
// "(has not been seen in the wild so far)", "Stichting TTP Infos CA," // compromised during DigiNotar breach
{ "1184640175", "DigiNotar Root CA" }, // DigiNotar intermediate cross-signed by Entrust
{ "1184644297", "DigiNotar Root CA" }, // DigiNotar intermediate cross-signed by Entrust
{ "120001705", "Digisign Server ID (Enrich)" }, // (Malaysian) Digicert Sdn. Bhd. cross-signed by Verizon CyberTrust
{ "1276011370", "Digisign Server ID - (Enrich)" }, // (Malaysian) Digicert Sdn. Bhd. cross-signed by Entrust
{ "72:03:21:05:c5:0c:08:57:3d:8e:a5:30:4e:fe:e8:b0", "UTN-USERFirst-Hardware" }, // comodogate test certificate
{ "41", "MD5 Collisions Inc. (http://www.phreedom.org/md5)" }, // http://www.phreedom.org/research/rogue-ca/
{ "2087", "*.EGO.GOV.TR" }, // Turktrust mis-issued intermediate certificate
{ "2148", "e-islem.kktcmerkezbankasi.org" }, // Turktrust mis-issued intermediate certificate
{ "204199", "AC DG Tr\xC3\xA9sor SSL" }, // intermediate certificate linking back to ANSSI French National Security Agency
{ "10115", "NIC Certifying Authority" }, // intermediate certificate from NIC India (2007)
{ "10130", "NIC CA 2011" }, // intermediate certificate from NIC India (2011)
{ "10161", "NIC CA 2014" } // intermediate certificate from NIC India (2014)
};
static const qint16 certBlacklistTblSize = sizeof(certBlacklistTbl) / sizeof(certBlacklistTblData);
bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate)
{
for (qint16 i = 0; i < certBlacklistTblSize; i++) {
QString blacklistedCommonName = QString::fromUtf8(certBlacklistTbl[i].name);
if (certificate.serialNumber() == certBlacklistTbl[i].serial &&
(certificate.subjectInfo(QSslCertificate::CommonName) == blacklistedCommonName ||
certificate.issuerInfo(QSslCertificate::CommonName) == blacklistedCommonName))
return true;
}
return false;
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QSslCertificate &certificate)
{
debug << "QSslCertificate("
<< certificate.version()
<< ',' << certificate.serialNumber()
<< ',' << certificate.digest().toBase64()
<< ',' << certificate.issuerInfo(QSslCertificate::Organization)
<< ',' << certificate.subjectInfo(QSslCertificate::Organization)
<< ',' << certificate.alternateSubjectNames()
#ifndef QT_NO_TEXTSTREAM
<< ',' << certificate.effectiveDate()
<< ',' << certificate.expiryDate()
#endif
<< ')';
return debug;
}
QDebug operator<<(QDebug debug, QSslCertificate::SubjectInfo info)
{
switch (info) {
case QSslCertificate::Organization: debug << "Organization"; break;
case QSslCertificate::CommonName: debug << "CommonName"; break;
case QSslCertificate::CountryName: debug << "CountryName"; break;
case QSslCertificate::LocalityName: debug << "LocalityName"; break;
case QSslCertificate::OrganizationalUnitName: debug << "OrganizationalUnitName"; break;
case QSslCertificate::StateOrProvinceName: debug << "StateOrProvinceName"; break;
}
return debug;
}
#endif
QT_END_NAMESPACE

View file

@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLCERTIFICATE_H
#define QSSLCERTIFICATE_H
#include <QtCore/qnamespace.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qregexp.h>
#include <QtCore/qsharedpointer.h>
#include <QtNetwork/qssl.h>
#include <QtNetwork/qcryptographichash.h>
QT_BEGIN_NAMESPACE
class QDateTime;
class QIODevice;
class QSslKey;
class QStringList;
template <typename T, typename U> class QMultiMap;
class QSslCertificatePrivate;
class Q_NETWORK_EXPORT QSslCertificate
{
public:
enum SubjectInfo {
Organization,
CommonName,
LocalityName,
OrganizationalUnitName,
CountryName,
StateOrProvinceName
};
QSslCertificate(QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem);
QSslCertificate( // ### s/encoded/data (to be consistent with signature in .cpp file) ?
const QByteArray &encoded = QByteArray(), QSsl::EncodingFormat format = QSsl::Pem);
QSslCertificate(const QSslCertificate &other);
~QSslCertificate();
QSslCertificate &operator=(const QSslCertificate &other);
bool operator==(const QSslCertificate &other) const;
inline bool operator!=(const QSslCertificate &other) const { return !operator==(other); }
bool isNull() const;
bool isValid() const;
void clear();
// Certificate info
QByteArray version() const;
QByteArray serialNumber() const;
QByteArray digest(QCryptographicHash::Algorithm algorithm = QCryptographicHash::Md5) const;
QString issuerInfo(SubjectInfo info) const;
QString issuerInfo(const QByteArray &tag) const;
QString subjectInfo(SubjectInfo info) const;
QString subjectInfo(const QByteArray &tag) const;
QMultiMap<QSsl::AlternateNameEntryType, QString> alternateSubjectNames() const;
QDateTime effectiveDate() const;
QDateTime expiryDate() const;
QSslKey publicKey() const;
QByteArray toPem() const;
QByteArray toDer() const;
static QList<QSslCertificate> fromPath(
const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
static QList<QSslCertificate> fromDevice(
QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem);
static QList<QSslCertificate> fromData(
const QByteArray &data, QSsl::EncodingFormat format = QSsl::Pem);
Qt::HANDLE handle() const;
private:
QExplicitlySharedDataPointer<QSslCertificatePrivate> d;
friend class QSslCertificatePrivate;
friend class QSslSocketBackendPrivate;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslCertificate &certificate);
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, QSslCertificate::SubjectInfo info);
#endif
QT_END_NAMESPACE
#endif

View file

@ -1,88 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLCERTIFICATE_P_H
#define QSSLCERTIFICATE_P_H
#include "qsslcertificate.h"
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of the QLibrary class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include "qsslsocket_p.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qmap.h>
#include <openssl/x509.h>
QT_BEGIN_NAMESPACE
class QSslCertificatePrivate
{
public:
QSslCertificatePrivate()
: null(true), x509(0)
{
QSslSocketPrivate::ensureInitialized();
}
~QSslCertificatePrivate()
{
if (x509)
X509_free(x509);
}
bool null;
QByteArray versionString;
QByteArray serialNumberString;
QMap<QString, QString> issuerInfo;
QMap<QString, QString> subjectInfo;
QDateTime notValidAfter;
QDateTime notValidBefore;
X509 *x509;
void init(const QByteArray &data, QSsl::EncodingFormat format);
static QByteArray QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format);
static QSslCertificate QSslCertificate_from_X509(X509 *x509);
static QList<QSslCertificate> certificatesFromPem(const QByteArray &pem, int count = -1);
static QList<QSslCertificate> certificatesFromDer(const QByteArray &der, int count = -1);
static bool isBlacklisted(const QSslCertificate &certificate);
friend class QSslSocketBackendPrivate;
QAtomicInt ref;
};
QT_END_NAMESPACE
#endif

View file

@ -1,218 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QSslCipher
\brief The QSslCipher class represents an SSL cryptographic cipher.
\since 4.3
\reentrant
\ingroup network
\ingroup ssl
\inmodule QtNetwork
QSslCipher stores information about one cryptographic cipher. It
is most commonly used with QSslSocket, either for configuring
which ciphers the socket can use, or for displaying the socket's
ciphers to the user.
\sa QSslSocket, QSslKey
*/
#include "qsslcipher.h"
#include "qsslcipher_p.h"
#include "qsslsocket.h"
#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/qdebug.h>
#endif
QT_BEGIN_NAMESPACE
/*!
Constructs an empty QSslCipher object.
*/
QSslCipher::QSslCipher()
: d(new QSslCipherPrivate)
{
}
/*!
Constructs a QSslCipher object for the cipher determined by \a
name and \a protocol. The constructor accepts only supported
ciphers (i.e., the \a name and \a protocol must identify a cipher
in the list of ciphers returned by
QSslSocket::supportedCiphers()).
You can call isNull() after construction to check if \a name and
\a protocol correctly identified a supported cipher.
*/
QSslCipher::QSslCipher(const QString &name, QSsl::SslProtocol protocol)
: d(new QSslCipherPrivate)
{
foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) {
if (cipher.name() == name && cipher.protocol() == protocol) {
*this = cipher;
break;
}
}
}
/*!
Constructs an identical copy of the \a other cipher.
*/
QSslCipher::QSslCipher(const QSslCipher &other)
: d(new QSslCipherPrivate)
{
*d.data() = *other.d.data();
}
/*!
Destroys the QSslCipher object.
*/
QSslCipher::~QSslCipher()
{
}
/*!
Copies the contents of \a other into this cipher, making the two
ciphers identical.
*/
QSslCipher &QSslCipher::operator=(const QSslCipher &other)
{
*d.data() = *other.d.data();
return *this;
}
/*!
Returns true if this cipher is the same as \a other; otherwise,
false is returned.
*/
bool QSslCipher::operator==(const QSslCipher &other) const
{
return d->name == other.d->name && d->protocol == other.d->protocol;
}
/*!
\fn bool QSslCipher::operator!=(const QSslCipher &other) const
Returns true if this cipher is not the same as \a other;
otherwise, false is returned.
*/
/*!
Returns true if this is a null cipher; otherwise returns false.
*/
bool QSslCipher::isNull() const
{
return d->isNull;
}
/*!
Returns the name of the cipher, or an empty QString if this is a null
cipher.
\sa isNull()
*/
QString QSslCipher::name() const
{
return d->name;
}
/*!
Returns the number of bits supported by the cipher.
\sa usedBits()
*/
int QSslCipher::supportedBits()const
{
return d->supportedBits;
}
/*!
Returns the number of bits used by the cipher.
\sa supportedBits()
*/
int QSslCipher::usedBits() const
{
return d->bits;
}
/*!
Returns the cipher's key exchange method as a QString.
*/
QString QSslCipher::keyExchangeMethod() const
{
return d->keyExchangeMethod;
}
/*!
Returns the cipher's authentication method as a QString.
*/
QString QSslCipher::authenticationMethod() const
{
return d->authenticationMethod;
}
/*!
Returns the cipher's encryption method as a QString.
*/
QString QSslCipher::encryptionMethod() const
{
return d->encryptionMethod;
}
/*!
Returns the cipher's protocol as a QString.
\sa protocol()
*/
QString QSslCipher::protocolString() const
{
return d->protocolString;
}
/*!
Returns the cipher's protocol type, or \l QSsl::UnknownProtocol if
QSslCipher is unable to determine the protocol (protocolString() may
contain more information).
\sa protocolString()
*/
QSsl::SslProtocol QSslCipher::protocol() const
{
return d->protocol;
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QSslCipher &cipher)
{
debug << "QSslCipher(name=" << qPrintable(cipher.name())
<< ", bits=" << cipher.usedBits()
<< ", proto=" << qPrintable(cipher.protocolString())
<< ')';
return debug;
}
#endif
QT_END_NAMESPACE

View file

@ -1,70 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLCIPHER_H
#define QSSLCIPHER_H
#include <QtCore/qstring.h>
#include <QtCore/qscopedpointer.h>
#include <QtNetwork/qssl.h>
QT_BEGIN_NAMESPACE
class QSslCipherPrivate;
class Q_NETWORK_EXPORT QSslCipher
{
public:
QSslCipher();
QSslCipher(const QString &name, QSsl::SslProtocol protocol);
QSslCipher(const QSslCipher &other);
~QSslCipher();
QSslCipher &operator=(const QSslCipher &other);
bool operator==(const QSslCipher &other) const;
inline bool operator!=(const QSslCipher &other) const { return !operator==(other); }
bool isNull() const;
QString name() const;
int supportedBits() const;
int usedBits() const;
QString keyExchangeMethod() const;
QString authenticationMethod() const;
QString encryptionMethod() const;
QString protocolString() const;
QSsl::SslProtocol protocol() const;
private:
QScopedPointer<QSslCipherPrivate> d;
friend class QSslSocketBackendPrivate;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslCipher &cipher);
#endif
QT_END_NAMESPACE
#endif

View file

@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLCIPHER_P_H
#define QSSLCIPHER_P_H
#include "qstring.h"
QT_BEGIN_NAMESPACE
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of the QLibrary class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
class QSslCipherPrivate
{
public:
QSslCipherPrivate()
: isNull(true), supportedBits(0), bits(0),
exportable(false), protocol(QSsl::UnknownProtocol)
{
}
bool isNull;
QString name;
int supportedBits;
int bits;
QString keyExchangeMethod;
QString authenticationMethod;
QString encryptionMethod;
bool exportable;
QString protocolString;
QSsl::SslProtocol protocol;
};
QT_END_NAMESPACE
#endif // QSSLCIPHER_P_H

View file

@ -1,551 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qsslconfiguration.h"
#include "qsslconfiguration_p.h"
#include "qsslsocket.h"
#include "qdebug.h"
QT_BEGIN_NAMESPACE
/*!
\class QSslConfiguration
\brief The QSslConfiguration class holds the configuration and state of an SSL connection
\since 4.4
\reentrant
\inmodule QtNetwork
\ingroup network
\ingroup ssl
QSslConfiguration is used by Qt networking classes to relay
information about an open SSL connection and to allow the
application to control certain features of that connection.
The settings that QSslConfiguration currently supports are:
\list
\o The SSL/TLS protocol to be used
\o The certificate to be presented to the peer during connection
and its associated private key
\o The ciphers allowed to be used for encrypting the connection
\o The list of Certificate Authorities certificates that are
used to validate the peer's certificate
\endlist
These settings are applied only during the connection
handshake. Setting them after the connection has been established
has no effect.
The state that QSslConfiguration supports are:
\list
\o The certificate the peer presented during handshake, along
with the chain leading to a CA certificate
\o The cipher used to encrypt this session
\endlist
The state can only be obtained once the SSL connection starts, but
not necessarily before it's done. Some settings may change during
the course of the SSL connection without need to restart it (for
instance, the cipher can be changed over time).
State in QSslConfiguration objects cannot be changed.
QSslConfiguration can be used with QSslSocket and the Network
Access API.
Note that changing settings in QSslConfiguration is not enough to
change the settings in the related SSL connection. You must call
setSslConfiguration on a modified QSslConfiguration object to
achieve that. The following example illustrates how to change the
protocol to TLSv1 in a QSslSocket object:
\snippet doc/src/snippets/code/src_network_ssl_qsslconfiguration.cpp 0
\sa QSsl::SslProtocol, QSslCertificate, QSslCipher, QSslKey
QSslSocket,
QSslSocket::sslConfiguration(), QSslSocket::setSslConfiguration()
*/
/*!
Constructs an empty SSL configuration. This configuration contains
no valid settings and the state will be empty. isNull() will
return true after this constructor is called.
Once any setter methods are called, isNull() will return false.
*/
QSslConfiguration::QSslConfiguration()
: d(new QSslConfigurationPrivate)
{
}
/*!
Copies the configuration and state of \a other. If \a other is
null, this object will be null too.
*/
QSslConfiguration::QSslConfiguration(const QSslConfiguration &other)
: d(other.d)
{
}
/*!
Releases any resources held by QSslConfiguration.
*/
QSslConfiguration::~QSslConfiguration()
{
// QSharedDataPointer deletes d for us if necessary
}
/*!
Copies the configuration and state of \a other. If \a other is
null, this object will be null too.
*/
QSslConfiguration &QSslConfiguration::operator=(const QSslConfiguration &other)
{
d = other.d;
return *this;
}
/*!
Returns true if this QSslConfiguration object is equal to \a
other.
Two QSslConfiguration objects are considered equal if they have
the exact same settings and state.
\sa operator!=()
*/
bool QSslConfiguration::operator==(const QSslConfiguration &other) const
{
if (d == other.d)
return true;
return d->peerCertificate == other.d->peerCertificate &&
d->peerCertificateChain == other.d->peerCertificateChain &&
d->localCertificate == other.d->localCertificate &&
d->privateKey == other.d->privateKey &&
d->sessionCipher == other.d->sessionCipher &&
d->ciphers == other.d->ciphers &&
d->caCertificates == other.d->caCertificates &&
d->protocol == other.d->protocol &&
d->peerVerifyMode == other.d->peerVerifyMode &&
d->peerVerifyDepth == other.d->peerVerifyDepth &&
d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
d->sslOptions == other.d->sslOptions;
}
/*!
\fn QSslConfiguration::operator!=(const QSslConfiguration &other) const
Returns true if this QSslConfiguration differs from \a other. Two
QSslConfiguration objects are considered different if any state or
setting is different.
\sa operator==()
*/
/*!
Returns true if this is a null QSslConfiguration object.
A QSslConfiguration object is null if it has been
default-constructed and no setter methods have been called.
\sa setProtocol(), setLocalCertificate(), setPrivateKey(),
setCiphers(), setCaCertificates()
*/
bool QSslConfiguration::isNull() const
{
return (d->protocol == QSsl::SecureProtocols &&
d->peerVerifyMode == QSslSocket::AutoVerifyPeer &&
d->peerVerifyDepth == 0 &&
d->allowRootCertOnDemandLoading == true &&
d->caCertificates.count() == 0 &&
d->ciphers.count() == 0 &&
d->localCertificate.isNull() &&
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
d->sslOptions == ( QSsl::SslOptionDisableEmptyFragments
|QSsl::SslOptionDisableLegacyRenegotiation
|QSsl::SslOptionDisableCompression));
}
/*!
Returns the protocol setting for this SSL configuration.
\sa setProtocol()
*/
QSsl::SslProtocol QSslConfiguration::protocol() const
{
return d->protocol;
}
/*!
Sets the protocol setting for this configuration to be \a
protocol.
Setting the protocol once the connection has already been
established has no effect.
\sa protocol()
*/
void QSslConfiguration::setProtocol(QSsl::SslProtocol protocol)
{
d->protocol = protocol;
}
/*!
Returns the verify mode. This mode decides whether QSslSocket should
request a certificate from the peer (i.e., the client requests a
certificate from the server, or a server requesting a certificate from the
client), and whether it should require that this certificate is valid.
The default mode is AutoVerifyPeer, which tells QSslSocket to use
VerifyPeer for clients, QueryPeer for servers.
\sa setPeerVerifyMode()
*/
QSslSocket::PeerVerifyMode QSslConfiguration::peerVerifyMode() const
{
return d->peerVerifyMode;
}
/*!
Sets the verify mode to \a mode. This mode decides whether QSslSocket
should request a certificate from the peer (i.e., the client requests a
certificate from the server, or a server requesting a certificate from the
client), and whether it should require that this certificate is valid.
The default mode is AutoVerifyPeer, which tells QSslSocket to use
VerifyPeer for clients, QueryPeer for servers.
\sa peerVerifyMode()
*/
void QSslConfiguration::setPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
{
d->peerVerifyMode = mode;
}
/*!
Returns the maximum number of certificates in the peer's certificate chain
to be checked during the SSL handshake phase, or 0 (the default) if no
maximum depth has been set, indicating that the whole certificate chain
should be checked.
The certificates are checked in issuing order, starting with the peer's
own certificate, then its issuer's certificate, and so on.
\sa setPeerVerifyDepth(), peerVerifyMode()
*/
int QSslConfiguration::peerVerifyDepth() const
{
return d->peerVerifyDepth;
}
/*!
Sets the maximum number of certificates in the peer's certificate chain to
be checked during the SSL handshake phase, to \a depth. Setting a depth of
0 means that no maximum depth is set, indicating that the whole
certificate chain should be checked.
The certificates are checked in issuing order, starting with the peer's
own certificate, then its issuer's certificate, and so on.
\sa peerVerifyDepth(), setPeerVerifyMode()
*/
void QSslConfiguration::setPeerVerifyDepth(int depth)
{
if (depth < 0) {
qWarning("QSslConfiguration::setPeerVerifyDepth: cannot set negative depth of %d", depth);
return;
}
d->peerVerifyDepth = depth;
}
/*!
Returns the certificate to be presented to the peer during the SSL
handshake process.
\sa setLocalCertificate()
*/
QSslCertificate QSslConfiguration::localCertificate() const
{
return d->localCertificate;
}
/*!
Sets the certificate to be presented to the peer during SSL
handshake to be \a certificate.
Setting the certificate once the connection has been established
has no effect.
A certificate is the means of identification used in the SSL
process. The local certificate is used by the remote end to verify
the local user's identity against its list of Certification
Authorities. In most cases, such as in HTTP web browsing, only
servers identify to the clients, so the client does not send a
certificate.
\sa localCertificate()
*/
void QSslConfiguration::setLocalCertificate(const QSslCertificate &certificate)
{
d->localCertificate = certificate;
}
/*!
Returns the peer's digital certificate (i.e., the immediate
certificate of the host you are connected to), or a null
certificate, if the peer has not assigned a certificate.
The peer certificate is checked automatically during the
handshake phase, so this function is normally used to fetch
the certificate for display or for connection diagnostic
purposes. It contains information about the peer, including
its host name, the certificate issuer, and the peer's public
key.
Because the peer certificate is set during the handshake phase, it
is safe to access the peer certificate from a slot connected to
the QSslSocket::sslErrors() signal, or the QSslSocket::encrypted()
signal.
If a null certificate is returned, it can mean the SSL handshake
failed, or it can mean the host you are connected to doesn't have
a certificate, or it can mean there is no connection.
If you want to check the peer's complete chain of certificates,
use peerCertificateChain() to get them all at once.
\sa peerCertificateChain(),
QSslSocket::sslErrors(), QSslSocket::ignoreSslErrors(
*/
QSslCertificate QSslConfiguration::peerCertificate() const
{
return d->peerCertificate;
}
/*!
Returns the peer's chain of digital certificates, starting with
the peer's immediate certificate and ending with the CA's
certificate.
Peer certificates are checked automatically during the handshake
phase. This function is normally used to fetch certificates for
display, or for performing connection diagnostics. Certificates
contain information about the peer and the certificate issuers,
including host name, issuer names, and issuer public keys.
Because the peer certificate is set during the handshake phase, it
is safe to access the peer certificate from a slot connected to
the QSslSocket::sslErrors() signal, or the QSslSocket::encrypted()
signal.
If an empty list is returned, it can mean the SSL handshake
failed, or it can mean the host you are connected to doesn't have
a certificate, or it can mean there is no connection.
If you want to get only the peer's immediate certificate, use
peerCertificate().
\sa peerCertificate(),
QSslSocket::sslErrors(), QSslSocket::ignoreSslErrors()
*/
QList<QSslCertificate> QSslConfiguration::peerCertificateChain() const
{
return d->peerCertificateChain;
}
/*!
Returns the socket's cryptographic \l {QSslCipher} {cipher}, or a
null cipher if the connection isn't encrypted. The socket's cipher
for the session is set during the handshake phase. The cipher is
used to encrypt and decrypt data transmitted through the socket.
The SSL infrastructure also provides functions for setting the
ordered list of ciphers from which the handshake phase will
eventually select the session cipher. This ordered list must be in
place before the handshake phase begins.
\sa ciphers(), setCiphers(), QSslSocket::supportedCiphers()
*/
QSslCipher QSslConfiguration::sessionCipher() const
{
return d->sessionCipher;
}
/*!
Returns the \l {QSslKey} {SSL key} assigned to this connection or
a null key if none has been assigned yet.
\sa setPrivateKey(), localCertificate()
*/
QSslKey QSslConfiguration::privateKey() const
{
return d->privateKey;
}
/*!
Sets the connection'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
SSL peers.
Both the key and the local certificate are required if you are
creating an SSL server socket. If you are creating an SSL client
socket, the key and local certificate are required if your client
must identify itself to an SSL server.
\sa privateKey(), setLocalCertificate()
*/
void QSslConfiguration::setPrivateKey(const QSslKey &key)
{
d->privateKey = key;
}
/*!
Returns this connection's current cryptographic cipher suite. This
list is used during the handshake phase for choosing a
session cipher. The returned list of ciphers is ordered by
descending preference. (i.e., the first cipher in the list is the
most preferred cipher). The session cipher will be the first one
in the list that is also supported by the peer.
By default, the handshake phase can choose any of the ciphers
supported by this system's SSL libraries, which may vary from
system to system. The list of ciphers supported by this system's
SSL libraries is returned by QSslSocket::supportedCiphers(). You can restrict
the list of ciphers used for choosing the session cipher for this
socket by calling setCiphers() with a subset of the supported
ciphers. You can revert to using the entire set by calling
setCiphers() with the list returned by QSslSocket::supportedCiphers().
\sa setCiphers(), QSslSocket::supportedCiphers()
*/
QList<QSslCipher> QSslConfiguration::ciphers() const
{
return d->ciphers;
}
/*!
Sets the cryptographic cipher suite for this socket to \a ciphers,
which must contain a subset of the ciphers in the list returned by
supportedCiphers().
Restricting the cipher suite must be done before the handshake
phase, where the session cipher is chosen.
\sa ciphers(), QSslSocket::supportedCiphers()
*/
void QSslConfiguration::setCiphers(const QList<QSslCipher> &ciphers)
{
d->ciphers = ciphers;
}
/*!
Returns this connection's CA certificate database. The CA certificate
database is used by the socket during the handshake phase to
validate the peer's certificate. It can be modified prior to the
handshake with setCaCertificates(), or with \l{QSslSocket}'s
\l{QSslSocket::}{addCaCertificate()} and
\l{QSslSocket::}{addCaCertificates()}.
\sa setCaCertificates()
*/
QList<QSslCertificate> QSslConfiguration::caCertificates() const
{
return d->caCertificates;
}
/*!
Sets this socket's CA certificate database to be \a certificates.
The certificate database must be set prior to the SSL handshake.
The CA certificate database is used by the socket during the
handshake phase to validate the peer's certificate.
\sa caCertificates()
*/
void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certificates)
{
d->caCertificates = certificates;
d->allowRootCertOnDemandLoading = false;
}
/*!
Enables or disables an SSL compatibility option.
\sa testSSlOption()
*/
void QSslConfiguration::setSslOption(QSsl::SslOption option, bool on)
{
if (on)
d->sslOptions |= option;
else
d->sslOptions &= ~option;
}
/*!
\since 4.8
Returns true if the specified SSL compatibility option is enabled.
\sa testSSlOption()
*/
bool QSslConfiguration::testSslOption(QSsl::SslOption option) const
{
return d->sslOptions & option;
}
/*!
Returns the default SSL configuration to be used in new SSL
connections.
The default SSL configuration consists of:
\list
\o no local certificate and no private key
\o protocol SecureProtocols (meaning either TLS 1.0 or SSL 3 will be used)
\o the system's default CA certificate list
\o the cipher list equal to the list of the SSL libraries'
supported SSL ciphers
\endlist
\sa QSslSocket::supportedCiphers(), setDefaultConfiguration()
*/
QSslConfiguration QSslConfiguration::defaultConfiguration()
{
return QSslConfigurationPrivate::defaultConfiguration();
}
/*!
Sets the default SSL configuration to be used in new SSL
connections to be \a configuration. Existing connections are not
affected by this call.
\sa QSslSocket::supportedCiphers(), defaultConfiguration()
*/
void QSslConfiguration::setDefaultConfiguration(const QSslConfiguration &configuration)
{
QSslConfigurationPrivate::setDefaultConfiguration(configuration);
}
QT_END_NAMESPACE

View file

@ -1,98 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLCONFIGURATION_H
#define QSSLCONFIGURATION_H
#include <QtCore/qshareddata.h>
#include <QtNetwork/qsslsocket.h>
#include <QtNetwork/qssl.h>
QT_BEGIN_NAMESPACE
template<typename T> class QList;
class QSslCertificate;
class QSslCipher;
class QSslKey;
class QSslConfigurationPrivate;
class Q_NETWORK_EXPORT QSslConfiguration
{
public:
QSslConfiguration();
QSslConfiguration(const QSslConfiguration &other);
~QSslConfiguration();
QSslConfiguration &operator=(const QSslConfiguration &other);
bool operator==(const QSslConfiguration &other) const;
inline bool operator!=(const QSslConfiguration &other) const
{ return !(*this == other); }
bool isNull() const; // ### Qt 5: remove; who would need this?
QSsl::SslProtocol protocol() const;
void setProtocol(QSsl::SslProtocol protocol);
// Verification
QSslSocket::PeerVerifyMode peerVerifyMode() const;
void setPeerVerifyMode(QSslSocket::PeerVerifyMode mode);
int peerVerifyDepth() const;
void setPeerVerifyDepth(int depth);
// Certificate & cipher configuration
QSslCertificate localCertificate() const;
void setLocalCertificate(const QSslCertificate &certificate);
QSslCertificate peerCertificate() const;
QList<QSslCertificate> peerCertificateChain() const;
QSslCipher sessionCipher() const;
// Private keys, for server sockets
QSslKey privateKey() const;
void setPrivateKey(const QSslKey &key);
// Cipher settings
QList<QSslCipher> ciphers() const;
void setCiphers(const QList<QSslCipher> &ciphers);
// Certificate Authority (CA) settings
QList<QSslCertificate> caCertificates() const;
void setCaCertificates(const QList<QSslCertificate> &certificates);
void setSslOption(QSsl::SslOption option, bool on);
bool testSslOption(QSsl::SslOption option) const;
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
private:
friend class QSslSocket;
friend class QSslConfigurationPrivate;
QSslConfiguration(QSslConfigurationPrivate *dd);
QSharedDataPointer<QSslConfigurationPrivate> d;
};
QT_END_NAMESPACE
#endif

View file

@ -1,87 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLCONFIGURATION_P_H
#define QSSLCONFIGURATION_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of the QSslSocket API. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include "qsslconfiguration.h"
#include "qlist.h"
#include "qsslcertificate.h"
#include "qsslcipher.h"
#include "qsslkey.h"
QT_BEGIN_NAMESPACE
class QSslConfigurationPrivate: public QSharedData
{
public:
QSslConfigurationPrivate()
: protocol(QSsl::SecureProtocols),
peerVerifyMode(QSslSocket::AutoVerifyPeer),
peerVerifyDepth(0),
allowRootCertOnDemandLoading(true),
sslOptions(QSsl::SslOptionDisableEmptyFragments
|QSsl::SslOptionDisableLegacyRenegotiation
|QSsl::SslOptionDisableCompression)
{ }
QSslCertificate peerCertificate;
QList<QSslCertificate> peerCertificateChain;
QSslCertificate localCertificate;
QSslKey privateKey;
QSslCipher sessionCipher;
QList<QSslCipher> ciphers;
QList<QSslCertificate> caCertificates;
QSsl::SslProtocol protocol;
QSslSocket::PeerVerifyMode peerVerifyMode;
int peerVerifyDepth;
bool allowRootCertOnDemandLoading;
QSsl::SslOptions sslOptions;
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
static void deepCopyDefaultConfiguration(QSslConfigurationPrivate *config);
};
// implemented here for inlining purposes
inline QSslConfiguration::QSslConfiguration(QSslConfigurationPrivate *dd)
: d(dd)
{
}
QT_END_NAMESPACE
#endif

View file

@ -1,280 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qsslerror.h"
#include "qsslsocket.h"
#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/qdebug.h>
#endif
/*!
\class QSslError
\brief The QSslError class provides an SSL error.
\since 4.3
\reentrant
\ingroup network
\ingroup ssl
\inmodule QtNetwork
QSslError provides a simple API for managing errors during QSslSocket's
SSL handshake.
\sa QSslSocket, QSslCertificate, QSslCipher
*/
/*!
\enum QSslError::SslError
Describes all recognized errors that can occur during an SSL handshake.
\value NoError
\value UnableToGetIssuerCertificate
\value UnableToDecryptCertificateSignature
\value UnableToDecodeIssuerPublicKey
\value CertificateSignatureFailed
\value CertificateNotYetValid
\value CertificateExpired
\value InvalidNotBeforeField
\value InvalidNotAfterField
\value SelfSignedCertificate
\value SelfSignedCertificateInChain
\value UnableToGetLocalIssuerCertificate
\value UnableToVerifyFirstCertificate
\value CertificateRevoked
\value InvalidCaCertificate
\value PathLengthExceeded
\value InvalidPurpose
\value CertificateUntrusted
\value CertificateRejected
\value SubjectIssuerMismatch
\value AuthorityIssuerSerialNumberMismatch
\value NoPeerCertificate
\value HostNameMismatch
\value UnspecifiedError
\value NoSslSupport
\value CertificateBlacklisted
\sa QSslError::errorString()
*/
QT_BEGIN_NAMESPACE
class QSslErrorPrivate
{
public:
QSslError::SslError error;
QSslCertificate certificate;
};
/*!
Constructs a QSslError object with no error and default certificate.
*/
// RVCT compiler in debug build does not like about default values in const-
// So as an workaround we define all constructor overloads here explicitly
QSslError::QSslError()
: d(new QSslErrorPrivate)
{
d->error = QSslError::NoError;
d->certificate = QSslCertificate();
}
/*!
Constructs a QSslError object. The argument specifies the \a
error that occurred.
*/
QSslError::QSslError(SslError error)
: d(new QSslErrorPrivate)
{
d->error = error;
d->certificate = QSslCertificate();
}
/*!
Constructs a QSslError object. The two arguments specify the \a
error that occurred, and which \a certificate the error relates to.
\sa QSslCertificate
*/
QSslError::QSslError(SslError error, const QSslCertificate &certificate)
: d(new QSslErrorPrivate)
{
d->error = error;
d->certificate = certificate;
}
/*!
Constructs an identical copy of \a other.
*/
QSslError::QSslError(const QSslError &other)
: d(new QSslErrorPrivate)
{
d->error = other.d->error;
d->certificate = other.d->certificate;
}
/*!
Destroys the QSslError object.
*/
QSslError::~QSslError()
{
delete d;
}
/*!
\since 4.4
Assigns the contents of \a other to this error.
*/
QSslError &QSslError::operator=(const QSslError &other)
{
d->error = other.d->error;
d->certificate = other.d->certificate;
return *this;
}
/*!
\since 4.4
Returns true if this error is equal to \a other; otherwise returns false.
*/
bool QSslError::operator==(const QSslError &other) const
{
return d->error == other.d->error
&& d->certificate == other.d->certificate;
}
/*!
\fn bool QSslError::operator!=(const QSslError &other) const
\since 4.4
Returns true if this error is not equal to \a other; otherwise returns
false.
*/
/*!
Returns the type of the error.
\sa errorString(), certificate()
*/
QSslError::SslError QSslError::error() const
{
return d->error;
}
/*!
Returns a short localized human-readable description of the error.
\sa error(), certificate()
*/
QString QSslError::errorString() const
{
switch (d->error) {
case QSslError::NoError:
return QSslSocket::tr("No error");
case QSslError::UnableToGetIssuerCertificate:
return QSslSocket::tr("The issuer certificate could not be found");
case QSslError::UnableToDecryptCertificateSignature:
return QSslSocket::tr("The certificate signature could not be decrypted");
case QSslError::UnableToDecodeIssuerPublicKey:
return QSslSocket::tr("The public key in the certificate could not be read");
case QSslError::CertificateSignatureFailed:
return QSslSocket::tr("The signature of the certificate is invalid");
case QSslError::CertificateNotYetValid:
return QSslSocket::tr("The certificate is not yet valid");
case QSslError::CertificateExpired:
return QSslSocket::tr("The certificate has expired");
case QSslError::InvalidNotBeforeField:
return QSslSocket::tr("The certificate's notBefore field contains an invalid time");
case QSslError::InvalidNotAfterField:
return QSslSocket::tr("The certificate's notAfter field contains an invalid time");
case QSslError::SelfSignedCertificate:
return QSslSocket::tr("The certificate is self-signed, and untrusted");
case QSslError::SelfSignedCertificateInChain:
return QSslSocket::tr("The root certificate of the certificate chain is self-signed, and untrusted");
case QSslError::UnableToGetLocalIssuerCertificate:
return QSslSocket::tr("The issuer certificate of a locally looked up certificate could not be found");
case QSslError::UnableToVerifyFirstCertificate:
return QSslSocket::tr("No certificates could be verified");
case QSslError::InvalidCaCertificate:
return QSslSocket::tr("One of the CA certificates is invalid");
case QSslError::PathLengthExceeded:
return QSslSocket::tr("The basicConstraints path length parameter has been exceeded");
case QSslError::InvalidPurpose:
return QSslSocket::tr("The supplied certificate is unsuitable for this purpose");
case QSslError::CertificateUntrusted:
return QSslSocket::tr("The root CA certificate is not trusted for this purpose");
case CertificateRejected:
return QSslSocket::tr("The root CA certificate is marked to reject the specified purpose");
case QSslError::SubjectIssuerMismatch: // hostname mismatch
return QSslSocket::tr("The current candidate issuer certificate was rejected because its"
" subject name did not match the issuer name of the current certificate");
case QSslError::AuthorityIssuerSerialNumberMismatch:
return QSslSocket::tr("The current candidate issuer certificate was rejected because"
" its issuer name and serial number was present and did not match the"
" authority key identifier of the current certificate");
case QSslError::NoPeerCertificate:
return QSslSocket::tr("The peer did not present any certificate");
case QSslError::HostNameMismatch:
return QSslSocket::tr("The host name did not match any of the valid hosts"
" for this certificate");
case QSslError::CertificateBlacklisted:
return QSslSocket::tr("The peer certificate is blacklisted");
case QSslError::NoSslSupport:
return QString();
default:
return QSslSocket::tr("Unknown error");
}
return QString();
}
/*!
Returns the certificate associated with this error, or a null certificate
if the error does not relate to any certificate.
\sa error(), errorString()
*/
QSslCertificate QSslError::certificate() const
{
return d->certificate;
}
#ifndef QT_NO_DEBUG_STREAM
//class QDebug;
QDebug operator<<(QDebug debug, const QSslError &error)
{
debug << error.errorString();
return debug;
}
QDebug operator<<(QDebug debug, const QSslError::SslError &error)
{
debug << QSslError(error).errorString();
return debug;
}
#endif
QT_END_NAMESPACE

View file

@ -1,97 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLERROR_H
#define QSSLERROR_H
#include <QtCore/qstring.h>
#include <QtNetwork/qsslcertificate.h>
QT_BEGIN_NAMESPACE
class QSslErrorPrivate;
class Q_NETWORK_EXPORT QSslError
{
public:
enum SslError {
NoError,
UnableToGetIssuerCertificate,
UnableToDecryptCertificateSignature,
UnableToDecodeIssuerPublicKey,
CertificateSignatureFailed,
CertificateNotYetValid,
CertificateExpired,
InvalidNotBeforeField,
InvalidNotAfterField,
SelfSignedCertificate,
SelfSignedCertificateInChain,
UnableToGetLocalIssuerCertificate,
UnableToVerifyFirstCertificate,
CertificateRevoked,
InvalidCaCertificate,
PathLengthExceeded,
InvalidPurpose,
CertificateUntrusted,
CertificateRejected,
SubjectIssuerMismatch, // hostname mismatch?
AuthorityIssuerSerialNumberMismatch,
NoPeerCertificate,
HostNameMismatch,
NoSslSupport,
CertificateBlacklisted,
UnspecifiedError = -1
};
// RVCT compiler in debug build does not like about default values in const-
// So as an workaround we define all constructor overloads here explicitly
QSslError();
QSslError(SslError error);
QSslError(SslError error, const QSslCertificate &certificate);
QSslError(const QSslError &other);
~QSslError();
QSslError &operator=(const QSslError &other);
bool operator==(const QSslError &other) const;
inline bool operator!=(const QSslError &other) const
{ return !(*this == other); }
SslError error() const;
QString errorString() const;
QSslCertificate certificate() const;
private:
QSslErrorPrivate *d;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError &error);
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError::SslError &error);
#endif
QT_END_NAMESPACE
#endif

View file

@ -1,516 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qsslsocket_openssl_p.h"
#include "qsslkey.h"
#include "qsslkey_p.h"
#include "qsslsocket.h"
#include "qsslsocket_p.h"
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qiodevice.h>
#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/qdebug.h>
#endif
/*!
\class QSslKey
\brief The QSslKey class provides an interface for private and public keys.
\since 4.3
\reentrant
\ingroup network
\ingroup ssl
\inmodule QtNetwork
QSslKey provides a simple API for managing keys.
\sa QSslSocket, QSslCertificate, QSslCipher
*/
QT_BEGIN_NAMESPACE
/*!
\internal
*/
void QSslKeyPrivate::clear()
{
isNull = true;
if (!QSslSocket::supportsSsl())
return;
if (rsa) {
RSA_free(rsa);
rsa = 0;
}
if (dsa) {
DSA_free(dsa);
dsa = 0;
}
if (dh) {
DH_free(dh);
dh = 0;
}
}
/*!
\internal
Allocates a new rsa or dsa struct and decodes \a pem into it
according to the current algorithm and type.
If \a passPhrase is non-empty, it will be used for decrypting
\a pem.
*/
void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase)
{
if (pem.isEmpty())
return;
clear();
if (!QSslSocket::supportsSsl())
return;
BIO *bio = BIO_new_mem_buf(pem.constData(), pem.size());
if (!bio)
return;
void *phrase = (void *)passPhrase.constData();
switch (algorithm) {
case QSsl::Rsa: {
RSA *result = (type == QSsl::PublicKey)
? PEM_read_bio_RSA_PUBKEY(bio, &rsa, 0, phrase)
: PEM_read_bio_RSAPrivateKey(bio, &rsa, 0, phrase);
if (rsa && rsa == result)
isNull = false;
break;
}
case QSsl::Dsa: {
DSA *result = (type == QSsl::PublicKey)
? PEM_read_bio_DSA_PUBKEY(bio, &dsa, 0, phrase)
: PEM_read_bio_DSAPrivateKey(bio, &dsa, 0, phrase);
if (dsa && dsa == result)
isNull = false;
break;
}
case QSsl::Dh: {
EVP_PKEY *result = (type == QSsl::PublicKey)
? PEM_read_bio_PUBKEY(bio, 0, 0, phrase)
: PEM_read_bio_PrivateKey(bio, 0, 0, phrase);
if (result)
dh = EVP_PKEY_get1_DH(result);
if (dh)
isNull = false;
EVP_PKEY_free(result);
break;
}
}
BIO_free(bio);
}
/*!
Constructs a null key.
\sa isNull()
*/
QSslKey::QSslKey()
: d(new QSslKeyPrivate)
{
}
/*!
\internal
*/
QByteArray QSslKeyPrivate::pemHeader() const
{
if (type == QSsl::PublicKey)
return QByteArray::fromRawData("-----BEGIN PUBLIC KEY-----\n", 27);
switch (algorithm) {
case QSsl::Rsa:
return QByteArray::fromRawData("-----BEGIN RSA PRIVATE KEY-----\n", 32);
case QSsl::Dsa:
return QByteArray::fromRawData("-----BEGIN DSA PRIVATE KEY-----\n", 32);
case QSsl::Dh:
return QByteArray::fromRawData("-----BEGIN PRIVATE KEY-----\n", 28);
}
return QByteArray();
}
/*!
\internal
*/
QByteArray QSslKeyPrivate::pemFooter() const
{
if (type == QSsl::PublicKey)
return QByteArray::fromRawData("-----END PUBLIC KEY-----\n", 25);
switch (algorithm) {
case QSsl::Rsa:
return QByteArray::fromRawData("-----END RSA PRIVATE KEY-----\n", 30);
case QSsl::Dsa:
return QByteArray::fromRawData("-----END DSA PRIVATE KEY-----\n", 30);
case QSsl::Dh:
return QByteArray::fromRawData("-----END PRIVATE KEY-----\n", 26);
}
return QByteArray();
}
/*!
\internal
Returns a DER key formatted as PEM.
*/
QByteArray QSslKeyPrivate::pemFromDer(const QByteArray &der) const
{
QByteArray pem(der.toBase64());
const int lineWidth = 64; // RFC 1421
const int newLines = pem.size() / lineWidth;
const bool rem = pem.size() % lineWidth;
// ### optimize
for (int i = 0; i < newLines; ++i)
pem.insert((i + 1) * lineWidth + i, '\n');
if (rem)
pem.append('\n'); // ###
pem.prepend(pemHeader());
pem.append(pemFooter());
return pem;
}
/*!
\internal
Returns a PEM key formatted as DER.
*/
QByteArray QSslKeyPrivate::derFromPem(const QByteArray &pem) const
{
const QByteArray header = pemHeader();
const QByteArray footer = pemFooter();
QByteArray der(pem);
const int headerIndex = der.indexOf(header);
const int footerIndex = der.indexOf(footer);
if (headerIndex == -1 || footerIndex == -1)
return QByteArray();
der = der.mid(headerIndex + header.size(), footerIndex - (headerIndex + header.size()));
return QByteArray::fromBase64(der); // ignores newlines
}
/*!
Constructs a QSslKey by decoding the string in the byte array
\a encoded using a specified \a algorithm and \a encoding format.
If the encoded key is encrypted, \a passPhrase is used to decrypt
it. \a type specifies whether the key is public or private.
After construction, use isNull() to check if \a encoded contained
a valid key.
*/
QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
QSsl::EncodingFormat encoding, QSsl::KeyType type, const QByteArray &passPhrase)
: d(new QSslKeyPrivate)
{
d->type = type;
d->algorithm = algorithm;
d->decodePem((encoding == QSsl::Der)
? d->pemFromDer(encoded) : encoded,
passPhrase);
}
/*!
Constructs a QSslKey by reading and decoding data from a
\a device using a specified \a algorithm and \a encoding format.
If the encoded key is encrypted, \a passPhrase is used to decrypt
it. \a type specifies whether the key is public or private.
After construction, use isNull() to check if \a device provided
a valid key.
*/
QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::EncodingFormat encoding,
QSsl::KeyType type, const QByteArray &passPhrase)
: d(new QSslKeyPrivate)
{
QByteArray encoded;
if (device)
encoded = device->readAll();
d->type = type;
d->algorithm = algorithm;
d->decodePem((encoding == QSsl::Der) ?
d->pemFromDer(encoded) : encoded,
passPhrase);
}
/*!
Constructs an identical copy of \a other.
*/
QSslKey::QSslKey(const QSslKey &other) : d(other.d)
{
}
/*!
Destroys the QSslKey object.
*/
QSslKey::~QSslKey()
{
}
/*!
Copies the contents of \a other into this key, making the two keys
identical.
Returns a reference to this QSslKey.
*/
QSslKey &QSslKey::operator=(const QSslKey &other)
{
d = other.d;
return *this;
}
/*!
Returns true if this is a null key; otherwise false.
\sa clear()
*/
bool QSslKey::isNull() const
{
return d->isNull;
}
/*!
Clears the contents of this key, making it a null key.
\sa isNull()
*/
void QSslKey::clear()
{
d = new QSslKeyPrivate;
}
/*!
Returns the length of the key in bits, or -1 if the key is null.
*/
int QSslKey::length() const
{
if (d->isNull)
return -1;
switch (d->algorithm) {
case QSsl::Rsa: {
return RSA_bits(d->rsa);
}
case QSsl::Dsa: {
const BIGNUM *p = NULL;
DSA_get0_pqg(d->dsa, &p, NULL, NULL);
return BN_num_bits(p);
}
case QSsl::Dh: {
return DH_bits(d->dh);
}
}
return -1;
}
/*!
Returns the type of the key (i.e., PublicKey or PrivateKey).
*/
QSsl::KeyType QSslKey::type() const
{
return d->type;
}
/*!
Returns the key algorithm.
*/
QSsl::KeyAlgorithm QSslKey::algorithm() const
{
return d->algorithm;
}
/*!
Returns the key in DER encoding. The result is encrypted with
\a passPhrase if the key is a private key and \a passPhrase is
non-empty.
*/
// ### autotest failure for non-empty passPhrase and private key
QByteArray QSslKey::toDer(const QByteArray &passPhrase) const
{
if (d->isNull)
return QByteArray();
return d->derFromPem(toPem(passPhrase));
}
/*!
Returns the key in PEM encoding. The result is encrypted with
\a passPhrase if the key is a private key and \a passPhrase is
non-empty.
*/
QByteArray QSslKey::toPem(const QByteArray &passPhrase) const
{
if (!QSslSocket::supportsSsl() || d->isNull)
return QByteArray();
BIO *bio = BIO_new(BIO_s_mem());
if (!bio)
return QByteArray();
bool fail = false;
switch (d->algorithm) {
case QSsl::Rsa: {
if (d->type == QSsl::PublicKey) {
if (!PEM_write_bio_RSA_PUBKEY(bio, d->rsa))
fail = true;
} else {
if (!PEM_write_bio_RSAPrivateKey(
bio, d->rsa,
// ### the cipher should be selectable in the API:
passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : EVP_des_ede3_cbc(),
(uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) {
fail = true;
}
}
break;
}
case QSsl::Dsa: {
if (d->type == QSsl::PublicKey) {
if (!PEM_write_bio_DSA_PUBKEY(bio, d->dsa))
fail = true;
} else {
if (!PEM_write_bio_DSAPrivateKey(
bio, d->dsa,
// ### the cipher should be selectable in the API:
passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : EVP_des_ede3_cbc(),
(uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) {
fail = true;
}
}
break;
}
case QSsl::Dh: {
EVP_PKEY *result = EVP_PKEY_new();
if (!result || !EVP_PKEY_set1_DH(result, d->dh)) {
fail = true;
} else if (d->type == QSsl::PublicKey) {
if (!PEM_write_bio_PUBKEY(bio, result))
fail = true;
} else if (!PEM_write_bio_PrivateKey(
// ### the cipher should be selectable in the API:
bio, result, passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : EVP_des_ede3_cbc(),
(uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) {
fail = true;
}
EVP_PKEY_free(result);
break;
}
}
QByteArray pem;
if (!fail) {
char *data;
long size = BIO_get_mem_data(bio, &data);
pem = QByteArray(data, size);
}
BIO_free(bio);
return pem;
}
/*!
Returns a pointer to the native key handle, if it is available;
otherwise a null pointer is returned.
You can use this handle together with the native API to access
extended information about the key.
\warning Use of this function has a high probability of being
non-portable, and its return value may vary across platforms, and
between minor Qt releases.
*/
Qt::HANDLE QSslKey::handle() const
{
switch (d->algorithm) {
case QSsl::Rsa:
return Qt::HANDLE(d->rsa);
case QSsl::Dsa:
return Qt::HANDLE(d->dsa);
case QSsl::Dh:
return Qt::HANDLE(d->dh);
}
Q_UNREACHABLE();
}
/*!
Returns true if this key is equal to \a other; otherwise returns false.
*/
bool QSslKey::operator==(const QSslKey &other) const
{
if (isNull())
return other.isNull();
if (other.isNull())
return isNull();
if (algorithm() != other.algorithm())
return false;
if (type() != other.type())
return false;
if (length() != other.length())
return false;
return toDer() == other.toDer();
}
/*! \fn bool QSslKey::operator!=(const QSslKey &other) const
Returns true if this key is not equal to key \a other; otherwise
returns false.
*/
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
QDebug operator<<(QDebug debug, const QSslKey &key)
{
debug << "QSslKey("
<< (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey");
switch (key.algorithm()) {
case QSsl::Rsa: {
debug << ", " << "RSA";
break;
}
case QSsl::Dsa: {
debug << ", " << "DSA";
break;
}
case QSsl::Dh: {
debug << ", " << "DH";
break;
}
}
debug << ", " << key.length()
<< ')';
return debug;
}
#endif
QT_END_NAMESPACE

View file

@ -1,83 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLKEY_H
#define QSSLKEY_H
#include <QtCore/qnamespace.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qsharedpointer.h>
#include <QtNetwork/qssl.h>
QT_BEGIN_NAMESPACE
template <typename A, typename B> struct QPair;
class QIODevice;
class QSslKeyPrivate;
class Q_NETWORK_EXPORT QSslKey
{
public:
QSslKey();
QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
QSsl::EncodingFormat format = QSsl::Pem,
QSsl::KeyType type = QSsl::PrivateKey,
const QByteArray &passPhrase = QByteArray());
QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm,
QSsl::EncodingFormat format = QSsl::Pem,
QSsl::KeyType type = QSsl::PrivateKey,
const QByteArray &passPhrase = QByteArray());
QSslKey(const QSslKey &other);
~QSslKey();
QSslKey &operator=(const QSslKey &other);
bool isNull() const;
void clear();
int length() const;
QSsl::KeyType type() const;
QSsl::KeyAlgorithm algorithm() const;
QByteArray toPem(const QByteArray &passPhrase = QByteArray()) const;
QByteArray toDer(const QByteArray &passPhrase = QByteArray()) const;
Qt::HANDLE handle() const;
bool operator==(const QSslKey &key) const;
inline bool operator!=(const QSslKey &key) const { return !operator==(key); }
private:
QExplicitlySharedDataPointer<QSslKeyPrivate> d;
friend class QSslCertificate;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslKey &key);
#endif
QT_END_NAMESPACE
#endif

View file

@ -1,82 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLKEY_P_H
#define QSSLKEY_P_H
#include "qsslkey.h"
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of qsslcertificate.cpp. This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
QT_BEGIN_NAMESPACE
class QSslKeyPrivate
{
public:
inline QSslKeyPrivate()
: isNull(true)
, rsa(nullptr)
, dsa(nullptr)
, dh(nullptr)
{
}
inline ~QSslKeyPrivate()
{ clear(); }
void clear();
void decodePem(const QByteArray &pem, const QByteArray &passPhrase);
QByteArray pemHeader() const;
QByteArray pemFooter() const;
QByteArray pemFromDer(const QByteArray &der) const;
QByteArray derFromPem(const QByteArray &pem) const;
bool isNull;
QSsl::KeyType type;
QSsl::KeyAlgorithm algorithm;
RSA *rsa;
DSA *dsa;
DH *dh;
QAtomicInt ref;
private:
Q_DISABLE_COPY(QSslKeyPrivate)
};
QT_END_NAMESPACE
#endif // QSSLKEY_P_H

File diff suppressed because it is too large Load diff

View file

@ -1,192 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLSOCKET_H
#define QSSLSOCKET_H
#include <QtCore/qlist.h>
#include <QtCore/qregexp.h>
#include <QtNetwork/qtcpsocket.h>
#include <QtNetwork/qsslerror.h>
QT_BEGIN_NAMESPACE
class QSslCipher;
class QSslCertificate;
class QSslConfiguration;
class QSslSocketPrivate;
class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket
{
Q_OBJECT
public:
enum SslMode {
UnencryptedMode,
SslClientMode,
SslServerMode
};
enum PeerVerifyMode {
VerifyNone,
QueryPeer,
VerifyPeer,
AutoVerifyPeer
};
QSslSocket(QObject *parent = nullptr);
~QSslSocket();
virtual void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite);
virtual void disconnectFromHost();
// Autostarting the SSL client handshake.
void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode = ReadWrite);
void connectToHostEncrypted(const QString &hostName, quint16 port, const QString &sslPeerName, OpenMode mode = ReadWrite);
bool setSocketDescriptor(int socketDescriptor, SocketState state = ConnectedState,
OpenMode openMode = ReadWrite);
void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value);
QVariant socketOption(QAbstractSocket::SocketOption option);
SslMode mode() const;
bool isEncrypted() const;
QSsl::SslProtocol protocol() const;
void setProtocol(QSsl::SslProtocol protocol);
QSslSocket::PeerVerifyMode peerVerifyMode() const;
void setPeerVerifyMode(QSslSocket::PeerVerifyMode mode);
int peerVerifyDepth() const;
void setPeerVerifyDepth(int depth);
QString peerVerifyName() const;
void setPeerVerifyName(const QString &hostName);
// From QIODevice
qint64 bytesAvailable() const;
qint64 bytesToWrite() const;
bool canReadLine() const;
void close();
bool atEnd() const;
bool flush();
void abort();
// From QAbstractSocket:
void setReadBufferSize(qint64 size);
// Similar to QIODevice's:
qint64 encryptedBytesAvailable() const;
qint64 encryptedBytesToWrite() const;
// SSL configuration
QSslConfiguration sslConfiguration() const;
void setSslConfiguration(const QSslConfiguration &config);
// Certificate & cipher accessors.
void setLocalCertificate(const QSslCertificate &certificate);
void setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format = QSsl::Pem);
QSslCertificate localCertificate() const;
QSslCertificate peerCertificate() const;
QList<QSslCertificate> peerCertificateChain() const;
QSslCipher sessionCipher() const;
// Private keys, for server sockets.
void setPrivateKey(const QSslKey &key);
void setPrivateKey(const QString &fileName, QSsl::KeyAlgorithm algorithm = QSsl::Rsa,
QSsl::EncodingFormat format = QSsl::Pem,
const QByteArray &passPhrase = QByteArray());
QSslKey privateKey() const;
// Cipher settings.
QList<QSslCipher> ciphers() const;
void setCiphers(const QList<QSslCipher> &ciphers);
void setCiphers(const QString &ciphers);
static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
static QList<QSslCipher> defaultCiphers();
static QList<QSslCipher> supportedCiphers();
// CA settings.
bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
void addCaCertificate(const QSslCertificate &certificate);
void addCaCertificates(const QList<QSslCertificate> &certificates);
void setCaCertificates(const QList<QSslCertificate> &certificates);
QList<QSslCertificate> caCertificates() const;
static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
static void addDefaultCaCertificate(const QSslCertificate &certificate);
static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates);
static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates);
static QList<QSslCertificate> defaultCaCertificates();
static QList<QSslCertificate> systemCaCertificates();
bool waitForConnected(int msecs = 30000);
bool waitForEncrypted(int msecs = 30000);
bool waitForReadyRead(int msecs = 30000);
bool waitForBytesWritten(int msecs = 30000);
bool waitForDisconnected(int msecs = 30000);
QList<QSslError> sslErrors() const;
static bool supportsSsl();
void ignoreSslErrors(const QList<QSslError> &errors);
public Q_SLOTS:
void startClientEncryption();
void startServerEncryption();
void ignoreSslErrors();
Q_SIGNALS:
void encrypted();
void peerVerifyError(const QSslError &error);
void sslErrors(const QList<QSslError> &errors);
void modeChanged(QSslSocket::SslMode newMode);
void encryptedBytesWritten(qint64 totalBytes);
protected:
qint64 readData(char *data, qint64 maxlen);
qint64 writeData(const char *data, qint64 len);
private:
Q_DECLARE_PRIVATE(QSslSocket)
Q_DISABLE_COPY(QSslSocket)
Q_PRIVATE_SLOT(d_func(), void _q_connectedSlot())
Q_PRIVATE_SLOT(d_func(), void _q_hostFoundSlot())
Q_PRIVATE_SLOT(d_func(), void _q_disconnectedSlot())
Q_PRIVATE_SLOT(d_func(), void _q_stateChangedSlot(QAbstractSocket::SocketState))
Q_PRIVATE_SLOT(d_func(), void _q_errorSlot(QAbstractSocket::SocketError))
Q_PRIVATE_SLOT(d_func(), void _q_readyReadSlot())
Q_PRIVATE_SLOT(d_func(), void _q_bytesWrittenSlot(qint64))
Q_PRIVATE_SLOT(d_func(), void _q_flushWriteBuffer())
Q_PRIVATE_SLOT(d_func(), void _q_flushReadBuffer())
friend class QSslSocketBackendPrivate;
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QList<QSslError>)
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,107 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLSOCKET_OPENSSL_P_H
#define QSSLSOCKET_OPENSSL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of the QLibrary class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include "qsslsocket_p.h"
#include <openssl/ssl.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/pkcs7.h>
#include <openssl/rand.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
#include <openssl/crypto.h>
#if !defined(OPENSSL_NO_TLSEXT)
#include <openssl/tls1.h>
#endif
// LibreSSL does not have it defined
#ifndef OPENSSL_STACK
#define OPENSSL_STACK _STACK
#endif
QT_BEGIN_NAMESPACE
class QSslSocketBackendPrivate : public QSslSocketPrivate
{
Q_DECLARE_PUBLIC(QSslSocket)
public:
QSslSocketBackendPrivate();
virtual ~QSslSocketBackendPrivate();
// SSL context
bool initSslContext();
void destroySslContext();
SSL *ssl;
SSL_CTX *ctx;
EVP_PKEY *pkey;
BIO *readBio;
BIO *writeBio;
SSL_SESSION *session;
X509_STORE *certificateStore;
X509_STORE_CTX *certificateStoreCtx;
QList<QPair<int, int> > errorList;
// Platform specific functions
void startClientEncryption();
void startServerEncryption();
void transmit();
bool startHandshake();
void disconnectFromHost();
void disconnected();
QSslCipher sessionCipher() const;
static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
static QString getErrorsFromOpenSsl();
};
QT_END_NAMESPACE
#endif

View file

@ -1,131 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtNetwork module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSSLSOCKET_P_H
#define QSSLSOCKET_P_H
#include "qsslsocket.h"
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of the QLibrary class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include "qtcpsocket_p.h"
#include "qsslkey.h"
#include "qsslconfiguration_p.h"
#include "qstringlist.h"
QT_BEGIN_NAMESPACE
class QSslSocketPrivate : public QTcpSocketPrivate
{
Q_DECLARE_PUBLIC(QSslSocket)
public:
QSslSocketPrivate();
virtual ~QSslSocketPrivate();
void init();
bool initialized;
QSslSocket::SslMode mode;
bool autoStartHandshake;
bool connectionEncrypted;
bool shutdown;
bool ignoreAllSslErrors;
QList<QSslError> ignoreErrorsList;
bool* readyReadEmittedPointer;
QSslConfigurationPrivate configuration;
QList<QSslError> sslErrors;
// if set, this hostname is used for certificate validation instead of the hostname
// that was used for connecting to.
QString verificationPeerName;
bool allowRootCertOnDemandLoading;
static bool supportsSsl();
static void ensureInitialized();
static QList<QSslCipher> defaultCiphers();
static QList<QSslCipher> supportedCiphers();
static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
static void setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers);
static void resetDefaultCiphers();
static QList<QSslCertificate> defaultCaCertificates();
static QList<QSslCertificate> systemCaCertificates();
static void setDefaultCaCertificates(const QList<QSslCertificate> &certs);
static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format,
QRegExp::PatternSyntax syntax);
static void addDefaultCaCertificate(const QSslCertificate &cert);
static void addDefaultCaCertificates(const QList<QSslCertificate> &certs);
// The socket itself, including private slots.
QTcpSocket *plainSocket;
void createPlainSocket(QIODevice::OpenMode openMode);
static void pauseSocketNotifiers(QSslSocket*);
static void resumeSocketNotifiers(QSslSocket*);
void _q_connectedSlot();
void _q_hostFoundSlot();
void _q_disconnectedSlot();
void _q_stateChangedSlot(QAbstractSocket::SocketState);
void _q_errorSlot(QAbstractSocket::SocketError);
void _q_readyReadSlot();
void _q_bytesWrittenSlot(qint64);
void _q_flushWriteBuffer();
void _q_flushReadBuffer();
virtual qint64 peek(char *data, qint64 maxSize);
virtual QByteArray peek(qint64 maxSize);
// Platform specific functions
virtual void startClientEncryption() = 0;
virtual void startServerEncryption() = 0;
virtual void transmit() = 0;
virtual void disconnectFromHost() = 0;
virtual void disconnected() = 0;
virtual QSslCipher sessionCipher() const = 0;
Q_AUTOTEST_EXPORT static bool rootCertOnDemandLoadingSupported();
private:
static bool ensureLibraryLoaded();
static void ensureCiphersAndCertsLoaded();
static bool s_libraryLoaded;
static bool s_loadedCiphersAndCerts;
protected:
static bool s_loadRootCertsOnDemand;
static QByteArray unixRootCertDirectory();
static QByteArray unixRootCertFile();
};
QT_END_NAMESPACE
#endif

View file

@ -482,12 +482,6 @@ static const struct ClassTblData {
{ QLatin1String("QSplashScreen"), QLatin1String("QtGui/qsplashscreen.h") },
{ QLatin1String("QSplitter"), QLatin1String("QtGui/qsplitter.h") },
{ QLatin1String("QSplitterHandle"), QLatin1String("QtGui/qsplitter.h") },
{ QLatin1String("QSslCertificate"), QLatin1String("QtNetwork/qsslcertificate.h") },
{ QLatin1String("QSslCipher"), QLatin1String("QtNetwork/qsslcipher.h") },
{ QLatin1String("QSslConfiguration"), QLatin1String("QtNetwork/qsslconfiguration.h") },
{ QLatin1String("QSslError"), QLatin1String("QtNetwork/qsslerror.h") },
{ QLatin1String("QSslKey"), QLatin1String("QtNetwork/qsslkey.h") },
{ QLatin1String("QSslSocket"), QLatin1String("QtNetwork/qsslsocket.h") },
{ QLatin1String("QStack"), QLatin1String("QtCore/qstack.h") },
{ QLatin1String("QStackedLayout"), QLatin1String("QtGui/qstackedlayout.h") },
{ QLatin1String("QStackedWidget"), QLatin1String("QtGui/qstackedwidget.h") },

View file

@ -1,5 +0,0 @@
katie_test(tst_bench_qsslsocket
${CMAKE_CURRENT_SOURCE_DIR}/tst_qsslsocket.cpp
)
target_link_libraries(tst_bench_qsslsocket KtNetwork)

View file

@ -1,95 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the test suite of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <qcoreapplication.h>
#include <qsslconfiguration.h>
#include <qsslsocket.h>
#include "../../../../auto/network-settings.h"
//TESTED_CLASS=
//TESTED_FILES=
class tst_QSslSocket : public QObject
{
Q_OBJECT
public:
tst_QSslSocket();
virtual ~tst_QSslSocket();
public slots:
void initTestCase_data();
void init();
void cleanup();
private slots:
void rootCertLoading();
void systemCaCertificates();
};
tst_QSslSocket::tst_QSslSocket()
{
}
tst_QSslSocket::~tst_QSslSocket()
{
}
void tst_QSslSocket::initTestCase_data()
{
}
void tst_QSslSocket::init()
{
}
void tst_QSslSocket::cleanup()
{
}
//----------------------------------------------------------------------------------
void tst_QSslSocket::rootCertLoading()
{
QBENCHMARK_ONCE {
QSslSocket socket;
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
socket.waitForEncrypted();
}
}
void tst_QSslSocket::systemCaCertificates()
{
// The results of this test change if the benchmarking system changes too much.
// Therefore this benchmark is only good for manual regression checking between
// Qt versions.
QBENCHMARK_ONCE {
QList<QSslCertificate> list = QSslSocket::systemCaCertificates();
}
}
QTEST_MAIN(tst_QSslSocket)
#include "moc_tst_qsslsocket.cpp"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-21 08:48+0200\n"
"POT-Creation-Date: 2022-02-21 15:18+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -43,7 +43,7 @@ msgid "The plugin uses incompatible Katie library: %1 (%2, %3)"
msgstr ""
#: src/core/plugin/qlibrary.cpp:799 src/core/plugin/qpluginloader.cpp:278
#: src/core/io/qiodevice.cpp:1517 src/network/ssl/qsslerror.cpp:249
#: src/core/io/qiodevice.cpp:1517
#: src/network/socket/qnativesocketengine.cpp:249
#: src/uitools/formscriptrunner.cpp:104
msgid "Unknown error"
@ -1169,17 +1169,17 @@ msgstr ""
msgid "ListModel: undefined property '%1'"
msgstr ""
#: src/declarative/util/qdeclarativepixmapcache.cpp:257
#: src/declarative/util/qdeclarativepixmapcache.cpp:256
msgid "Error decoding: %1: %2"
msgstr ""
#: src/declarative/util/qdeclarativepixmapcache.cpp:360
#: src/declarative/util/qdeclarativepixmapcache.cpp:700
#: src/declarative/util/qdeclarativepixmapcache.cpp:359
#: src/declarative/util/qdeclarativepixmapcache.cpp:699
msgid "Failed to get image from provider: %1"
msgstr ""
#: src/declarative/util/qdeclarativepixmapcache.cpp:376
#: src/declarative/util/qdeclarativepixmapcache.cpp:718
#: src/declarative/util/qdeclarativepixmapcache.cpp:375
#: src/declarative/util/qdeclarativepixmapcache.cpp:717
msgid "Cannot open: %1"
msgstr ""
@ -4584,158 +4584,6 @@ msgstr ""
msgid "Insert Unicode control character"
msgstr ""
#: src/network/ssl/qsslerror.cpp:197
msgid "No error"
msgstr ""
#: src/network/ssl/qsslerror.cpp:199
msgid "The issuer certificate could not be found"
msgstr ""
#: src/network/ssl/qsslerror.cpp:201
msgid "The certificate signature could not be decrypted"
msgstr ""
#: src/network/ssl/qsslerror.cpp:203
msgid "The public key in the certificate could not be read"
msgstr ""
#: src/network/ssl/qsslerror.cpp:205
msgid "The signature of the certificate is invalid"
msgstr ""
#: src/network/ssl/qsslerror.cpp:207
msgid "The certificate is not yet valid"
msgstr ""
#: src/network/ssl/qsslerror.cpp:209
msgid "The certificate has expired"
msgstr ""
#: src/network/ssl/qsslerror.cpp:211
msgid "The certificate's notBefore field contains an invalid time"
msgstr ""
#: src/network/ssl/qsslerror.cpp:213
msgid "The certificate's notAfter field contains an invalid time"
msgstr ""
#: src/network/ssl/qsslerror.cpp:215
msgid "The certificate is self-signed, and untrusted"
msgstr ""
#: src/network/ssl/qsslerror.cpp:217
msgid ""
"The root certificate of the certificate chain is self-signed, and untrusted"
msgstr ""
#: src/network/ssl/qsslerror.cpp:219
msgid ""
"The issuer certificate of a locally looked up certificate could not be found"
msgstr ""
#: src/network/ssl/qsslerror.cpp:221
msgid "No certificates could be verified"
msgstr ""
#: src/network/ssl/qsslerror.cpp:223
msgid "One of the CA certificates is invalid"
msgstr ""
#: src/network/ssl/qsslerror.cpp:225
msgid "The basicConstraints path length parameter has been exceeded"
msgstr ""
#: src/network/ssl/qsslerror.cpp:227
msgid "The supplied certificate is unsuitable for this purpose"
msgstr ""
#: src/network/ssl/qsslerror.cpp:229
msgid "The root CA certificate is not trusted for this purpose"
msgstr ""
#: src/network/ssl/qsslerror.cpp:231
msgid "The root CA certificate is marked to reject the specified purpose"
msgstr ""
#: src/network/ssl/qsslerror.cpp:233
msgid ""
"The current candidate issuer certificate was rejected because its subject "
"name did not match the issuer name of the current certificate"
msgstr ""
#: src/network/ssl/qsslerror.cpp:236
msgid ""
"The current candidate issuer certificate was rejected because its issuer "
"name and serial number was present and did not match the authority key "
"identifier of the current certificate"
msgstr ""
#: src/network/ssl/qsslerror.cpp:240
msgid "The peer did not present any certificate"
msgstr ""
#: src/network/ssl/qsslerror.cpp:242
msgid "The host name did not match any of the valid hosts for this certificate"
msgstr ""
#: src/network/ssl/qsslerror.cpp:245
msgid "The peer certificate is blacklisted"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:154
msgid "Error creating SSL context (%1)"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:204
msgid "Invalid or empty cipher list (%1)"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:236
msgid "Cannot provide a certificate with no key, %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:243
msgid "Error loading local certificate, %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:268
msgid "Error loading private key, %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:275
msgid "Private key does not certify public key, %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:295
msgid "Error creating SSL session, %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:329
msgid "Error creating SSL session: %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:550
msgid "Unable to write data: %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:620
msgid "Unable to decrypt data: %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:693
msgid "The TLS/SSL connection has been closed"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:701
#: src/network/ssl/qsslsocket_openssl.cpp:711
msgid "Error while reading: %1"
msgstr ""
#: src/network/ssl/qsslsocket_openssl.cpp:805
msgid "Error during SSL handshake: %1"
msgstr ""
#: src/network/kernel/qhostinfo_p.h:74
msgctxt "QHostInfo"
msgid "Unknown error"
@ -4748,7 +4596,7 @@ msgstr ""
#: src/network/kernel/qhostinfo_unix.cpp:87
#: src/network/kernel/qhostinfo_unix.cpp:171
#: src/network/socket/qabstractsocket.cpp:830
#: src/network/socket/qabstractsocket.cpp:827
msgid "Host not found"
msgstr ""
@ -4765,9 +4613,9 @@ msgid "Unknown address type"
msgstr ""
#: src/network/socket/qtcpserver.cpp:266 src/network/socket/qtcpserver.cpp:384
#: src/network/socket/qabstractsocket.cpp:485
#: src/network/socket/qabstractsocket.cpp:1268
#: src/network/socket/qabstractsocket.cpp:1478
#: src/network/socket/qabstractsocket.cpp:482
#: src/network/socket/qabstractsocket.cpp:1265
#: src/network/socket/qabstractsocket.cpp:1475
msgid "Operation on socket is not supported"
msgstr ""
@ -4789,21 +4637,21 @@ msgstr ""
msgid "%1: Unknown error %2"
msgstr ""
#: src/network/socket/qabstractsocket.cpp:872
#: src/network/socket/qabstractsocket.cpp:869
#: src/network/socket/qnativesocketengine.cpp:213
msgid "Connection refused"
msgstr ""
#: src/network/socket/qabstractsocket.cpp:1014
#: src/network/socket/qabstractsocket.cpp:1011
#: src/network/socket/qnativesocketengine.cpp:210
msgid "Connection timed out"
msgstr ""
#: src/network/socket/qabstractsocket.cpp:1646
#: src/network/socket/qabstractsocket.cpp:1643
msgid "Socket operation timed out"
msgstr ""
#: src/network/socket/qabstractsocket.cpp:2057
#: src/network/socket/qabstractsocket.cpp:2053
msgid "Socket is not connected"
msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-21 08:48+0200\n"
"POT-Creation-Date: 2022-02-21 15:18+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"