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:
Qt Code:
  1. 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:
Qt Code:
  1. QSslConfiguration sslConfiguration;
  2. sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
  3. //sslConfiguration.setProtocol(QSsl::TlsV1_3); //not required default will be TLSv1.3
  4.  
  5. sslSocket.setSslConfiguration(sslConfiguration);
  6.  
  7. QObject::connect(&sslSocket, &QSslSocket::preSharedKeyAuthenticationRequired,
  8. this,
  9. [](QSslPreSharedKeyAuthenticator* authenticator)
  10. {
  11. authenticator->setIdentity("xxxx");
  12. authenticator->setPreSharedKey(QByteArrayLiteral("xxxx"));
  13. }
  14. , Qt::DirectConnection);
  15.  
  16. sslSocket.connectToHostEncrypted("127.0.0.1", 1234);
  17. if (!sslSocket.waitForEncrypted()) {
  18. qDebug() << sslSocket.errorString();
  19. }
To copy to clipboard, switch view to plain text mode 

server code:
Qt Code:
  1. QSslSocket* sslSocket = qobject_cast<QSslSocket*>(nextPendingConnection()); //just added for reference. it will be part of SSLQTcpServer
  2.  
  3. QSslConfiguration sslConfiguration;
  4. sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
  5. //sslConfiguration.setProtocol(QSsl::TlsV1_3); //not required default will be TLSv1.3
  6.  
  7. connect(sslSocket, &QSslSocket::preSharedKeyAuthenticationRequired,
  8. this,
  9. [](QSslPreSharedKeyAuthenticator* authenticator)
  10. {
  11. //QByteArray expectedClientId { xxxxx };
  12. if (expectedClientId == authenticator->identity())
  13. {
  14. authenticator->setPreSharedKey(QByteArrayLiteral(xxxx));
  15. }
  16. }, Qt::DirectConnection);
  17.  
  18. sslSocket->setSslConfiguration(sslConfiguration);
  19. 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.

Qt Code:
  1. //qsslsocket_openssl.cpp
  2. #if OPENSSL_VERSION_NUMBER >= 0x10101006L
  3. // Set the client callback for TLSv1.3 PSK
  4. if (mode == QSslSocket::SslClientMode
  5. && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
  6. q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback); // <--
  7. }
  8. #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'.

Qt Code:
  1. //q_ssl_psk_use_session_callback()
  2.  
  3. // Temporarily rebind the psk because it will be called next. The function will restore it.
  4. q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client); // <--
  5.  
  6. return 1; // need to return 1 or else "the connection setup fails."
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. //q_ssl_psk_restore_client()
  2.  
  3. 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