Почему не включается TlsV1.2 в Qt 4.8.1

Попытаемся сначала разобраться как работает TCP , ssl под Qt 4.8.1 .

собираем приложение с исходниками openssl 1.0.2 под Qt Creator 2.4.1

Что мы знаем на начальный момент : Qt 4.8.1 использует свободную библиотеку openssl, подключая ее функционал через 2 библиотеки libeay32 и ssleay32, а также подключает заголовочные файлы , поставляемые с этими библиотеками.

Запрос к серверу начинается у нас с команды :

QNetworkReply *reply = qnam.get(request );

Как проследить дальнейший путь ? Дело в том , что далее будет создан отдельный поток для выполнения запроса.

На самом деле все просто: собираем библиотеки Qt 4.8.1 с отладочной информацией (debug вариант, ключ -MDd). Потом делаем маленький тестовый проект для тестирования запроса к серверу.

И открываем оба проекта : сырцы Qt 4.8.1 (src.pro) и наш тестовый проект (назовем его my_qt_ssl.pro) в одном Qt Creator.

В результате будем запускать my_qt_ssl.pro в режиме отладки , и можно ставить точки останова в сырцах. Отладка будет останавливаться в сырцах.

Таким образом было установлено примерно такое исполнение запроса к серверу:

void QNetworkAccessHttpBackend::postRequest()
....
// Create the HTTP thread delegate
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
....
connect(this, SIGNAL(startHttpRequest()), delegate, SLOT(startRequest()));
......
emit startHttpRequest()
.....
void QHttpThreadDelegate::startRequest()
....
QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetworkRequest &request)

Также можно в network.pro влючить дефайны отладочного вывода.

После этого не надо пересобирать все исходники src.pro , достаточно пересобрать только network.pro.

В результате по дебаг выводу стало видно, что не смотря на то , что у нас openssl 1.0.2 , qt все равно посылает первые байты такие:

0x16 0x03 0x01 0x02

16 это просто тип пакета.
А вот 3 1 означает протокол TLSv1.0.

На момент создания библиотек qt 4.8.1 (примерно 2008 г.) максимально использовали только TLSv1.0. Поэтому все логично и надо как-то библиотеки qt изменить , чтобы не использовали TLSv1.0, также кстати не использовали TLSv1.1, а использовали TLSv1.2.

# define TLS1_VERSION                    0x0301
# define TLS1_1_VERSION                  0x0302
# define TLS1_2_VERSION                  0x0303
# define TLS_MAX_VERSION                 TLS1_2_VERSION

# define TLS1_VERSION_MAJOR              0x03
# define TLS1_VERSION_MINOR              0x01

# define TLS1_1_VERSION_MAJOR            0x03
# define TLS1_1_VERSION_MINOR            0x02

# define TLS1_2_VERSION_MAJOR            0x03
# define TLS1_2_VERSION_MINOR            0x03

Инициализация соединения , handshake и посылка первого пакета серверу очевидно происходит здесь:

void QSslSocketPrivate::resetDefaultCiphers()

вариант SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method());

BC3-SHA:DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA

меняем на

SSL_CTX *myCtx = q_SSL_CTX_new(TLSv1_2_client_method());

ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DH-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DH-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DH-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:PSK-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA

Обращаем внимание на функцию resetDefaultCiphers.


setSslConfiguration
  defaultConfiguration
    ensureInitialized
      ensureCiphersAndCertsLoaded
        resetDefaultCiphers
          QSslCipher_from_SSL_CIPHER

Не важно какую из функций в resetDefaultCiphers мы вызовем

    SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method());
    SSL_CTX *myCtx = q_SSL_CTX_new(TLSv1_2_client_method());

Список поддерживаемых наборов шифрования (cipher suites) получится такой :такой :

