Skip to content

ssl: server selecting wrong certificate when multiple cert_keys are configured #10915

@v0idpwn

Description

@v0idpwn

Describe the bug
When a TLS 1.3 server is configured with multiple certificate/key pairs via certs_keys, the server may select a certificate whose public key type is incompatible with the client's signature_algorithms extension. This causes the handshake to fail with insufficient_security / no_suitable_signature_algorithm even though a suitable certificate exists in the server's configuration.

In my tests, this happened when I used two certs: one ECDSA and one RSA, both signed by the same RSA CA. When using a client that only accepts RSA, ssl prioritizes using ECDSA and then fails with:

TLS server: In state start at tls_handshake_1_3.erl:1505 generated SERVER ALERT: Fatal - Insufficient Security
      - no_suitable_signature_algorithm

To Reproduce

Have a server listening with multiple cert types:

CertsKeys = [
  #{cert => ECDSACert, key => ECDSAKey},
  #{cert => RSACert,   key => RSAKey}
],
ServerOpts = [{certs_keys, CertsKeys}, {versions, ['tlsv1.3']}],
{ok, LSock} = ssl:listen(Port, ServerOpts).

Connect to it with restricted signature_algs:

ClientOpts = [
  {verify, verify_peer},
  {cacerts, [RSACACert]},
  {versions, ['tlsv1.3']},
  {signature_algs, [rsa_pss_rsae_sha256]},
  {signature_algs_cert, [rsa_pkcs1_sha256, rsa_pss_rsae_sha256]}
],
{ok, Sock} = ssl:connect(Host, Port, ClientOpts).

A script in this repository does all the setup and compares the erlang server with openssl_s, which succeeds with the same client configuration.

Expected behavior
Sucessfully handshake, like openssl_s.

Affected versions
At least 27.3 and main.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue is reported as a bugteam:PSAssigned to OTP team PS

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions