0

When I am testing mutual TLS handshake performance on TLS1.3 using OpenSSL, I find a very wired thing:

I created two groups of servers and clients:

  1. Server1 has a certificate signed using RSA3072, and Client1 has a certificate signed using ECDSAP256
  2. Server1 has a certificate signed using ECDSAP256, and Client1 has a certificate signed using RSA3072

In theory, the handshake performance for Group 1 and 2 should be roughly the same because:

  1. both combinations should generate one RSA3072 and one ECDSA256 signature for CertificateVerify.
  2. both combinations will verify two RSA3072 and two ECDSA256 signature.

However, the test result is different. The handshake setup speed of Group1 is much faster than Group2.

Result for Group 1 enter image description here

Result for Group 2 enter image description here

According to algorithm performance, the verify speed of RSA3072 is slightly faster than ECDSAP256 but its sign speed is much slower than ECDSAP256. Therefore, I suspect that the CertificateVerify message from the server is not generated during the handshake process.

I am very confused about this guess because, in the tls1.3 IETF, it says that:

CertificateVerify: A signature over the entire handshake using the private key corresponding to the public key in the Certificate message.

The CertificateVerify is generated based on the handshake information so it should be generated during this process.

My questions here are:

Is there any error in my test and my guess?

If my guess is right then when does the server generate the CertificateVerify message?

More Clarification:

The certificate chain is generated by my own using the openssl command and the root certificate is self-signed.

For the testing, I used s_server and s_time to test the performance. I also used s_client with -msg to trace the process of the handshake. The certificate verification happened and the CertificateVerify messages for both server and client are sent.

  • To be clear, what matters to the protocol is the key _in_ the certificate, not the signature _on_ it; these may be different, although they usually aren't, and if you generated your own certs with e.g. `openssl req -new -x509` they definitely aren't. If you don't use selfsigned (pseudo-root) certs, _and_ are verifying (e.g. _not_ using `openssl s_client` default), then each party needs to _generate_ one signature (protocol) but _verify_ at least two (protocol and certificate), which will affect timing. – dave_thompson_085 Mar 22 '22 at 02:54
  • But as to your Q, 1.3 always sends CertVerify and always with a newly-generated signature -- except if doing session resumption, which doesn't use any cert(s) at all, and would be the same in all your four cases i.e. regardless of what type of certs it doesn't use. Do you have traces or (precisely) timed logs showing this behavior? – dave_thompson_085 Mar 22 '22 at 02:58
  • Hi Thompson, thank you for helping me. Here is my clarification: I created a self-signed root cert using openssl. The server and the client are both signed by the rootCA. I then used `openssl s_time` to test the performance. I also used `openssl s_client` with `-msg` key to trace the process of the handshake. The certificate verification indeed happened and the CertificateVerify message is sent for both server and client. – JIQING CHEN Mar 22 '22 at 03:22

0 Answers0