30#include <QtCore/QStringList>
31#include <QtNetwork/QSslKey>
32#include <QtNetwork/QSslCipher>
33#include <QtNetwork/QHostAddress>
34#include <QtNetwork/QNetworkProxy>
45 case QSsl::AnyProtocol:
47#if QT_VERSION >= 0x040800
48 case QSsl::TlsV1SslV3:
50 case QSsl::SecureProtocols:
63 return QSsl::AnyProtocol;
67#if QT_VERSION >= 0x040800
71 if (!(sslVersion & validVersions)) {
72 return QSsl::UnknownProtocol;
82#if QT_VERSION >= 0x040800
84 return QSsl::TlsV1SslV3;
86 return QSsl::SecureProtocols;
91 return QSsl::AnyProtocol;
102 foreach (
const QSslCipher &c, QSslSocket::supportedCiphers()) {
103 allCiphers.insert(c.name(), c);
109 return allCiphers.value(ksc.
name());
117class KSslErrorPrivate
123 case QSslError::NoError:
125 case QSslError::UnableToGetLocalIssuerCertificate:
126 case QSslError::InvalidCaCertificate:
128 case QSslError::InvalidNotBeforeField:
129 case QSslError::InvalidNotAfterField:
130 case QSslError::CertificateNotYetValid:
131 case QSslError::CertificateExpired:
133 case QSslError::UnableToDecodeIssuerPublicKey:
134 case QSslError::SubjectIssuerMismatch:
135 case QSslError::AuthorityIssuerSerialNumberMismatch:
137 case QSslError::SelfSignedCertificate:
138 case QSslError::SelfSignedCertificateInChain:
140 case QSslError::CertificateRevoked:
142 case QSslError::InvalidPurpose:
144 case QSslError::CertificateUntrusted:
146 case QSslError::CertificateRejected:
148 case QSslError::NoPeerCertificate:
150 case QSslError::HostNameMismatch:
152 case QSslError::UnableToVerifyFirstCertificate:
153 case QSslError::UnableToDecryptCertificateSignature:
154 case QSslError::UnableToGetIssuerCertificate:
155 case QSslError::CertificateSignatureFailed:
157 case QSslError::PathLengthExceeded:
159 case QSslError::UnspecifiedError:
160 case QSslError::NoSslSupport:
170 return i18nc(
"SSL error",
"No error");
172 return i18nc(
"SSL error",
"The certificate authority's certificate is invalid");
174 return i18nc(
"SSL error",
"The certificate has expired");
176 return i18nc(
"SSL error",
"The certificate is invalid");
178 return i18nc(
"SSL error",
"The certificate is not signed by any trusted certificate authority");
180 return i18nc(
"SSL error",
"The certificate has been revoked");
182 return i18nc(
"SSL error",
"The certificate is unsuitable for this purpose");
184 return i18nc(
"SSL error",
"The root certificate authority's certificate is not trusted for this purpose");
186 return i18nc(
"SSL error",
"The certificate authority's certificate is marked to reject this certificate's purpose");
188 return i18nc(
"SSL error",
"The peer did not present any certificate");
190 return i18nc(
"SSL error",
"The certificate does not apply to the given host");
192 return i18nc(
"SSL error",
"The certificate cannot be verified for internal reasons");
194 return i18nc(
"SSL error",
"The certificate chain is too long");
197 return i18nc(
"SSL error",
"Unknown error");
202 QSslCertificate certificate;
207 : d(new KSslErrorPrivate())
209 d->error = errorCode;
215 : d(new KSslErrorPrivate())
217 d->error = KSslErrorPrivate::errorFromQSslError(other.error());
218 d->certificate = other.certificate();
223 : d(new KSslErrorPrivate())
250 return KSslErrorPrivate::errorString(d->error);
256 return d->certificate;
260class KTcpSocketPrivate
265 certificatesLoaded(false),
266 emittedReadyRead(false)
275 case QAbstractSocket::UnconnectedState:
277 case QAbstractSocket::HostLookupState:
279 case QAbstractSocket::ConnectingState:
281 case QAbstractSocket::ConnectedState:
283 case QAbstractSocket::ClosingState:
285 case QAbstractSocket::BoundState:
286 case QAbstractSocket::ListeningState:
296 case QSslSocket::SslClientMode:
298 case QSslSocket::SslServerMode:
308 case QAbstractSocket::ConnectionRefusedError:
310 case QAbstractSocket::RemoteHostClosedError:
312 case QAbstractSocket::HostNotFoundError:
314 case QAbstractSocket::SocketAccessError:
316 case QAbstractSocket::SocketResourceError:
318 case QAbstractSocket::SocketTimeoutError:
320 case QAbstractSocket::NetworkError:
322 case QAbstractSocket::UnsupportedSocketOperationError:
324 case QAbstractSocket::SslHandshakeFailedError:
326 case QAbstractSocket::DatagramTooLargeError:
328 case QAbstractSocket::AddressInUseError:
329 case QAbstractSocket::SocketAddressNotAvailableError:
331 case QAbstractSocket::ProxyAuthenticationRequiredError:
333 case QAbstractSocket::UnknownSocketError:
340 void reemitSocketError(QAbstractSocket::SocketError e)
342 emit q->error(errorFromAbsSocket(e));
349 foreach (
const QSslError &e, errors) {
352 emit q->sslErrors(kErrors);
355 void reemitStateChanged(QAbstractSocket::SocketState s)
357 emit q->stateChanged(state(s));
360 void reemitModeChanged(QSslSocket::SslMode m)
362 emit q->encryptionModeChanged(encryptionMode(m));
368 void reemitReadyRead()
370 if (!emittedReadyRead) {
371 emittedReadyRead =
true;
373 emittedReadyRead =
false;
377 void maybeLoadCertificates()
379 if (!certificatesLoaded) {
381 certificatesLoaded =
true;
386 bool certificatesLoaded;
387 bool emittedReadyRead;
397 d(new KTcpSocketPrivate(this))
399 d->advertisedSslVersion =
SslV3;
401 connect(&d->sock, SIGNAL(aboutToClose()),
this, SIGNAL(aboutToClose()));
402 connect(&d->sock, SIGNAL(bytesWritten(
qint64)),
this, SIGNAL(bytesWritten(
qint64)));
404 connect(&d->sock, SIGNAL(readyRead()),
this, SLOT(reemitReadyRead()));
408#ifndef QT_NO_NETWORKPROXY
412 connect(&d->sock, SIGNAL(
error(QAbstractSocket::SocketError)),
413 this, SLOT(reemitSocketError(QAbstractSocket::SocketError)));
417 connect(&d->sock, SIGNAL(
stateChanged(QAbstractSocket::SocketState)),
418 this, SLOT(reemitStateChanged(QAbstractSocket::SocketState)));
419 connect(&d->sock, SIGNAL(modeChanged(QSslSocket::SslMode)),
420 this, SLOT(reemitModeChanged(QSslSocket::SslMode)));
433 return d->sock.atEnd() && QIODevice::atEnd();
439 return d->sock.bytesAvailable() + QIODevice::bytesAvailable();
445 return d->sock.bytesToWrite();
451 return d->sock.canReadLine() || QIODevice::canReadLine();
470 bool ret = d->sock.open(
open);
471 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
478 return d->sock.waitForBytesWritten(msecs);
484 return d->sock.waitForReadyRead(msecs);
490 return d->sock.read(data, maxSize);
496 return d->sock.write(data, maxSize);
512 d->sock.connectToHost(hostName, port);
519 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
528 d->sock.connectToHost(hostAddress, port);
529 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
538 d->sock.connectToHost(url.host(), url.port());
539 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
545 d->sock.disconnectFromHost();
546 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
552 return d->errorFromAbsSocket(d->sock.error());
562 foreach (
const QSslError &e, d->sock.sslErrors())
570 return d->sock.flush();
576 return d->sock.isValid();
582 return d->sock.localAddress();
588 return d->sock.peerAddress();
594 return d->sock.peerName();
600 return d->sock.peerPort();
604#ifndef QT_NO_NETWORKPROXY
607 return d->sock.proxy();
613 return d->sock.readBufferSize();
617#ifndef QT_NO_NETWORKPROXY
620 d->sock.setProxy(
proxy);
626 d->sock.setReadBufferSize(size);
632 return d->state(d->sock.state());
638 bool ret = d->sock.waitForConnected(msecs);
640 setErrorString(d->sock.errorString());
641 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
648 bool ret = d->sock.waitForDisconnected(msecs);
650 setErrorString(d->sock.errorString());
651 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
659 d->maybeLoadCertificates();
660 d->sock.addCaCertificate(certificate);
676 d->maybeLoadCertificates();
677 d->sock.addCaCertificates(certificates);
683 d->maybeLoadCertificates();
684 return d->sock.caCertificates();
696 d->maybeLoadCertificates();
698 d->sock.connectToHostEncrypted(hostName, port, openMode);
699 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
705 return d->sock.localCertificate();
711 return d->sock.peerCertificateChain();
717 return KSslKey(d->sock.privateKey());
729 d->sock.setCaCertificates(certificates);
730 d->certificatesLoaded =
true;
739 cl.append(d->ccc.converted(c));
741 d->sock.setCiphers(cl);
747 d->sock.setLocalCertificate(certificate);
753 d->sock.setLocalCertificate(fileName, format);
759#if QT_VERSION >= 0x040800
760 d->sock.setPeerVerifyName(hostName);
773 QSslKey _key(key.
toDer(),
778 d->sock.setPrivateKey(_key);
783 QSsl::EncodingFormat format,
const QByteArray &passPhrase)
789 d->sock.setPrivateKey(fileName,
798 return d->sock.waitForEncrypted(msecs);
804 return d->encryptionMode(d->sock.mode());
809 return d->sock.socketOption(options);
814 d->sock.setSocketOption(options, value);
819 return d->sock.sslConfiguration();
824 d->sock.setSslConfiguration(configuration);
830 d->sock.ignoreSslErrors();
837 d->maybeLoadCertificates();
839 d->sock.startClientEncryption();
844void KTcpSocket::showSslErrors()
846 foreach (
const QSslError &e, d->sock.sslErrors())
847 kDebug(7029) << e.errorString();
853 d->advertisedSslVersion = version;
859 return d->advertisedSslVersion;
865 if (!d->sock.isEncrypted()) {
874 if (!d->sock.isEncrypted()) {
877 return d->sock.sessionCipher().protocolString();
904 : d(new KSslKeyPrivate)
908 d->isExportable =
true;
913 : d(new KSslKeyPrivate)
920 : d(new KSslKeyPrivate)
922 d->algorithm = d->convertAlgorithm(qsk.algorithm());
924 d->isExportable =
true;
925 d->der = qsk.toDer();
950 return d->isExportable;
968class KSslCipherPrivate
983 : d(new KSslCipherPrivate)
986 d->supportedBits = 0;
992 : d(new KSslCipherPrivate)
999 : d(new KSslCipherPrivate)
1001 d->authenticationMethod = qsc.authenticationMethod();
1002 d->encryptionMethod = qsc.encryptionMethod();
1005 int parenIdx = d->encryptionMethod.indexOf(QLatin1Char(
'('));
1007 d->encryptionMethod.truncate(parenIdx);
1008 d->keyExchangeMethod = qsc.keyExchangeMethod();
1009 d->name = qsc.name();
1010 d->isNull = qsc.isNull();
1011 d->supportedBits = qsc.supportedBits();
1012 d->usedBits = qsc.usedBits();
1037 return d->authenticationMethod;
1043 return d->encryptionMethod;
1049 return d->keyExchangeMethod;
1057 if (d->name.endsWith(QLatin1String(
"SHA")))
1058 return QString::fromLatin1(
"SHA-1");
1059 else if (d->name.endsWith(QLatin1String(
"MD5")))
1060 return QString::fromLatin1(
"MD5");
1062 return QString::fromLatin1(
"");
1074 return d->supportedBits;
1089 foreach(
const QSslCipher &c, candidates) {
1123 foreach (
const QSslError &e, socket->sslErrors())
1126 d->
ip = socket->peerAddress().toString();
1127 d->
host = socket->peerName();
1128 if (socket->isEncrypted()) {
1129 d->
sslProtocol = socket->sessionCipher().protocolString();
1131 d->
cipher = socket->sessionCipher().name();
1132 d->
usedBits = socket->sessionCipher().usedBits();
1133 d->
bits = socket->sessionCipher().supportedBits();
1153#include "ktcpsocket.moc"
static KSslCertificateManager * self()
QString encryptionMethod() const
QString keyExchangeMethod() const
QString authenticationMethod() const
QString digestMethod() const
int supportedBits() const
KSslCipher & operator=(const KSslCipher &other)
static QList< KSslCipher > supportedCiphers()
QList< KSslError > sslErrors
QList< QSslCertificate > certificateChain
This class can hold all the necessary data from a KTcpSocket to ask the user to continue connecting i...
KSslErrorUiData()
Default construct an instance with no useful data.
~KSslErrorUiData()
Destructor.
KSslErrorUiData & operator=(const KSslErrorUiData &)
KSslError & operator=(const KSslError &other)
QSslCertificate certificate() const
@ CertificateSignatureFailed
@ InvalidCertificatePurpose
@ InvalidCertificateAuthorityCertificate
QString errorString() const
KSslError(KSslError::Error error=NoError, const QSslCertificate &cert=QSslCertificate())
bool isExportable() const
KSslKey & operator=(const KSslKey &other)
Algorithm algorithm() const
KeySecrecy secrecy() const
bool waitForEncrypted(int msecs=30000)
virtual bool waitForReadyRead(int msecs=30000)
void addCaCertificates(const QList< QSslCertificate > &certificates)
virtual bool canReadLine() const
QSslConfiguration sslConfiguration() const
Returns the socket's SSL configuration.
virtual qint64 bytesToWrite() const
KSslCipher sessionCipher() const
KSslKey privateKey() const
QList< QSslCertificate > peerCertificateChain() const
QVariant socketOption(QAbstractSocket::SocketOption options) const
Returns the state of the socket option.
void setProxy(const QNetworkProxy &proxy)
void encryptedBytesWritten(qint64 written)
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
virtual bool atEnd() const
void connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy=AutoProxy)
void setCaCertificates(const QList< QSslCertificate > &certificates)
virtual qint64 readData(char *data, qint64 maxSize)
EncryptionMode encryptionMode() const
QHostAddress localAddress() const
void setSslConfiguration(const QSslConfiguration &configuration)
Sets the socket's SSL configuration.
void setCiphers(const QList< KSslCipher > &ciphers)
virtual qint64 writeData(const char *data, qint64 maxSize)
void setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value)
Sets the socket option to value.
qint64 readBufferSize() const
void addCaCertificate(const QSslCertificate &certificate)
@ AutoProxy
Use the proxy that KProtocolManager suggests for the connection parameters given.
bool waitForDisconnected(int msecs=30000)
QString negotiatedSslVersionName() const
void stateChanged(KTcpSocket::State)
QNetworkProxy proxy() const
QHostAddress peerAddress() const
void setLocalCertificate(const QSslCertificate &certificate)
virtual bool waitForBytesWritten(int msecs)
QList< QSslCertificate > caCertificates() const
virtual qint64 bytesAvailable() const
QList< KSslCipher > ciphers() const
SslVersion advertisedSslVersion() const
QList< KSslError > sslErrors() const
void setReadBufferSize(qint64 size)
virtual bool isSequential() const
@ UnsupportedSocketOperationError
@ SslHandshakeFailedError
void disconnectFromHost()
virtual bool open(QIODevice::OpenMode open)
SslVersion negotiatedSslVersion() const
KTcpSocket(QObject *parent=0)
void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode=ReadWrite)
QSslCertificate localCertificate() const
void setPrivateKey(const KSslKey &key)
void setAdvertisedSslVersion(SslVersion version)
bool waitForConnected(int msecs=30000)
void startClientEncryption()
void setVerificationPeerName(const QString &hostName)
Represents and parses a URL.
QString i18nc(const char *ctxt, const char *text)
Returns a localized version of a string and a context.
static KTcpSocket::SslVersion kSslVersionFromQ(QSsl::SslProtocol protocol)
static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion sslVersion)