Мне нужно обмениваться данными с сервером, для которого требуется локальный сертификат (файл .crt). Я пробую это:
loginRequest = QNetworkRequest(QUrl("https://somesite.com/login"));
QSslConfiguration sslConf = loginRequest.sslConfiguration();
QList<QSslCertificate> certs = QSslCertificate::fromPath(Preferences::certificatePath());
qDebug() << certs.first().issuerInfo(QSslCertificate::Organization); // prints name
sslConf.setLocalCertificate(certs.first());
qDebug() << "is valid " << sslConf.localCertificate().isValid(); // true
qDebug() << "is null " << sslConf.localCertificate().isNull(); // false
qDebug() << "protocol " << sslConf.protocol(); // 0
sslConf.setProtocol(QSsl::SslV3); // i also tried Qssl::AnyProtocol
qDebug() << "protocol " << sslConf.protocol(); // 0
// if i uncomment these i expect everithing to work
//QSslConfiguration::setDefaultConfiguration(sslConf);
//QSslSocket::addDefaultCaCertificate(certs.first());
//loginRequest.setSslConfiguration(sslConf);
QObject::connect(connectionManager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), this, SLOT(printSslErrors2(QNetworkReply*,QList<QSslError>)));
m_reply = connectionManager->get(loginRequest);
QObject::connect(m_reply, SIGNAL(readyRead()), this, SLOT(getCookie()));
QObject::connect(m_reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(printSslErrors(QList<QSslError>)));
Когда этот код выполняется, у меня есть следующие сообщения в WireShark (фильтр: tcp && ssl && ip.addr == my_addr):
Client Hello
ServerHello, Certificate
Server Key Exchange, Certificate request, Server Hello Done
Alert (level: Warning, Description: no certificate), client key exchange, change cipher spec, encrypted handshake message
Alert (level: Fatal, Description: Handshake failure)
Это ожидаемо - код для применения сертификата закомментирован, но странная вещь - я не получаю никаких ошибок ssl от моего QNetworkAccessManager и QNetworkReply (слоты printSslErrors и printSslErrors2).
Если я раскомментирую любую из этих 3 строк:
//QSslConfiguration::setDefaultConfiguration(sslConf);
//QSslSocket::addDefaultCaCertificate(certs.first());
//loginRequest.setSslConfiguration(sslConf);
Я НИЧЕГО не получаю в wireshark (мало сообщений SYN, ACK и FIN tcp, но нет трафика http или ssl). Также до сих пор нет ошибок от QNetworkAccessManager и QNetworkReply, поэтому я понятия не имею, что происходит не так.
Есть ли шанс заставить Qt принять мой локальный сертификат или может быть какая-то сторонняя библиотека, ориентированная на qt, чтобы помочь мне?
P.S.: Кстати, несколько дней назад ssl и https работали нормально, до того, как сервер был изменен, чтобы требовать сертификаты на стороне клиента.
PPS: сертификат является самоподписанным, если это имеет значение. Также я попытался «установить» его (файл p12) в систему, и Chrome и IE7 могут использовать его и взаимодействовать с сервером.