"ECDHE-RSA-AES256-GCM-SHA384" 
"ECDHE-ECDSA-AES256-GCM-SHA384" 
"ECDHE-RSA-AES256-SHA384" 
"ECDHE-ECDSA-AES256-SHA384" 
"ECDHE-RSA-AES256-SHA" 
"ECDHE-ECDSA-AES256-SHA" 
"SRP-DSS-AES-256-CBC-SHA" 
"SRP-RSA-AES-256-CBC-SHA" 
"SRP-AES-256-CBC-SHA" 
"DH-DSS-AES256-GCM-SHA384" 
"DHE-DSS-AES256-GCM-SHA384" 
"DH-RSA-AES256-GCM-SHA384" 
"DHE-RSA-AES256-GCM-SHA384" 
"DHE-RSA-AES256-SHA256" 
"DHE-DSS-AES256-SHA256" 
"DH-RSA-AES256-SHA256" 
"DH-DSS-AES256-SHA256" 
"DHE-RSA-AES256-SHA" 
"DHE-DSS-AES256-SHA" 
"DH-RSA-AES256-SHA" 
"DH-DSS-AES256-SHA" 
"DHE-RSA-CAMELLIA256-SHA" 
"DHE-DSS-CAMELLIA256-SHA" 
"DH-RSA-CAMELLIA256-SHA" 
"DH-DSS-CAMELLIA256-SHA" 
"ECDH-RSA-AES256-GCM-SHA384" 
"ECDH-ECDSA-AES256-GCM-SHA384" 
"ECDH-RSA-AES256-SHA384" 
"ECDH-ECDSA-AES256-SHA384" 
"ECDH-RSA-AES256-SHA" 
"ECDH-ECDSA-AES256-SHA" 
"AES256-GCM-SHA384" 
"AES256-SHA256" 
"AES256-SHA" 
"CAMELLIA256-SHA" 
"PSK-AES256-CBC-SHA" 
"ECDHE-RSA-AES128-GCM-SHA256" 
"ECDHE-ECDSA-AES128-GCM-SHA256" 
"ECDHE-RSA-AES128-SHA256" 
"ECDHE-ECDSA-AES128-SHA256" 
"ECDHE-RSA-AES128-SHA" 
"ECDHE-ECDSA-AES128-SHA" 
"SRP-DSS-AES-128-CBC-SHA" 
"SRP-RSA-AES-128-CBC-SHA" 
"SRP-AES-128-CBC-SHA" 
"DH-DSS-AES128-GCM-SHA256" 
"DHE-DSS-AES128-GCM-SHA256" 
"DH-RSA-AES128-GCM-SHA256" 
"DHE-RSA-AES128-GCM-SHA256" 
"DHE-RSA-AES128-SHA256" 
"DHE-DSS-AES128-SHA256" 
"DH-RSA-AES128-SHA256" 
"DH-DSS-AES128-SHA256" 
"DHE-RSA-AES128-SHA" 
"DHE-DSS-AES128-SHA" 
"DH-RSA-AES128-SHA" 
"DH-DSS-AES128-SHA" 
"DHE-RSA-SEED-SHA" 
"DHE-DSS-SEED-SHA" 
"DH-RSA-SEED-SHA" 
"DH-DSS-SEED-SHA" 
"DHE-RSA-CAMELLIA128-SHA" 
"DHE-DSS-CAMELLIA128-SHA" 
"DH-RSA-CAMELLIA128-SHA" 
"DH-DSS-CAMELLIA128-SHA" 
"ECDH-RSA-AES128-GCM-SHA256" 
"ECDH-ECDSA-AES128-GCM-SHA256" 
"ECDH-RSA-AES128-SHA256" 
"ECDH-ECDSA-AES128-SHA256" 
"ECDH-RSA-AES128-SHA" 
"ECDH-ECDSA-AES128-SHA" 
"AES128-GCM-SHA256" 
"AES128-SHA256" 
"AES128-SHA" 
"SEED-SHA" 
"CAMELLIA128-SHA" 
"IDEA-CBC-SHA" 
"PSK-AES128-CBC-SHA" 
"ECDHE-RSA-RC4-SHA" 
"ECDHE-ECDSA-RC4-SHA" 
"ECDH-RSA-RC4-SHA" 
"ECDH-ECDSA-RC4-SHA" 
"RC4-SHA" 
"RC4-MD5" 
"PSK-RC4-SHA" 
"ECDHE-RSA-DES-CBC3-SHA" 
"ECDHE-ECDSA-DES-CBC3-SHA" 
"SRP-DSS-3DES-EDE-CBC-SHA" 
"SRP-RSA-3DES-EDE-CBC-SHA" 
"SRP-3DES-EDE-CBC-SHA" 
"EDH-RSA-DES-CBC3-SHA" 
"EDH-DSS-DES-CBC3-SHA" 
"DH-RSA-DES-CBC3-SHA" 
"DH-DSS-DES-CBC3-SHA" 
"ECDH-RSA-DES-CBC3-SHA" 
"ECDH-ECDSA-DES-CBC3-SHA" 
"DES-CBC3-SHA" 
"PSK-3DES-EDE-CBC-SHA"