Skip to content

Commit

Permalink
Add API to retrieve the parsed supported groups
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit eafdece
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 17:34:32 2023 -0400

    api documentation

commit 1339702
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 17:10:54 2023 -0400

    cleanup test

commit 08c552d
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 16:55:52 2023 -0400

    self talk test for all security policies

commit fa8faa3
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 15:40:18 2023 -0400

    fixes

commit 61606d6
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 15:23:10 2023 -0400

    ch cb self-talk test

commit 19e503c
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 14:47:14 2023 -0400

    self-talk setup

commit d118ac1
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 13:57:35 2023 -0400

    fixes

commit 865f5bb
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 13:54:39 2023 -0400

    client hello cb

commit 5a44ae6
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 13:34:44 2023 -0400

    add new error for trying to get an unreceived extension

commit 15bbefa
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 13:23:51 2023 -0400

    test for unparsed client hello

commit 9a74e1c
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 13:21:18 2023 -0400

    move tests to separate file

commit 7421bd8
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 11:53:49 2023 -0400

    random groups data test

commit 033891a
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 10:22:24 2023 -0400

    test wip

commit 3530f04
Author: Sam Clark <[email protected]>
Date:   Wed Sep 20 00:53:15 2023 -0400

    fixes

commit b41b892
Author: Sam Clark <[email protected]>
Date:   Tue Sep 19 23:24:55 2023 -0400

    test not sending extension

commit fd16f15
Author: Sam Clark <[email protected]>
Date:   Tue Sep 19 19:39:21 2023 -0400

    improve malformed length tests

commit 8ed2600
Author: Sam Clark <[email protected]>
Date:   Tue Sep 19 19:28:17 2023 -0400

    refactor into parse_count and parse_groups

commit 202a1f0
Author: Sam Clark <[email protected]>
Date:   Tue Sep 19 19:02:01 2023 -0400

    tests wip

commit 201852c
Author: Sam Clark <[email protected]>
Date:   Tue Sep 19 16:56:10 2023 -0400

    parse supported groups into a buffer
  • Loading branch information
