Emit QSslSocket::error in case of openssl gives an error.

Create new QAbstractSocket::SocketError value that denotes a error in
the SSL library: SslInternalError
Create QAbstractSocket::SocketError value that denotes a error in data
provided by user cauding an SSL library error: SslInvalidUserDataError

Change-Id: I466a9389d9d7052efd8eddd1a2d6067ba26dfddb
Reviewed-by: Richard J. Moore <rich@kde.org>
Reviewed-by: Shane Kearns <ext-shane.2.kearns@nokia.com>
This commit is contained in:
Jonas M. Gastal 2012-01-26 11:28:39 -02:00 committed by Qt by Nokia
parent 96f1fe8855
commit 695dded37b
3 changed files with 38 additions and 25 deletions

View File

@ -317,6 +317,10 @@
because the response from the proxy server could not be understood.
\value OperationError An operation was attempted while the socket was in a state that
did not permit it.
\value SslInternalError The SSL library being used reported a internal error, this is
probably the result of a bad installation or misconfiguration of the library.
\value SslInvalidUserDataError Invalid data(certificate, key, cypher, etc.) was
provided and its use resulted in an error in the SSL library.
\value UnknownSocketError An unidentified error occurred.
\sa QAbstractSocket::error()

View File

@ -97,6 +97,8 @@ public:
ProxyNotFoundError,
ProxyProtocolError,
OperationError,
SslInternalError, /* 20 */
SslInvalidUserDataError,
UnknownSocketError = -1
};

View File

@ -327,10 +327,9 @@ init_context:
goto init_context;
}
// ### Bad error code
q->setErrorString(QSslSocket::tr("Error creating SSL context (%1)").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return false;
}
@ -353,10 +352,9 @@ init_context:
}
if (!q_SSL_CTX_set_cipher_list(ctx, cipherString.data())) {
// ### Bad error code
q->setErrorString(QSslSocket::tr("Invalid or empty cipher list (%1)").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
emit q->error(QAbstractSocket::SslInvalidUserDataError);
return false;
}
@ -399,14 +397,16 @@ init_context:
// Require a private key as well.
if (configuration.privateKey.isNull()) {
q->setErrorString(QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(getErrorsFromOpenSsl()));
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
emit q->error(QAbstractSocket::SslInvalidUserDataError);
return false;
}
// Load certificate
if (!q_SSL_CTX_use_certificate(ctx, reinterpret_cast<X509 *>(configuration.localCertificate.handle()))) {
q->setErrorString(QSslSocket::tr("Error loading local certificate, %1").arg(getErrorsFromOpenSsl()));
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return false;
}
@ -426,7 +426,8 @@ init_context:
if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) {
q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(getErrorsFromOpenSsl()));
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return false;
}
if (configuration.privateKey.algorithm() == QSsl::Opaque)
@ -435,7 +436,8 @@ init_context:
// Check if the certificate matches the private key.
if (!q_SSL_CTX_check_private_key(ctx)) {
q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg(getErrorsFromOpenSsl()));
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
emit q->error(QAbstractSocket::SslInvalidUserDataError);
return false;
}
}
@ -455,8 +457,8 @@ init_context:
if (!(ssl = q_SSL_new(ctx))) {
// ### Bad error code
q->setErrorString(QSslSocket::tr("Error creating SSL session, %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return false;
}
@ -489,10 +491,9 @@ init_context:
readBio = q_BIO_new(q_BIO_s_mem());
writeBio = q_BIO_new(q_BIO_s_mem());
if (!readBio || !writeBio) {
// ### Bad error code
q->setErrorString(QSslSocket::tr("Error creating SSL session: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return false;
}
@ -805,8 +806,11 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
void QSslSocketBackendPrivate::startClientEncryption()
{
Q_Q(QSslSocket);
if (!initSslContext()) {
// ### report error: internal OpenSSL failure
q->setErrorString(QSslSocket::tr("Unable to init Ssl Context: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return;
}
@ -818,8 +822,11 @@ void QSslSocketBackendPrivate::startClientEncryption()
void QSslSocketBackendPrivate::startServerEncryption()
{
Q_Q(QSslSocket);
if (!initSslContext()) {
// ### report error: internal OpenSSL failure
q->setErrorString(QSslSocket::tr("Unable to init Ssl Context: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return;
}
@ -856,8 +863,8 @@ void QSslSocketBackendPrivate::transmit()
if (writtenBytes <= 0) {
// ### Better error handling.
q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return;
}
#ifdef QSSLSOCKET_DEBUG
@ -926,8 +933,8 @@ void QSslSocketBackendPrivate::transmit()
} else {
// ### Better error handling.
q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return;
}
@ -1007,8 +1014,8 @@ void QSslSocketBackendPrivate::transmit()
// we do not know exactly what the error is, nor whether we can recover from it,
// so just return to prevent an endless loop in the outer "while" statement
q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
return;
default:
// SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
@ -1017,8 +1024,8 @@ void QSslSocketBackendPrivate::transmit()
// SSL_CTX_set_client_cert_cb(), which we do not call.
// So this default case should never be triggered.
q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
q->setSocketError(QAbstractSocket::SslInternalError);
emit q->error(QAbstractSocket::SslInternalError);
break;
}
} while (ssl && readBytes > 0);