erlang/otp

Curve secp521r1 not matched on ssl_handshake:curve_to_atom() because of a trimmed leading zero byte

maszlasz opened this issue · 1 comments

Describe the bug
ssl_handshake:curve_to_atom() expects the given curve to be an exact match, even though in my understanding the leading zero bytes in its parameters can be trimmed due to DER encoding, which can happen with secp521r1 and its B parameter. It can be

<<81,149,62,185,97,142,28,154,31,146,154,33,160,182,133,
  64,238,162,218,114,91,153,179,21,243,184,180,137,145,142,241,
  9,225,86,25,57,81,236,126,147,123,22,82,192,189,59,177,
  191,7,53,115,223,136,61,44,52,241,239,69,31,212,107,80,
  63,0>>

which misses the leading zero found here:

curve_to_atom(#'Curve'{
a = <<1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,252>>,
b = <<0,81,149,62,185,97,142,28,154,31,146,154,33,160,182,133,
64,238,162,218,114,91,153,179,21,243,184,180,137,145,142,241,
9,225,86,25,57,81,236,126,147,123,22,82,192,189,59,177,
191,7,53,115,223,136,61,44,52,241,239,69,31,212,107,80,
63,0>>,
seed = <<208,158,136,0,41,28,184,83,150,204,103,23,57,50,132,170,
160,218,100,186>>},
<<4,0,198,133,142,6,183,4,4,233,205,158,62,203,102,35,
149,180,66,156,100,129,57,5,63,181,33,248,40,175,96,107,
77,61,186,161,75,94,119,239,231,89,40,254,29,193,39,162,
255,168,222,51,72,179,193,133,106,66,155,249,126,126,49,194,
229,189,102,1,24,57,41,106,120,154,59,192,4,92,138,95,
180,44,125,27,217,152,245,68,73,87,155,68,104,23,175,189,
23,39,62,102,44,151,238,114,153,94,244,38,64,197,80,185,
1,63,173,7,97,53,60,112,134,162,114,194,64,136,190,148,
118,159,209,102,80>>,
6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449,
1) ->
secp521r1;

To Reproduce
A private key and a signing request is created with OpenSSL 1.0.2 via:
openssl req -new -newkey ec -pkeyopt "ec_paramgen_curve:secp521r1" -keyout example.key -out example.csr [...]
which is then signed with digest sha512 and provided to an Erlang server. The server is configured for TLS 1.3 and has the support for ecdsa_secp521r1_sha512.
When a client tries to establish a TLS 1.3 connection (with the indication of support for ecdsa_secp521r1_sha512), the server on the reception of the Client Hello tries to decode its own cert and, due to the above issue, has the elliptic curve marked as unsupported. The handshake then fails as the server now has no suitable signature algorithm to select.

The same situation works with curves prime256v1/secp256r1 and secp384r1 (and the matching sign algs), as their curve parameters have no leading zero bytes and they have a correct match on clauses of curve_to_atom().

Expected behavior
ssl:curve_to_atom() matching curves with or without leading zeros.

Affected versions
Tested on OTP 25.

Additional context
Not entirely sure if it's a bug or perhaps I'm missing something here...

We will look into it, it is vacation period right now so please have some patience.