goatgoose committed Sep 20, 2023
1 parent b4f0c5c commit 7b89c74
Show file tree
Hide file tree
Showing 8 changed files with 510 additions and 9 deletions.
26 changes: 26 additions & 0 deletions api/s2n.h
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,32 @@ S2N_API extern int s2n_client_hello_get_session_id_length(struct s2n_client_hell
*/
S2N_API extern int s2n_client_hello_get_session_id(struct s2n_client_hello *ch, uint8_t *out, uint32_t *out_length, uint32_t max_length);

/**
* Retrieves the supported groups received in the supported groups extension.
*
* IANA values for each of the received supported groups are written to the provided
* `supported_groups` array, and `supported_groups_count` is set to the number of received
* supported groups.
*
* `max_count` should be set to the maximum capacity of the `supported_groups` array. If
* `max_count` is less than the number of received supported groups, this function will error. To
* determine how large `supported_groups` should be in advance, use
* `s2n_client_hello_get_extension_length()` with the S2N_EXTENSION_SUPPORTED_GROUPS extension
* type.
*
* If no supported groups extension was received from the peer, or the received supported groups
* extension is malformed, this function will error.
*
* @param ch A pointer to the ClientHello. Can be retrieved from a connection via
* `s2n_connection_get_client_hello()`.
* @param supported_groups An array that will be filled with the received supported groups.
* @param supported_groups_count Set to the number of received supported groups.
* @param max_count The maximum number of supported groups that can fit in `supported_groups`.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure.
*/
S2N_API extern int s2n_client_hello_get_supported_groups(struct s2n_client_hello *ch, uint16_t *supported_groups,
uint16_t *supported_groups_count, uint16_t max_count);

/**
* Sets the file descriptor for a s2n connection.
*
Expand Down
1 change: 1 addition & 0 deletions error/s2n_errno.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ static const char *no_such_error = "Internal s2n error";
ERR_ENTRY(S2N_ERR_SEND_SIZE, "Retried s2n_send() size is invalid") \
ERR_ENTRY(S2N_ERR_CORK_SET_ON_UNMANAGED, "Attempt to set connection cork management on unmanaged IO") \
ERR_ENTRY(S2N_ERR_UNRECOGNIZED_EXTENSION, "TLS extension not recognized") \
ERR_ENTRY(S2N_ERR_EXTENSION_NOT_RECEIVED, "The TLS extension was not received") \
ERR_ENTRY(S2N_ERR_INVALID_SCT_LIST, "SCT list is invalid") \
ERR_ENTRY(S2N_ERR_INVALID_OCSP_RESPONSE, "OCSP response is invalid") \
ERR_ENTRY(S2N_ERR_UPDATING_EXTENSION, "Updating extension data failed") \
Expand Down
1 change: 1 addition & 0 deletions error/s2n_errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ typedef enum {
S2N_ERR_SEND_SIZE,
S2N_ERR_CORK_SET_ON_UNMANAGED,
S2N_ERR_UNRECOGNIZED_EXTENSION,
S2N_ERR_EXTENSION_NOT_RECEIVED,
S2N_ERR_INVALID_SCT_LIST,
S2N_ERR_INVALID_OCSP_RESPONSE,
S2N_ERR_UPDATING_EXTENSION,
Expand Down
409 changes: 409 additions & 0 deletions tests/unit/s2n_client_hello_get_supported_groups_test.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/unit/s2n_client_hello_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ int main(int argc, char **argv)
EXPECT_EQUAL(s2n_client_hello_get_extension_length(client_hello, S2N_EXTENSION_CERTIFICATE_TRANSPARENCY), 0);
EXPECT_NOT_NULL(ext_data = malloc(server_name_extension_len));
EXPECT_EQUAL(s2n_client_hello_get_extension_by_id(client_hello, S2N_EXTENSION_CERTIFICATE_TRANSPARENCY, ext_data, server_name_extension_len), 0);
EXPECT_EQUAL(s2n_errno, S2N_ERR_NULL);
EXPECT_EQUAL(s2n_errno, S2N_ERR_EXTENSION_NOT_RECEIVED);
free(ext_data);
ext_data = NULL;

Expand Down
46 changes: 39 additions & 7 deletions tls/extensions/s2n_client_supported_groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,37 @@ static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct
return S2N_SUCCESS;
}

S2N_RESULT s2n_client_supported_groups_parse_groups_count(struct s2n_stuffer *extension, uint16_t *count)
{
RESULT_ENSURE_REF(count);
*count = 0;
RESULT_ENSURE_REF(extension);

uint16_t supported_groups_list_size = 0;
RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(extension, &supported_groups_list_size));

RESULT_ENSURE_LTE(supported_groups_list_size, s2n_stuffer_data_available(extension));
RESULT_ENSURE_EQ(supported_groups_list_size % sizeof(uint16_t), 0);

*count = supported_groups_list_size / 2;

return S2N_RESULT_OK;
}

S2N_RESULT s2n_client_supported_groups_parse_groups(struct s2n_stuffer *extension, uint16_t supported_groups_count,
uint16_t *groups_list, uint16_t groups_list_capacity)
{
RESULT_ENSURE_REF(extension);
RESULT_ENSURE_REF(groups_list);
RESULT_ENSURE_LTE(supported_groups_count, groups_list_capacity);

for (size_t i = 0; i < supported_groups_count; i++) {
RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(extension, &groups_list[i]));
}

return S2N_RESULT_OK;
}

/* Populates the appropriate index of either the mutually_supported_curves or
* mutually_supported_kem_groups array based on the received IANA ID. Will
* ignore unrecognized IANA IDs (and return success). */
Expand Down Expand Up @@ -165,17 +196,18 @@ static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct
POSIX_ENSURE_REF(conn);
POSIX_ENSURE_REF(extension);

uint16_t size_of_all;
POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
if (size_of_all > s2n_stuffer_data_available(extension) || (size_of_all % sizeof(uint16_t))) {
uint16_t supported_groups_count = 0;
if (s2n_result_is_error(s2n_client_supported_groups_parse_groups_count(extension, &supported_groups_count))) {
/* Malformed length, ignore the extension */
return S2N_SUCCESS;
}

for (size_t i = 0; i < (size_of_all / sizeof(uint16_t)); i++) {
uint16_t iana_id;
POSIX_GUARD(s2n_stuffer_read_uint16(extension, &iana_id));
POSIX_GUARD(s2n_client_supported_groups_recv_iana_id(conn, iana_id));
uint16_t supported_groups[S2N_RECEIVED_SUPPORTED_GROUPS_MAX] = { 0 };
POSIX_GUARD_RESULT(s2n_client_supported_groups_parse_groups(extension, supported_groups_count, supported_groups,
S2N_RECEIVED_SUPPORTED_GROUPS_MAX));

for (size_t i = 0; i < supported_groups_count; i++) {
POSIX_GUARD(s2n_client_supported_groups_recv_iana_id(conn, supported_groups[i]));
}

POSIX_GUARD(s2n_choose_supported_group(conn));
Expand Down
6 changes: 6 additions & 0 deletions tls/extensions/s2n_client_supported_groups.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@
#include "tls/extensions/s2n_extension_type.h"
#include "tls/s2n_connection.h"

#define S2N_RECEIVED_SUPPORTED_GROUPS_MAX 64

extern const s2n_extension_type s2n_client_supported_groups_extension;
bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn);

S2N_RESULT s2n_client_supported_groups_parse_groups_count(struct s2n_stuffer *extension, uint16_t *count);
S2N_RESULT s2n_client_supported_groups_parse_groups(struct s2n_stuffer *extension, uint16_t supported_groups_count,
uint16_t *groups_list, uint16_t groups_list_capacity);

/* Old-style extension functions -- remove after extensions refactor is complete */
int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension);
28 changes: 27 additions & 1 deletion tls/s2n_client_hello.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "utils/s2n_bitmap.h"
#include "utils/s2n_random.h"
#include "utils/s2n_safety.h"
#include "tls/extensions/s2n_client_supported_groups.h"

struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn)
{
Expand Down Expand Up @@ -863,7 +864,7 @@ int s2n_client_hello_get_parsed_extension(s2n_tls_extension_type extension_type,
POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type, &extension_type_id));

