Skip to content

Commit

Permalink
sslgetcert: Add EC Point Formats extension to TLS handshake (fix conn…
Browse files Browse the repository at this point in the history
…ections to Vercel servers)

As described in Section 5.1.2 of RFC 8422, the EC Point Formats
extension is valid for TLS 1.2 and earlier.  It is deprecated in TLS
1.3 (RFC 8446), but that doesn't stop some servers from requiring it.
There is no harm in supplying the extension to a TLS 1.3 server.

In particular, Vercel (https://vercel.com/) TLS terminators seem to
respond with a handshake failure alert if the EC Point Format
extension is not present in the Client Hello.

This can be seen with measurement 49131334:
https://atlas.ripe.net/measurements/49131334/#probes

This changeset should add the EC Point Format extension to the probe,
which will result in successful certificate harvesting from Vercel
servers, without introducing any incompatibilities to other servers.
  • Loading branch information
dkg committed Mar 3, 2023
1 parent 4ffcc7f commit aabb55e
Showing 1 changed file with 46 additions and 1 deletion.
47 changes: 46 additions & 1 deletion eperd/sslgetcert.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,29 @@ static void add_compression(struct hsbuf *hsbuf)
hsbuf_add(hsbuf, compression, len);
}

static void ext_ec_point_formats(struct hsbuf *hsbuf)
{
/*
The EC Point Format extension contains one octet of length,
followed by a series of one-octet values of entries in the
EC Point Format registry.
*/
uint16_t epfextlen;
uint8_t epflen;
size_t len;
uint8_t point_formats[]= { 0x0 /* uncompressed */ };

len = sizeof(point_formats);

epflen = len;
epfextlen = 1 + len;

hsbuf_add_u16(hsbuf, 11 /*ec_point_formats*/);
hsbuf_add_u16(hsbuf, epfextlen);
hsbuf_add(hsbuf, &epflen, sizeof(epflen));
hsbuf_add(hsbuf, point_formats, len);
}

static void ext_sigs(struct hsbuf *hsbuf)
{
uint16_t sigextlen, siglen;
Expand Down Expand Up @@ -682,18 +705,32 @@ static void sni(struct hsbuf *hsbuf, const char *server_name)
hsbuf_add(hsbuf, server_name, size_hostname);
}

/* Only add EC point format extension for TLS versions 1.0, 1.1, and 1.2 */
static int ec_point_ext_ok(const struct state *state) {
return (state->major_version == 3) &&
(state->minor_version >= 1) &&
(state->minor_version <= 3);
}

static void add_extensions(struct state *state, struct hsbuf *hsbuf)
{
size_t size_extensions;
struct hsbuf ext_sigs_buf;
struct hsbuf sni_buf;
struct hsbuf ec_point_formats_buf;
struct hsbuf elliptic_curves_buf;

/* SNI */
hsbuf_init(&sni_buf);
if (state->sni)
sni(&sni_buf, state->sni);

/* EC point format */
if (ec_point_ext_ok(state)) {
hsbuf_init(&ec_point_formats_buf);
ext_ec_point_formats(&ec_point_formats_buf);
}

/* Signatures */
hsbuf_init(&ext_sigs_buf);
ext_sigs(&ext_sigs_buf);
Expand All @@ -702,12 +739,20 @@ static void add_extensions(struct state *state, struct hsbuf *hsbuf)
hsbuf_init(&elliptic_curves_buf);
elliptic_curves(&elliptic_curves_buf);

size_extensions= hsbuf_len(&sni_buf) + hsbuf_len(&ext_sigs_buf) +
size_extensions= hsbuf_len(&sni_buf) +
hsbuf_len(&ext_sigs_buf) +
hsbuf_len(&elliptic_curves_buf);

if (ec_point_ext_ok(state))
size_extensions += hsbuf_len(&ec_point_formats_buf);

hsbuf_add_u16(hsbuf, size_extensions);
hsbuf_copy(hsbuf, &sni_buf);
hsbuf_cleanup(&sni_buf);
if (ec_point_ext_ok(state)) {
hsbuf_copy(hsbuf, &ec_point_formats_buf);
hsbuf_cleanup(&ec_point_formats_buf);
}
hsbuf_copy(hsbuf, &ext_sigs_buf);
hsbuf_cleanup(&ext_sigs_buf);
hsbuf_copy(hsbuf, &elliptic_curves_buf);
Expand Down

0 comments on commit aabb55e

Please sign in to comment.