1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtNetwork module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 41 #ifndef QSSLSOCKET_P_H 42 #define QSSLSOCKET_P_H 43 44 #include "qsslsocket.h" 45 46 // 47 // W A R N I N G 48 // ------------- 49 // 50 // This file is not part of the Qt API. It exists purely as an 51 // implementation detail. This header file may change from version to 52 // version without notice, or even be removed. 53 // 54 // We mean it. 55 // 56 57 #include <QtNetwork/private/qtnetworkglobal_p.h> 58 #include <private/qtcpsocket_p.h> 59 #include "qsslkey.h" 60 #include "qsslconfiguration_p.h" 61 #include "qocspresponse.h" 62 #ifndef QT_NO_OPENSSL 63 #include <private/qsslcontext_openssl_p.h> 64 #else 65 class QSslContext; 66 #endif 67 68 #include <QtCore/qstringlist.h> 69 #include <QtCore/qvector.h> 70 #include <private/qringbuffer_p.h> 71 72 #if defined(Q_OS_MAC) 73 #include <Security/SecCertificate.h> 74 #include <CoreFoundation/CFArray.h> 75 #elif defined(Q_OS_WIN) 76 #include <QtCore/qt_windows.h> 77 #include <memory> 78 #ifndef Q_OS_WINRT 79 #include <wincrypt.h> 80 #endif // !Q_OS_WINRT 81 #ifndef HCRYPTPROV_LEGACY 82 #define HCRYPTPROV_LEGACY HCRYPTPROV 83 #endif // !HCRYPTPROV_LEGACY 84 #endif // Q_OS_WIN 85 86 QT_BEGIN_NAMESPACE 87 88 #if defined(Q_OS_MACX) 89 typedef CFDataRef (*PtrSecCertificateCopyData)(SecCertificateRef); 90 typedef OSStatus (*PtrSecTrustSettingsCopyCertificates)(int, CFArrayRef*); 91 typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*); 92 #endif 93 94 #if defined(Q_OS_WIN) 95 96 // Those are needed by both OpenSSL and SChannel back-ends on Windows: 97 struct QHCertStoreDeleter { operatorQHCertStoreDeleter98 void operator()(HCERTSTORE store) 99 { 100 CertCloseStore(store, 0); 101 } 102 }; 103 104 using QHCertStorePointer = std::unique_ptr<void, QHCertStoreDeleter>; 105 106 #endif // Q_OS_WIN 107 108 class QSslSocketPrivate : public QTcpSocketPrivate 109 { 110 Q_DECLARE_PUBLIC(QSslSocket) 111 public: 112 QSslSocketPrivate(); 113 virtual ~QSslSocketPrivate(); 114 115 void init(); 116 bool verifyProtocolSupported(const char *where); 117 bool initialized; 118 119 QSslSocket::SslMode mode; 120 bool autoStartHandshake; 121 bool connectionEncrypted; 122 bool shutdown; 123 bool ignoreAllSslErrors; 124 QList<QSslError> ignoreErrorsList; 125 bool* readyReadEmittedPointer; 126 127 QSslConfigurationPrivate configuration; 128 QList<QSslError> sslErrors; 129 QSharedPointer<QSslContext> sslContextPointer; 130 131 // if set, this hostname is used for certificate validation instead of the hostname 132 // that was used for connecting to. 133 QString verificationPeerName; 134 135 bool allowRootCertOnDemandLoading; 136 137 static bool s_loadRootCertsOnDemand; 138 139 static bool supportsSsl(); 140 static long sslLibraryVersionNumber(); 141 static QString sslLibraryVersionString(); 142 static long sslLibraryBuildVersionNumber(); 143 static QString sslLibraryBuildVersionString(); 144 static void ensureInitialized(); 145 static QList<QSslCipher> defaultCiphers(); 146 static QList<QSslCipher> supportedCiphers(); 147 static void setDefaultCiphers(const QList<QSslCipher> &ciphers); 148 static void setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers); 149 static void resetDefaultCiphers(); 150 151 static QVector<QSslEllipticCurve> supportedEllipticCurves(); 152 static void setDefaultSupportedEllipticCurves(const QVector<QSslEllipticCurve> &curves); 153 static void resetDefaultEllipticCurves(); 154 155 static QList<QSslCertificate> defaultCaCertificates(); 156 static QList<QSslCertificate> systemCaCertificates(); 157 static void setDefaultCaCertificates(const QList<QSslCertificate> &certs); 158 static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format, 159 QRegExp::PatternSyntax syntax); 160 static void addDefaultCaCertificate(const QSslCertificate &cert); 161 static void addDefaultCaCertificates(const QList<QSslCertificate> &certs); 162 Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QSslCertificate &cert, 163 const QString &peerName); 164 Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname); 165 166 // The socket itself, including private slots. 167 QTcpSocket *plainSocket; 168 void createPlainSocket(QIODevice::OpenMode openMode); 169 static void pauseSocketNotifiers(QSslSocket*); 170 static void resumeSocketNotifiers(QSslSocket*); 171 // ### The 2 methods below should be made member methods once the QSslContext class is made public 172 static void checkSettingSslContext(QSslSocket*, QSharedPointer<QSslContext>); 173 static QSharedPointer<QSslContext> sslContext(QSslSocket *socket); 174 bool isPaused() const; 175 bool bind(const QHostAddress &address, quint16, QAbstractSocket::BindMode) override; 176 void _q_connectedSlot(); 177 void _q_hostFoundSlot(); 178 void _q_disconnectedSlot(); 179 void _q_stateChangedSlot(QAbstractSocket::SocketState); 180 void _q_errorSlot(QAbstractSocket::SocketError); 181 void _q_readyReadSlot(); 182 void _q_channelReadyReadSlot(int); 183 void _q_bytesWrittenSlot(qint64); 184 void _q_channelBytesWrittenSlot(int, qint64); 185 void _q_readChannelFinishedSlot(); 186 void _q_flushWriteBuffer(); 187 void _q_flushReadBuffer(); 188 void _q_resumeImplementation(); 189 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) 190 virtual void _q_caRootLoaded(QSslCertificate,QSslCertificate) = 0; 191 #endif 192 193 static QList<QByteArray> unixRootCertDirectories(); // used also by QSslContext 194 195 virtual qint64 peek(char *data, qint64 maxSize) override; 196 virtual QByteArray peek(qint64 maxSize) override; 197 qint64 skip(qint64 maxSize) override; 198 bool flush() override; 199 200 // Platform specific functions 201 virtual void startClientEncryption() = 0; 202 virtual void startServerEncryption() = 0; 203 virtual void transmit() = 0; 204 virtual void disconnectFromHost() = 0; 205 virtual void disconnected() = 0; 206 virtual QSslCipher sessionCipher() const = 0; 207 virtual QSsl::SslProtocol sessionProtocol() const = 0; 208 virtual void continueHandshake() = 0; 209 210 Q_AUTOTEST_EXPORT static bool rootCertOnDemandLoadingSupported(); 211 212 private: 213 static bool ensureLibraryLoaded(); 214 static void ensureCiphersAndCertsLoaded(); 215 #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) 216 static QList<QByteArray> fetchSslCertificateData(); 217 #endif 218 219 static bool s_libraryLoaded; 220 static bool s_loadedCiphersAndCerts; 221 protected: 222 bool verifyErrorsHaveBeenIgnored(); 223 bool paused; 224 bool flushTriggered; 225 bool systemOrSslErrorDetected = false; 226 QVector<QOcspResponse> ocspResponses; 227 bool fetchAuthorityInformation = false; 228 }; 229 230 #if QT_CONFIG(securetransport) || QT_CONFIG(schannel) 231 // Implemented in qsslsocket_qt.cpp 232 QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase); 233 #endif 234 235 QT_END_NAMESPACE 236 237 #endif 238