Hi Everyone,
Now I am trying to write a sample server and client application which will use TLSv1.3 with PSK based authentication.
But it is failing during handshake process. During client Hello PSK identity/key is not shared from client side and this is causing the issue.
Error on server is:
Error during SSL handshake: error:14201076:SSL routines:tls_choose_sigalg:no suitable signature algorithm" local: "tcps://127.0.0.1:xxxxx/" remote: "tcps://127.0.0.1:xxxxx/" peer verify name: ""
Error during SSL handshake: error:14201076:SSL routines:tls_choose_sigalg:no suitable signature algorithm" local: "tcps://127.0.0.1:xxxxx/" remote: "tcps://127.0.0.1:xxxxx/" peer verify name: ""
To copy to clipboard, switch view to plain text mode
Client code:
QSslConfiguration sslConfiguration;
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
//sslConfiguration.setProtocol(QSsl::TlsV1_3); //not required default will be TLSv1.3
sslSocket.setSslConfiguration(sslConfiguration);
QObject::connect(&sslSocket,
&QSslSocket
::preSharedKeyAuthenticationRequired,
this,
[](QSslPreSharedKeyAuthenticator* authenticator)
{
authenticator->setIdentity("xxxx");
authenticator->setPreSharedKey(QByteArrayLiteral("xxxx"));
}
, Qt::DirectConnection);
sslSocket.connectToHostEncrypted("127.0.0.1", 1234);
if (!sslSocket.waitForEncrypted()) {
qDebug() << sslSocket.errorString();
}
QSslConfiguration sslConfiguration;
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
//sslConfiguration.setProtocol(QSsl::TlsV1_3); //not required default will be TLSv1.3
sslSocket.setSslConfiguration(sslConfiguration);
QObject::connect(&sslSocket, &QSslSocket::preSharedKeyAuthenticationRequired,
this,
[](QSslPreSharedKeyAuthenticator* authenticator)
{
authenticator->setIdentity("xxxx");
authenticator->setPreSharedKey(QByteArrayLiteral("xxxx"));
}
, Qt::DirectConnection);
sslSocket.connectToHostEncrypted("127.0.0.1", 1234);
if (!sslSocket.waitForEncrypted()) {
qDebug() << sslSocket.errorString();
}
To copy to clipboard, switch view to plain text mode
server code:
QSslSocket* sslSocket = qobject_cast<QSslSocket*>(nextPendingConnection()); //just added for reference. it will be part of SSLQTcpServer
QSslConfiguration sslConfiguration;
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
//sslConfiguration.setProtocol(QSsl::TlsV1_3); //not required default will be TLSv1.3
connect(sslSocket, &QSslSocket::preSharedKeyAuthenticationRequired,
this,
[](QSslPreSharedKeyAuthenticator* authenticator)
{
//QByteArray expectedClientId { xxxxx };
if (expectedClientId == authenticator->identity())
{
authenticator->setPreSharedKey(QByteArrayLiteral(xxxx));
}
}, Qt::DirectConnection);
sslSocket->setSslConfiguration(sslConfiguration);
sslSocket->startServerEncryption();
QSslSocket* sslSocket = qobject_cast<QSslSocket*>(nextPendingConnection()); //just added for reference. it will be part of SSLQTcpServer
QSslConfiguration sslConfiguration;
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
//sslConfiguration.setProtocol(QSsl::TlsV1_3); //not required default will be TLSv1.3
connect(sslSocket, &QSslSocket::preSharedKeyAuthenticationRequired,
this,
[](QSslPreSharedKeyAuthenticator* authenticator)
{
//QByteArray expectedClientId { xxxxx };
if (expectedClientId == authenticator->identity())
{
authenticator->setPreSharedKey(QByteArrayLiteral(xxxx));
}
}, Qt::DirectConnection);
sslSocket->setSslConfiguration(sslConfiguration);
sslSocket->startServerEncryption();
To copy to clipboard, switch view to plain text mode
I tried a lot to figure out the error. But did not get anything. Then I looked into the Qt source code to know what is happening.
I found for TLSv1.3 'q_SSL_set_psk_use_session_callback' is used to register the PSK callback.
//qsslsocket_openssl.cpp
#if OPENSSL_VERSION_NUMBER >= 0x10101006L
// Set the client callback for TLSv1.3 PSK
if (mode == QSslSocket::SslClientMode
&& QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback); // <--
}
#endif // openssl version >= 0x10101006L
//qsslsocket_openssl.cpp
#if OPENSSL_VERSION_NUMBER >= 0x10101006L
// Set the client callback for TLSv1.3 PSK
if (mode == QSslSocket::SslClientMode
&& QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback); // <--
}
#endif // openssl version >= 0x10101006L
To copy to clipboard, switch view to plain text mode
and inside 'q_ssl_psk_use_session_callback' 'q_SSL_set_psk_client_callback' is used to register 'q_ssl_psk_restore_client'.
'q_ssl_psk_restore_client' again used 'q_SSL_set_psk_client_callback' to register 'q_ssl_psk_client_callback'.
//q_ssl_psk_use_session_callback()
// Temporarily rebind the psk because it will be called next. The function will restore it.
q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client); // <--
return 1; // need to return 1 or else "the connection setup fails."
//q_ssl_psk_use_session_callback()
// Temporarily rebind the psk because it will be called next. The function will restore it.
q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client); // <--
return 1; // need to return 1 or else "the connection setup fails."
To copy to clipboard, switch view to plain text mode
//q_ssl_psk_restore_client()
q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
//q_ssl_psk_restore_client()
q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
To copy to clipboard, switch view to plain text mode
As per my understanding:
During handshake process openssl will call 'q_ssl_psk_use_session_callback' and then it will call 'q_ssl_psk_restore_client' as a fallback. But still it will not get the actual key and it will ignore.
In 'q_ssl_psk_use_session_callback' method instead of 'q_ssl_psk_restore_client' if ' q_ssl_psk_client_callback' is registered then everything will work as expected.
So now I want to know
Is my understanding correct and it is a bug in Qt? If not then what is missing in my side? How can I fix it?
I am using Qt 5.15.2 and it is built with openssl version "OpenSSL 1.1.1g". OS is Ubuntu 18.04.
Thanks,
Bibhu
Bookmarks