mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-23 18:32:55 +00:00
drop SSL support
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
808d94b266
commit
fba2c2132c
35 changed files with 19 additions and 7665 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -508,13 +508,6 @@ classlist = [
|
|||
"QSplitter",
|
||||
"QSplitterHandle",
|
||||
"QSpontaneKeyEvent",
|
||||
"QSsl",
|
||||
"QSslCertificate",
|
||||
"QSslCipher",
|
||||
"QSslConfiguration",
|
||||
"QSslError",
|
||||
"QSslKey",
|
||||
"QSslSocket",
|
||||
"QStack",
|
||||
"QStackedLayout",
|
||||
"QStackedWidget",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -68,10 +68,9 @@ public:
|
|||
UnsupportedSocketOperationError, /* 10 */
|
||||
UnfinishedSocketOperationError,
|
||||
ProxyAuthenticationRequiredError,
|
||||
SslHandshakeFailedError,
|
||||
ProxyConnectionRefusedError,
|
||||
ProxyConnectionClosedError, /* 15 */
|
||||
ProxyConnectionTimeoutError,
|
||||
ProxyConnectionClosedError,
|
||||
ProxyConnectionTimeoutError, /* 15 */
|
||||
ProxyNotFoundError,
|
||||
ProxyProtocolError,
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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") },
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
katie_test(tst_bench_qsslsocket
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qsslsocket.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(tst_bench_qsslsocket KtNetwork)
|
|
@ -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"
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue