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
65class 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
86QT_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:
97struct QHCertStoreDeleter {
98 void operator()(HCERTSTORE store)
99 {
100 CertCloseStore(store, 0);
101 }
102};
103
104using QHCertStorePointer = std::unique_ptr<void, QHCertStoreDeleter>;
105
106#endif // Q_OS_WIN
107
108class QSslSocketPrivate : public QTcpSocketPrivate
109{
110 Q_DECLARE_PUBLIC(QSslSocket)
111public:
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
212private:
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;
221protected:
222 bool verifyErrorsHaveBeenIgnored();
223 // Only implemented/useful in Schannel for now
224 virtual bool hasUndecryptedData() { return false; };
225 bool paused;
226 bool flushTriggered;
227 bool systemOrSslErrorDetected = false;
228 QVector<QOcspResponse> ocspResponses;
229 bool fetchAuthorityInformation = false;
230};
231
232#if QT_CONFIG(securetransport) || QT_CONFIG(schannel)
233// Implemented in qsslsocket_qt.cpp
234QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
235#endif
236
237QT_END_NAMESPACE
238
239#endif
240

source code of qtbase/src/network/ssl/qsslsocket_p.h