Reputation: 1463
I'm writing a proxy server, http part is ready, but are having problems with https. I created a certificate and private key (as I understood, without it will not work) in this way:
OpenSSL> req-x509-newkey rsa: 2048-keyout server.key-nodes-days 365-out server.csr
I did a simple QTcpServer that is passed a socketDescriptor to the created object on newIncomingConnection(). In constructor of my object I did:
sock = new QSslSocket();
connect (sock,SIGNAL(readyRead()),this,SLOT(onQuery()));
connect(sock,SIGNAL(disconnected()),this,SLOT(deleteLater()));
connect(sock,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError(QAbstractSocket::SocketError)));
connect(sock,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(sltSslErrors(QList<QSslError>)));
...
Load key and cert
...
sock->setProtocol(QSsl::AnyProtocol);
QSslKey sslKey(key, QSsl::Rsa);
QSslCertificate sslCert(cert);
sock->setPrivateKey(sslKey);
sock->setLocalCertificate(sslCert);
sock->setSocketDescriptor(socketDesc);
sock->startServerEncryption();
if(!sock->waitForEncrypted(30000)) {
qDebug()<<"wait for encrypted failed";
}
On connect in console I see "wait for encrypted failed" and socket emited signal error() with QAbstractSocket::SslHandshakeFailedError. Could you give advice on what else to do that would be to establish the ssl connection without error ?
Upvotes: 0
Views: 1436
Reputation: 11
I believe you need to call setSocketDescriptor
before calling the setPrivateKey
and setLocalCertificate
methods.
Below is code that I've used to create a HTTPS Server Socket
, extending QTcpServer
.
void SslServer::incomingConnection(qintptr socketDescriptor)
{
QSslSocket *serverSocket = new QSslSocket;
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
QFile keyFile(<sslKeyFileName>);
if (!keyFile.open(QIODevice::ReadOnly)) {
delete serverSocket;
return;
}
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
if (key.isNull()) {
delete serverSocket;
return;
}
keyFile.close();
serverSocket->setPrivateKey(key);
// to prevent asking for client certificate.
serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
serverSocket->setLocalCertificate(<certificateFileName>);
serverSocket->startServerEncryption();
if (serverSocket->waitForEncrypted(3000)) {
// this will emit a newConnection() signal
addPendingConnection(serverSocket);
} else {
qDebug() << "Encryption Failed.";
delete serverSocket;
}
} else {
delete serverSocket;
}
}
Upvotes: 1