s2n_parsed_extension *found_parsed_extension = &parsed_extension_list->parsed_extensions[extension_type_id];
POSIX_ENSURE_REF(found_parsed_extension->extension.data);
POSIX_ENSURE(found_parsed_extension->extension.data, S2N_ERR_EXTENSION_NOT_RECEIVED);
POSIX_ENSURE(found_parsed_extension->extension_type == extension_type, S2N_ERR_INVALID_PARSED_EXTENSIONS);

*parsed_extension = found_parsed_extension;
Expand Down Expand Up @@ -971,3 +972,28 @@ int s2n_client_hello_has_extension(struct s2n_client_hello *ch, uint16_t extensi
}
return S2N_SUCCESS;
}

int s2n_client_hello_get_supported_groups(struct s2n_client_hello *ch, uint16_t *supported_groups,
uint16_t *supported_groups_count_out, uint16_t max_count)
{
POSIX_ENSURE_REF(supported_groups_count_out);
*supported_groups_count_out = 0;

POSIX_ENSURE_REF(ch);
POSIX_ENSURE_REF(supported_groups);

s2n_parsed_extension *supported_groups_extension = NULL;
POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SUPPORTED_GROUPS, &ch->extensions, &supported_groups_extension));
POSIX_ENSURE_REF(supported_groups_extension);

struct s2n_stuffer extension_stuffer = { 0 };
POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &supported_groups_extension->extension));

uint16_t supported_groups_count = 0;
POSIX_GUARD_RESULT(s2n_client_supported_groups_parse_groups_count(&extension_stuffer, &supported_groups_count));
POSIX_GUARD_RESULT(s2n_client_supported_groups_parse_groups(&extension_stuffer, supported_groups_count, supported_groups, max_count));

*supported_groups_count_out = supported_groups_count;

return S2N_SUCCESS;
}

0 comments on commit 7b89c74

Please sign in to comment.