Details
-
Bug
-
Resolution: Done
-
Not Evaluated
-
None
-
4.8.6
-
None
Description
QSslSocket provides a set and get method for the SSL/TLS protocol to be used the handshake process. However, it provides no means of accessing the actual negotiated protocol directly through QSslSocket. Currently the only means to obtain such information is through the session cipher returned by calling sessionCipher() on the socket. Unfortunately, the protocol as well as the string representation of the protocol returned by QSslCipher are only correct by chance.
I make the above claim because the openSSL documentation at http://www.openssl.org/docs/ssl/SSL_CIPHER_get_name.html states that the protocol information found there is only present to convey historical information:
"SSL_CIPHER_get_version() returns string which indicates the SSL/TLS protocol version that first defined the cipher. This is currently SSLv2 or TLSv1/SSLv3. In some cases it should possibly return ``TLSv1.2'' but does not; use SSL_CIPHER_description() instead. If cipher is NULL, ``(NONE)'' is returned."
In other words the protocol information is only there to inform when that cipher was first defined. This explains why one gets a mismatch when comparing the output from the openssl command line with the information from QSslCipher for any TLSv1.1/TLSv1.0 sites. For example, blogs.mozilla.org returns the following when connecting from command line with openssl:
SSL handshake has read 3845 bytes and written 522 bytes
—
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.1
Cipher : DHE-RSA-AES128-SHA
Session-ID: 3C086565B306F6820E32B32DEBB7AB8AD08F34C75762E5A57C6F58A779B3D0CC
Session-ID-ctx:
Master-Key: 9CB04F4016FA9C9A3F83D7040B9BA98D0C6C67E33AE4A85B4FE37DB1DEE8FE97F9B9A5B10B45B4F176118094C0A8ACA1
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1413953653
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
while the QSslSocket session cipher returns the following:
QSslCipher Information:
=======================
name: "DHE-RSA-AES128-SHA"
authenticationmethod: "RSA"
encryptionMethod: "AES(128)"
keyExchangeMethod: "DH"
protocol: 0
protocolString: "SSLv3"
supportedBits: 128
usedBits: 128
As you can see from both outputs the negotiated cipher is the same, "DHE-RSA-AES128-SHA". However, where as QSslCipher's protocol indicates seems to indicate the connection is using "SSLv3" protocol, the openSSL one shows it is using "TLSv1.1". Grepping the openssl cipher list for the negotiated cipher clearly shows where QSslCipher obtained the protocol from:
$ openssl ciphers -v | grep -e "^DHE-RSA-AES128-SHA "
DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1