From 73ad2bf32f83a19630ae12845627a33bbb76985d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20L=C3=B6sch?= Date: Tue, 11 Aug 2015 10:27:16 +0200 Subject: Make ephemeral server key available When using cipher algorithms with forward secrecy an ephemeral key is used to generate the symmetric session key. Beside the SSL certificate's key, this ephemeral key is of cryptographic interest. The ephemeral key is chosen by the server side - currently statically in the Qt implementation - so it is only of interest on the client side to check it. Therefore the ephemeral key is the null key if the connection is set up in server mode or a cipher without forward secrecy is used. Change-Id: If241247dbb8490a91233ae47f2b38952c6591bf4 Reviewed-by: Markus Goetz (Woboq GmbH) --- src/network/ssl/qsslconfiguration.cpp | 17 +++++++++++++++++ src/network/ssl/qsslconfiguration.h | 2 ++ src/network/ssl/qsslconfiguration_p.h | 2 ++ src/network/ssl/qsslsocket_openssl.cpp | 8 ++++++++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 3 +++ 5 files changed, 32 insertions(+) (limited to 'src/network/ssl') diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 4803e47224..1f9055b50c 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -730,6 +730,23 @@ int QSslConfiguration::sessionTicketLifeTimeHint() const return d->sslSessionTicketLifeTimeHint; } +/*! + \since 5.7 + + Returns the ephemeral server key used for cipher algorithms + with forward secrecy, e.g. DHE-RSA-AES128-SHA. + + The ephemeral key is only available when running in client mode, i.e. + QSslSocket::SslClientMode. When running in server mode or using a + cipher algorithm without forward secrecy a null key is returned. + The ephemeral server key will be set before emitting the encrypted() + signal. + */ +QSslKey QSslConfiguration::ephemeralServerKey() const +{ + return d->ephemeralServerKey; +} + /*! \since 5.5 diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index 2cbc31b032..29ae95746e 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -128,6 +128,8 @@ public: void setSessionTicket(const QByteArray &sessionTicket); int sessionTicketLifeTimeHint() const; + QSslKey ephemeralServerKey() const; + // EC settings QVector ellipticCurves() const; void setEllipticCurves(const QVector &curves); diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h index 3fd1252a7b..e636699854 100644 --- a/src/network/ssl/qsslconfiguration_p.h +++ b/src/network/ssl/qsslconfiguration_p.h @@ -113,6 +113,8 @@ public: QByteArray sslSession; int sslSessionTicketLifeTimeHint; + QSslKey ephemeralServerKey; + QList nextAllowedProtocols; QByteArray nextNegotiatedProtocol; QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus; diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index bbd712317c..a5ca844e88 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1566,6 +1566,14 @@ void QSslSocketBackendPrivate::continueHandshake() } #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) { + EVP_PKEY *key; + if (q_SSL_get_server_tmp_key(ssl, &key)) + configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey); + } +#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ... + connectionEncrypted = true; emit q->encrypted(); if (autoStartHandshake && pendingClose) { diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 7f87f11b7c..08d84a440b 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -483,6 +483,9 @@ size_t q_EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); int q_EC_curve_nist2nid(const char *name); #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L #endif // OPENSSL_NO_EC +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +#define q_SSL_get_server_tmp_key(ssl, key) q_SSL_ctrl((ssl), SSL_CTRL_GET_SERVER_TMP_KEY, 0, (char *)key) +#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L // PKCS#12 support int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); -- cgit v1.2.3