1 /*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 #include <sys/param.h>
17 #include <stdint.h>
18
19 #include "tls/extensions/s2n_client_supported_groups.h"
20 #include "tls/extensions/s2n_ec_point_format.h"
21 #include "tls/s2n_tls.h"
22
23 #include "utils/s2n_safety.h"
24
25 static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out);
26 static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
27
28 const s2n_extension_type s2n_client_ec_point_format_extension = {
29 .iana_value = TLS_EXTENSION_EC_POINT_FORMATS,
30 .is_response = false,
31 .send = s2n_ec_point_format_send,
32 .recv = s2n_ec_point_format_recv,
33 .should_send = s2n_extension_should_send_if_ecc_enabled,
34 .if_missing = s2n_extension_noop_if_missing,
35 };
36
37 static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn);
38
39 const s2n_extension_type s2n_server_ec_point_format_extension = {
40 .iana_value = TLS_EXTENSION_EC_POINT_FORMATS,
41 .is_response = true,
42 .send = s2n_ec_point_format_send,
43 .recv = s2n_extension_recv_noop,
44 .should_send = s2n_server_ec_point_format_should_send,
45 .if_missing = s2n_extension_noop_if_missing,
46 };
47
s2n_server_ec_point_format_should_send(struct s2n_connection * conn)48 static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn)
49 {
50 return conn && conn->secure.cipher_suite
51 && s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe);
52 }
53
s2n_ec_point_format_send(struct s2n_connection * conn,struct s2n_stuffer * out)54 static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out)
55 {
56 /* Point format list len. We only support one. */
57 POSIX_GUARD(s2n_stuffer_write_uint8(out, 1));
58
59 /* Only allow uncompressed format */
60 POSIX_GUARD(s2n_stuffer_write_uint8(out, TLS_EC_POINT_FORMAT_UNCOMPRESSED));
61
62 return S2N_SUCCESS;
63 }
64
s2n_ec_point_format_recv(struct s2n_connection * conn,struct s2n_stuffer * extension)65 static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
66 {
67 /**
68 * Only uncompressed points are supported by the server and the client must include it in
69 * the extension. Just skip the extension.
70 */
71 conn->ec_point_formats = 1;
72 return S2N_SUCCESS;
73 }
74
75 /* Old-style extension functions -- remove after extensions refactor is complete */
76
s2n_server_ecc_point_format_extension_size(struct s2n_connection * conn)77 int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn)
78 {
79 if (s2n_server_ec_point_format_extension.should_send(conn) && s2n_server_can_send_ec_point_formats(conn)) {
80 return sizeof(uint16_t) /* extension type */
81 + sizeof(uint16_t) /* extension size */
82 + sizeof(uint8_t) /* point list size */
83 + sizeof(uint8_t); /* point */
84 }
85 return 0;
86 }
87
s2n_recv_client_ec_point_formats(struct s2n_connection * conn,struct s2n_stuffer * extension)88 int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension)
89 {
90 return s2n_extension_recv(&s2n_client_ec_point_format_extension, conn, extension);
91 }
92