s2n_client_hello.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  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. #include "tls/s2n_client_hello.h"
  16. #include <stdint.h>
  17. #include <stdlib.h>
  18. #include <sys/param.h>
  19. #include <time.h>
  20. #include "api/unstable/fingerprint.h"
  21. #include "crypto/s2n_fips.h"
  22. #include "crypto/s2n_hash.h"
  23. #include "crypto/s2n_rsa_signing.h"
  24. #include "error/s2n_errno.h"
  25. #include "stuffer/s2n_stuffer.h"
  26. #include "tls/extensions/s2n_client_supported_groups.h"
  27. #include "tls/extensions/s2n_extension_list.h"
  28. #include "tls/extensions/s2n_server_key_share.h"
  29. #include "tls/s2n_alerts.h"
  30. #include "tls/s2n_auth_selection.h"
  31. #include "tls/s2n_cipher_preferences.h"
  32. #include "tls/s2n_cipher_suites.h"
  33. #include "tls/s2n_connection.h"
  34. #include "tls/s2n_handshake_type.h"
  35. #include "tls/s2n_security_policies.h"
  36. #include "tls/s2n_signature_algorithms.h"
  37. #include "tls/s2n_tls.h"
  38. #include "utils/s2n_bitmap.h"
  39. #include "utils/s2n_random.h"
  40. #include "utils/s2n_safety.h"
  41. struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn)
  42. {
  43. if (conn->client_hello.parsed != 1) {
  44. return NULL;
  45. }
  46. return &conn->client_hello;
  47. }
  48. static uint32_t min_size(struct s2n_blob *blob, uint32_t max_length)
  49. {
  50. return blob->size < max_length ? blob->size : max_length;
  51. }
  52. static S2N_RESULT s2n_generate_client_session_id(struct s2n_connection *conn)
  53. {
  54. RESULT_ENSURE_REF(conn);
  55. RESULT_ENSURE_REF(conn->config);
  56. /* Session id already generated - no-op */
  57. if (conn->session_id_len) {
  58. return S2N_RESULT_OK;
  59. }
  60. /* Only generate the session id if using tickets */
  61. bool generate = conn->config->use_tickets;
  62. /* TLS1.3 doesn't require session ids. The field is actually renamed to legacy_session_id.
  63. * However, we still set a session id if dealing with troublesome middleboxes
  64. * (middlebox compatibility mode) or if trying to use a TLS1.2 ticket.
  65. */
  66. if (conn->client_protocol_version >= S2N_TLS13) {
  67. generate = s2n_is_middlebox_compat_enabled(conn) || conn->resume_protocol_version;
  68. }
  69. /* Session id not needed - no-op */
  70. if (!generate) {
  71. return S2N_RESULT_OK;
  72. }
  73. /* QUIC should not allow session ids for any reason.
  74. *
  75. *= https://tools.ietf.org/rfc/rfc9001#section-8.4
  76. *# A server SHOULD treat the receipt of a TLS ClientHello with a non-empty
  77. *# legacy_session_id field as a connection error of type PROTOCOL_VIOLATION.
  78. */
  79. RESULT_ENSURE(!conn->quic_enabled, S2N_ERR_UNSUPPORTED_WITH_QUIC);
  80. struct s2n_blob session_id = { 0 };
  81. RESULT_GUARD_POSIX(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
  82. RESULT_GUARD(s2n_get_public_random_data(&session_id));
  83. conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
  84. return S2N_RESULT_OK;
  85. }
  86. ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch)
  87. {
  88. POSIX_ENSURE_REF(ch);
  89. return ch->raw_message.size;
  90. }
  91. ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
  92. {
  93. POSIX_ENSURE_REF(ch);
  94. POSIX_ENSURE_REF(out);
  95. uint32_t len = min_size(&ch->raw_message, max_length);
  96. POSIX_CHECKED_MEMCPY(out, ch->raw_message.data, len);
  97. return len;
  98. }
  99. ssize_t s2n_client_hello_get_cipher_suites_length(struct s2n_client_hello *ch)
  100. {
  101. POSIX_ENSURE_REF(ch);
  102. return ch->cipher_suites.size;
  103. }
  104. int s2n_client_hello_cb_done(struct s2n_connection *conn)
  105. {
  106. POSIX_ENSURE_REF(conn);
  107. POSIX_ENSURE_REF(conn->config);
  108. POSIX_ENSURE(conn->config->client_hello_cb_mode == S2N_CLIENT_HELLO_CB_NONBLOCKING, S2N_ERR_INVALID_STATE);
  109. POSIX_ENSURE(conn->client_hello.callback_invoked == 1, S2N_ERR_ASYNC_NOT_PERFORMED);
  110. POSIX_ENSURE(conn->client_hello.parsed == 1, S2N_ERR_INVALID_STATE);
  111. conn->client_hello.callback_async_blocked = 0;
  112. conn->client_hello.callback_async_done = 1;
  113. return S2N_SUCCESS;
  114. }
  115. ssize_t s2n_client_hello_get_cipher_suites(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
  116. {
  117. POSIX_ENSURE_REF(ch);
  118. POSIX_ENSURE_REF(out);
  119. POSIX_ENSURE_REF(ch->cipher_suites.data);
  120. uint32_t len = min_size(&ch->cipher_suites, max_length);
  121. POSIX_CHECKED_MEMCPY(out, ch->cipher_suites.data, len);
  122. return len;
  123. }
  124. ssize_t s2n_client_hello_get_extensions_length(struct s2n_client_hello *ch)
  125. {
  126. POSIX_ENSURE_REF(ch);
  127. return ch->extensions.raw.size;
  128. }
  129. ssize_t s2n_client_hello_get_extensions(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
  130. {
  131. POSIX_ENSURE_REF(ch);
  132. POSIX_ENSURE_REF(out);
  133. POSIX_ENSURE_REF(ch->extensions.raw.data);
  134. uint32_t len = min_size(&ch->extensions.raw, max_length);
  135. POSIX_CHECKED_MEMCPY(out, ch->extensions.raw.data, len);
  136. return len;
  137. }
  138. int s2n_client_hello_free_raw_message(struct s2n_client_hello *client_hello)
  139. {
  140. POSIX_ENSURE_REF(client_hello);
  141. POSIX_GUARD(s2n_free(&client_hello->raw_message));
  142. /* These point to data in the raw_message stuffer,
  143. so we don't need to free them */
  144. client_hello->cipher_suites.data = NULL;
  145. client_hello->extensions.raw.data = NULL;
  146. return 0;
  147. }
  148. int s2n_client_hello_free(struct s2n_client_hello **ch)
  149. {
  150. POSIX_ENSURE_REF(ch);
  151. if (*ch == NULL) {
  152. return S2N_SUCCESS;
  153. }
  154. POSIX_ENSURE((*ch)->alloced, S2N_ERR_INVALID_ARGUMENT);
  155. POSIX_GUARD(s2n_client_hello_free_raw_message(*ch));
  156. POSIX_GUARD(s2n_free_object((uint8_t **) ch, sizeof(struct s2n_client_hello)));
  157. *ch = NULL;
  158. return S2N_SUCCESS;
  159. }
  160. int s2n_collect_client_hello(struct s2n_client_hello *ch, struct s2n_stuffer *source)
  161. {
  162. POSIX_ENSURE_REF(ch);
  163. POSIX_ENSURE_REF(source);
  164. uint32_t size = s2n_stuffer_data_available(source);
  165. S2N_ERROR_IF(size == 0, S2N_ERR_BAD_MESSAGE);
  166. POSIX_GUARD(s2n_realloc(&ch->raw_message, size));
  167. POSIX_GUARD(s2n_stuffer_read(source, &ch->raw_message));
  168. return 0;
  169. }
  170. static S2N_RESULT s2n_client_hello_verify_for_retry(struct s2n_connection *conn,
  171. struct s2n_client_hello *old_ch, struct s2n_client_hello *new_ch,
  172. uint8_t *previous_client_random)
  173. {
  174. RESULT_ENSURE_REF(conn);
  175. RESULT_ENSURE_REF(old_ch);
  176. RESULT_ENSURE_REF(new_ch);
  177. RESULT_ENSURE_REF(previous_client_random);
  178. if (!s2n_is_hello_retry_handshake(conn)) {
  179. return S2N_RESULT_OK;
  180. }
  181. /*
  182. *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2
  183. *# The client will also send a
  184. *# ClientHello when the server has responded to its ClientHello with a
  185. *# HelloRetryRequest. In that case, the client MUST send the same
  186. *# ClientHello without modification, except as follows:
  187. *
  188. * All of the exceptions that follow are extensions.
  189. * Ignoring the extensions, the client hellos should match /exactly/.
  190. */
  191. ssize_t old_msg_len = old_ch->raw_message.size;
  192. /* Also consider the 2-byte size of the extension list */
  193. ssize_t old_extensions_len = old_ch->extensions.raw.size + sizeof(uint16_t);
  194. RESULT_ENSURE_GT(old_msg_len, old_extensions_len);
  195. size_t verify_len = old_msg_len - old_extensions_len;
  196. RESULT_ENSURE_LTE(verify_len, new_ch->raw_message.size);
  197. RESULT_ENSURE(s2n_constant_time_equals(
  198. old_ch->raw_message.data,
  199. new_ch->raw_message.data,
  200. verify_len),
  201. S2N_ERR_BAD_MESSAGE);
  202. /* In the past, the s2n-tls client updated the client hello in ways not
  203. * allowed by RFC8446: https://github.com/aws/s2n-tls/pull/3311
  204. * Although the issue was addressed, its existence means that old versions
  205. * of the s2n-tls client will fail this validation.
  206. *
  207. * So to avoid breaking old s2n-tls clients, we do not enforce this validation
  208. * outside of tests. We continue to enforce it during tests to avoid regressions.
  209. */
  210. if (s2n_in_test()) {
  211. /*
  212. * We need to verify the client random separately
  213. * because we erase it from the client hello during parsing.
  214. * Compare the old value to the current value.
  215. */
  216. RESULT_ENSURE(s2n_constant_time_equals(
  217. previous_client_random,
  218. conn->handshake_params.client_random,
  219. S2N_TLS_RANDOM_DATA_LEN),
  220. S2N_ERR_BAD_MESSAGE);
  221. }
  222. /*
  223. * Now enforce that the extensions also exactly match,
  224. * except for the exceptions described in the RFC.
  225. */
  226. for (size_t i = 0; i < s2n_array_len(s2n_supported_extensions); i++) {
  227. s2n_parsed_extension *old_extension = &old_ch->extensions.parsed_extensions[i];
  228. uint32_t old_size = old_extension->extension.size;
  229. s2n_parsed_extension *new_extension = &new_ch->extensions.parsed_extensions[i];
  230. uint32_t new_size = new_extension->extension.size;
  231. /* The extension type is only set if the extension is present.
  232. * Look for a non-zero-length extension.
  233. */
  234. uint16_t extension_type = 0;
  235. if (old_size != 0) {
  236. extension_type = old_extension->extension_type;
  237. } else if (new_size != 0) {
  238. extension_type = new_extension->extension_type;
  239. } else {
  240. continue;
  241. }
  242. switch (extension_type) {
  243. /*
  244. *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2
  245. *# - If a "key_share" extension was supplied in the HelloRetryRequest,
  246. *# replacing the list of shares with a list containing a single
  247. *# KeyShareEntry from the indicated group.
  248. */
  249. case TLS_EXTENSION_KEY_SHARE:
  250. /* Handled when parsing the key share extension */
  251. break;
  252. /*
  253. *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2
  254. *# - Removing the "early_data" extension (Section 4.2.10) if one was
  255. *# present. Early data is not permitted after a HelloRetryRequest.
  256. */
  257. case TLS_EXTENSION_EARLY_DATA:
  258. RESULT_ENSURE(new_size == 0, S2N_ERR_BAD_MESSAGE);
  259. break;
  260. /*
  261. *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2
  262. *# - Including a "cookie" extension if one was provided in the
  263. *# HelloRetryRequest.
  264. */
  265. case TLS_EXTENSION_COOKIE:
  266. /* Handled when parsing the cookie extension */
  267. break;
  268. /*
  269. *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2
  270. *# - Updating the "pre_shared_key" extension if present by recomputing
  271. *# the "obfuscated_ticket_age" and binder values and (optionally)
  272. *# removing any PSKs which are incompatible with the server's
  273. *# indicated cipher suite.
  274. */
  275. case TLS_EXTENSION_PRE_SHARED_KEY:
  276. /* Handled when parsing the psk extension */
  277. break;
  278. /*
  279. * No more exceptions.
  280. * All other extensions must match.
  281. */
  282. default:
  283. RESULT_ENSURE(old_size == new_size, S2N_ERR_BAD_MESSAGE);
  284. RESULT_ENSURE(s2n_constant_time_equals(
  285. new_extension->extension.data,
  286. old_extension->extension.data,
  287. old_size),
  288. S2N_ERR_BAD_MESSAGE);
  289. }
  290. }
  291. return S2N_RESULT_OK;
  292. }
  293. S2N_RESULT s2n_client_hello_parse_raw(struct s2n_client_hello *client_hello,
  294. uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN],
  295. uint8_t client_random[S2N_TLS_RANDOM_DATA_LEN])
  296. {
  297. RESULT_ENSURE_REF(client_hello);
  298. struct s2n_stuffer in_stuffer = { 0 };
  299. RESULT_GUARD_POSIX(s2n_stuffer_init_written(&in_stuffer, &client_hello->raw_message));
  300. struct s2n_stuffer *in = &in_stuffer;
  301. /**
  302. * https://tools.ietf.org/rfc/rfc8446#4.1.2
  303. * Structure of this message:
  304. *
  305. * uint16 ProtocolVersion;
  306. * opaque Random[32];
  307. *
  308. * uint8 CipherSuite[2];
  309. *
  310. * struct {
  311. * ProtocolVersion legacy_version = 0x0303;
  312. * Random random;
  313. * opaque legacy_session_id<0..32>;
  314. * CipherSuite cipher_suites<2..2^16-2>;
  315. * opaque legacy_compression_methods<1..2^8-1>;
  316. * Extension extensions<8..2^16-1>;
  317. * } ClientHello;
  318. **/
  319. /* legacy_version */
  320. RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(in, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
  321. /* random */
  322. RESULT_GUARD_POSIX(s2n_stuffer_erase_and_read_bytes(in, client_random, S2N_TLS_RANDOM_DATA_LEN));
  323. /* legacy_session_id */
  324. uint8_t session_id_len = 0;
  325. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &session_id_len));
  326. RESULT_ENSURE(session_id_len <= S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_BAD_MESSAGE);
  327. uint8_t *session_id = s2n_stuffer_raw_read(in, session_id_len);
  328. RESULT_ENSURE(session_id != NULL, S2N_ERR_BAD_MESSAGE);
  329. RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->session_id, session_id, session_id_len));
  330. /* cipher suites */
  331. uint16_t cipher_suites_length = 0;
  332. RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(in, &cipher_suites_length));
  333. RESULT_ENSURE(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
  334. RESULT_ENSURE(cipher_suites_length % S2N_TLS_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
  335. uint8_t *cipher_suites = s2n_stuffer_raw_read(in, cipher_suites_length);
  336. RESULT_ENSURE(cipher_suites != NULL, S2N_ERR_BAD_MESSAGE);
  337. RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->cipher_suites, cipher_suites, cipher_suites_length));
  338. /* legacy_compression_methods (ignored) */
  339. uint8_t num_compression_methods = 0;
  340. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &num_compression_methods));
  341. RESULT_GUARD_POSIX(s2n_stuffer_skip_read(in, num_compression_methods));
  342. /* extensions */
  343. RESULT_GUARD_POSIX(s2n_extension_list_parse(in, &client_hello->extensions));
  344. return S2N_RESULT_OK;
  345. }
  346. int s2n_parse_client_hello(struct s2n_connection *conn)
  347. {
  348. POSIX_ENSURE_REF(conn);
  349. /* If a retry, move the old version of the client hello
  350. * somewhere safe so we can compare it to the new client hello later.
  351. */
  352. DEFER_CLEANUP(struct s2n_client_hello previous_hello_retry = conn->client_hello,
  353. s2n_client_hello_free_raw_message);
  354. if (s2n_is_hello_retry_handshake(conn)) {
  355. POSIX_CHECKED_MEMSET(&conn->client_hello, 0, sizeof(struct s2n_client_hello));
  356. }
  357. POSIX_GUARD(s2n_collect_client_hello(&conn->client_hello, &conn->handshake.io));
  358. /* The ClientHello version must be TLS12 after a HelloRetryRequest */
  359. if (s2n_is_hello_retry_handshake(conn)) {
  360. POSIX_ENSURE_EQ(conn->client_hello_version, S2N_TLS12);
  361. }
  362. if (conn->client_hello_version == S2N_SSLv2) {
  363. POSIX_GUARD(s2n_sslv2_client_hello_recv(conn));
  364. return S2N_SUCCESS;
  365. }
  366. /* Save the current client_random for comparison in the case of a retry */
  367. uint8_t previous_client_random[S2N_TLS_RANDOM_DATA_LEN] = { 0 };
  368. POSIX_CHECKED_MEMCPY(previous_client_random, conn->handshake_params.client_random,
  369. S2N_TLS_RANDOM_DATA_LEN);
  370. /* Parse raw, collected client hello */
  371. uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
  372. POSIX_GUARD_RESULT(s2n_client_hello_parse_raw(&conn->client_hello,
  373. client_protocol_version, conn->handshake_params.client_random));
  374. /* Protocol version in the ClientHello is fixed at 0x0303(TLS 1.2) for
  375. * future versions of TLS. Therefore, we will negotiate down if a client sends
  376. * an unexpected value above 0x0303.
  377. */
  378. conn->client_protocol_version = MIN((client_protocol_version[0] * 10) + client_protocol_version[1], S2N_TLS12);
  379. conn->client_hello_version = conn->client_protocol_version;
  380. /* Copy the session id to the connection. */
  381. conn->session_id_len = conn->client_hello.session_id.size;
  382. POSIX_CHECKED_MEMCPY(conn->session_id, conn->client_hello.session_id.data, conn->session_id_len);
  383. /* Set default key exchange curve.
  384. * This is going to be our fallback if the client has no preference.
  385. *
  386. * P-256 is our preferred fallback option because the TLS1.3 RFC requires
  387. * all implementations to support it:
  388. *
  389. * https://tools.ietf.org/rfc/rfc8446#section-9.1
  390. * A TLS-compliant application MUST support key exchange with secp256r1 (NIST P-256)
  391. * and SHOULD support key exchange with X25519 [RFC7748]
  392. *
  393. *= https://tools.ietf.org/rfc/rfc4492#section-4
  394. *# A client that proposes ECC cipher suites may choose not to include these extensions.
  395. *# In this case, the server is free to choose any one of the elliptic curves or point formats listed in Section 5.
  396. *
  397. */
  398. const struct s2n_ecc_preferences *ecc_pref = NULL;
  399. POSIX_GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
  400. POSIX_ENSURE_REF(ecc_pref);
  401. POSIX_ENSURE_GT(ecc_pref->count, 0);
  402. if (s2n_ecc_preferences_includes_curve(ecc_pref, TLS_EC_CURVE_SECP_256_R1)) {
  403. conn->kex_params.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1;
  404. } else {
  405. /* If P-256 isn't allowed by the current security policy, instead choose
  406. * the first / most preferred curve.
  407. */
  408. conn->kex_params.server_ecc_evp_params.negotiated_curve = ecc_pref->ecc_curves[0];
  409. }
  410. POSIX_GUARD_RESULT(s2n_client_hello_verify_for_retry(conn,
  411. &previous_hello_retry, &conn->client_hello, previous_client_random));
  412. return S2N_SUCCESS;
  413. }
  414. static S2N_RESULT s2n_client_hello_parse_message_impl(struct s2n_client_hello **result,
  415. const uint8_t *raw_message, uint32_t raw_message_size)
  416. {
  417. RESULT_ENSURE_REF(result);
  418. DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
  419. RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_client_hello)));
  420. RESULT_GUARD_POSIX(s2n_blob_zero(&mem));
  421. DEFER_CLEANUP(struct s2n_client_hello *client_hello = NULL, s2n_client_hello_free);
  422. client_hello = (struct s2n_client_hello *) (void *) mem.data;
  423. client_hello->alloced = true;
  424. ZERO_TO_DISABLE_DEFER_CLEANUP(mem);
  425. DEFER_CLEANUP(struct s2n_stuffer in = { 0 }, s2n_stuffer_free);
  426. RESULT_GUARD_POSIX(s2n_stuffer_alloc(&in, raw_message_size));
  427. RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(&in, raw_message, raw_message_size));
  428. uint8_t message_type = 0;
  429. uint32_t message_len = 0;
  430. RESULT_GUARD(s2n_handshake_parse_header(&in, &message_type, &message_len));
  431. RESULT_ENSURE(message_type == TLS_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
  432. RESULT_ENSURE(message_len == s2n_stuffer_data_available(&in), S2N_ERR_BAD_MESSAGE);
  433. RESULT_GUARD_POSIX(s2n_collect_client_hello(client_hello, &in));
  434. RESULT_ENSURE(s2n_stuffer_data_available(&in) == 0, S2N_ERR_BAD_MESSAGE);
  435. uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
  436. uint8_t random[S2N_TLS_RANDOM_DATA_LEN] = { 0 };
  437. RESULT_GUARD(s2n_client_hello_parse_raw(client_hello, protocol_version, random));
  438. *result = client_hello;
  439. ZERO_TO_DISABLE_DEFER_CLEANUP(client_hello);
  440. return S2N_RESULT_OK;
  441. }
  442. struct s2n_client_hello *s2n_client_hello_parse_message(const uint8_t *raw_message, uint32_t raw_message_size)
  443. {
  444. struct s2n_client_hello *result = NULL;
  445. PTR_GUARD_RESULT(s2n_client_hello_parse_message_impl(&result, raw_message, raw_message_size));
  446. return result;
  447. }
  448. int s2n_process_client_hello(struct s2n_connection *conn)
  449. {
  450. POSIX_ENSURE_REF(conn);
  451. POSIX_ENSURE_REF(conn->secure);
  452. POSIX_ENSURE_REF(conn->secure->cipher_suite);
  453. /* Client hello is parsed and config is finalized.
  454. * Negotiate protocol version, cipher suite, ALPN, select a cert, etc. */
  455. struct s2n_client_hello *client_hello = &conn->client_hello;
  456. const struct s2n_security_policy *security_policy;
  457. POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
  458. if (!s2n_connection_supports_tls13(conn) || !s2n_security_policy_supports_tls13(security_policy)) {
  459. conn->server_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
  460. conn->actual_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
  461. }
  462. POSIX_GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, &conn->client_hello.extensions));
  463. /* After parsing extensions, select a curve and corresponding keyshare to use */
  464. if (conn->actual_protocol_version >= S2N_TLS13) {
  465. POSIX_GUARD(s2n_extensions_server_key_share_select(conn));
  466. }
  467. /* for pre TLS 1.3 connections, protocol selection is not done in supported_versions extensions, so do it here */
  468. if (conn->actual_protocol_version < S2N_TLS13) {
  469. conn->actual_protocol_version = MIN(conn->server_protocol_version, conn->client_protocol_version);
  470. }
  471. if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
  472. POSIX_GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
  473. POSIX_BAIL(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
  474. }
  475. if (s2n_connection_is_quic_enabled(conn)) {
  476. POSIX_ENSURE(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
  477. }
  478. /* Find potential certificate matches before we choose the cipher. */
  479. POSIX_GUARD(s2n_conn_find_name_matching_certs(conn));
  480. /* Save the previous cipher suite */
  481. uint8_t previous_cipher_suite_iana[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
  482. POSIX_CHECKED_MEMCPY(previous_cipher_suite_iana, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN);
  483. /* Now choose the ciphers we have certs for. */
  484. POSIX_GUARD(s2n_set_cipher_as_tls_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / 2));
  485. /* Check if this is the second client hello in a hello retry handshake */
  486. if (s2n_is_hello_retry_handshake(conn) && conn->handshake.message_number > 0) {
  487. /**
  488. *= https://tools.ietf.org/rfc/rfc8446#4.1.4
  489. *# Servers MUST ensure that they negotiate the
  490. *# same cipher suite when receiving a conformant updated ClientHello (if
  491. *# the server selects the cipher suite as the first step in the
  492. *# negotiation, then this will happen automatically).
  493. **/
  494. POSIX_ENSURE(s2n_constant_time_equals(previous_cipher_suite_iana, conn->secure->cipher_suite->iana_value,
  495. S2N_TLS_CIPHER_SUITE_LEN),
  496. S2N_ERR_BAD_MESSAGE);
  497. }
  498. /* If we're using a PSK, we don't need to choose a signature algorithm or certificate,
  499. * because no additional auth is required. */
  500. if (conn->psk_params.chosen_psk != NULL) {
  501. return S2N_SUCCESS;
  502. }
  503. /* And set the signature and hash algorithm used for key exchange signatures */
  504. POSIX_GUARD(s2n_choose_sig_scheme_from_peer_preference_list(conn,
  505. &conn->handshake_params.client_sig_hash_algs,
  506. &conn->handshake_params.server_cert_sig_scheme));
  507. /* And finally, set the certs specified by the final auth + sig_alg combo. */
  508. POSIX_GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
  509. return S2N_SUCCESS;
  510. }
  511. static S2N_RESULT s2n_client_hello_process_cb_response(struct s2n_connection *conn, int rc)
  512. {
  513. if (rc < 0) {
  514. goto fail;
  515. }
  516. switch (conn->config->client_hello_cb_mode) {
  517. case S2N_CLIENT_HELLO_CB_BLOCKING: {
  518. if (rc) {
  519. conn->server_name_used = 1;
  520. }
  521. return S2N_RESULT_OK;
  522. }
  523. case S2N_CLIENT_HELLO_CB_NONBLOCKING: {
  524. if (conn->client_hello.callback_async_done) {
  525. return S2N_RESULT_OK;
  526. }
  527. conn->client_hello.callback_async_blocked = 1;
  528. RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED);
  529. }
  530. }
  531. fail:
  532. /* rc < 0 */
  533. RESULT_GUARD_POSIX(s2n_queue_reader_handshake_failure_alert(conn));
  534. RESULT_BAIL(S2N_ERR_CANCELLED);
  535. }
  536. int s2n_client_hello_recv(struct s2n_connection *conn)
  537. {
  538. POSIX_ENSURE(!conn->client_hello.callback_async_blocked, S2N_ERR_ASYNC_BLOCKED);
  539. /* Only parse the ClientHello once */
  540. if (!conn->client_hello.parsed) {
  541. POSIX_GUARD(s2n_parse_client_hello(conn));
  542. /* Mark the collected client hello as available when parsing is done and before the client hello callback */
  543. conn->client_hello.parsed = true;
  544. }
  545. /* Only invoke the ClientHello callback once.
  546. * This means that we do NOT invoke the callback again on the second ClientHello
  547. * in a TLS1.3 retry handshake. We explicitly check for a retry because the
  548. * callback state may have been cleared while parsing the second ClientHello.
  549. */
  550. if (!conn->client_hello.callback_invoked && !IS_HELLO_RETRY_HANDSHAKE(conn)) {
  551. /* Mark the client hello callback as invoked to avoid calling it again. */
  552. conn->client_hello.callback_invoked = true;
  553. /* Call client_hello_cb if exists, letting application to modify s2n_connection or swap s2n_config */
  554. if (conn->config->client_hello_cb) {
  555. int rc = conn->config->client_hello_cb(conn, conn->config->client_hello_cb_ctx);
  556. POSIX_GUARD_RESULT(s2n_client_hello_process_cb_response(conn, rc));
  557. }
  558. }
  559. if (conn->client_hello_version != S2N_SSLv2) {
  560. POSIX_GUARD(s2n_process_client_hello(conn));
  561. }
  562. return 0;
  563. }
  564. S2N_RESULT s2n_cipher_suite_validate_available(struct s2n_connection *conn, struct s2n_cipher_suite *cipher)
  565. {
  566. RESULT_ENSURE_REF(conn);
  567. RESULT_ENSURE_REF(cipher);
  568. RESULT_ENSURE_EQ(cipher->available, true);
  569. RESULT_ENSURE_LTE(cipher->minimum_required_tls_version, conn->client_protocol_version);
  570. if (s2n_connection_is_quic_enabled(conn)) {
  571. RESULT_ENSURE_GTE(cipher->minimum_required_tls_version, S2N_TLS13);
  572. }
  573. return S2N_RESULT_OK;
  574. }
  575. int s2n_client_hello_send(struct s2n_connection *conn)
  576. {
  577. POSIX_ENSURE_REF(conn);
  578. const struct s2n_security_policy *security_policy;
  579. POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
  580. const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences;
  581. POSIX_ENSURE_REF(cipher_preferences);
  582. if (!s2n_connection_supports_tls13(conn) || !s2n_security_policy_supports_tls13(security_policy)) {
  583. conn->client_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
  584. conn->actual_protocol_version = MIN(conn->actual_protocol_version, S2N_TLS12);
  585. }
  586. struct s2n_stuffer *out = &conn->handshake.io;
  587. uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
  588. uint8_t reported_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
  589. client_protocol_version[0] = reported_protocol_version / 10;
  590. client_protocol_version[1] = reported_protocol_version % 10;
  591. conn->client_hello_version = reported_protocol_version;
  592. POSIX_GUARD(s2n_stuffer_write_bytes(out, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
  593. struct s2n_blob client_random = { 0 };
  594. POSIX_GUARD(s2n_blob_init(&client_random, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN));
  595. if (!s2n_is_hello_retry_handshake(conn)) {
  596. /* Only generate the random data for our first client hello.
  597. * If we retry, we'll reuse the value. */
  598. POSIX_GUARD_RESULT(s2n_get_public_random_data(&client_random));
  599. }
  600. POSIX_GUARD(s2n_stuffer_write(out, &client_random));
  601. POSIX_GUARD_RESULT(s2n_generate_client_session_id(conn));
  602. POSIX_GUARD(s2n_stuffer_write_uint8(out, conn->session_id_len));
  603. if (conn->session_id_len > 0) {
  604. POSIX_GUARD(s2n_stuffer_write_bytes(out, conn->session_id, conn->session_id_len));
  605. }
  606. /* Reserve space for size of the list of available ciphers */
  607. struct s2n_stuffer_reservation available_cipher_suites_size;
  608. POSIX_GUARD(s2n_stuffer_reserve_uint16(out, &available_cipher_suites_size));
  609. /* Now, write the IANA values of every available cipher suite in our list */
  610. struct s2n_cipher_suite *cipher = NULL;
  611. bool tls12_is_possible = false;
  612. for (size_t i = 0; i < security_policy->cipher_preferences->count; i++) {
  613. cipher = cipher_preferences->suites[i];
  614. if (s2n_result_is_error(s2n_cipher_suite_validate_available(conn, cipher))) {
  615. continue;
  616. }
  617. if (cipher->minimum_required_tls_version < S2N_TLS13) {
  618. tls12_is_possible = true;
  619. }
  620. POSIX_GUARD(s2n_stuffer_write_bytes(out, cipher->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
  621. }
  622. /**
  623. * For initial handshakes:
  624. *= https://tools.ietf.org/rfc/rfc5746#3.4
  625. *# o The client MUST include either an empty "renegotiation_info"
  626. *# extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling
  627. *# cipher suite value in the ClientHello. Including both is NOT
  628. *# RECOMMENDED.
  629. * For maximum backwards compatibility, we choose to use the TLS_EMPTY_RENEGOTIATION_INFO_SCSV cipher suite
  630. * rather than the "renegotiation_info" extension.
  631. *
  632. * For renegotiation handshakes:
  633. *= https://tools.ietf.org/rfc/rfc5746#3.5
  634. *# The SCSV MUST NOT be included.
  635. */
  636. if (tls12_is_possible && !s2n_handshake_is_renegotiation(conn)) {
  637. uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
  638. POSIX_GUARD(s2n_stuffer_write_bytes(out, renegotiation_info_scsv, S2N_TLS_CIPHER_SUITE_LEN));
  639. }
  640. /* Write size of the list of available ciphers */
  641. POSIX_GUARD(s2n_stuffer_write_vector_size(&available_cipher_suites_size));
  642. /* Zero compression methods */
  643. POSIX_GUARD(s2n_stuffer_write_uint8(out, 1));
  644. POSIX_GUARD(s2n_stuffer_write_uint8(out, 0));
  645. /* Write the extensions */
  646. POSIX_GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, out));
  647. /* Once the message is complete, finish calculating the PSK binders.
  648. *
  649. * The PSK binders require all the sizes in the ClientHello to be written correctly,
  650. * including the extension size and extension list size, and therefore have
  651. * to be calculated AFTER we finish writing the entire extension list. */
  652. POSIX_GUARD_RESULT(s2n_finish_psk_extension(conn));
  653. /* If early data was not requested as part of the ClientHello, it never will be. */
  654. if (conn->early_data_state == S2N_UNKNOWN_EARLY_DATA_STATE) {
  655. POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_EARLY_DATA_NOT_REQUESTED));
  656. }
  657. return S2N_SUCCESS;
  658. }
  659. /*
  660. * s2n-tls does NOT support SSLv2. However, it does support SSLv2 ClientHellos.
  661. * Clients may send SSLv2 ClientHellos advertising higher protocol versions for
  662. * backwards compatibility reasons. See https://tools.ietf.org/rfc/rfc2246 Appendix E.
  663. *
  664. * In this case, conn->client_hello_version will be SSLv2, but conn->client_protocol_version
  665. * will likely be higher.
  666. *
  667. * See http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html Section 2.5
  668. * for a description of the expected SSLv2 format.
  669. * Alternatively, the TLS1.0 RFC includes a more modern description of the format:
  670. * https://tools.ietf.org/rfc/rfc2246 Appendix E.1
  671. */
  672. int s2n_sslv2_client_hello_recv(struct s2n_connection *conn)
  673. {
  674. struct s2n_client_hello *client_hello = &conn->client_hello;
  675. client_hello->sslv2 = true;
  676. struct s2n_stuffer in_stuffer = { 0 };
  677. POSIX_GUARD(s2n_stuffer_init(&in_stuffer, &client_hello->raw_message));
  678. POSIX_GUARD(s2n_stuffer_skip_write(&in_stuffer, client_hello->raw_message.size));
  679. struct s2n_stuffer *in = &in_stuffer;
  680. const struct s2n_security_policy *security_policy;
  681. POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
  682. if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
  683. POSIX_GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
  684. POSIX_BAIL(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
  685. }
  686. conn->actual_protocol_version = MIN(conn->client_protocol_version, conn->server_protocol_version);
  687. /* We start 5 bytes into the record */
  688. uint16_t cipher_suites_length;
  689. POSIX_GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));
  690. POSIX_ENSURE(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
  691. POSIX_ENSURE(cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
  692. uint16_t session_id_length;
  693. POSIX_GUARD(s2n_stuffer_read_uint16(in, &session_id_length));
  694. uint16_t challenge_length;
  695. POSIX_GUARD(s2n_stuffer_read_uint16(in, &challenge_length));
  696. S2N_ERROR_IF(challenge_length > S2N_TLS_RANDOM_DATA_LEN, S2N_ERR_BAD_MESSAGE);
  697. client_hello->cipher_suites.size = cipher_suites_length;
  698. client_hello->cipher_suites.data = s2n_stuffer_raw_read(in, cipher_suites_length);
  699. POSIX_ENSURE_REF(client_hello->cipher_suites.data);
  700. /* Find potential certificate matches before we choose the cipher. */
  701. POSIX_GUARD(s2n_conn_find_name_matching_certs(conn));
  702. POSIX_GUARD(s2n_set_cipher_as_sslv2_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / S2N_SSLv2_CIPHER_SUITE_LEN));
  703. POSIX_GUARD(s2n_choose_default_sig_scheme(conn, &conn->handshake_params.server_cert_sig_scheme, S2N_SERVER));
  704. POSIX_GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
  705. S2N_ERROR_IF(session_id_length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
  706. POSIX_GUARD(s2n_blob_init(&client_hello->session_id, s2n_stuffer_raw_read(in, session_id_length), session_id_length));
  707. if (session_id_length > 0 && session_id_length <= S2N_TLS_SESSION_ID_MAX_LEN) {
  708. POSIX_CHECKED_MEMCPY(conn->session_id, client_hello->session_id.data, session_id_length);
  709. conn->session_id_len = (uint8_t) session_id_length;
  710. }
  711. struct s2n_blob b = { 0 };
  712. POSIX_GUARD(s2n_blob_init(&b, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN));
  713. b.data += S2N_TLS_RANDOM_DATA_LEN - challenge_length;
  714. b.size -= S2N_TLS_RANDOM_DATA_LEN - challenge_length;
  715. POSIX_GUARD(s2n_stuffer_read(in, &b));
  716. return 0;
  717. }
  718. int s2n_client_hello_get_parsed_extension(s2n_tls_extension_type extension_type,
  719. s2n_parsed_extensions_list *parsed_extension_list, s2n_parsed_extension **parsed_extension)
  720. {
  721. POSIX_ENSURE_REF(parsed_extension_list);
  722. POSIX_ENSURE_REF(parsed_extension);
  723. s2n_extension_type_id extension_type_id;
  724. POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type, &extension_type_id));
  725. s2n_parsed_extension *found_parsed_extension = &parsed_extension_list->parsed_extensions[extension_type_id];
  726. POSIX_ENSURE(found_parsed_extension->extension.data, S2N_ERR_EXTENSION_NOT_RECEIVED);
  727. POSIX_ENSURE(found_parsed_extension->extension_type == extension_type, S2N_ERR_INVALID_PARSED_EXTENSIONS);
  728. *parsed_extension = found_parsed_extension;
  729. return S2N_SUCCESS;
  730. }
  731. ssize_t s2n_client_hello_get_extension_length(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type)
  732. {
  733. POSIX_ENSURE_REF(ch);
  734. s2n_parsed_extension *parsed_extension = NULL;
  735. if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
  736. return 0;
  737. }
  738. return parsed_extension->extension.size;
  739. }
  740. ssize_t s2n_client_hello_get_extension_by_id(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type, uint8_t *out, uint32_t max_length)
  741. {
  742. POSIX_ENSURE_REF(ch);
  743. POSIX_ENSURE_REF(out);
  744. s2n_parsed_extension *parsed_extension = NULL;
  745. if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
  746. return 0;
  747. }
  748. uint32_t len = min_size(&parsed_extension->extension, max_length);
  749. POSIX_CHECKED_MEMCPY(out, parsed_extension->extension.data, len);
  750. return len;
  751. }
  752. int s2n_client_hello_get_session_id_length(struct s2n_client_hello *ch, uint32_t *out_length)
  753. {
  754. POSIX_ENSURE_REF(ch);
  755. POSIX_ENSURE_REF(out_length);
  756. *out_length = ch->session_id.size;
  757. return S2N_SUCCESS;
  758. }
  759. int s2n_client_hello_get_session_id(struct s2n_client_hello *ch, uint8_t *out, uint32_t *out_length, uint32_t max_length)
  760. {
  761. POSIX_ENSURE_REF(ch);
  762. POSIX_ENSURE_REF(out);
  763. POSIX_ENSURE_REF(out_length);
  764. uint32_t len = min_size(&ch->session_id, max_length);
  765. POSIX_CHECKED_MEMCPY(out, ch->session_id.data, len);
  766. *out_length = len;
  767. return S2N_SUCCESS;
  768. }
  769. static S2N_RESULT s2n_client_hello_get_raw_extension(uint16_t extension_iana,
  770. struct s2n_blob *raw_extensions, struct s2n_blob *extension)
  771. {
  772. RESULT_ENSURE_REF(raw_extensions);
  773. RESULT_ENSURE_REF(extension);
  774. *extension = (struct s2n_blob){ 0 };
  775. struct s2n_stuffer raw_extensions_stuffer = { 0 };
  776. RESULT_GUARD_POSIX(s2n_stuffer_init(&raw_extensions_stuffer, raw_extensions));
  777. RESULT_GUARD_POSIX(s2n_stuffer_skip_write(&raw_extensions_stuffer, raw_extensions->size));
  778. while (s2n_stuffer_data_available(&raw_extensions_stuffer) > 0) {
  779. uint16_t extension_type = 0;
  780. RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&raw_extensions_stuffer, &extension_type));
  781. uint16_t extension_size = 0;
  782. RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&raw_extensions_stuffer, &extension_size));
  783. uint8_t *extension_data = s2n_stuffer_raw_read(&raw_extensions_stuffer, extension_size);
  784. RESULT_ENSURE_REF(extension_data);
  785. if (extension_iana == extension_type) {
  786. RESULT_GUARD_POSIX(s2n_blob_init(extension, extension_data, extension_size));
  787. return S2N_RESULT_OK;
  788. }
  789. }
  790. return S2N_RESULT_OK;
  791. }
  792. int s2n_client_hello_has_extension(struct s2n_client_hello *ch, uint16_t extension_iana, bool *exists)
  793. {
  794. POSIX_ENSURE_REF(ch);
  795. POSIX_ENSURE_REF(exists);
  796. *exists = false;
  797. s2n_extension_type_id extension_type_id = s2n_unsupported_extension;
  798. if (s2n_extension_supported_iana_value_to_id(extension_iana, &extension_type_id) == S2N_SUCCESS) {
  799. s2n_parsed_extension *parsed_extension = NULL;
  800. if (s2n_client_hello_get_parsed_extension(extension_iana, &ch->extensions, &parsed_extension) == S2N_SUCCESS) {
  801. *exists = true;
  802. }
  803. return S2N_SUCCESS;
  804. }
  805. struct s2n_blob extension = { 0 };
  806. POSIX_GUARD_RESULT(s2n_client_hello_get_raw_extension(extension_iana, &ch->extensions.raw, &extension));
  807. if (extension.data != NULL) {
  808. *exists = true;
  809. }
  810. return S2N_SUCCESS;
  811. }
  812. int s2n_client_hello_get_supported_groups(struct s2n_client_hello *ch, uint16_t *groups,
  813. uint16_t groups_count_max, uint16_t *groups_count_out)
  814. {
  815. POSIX_ENSURE_REF(groups_count_out);
  816. *groups_count_out = 0;
  817. POSIX_ENSURE_REF(ch);
  818. POSIX_ENSURE_REF(groups);
  819. s2n_parsed_extension *supported_groups_extension = NULL;
  820. POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SUPPORTED_GROUPS, &ch->extensions, &supported_groups_extension));
  821. POSIX_ENSURE_REF(supported_groups_extension);
  822. struct s2n_stuffer extension_stuffer = { 0 };
  823. POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &supported_groups_extension->extension));
  824. uint16_t supported_groups_count = 0;
  825. POSIX_GUARD_RESULT(s2n_supported_groups_parse_count(&extension_stuffer, &supported_groups_count));
  826. POSIX_ENSURE(supported_groups_count <= groups_count_max, S2N_ERR_INSUFFICIENT_MEM_SIZE);
  827. for (size_t i = 0; i < supported_groups_count; i++) {
  828. /* s2n_stuffer_read_uint16 is used to read each of the supported groups in network-order
  829. * endianness.
  830. */
  831. POSIX_GUARD(s2n_stuffer_read_uint16(&extension_stuffer, &groups[i]));
  832. }
  833. *groups_count_out = supported_groups_count;
  834. return S2N_SUCCESS;
  835. }