s2n_config.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  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 <strings.h>
  16. #include <time.h>
  17. #include "api/unstable/npn.h"
  18. #include "crypto/s2n_certificate.h"
  19. #include "crypto/s2n_fips.h"
  20. #include "crypto/s2n_hkdf.h"
  21. #include "error/s2n_errno.h"
  22. #include "tls/s2n_cipher_preferences.h"
  23. #include "tls/s2n_internal.h"
  24. #include "tls/s2n_ktls.h"
  25. #include "tls/s2n_security_policies.h"
  26. #include "tls/s2n_tls13.h"
  27. #include "utils/s2n_blob.h"
  28. #include "utils/s2n_map.h"
  29. #include "utils/s2n_safety.h"
  30. #if defined(CLOCK_MONOTONIC_RAW)
  31. #define S2N_CLOCK_HW CLOCK_MONOTONIC_RAW
  32. #else
  33. #define S2N_CLOCK_HW CLOCK_MONOTONIC
  34. #endif
  35. #define S2N_CLOCK_SYS CLOCK_REALTIME
  36. static int monotonic_clock(void *data, uint64_t *nanoseconds)
  37. {
  38. struct timespec current_time = { 0 };
  39. POSIX_GUARD(clock_gettime(S2N_CLOCK_HW, &current_time));
  40. *nanoseconds = (uint64_t) current_time.tv_sec * 1000000000ull;
  41. *nanoseconds += current_time.tv_nsec;
  42. return 0;
  43. }
  44. static int wall_clock(void *data, uint64_t *nanoseconds)
  45. {
  46. struct timespec current_time = { 0 };
  47. POSIX_GUARD(clock_gettime(S2N_CLOCK_SYS, &current_time));
  48. *nanoseconds = (uint64_t) current_time.tv_sec * 1000000000ull;
  49. *nanoseconds += current_time.tv_nsec;
  50. return 0;
  51. }
  52. static struct s2n_config s2n_default_config = { 0 };
  53. static struct s2n_config s2n_default_fips_config = { 0 };
  54. static struct s2n_config s2n_default_tls13_config = { 0 };
  55. static int s2n_config_setup_default(struct s2n_config *config)
  56. {
  57. POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default"));
  58. return S2N_SUCCESS;
  59. }
  60. static int s2n_config_setup_tls13(struct s2n_config *config)
  61. {
  62. POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default_tls13"));
  63. return S2N_SUCCESS;
  64. }
  65. static int s2n_config_setup_fips(struct s2n_config *config)
  66. {
  67. POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default_fips"));
  68. return S2N_SUCCESS;
  69. }
  70. static int s2n_config_init(struct s2n_config *config)
  71. {
  72. config->wall_clock = wall_clock;
  73. config->monotonic_clock = monotonic_clock;
  74. config->ct_type = S2N_CT_SUPPORT_NONE;
  75. config->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
  76. config->alert_behavior = S2N_ALERT_FAIL_ON_WARNINGS;
  77. config->session_state_lifetime_in_nanos = S2N_STATE_LIFETIME_IN_NANOS;
  78. config->encrypt_decrypt_key_lifetime_in_nanos = S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS;
  79. config->decrypt_key_lifetime_in_nanos = S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS;
  80. config->async_pkey_validation_mode = S2N_ASYNC_PKEY_VALIDATION_FAST;
  81. /* By default, only the client will authenticate the Server's Certificate. The Server does not request or
  82. * authenticate any client certificates. */
  83. config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
  84. config->check_ocsp = 1;
  85. config->client_hello_cb_mode = S2N_CLIENT_HELLO_CB_BLOCKING;
  86. POSIX_GUARD(s2n_config_setup_default(config));
  87. if (s2n_use_default_tls13_config()) {
  88. POSIX_GUARD(s2n_config_setup_tls13(config));
  89. } else if (s2n_is_in_fips_mode()) {
  90. POSIX_GUARD(s2n_config_setup_fips(config));
  91. }
  92. POSIX_GUARD_PTR(config->domain_name_to_cert_map = s2n_map_new_with_initial_capacity(1));
  93. POSIX_GUARD_RESULT(s2n_map_complete(config->domain_name_to_cert_map));
  94. s2n_x509_trust_store_init_empty(&config->trust_store);
  95. return 0;
  96. }
  97. static int s2n_config_cleanup(struct s2n_config *config)
  98. {
  99. s2n_x509_trust_store_wipe(&config->trust_store);
  100. config->check_ocsp = 0;
  101. POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
  102. POSIX_GUARD(s2n_config_free_cert_chain_and_key(config));
  103. POSIX_GUARD(s2n_config_free_dhparams(config));
  104. POSIX_GUARD(s2n_free(&config->application_protocols));
  105. POSIX_GUARD_RESULT(s2n_map_free(config->domain_name_to_cert_map));
  106. return 0;
  107. }
  108. static int s2n_config_update_domain_name_to_cert_map(struct s2n_config *config,
  109. struct s2n_blob *name,
  110. struct s2n_cert_chain_and_key *cert_key_pair)
  111. {
  112. POSIX_ENSURE_REF(config);
  113. POSIX_ENSURE_REF(name);
  114. struct s2n_map *domain_name_to_cert_map = config->domain_name_to_cert_map;
  115. /* s2n_map does not allow zero-size key */
  116. if (name->size == 0) {
  117. return 0;
  118. }
  119. s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
  120. struct s2n_blob s2n_map_value = { 0 };
  121. bool key_found = false;
  122. POSIX_GUARD_RESULT(s2n_map_lookup(domain_name_to_cert_map, name, &s2n_map_value, &key_found));
  123. if (!key_found) {
  124. struct certs_by_type value = { { 0 } };
  125. value.certs[cert_type] = cert_key_pair;
  126. s2n_map_value.data = (uint8_t *) &value;
  127. s2n_map_value.size = sizeof(struct certs_by_type);
  128. POSIX_GUARD_RESULT(s2n_map_unlock(domain_name_to_cert_map));
  129. POSIX_GUARD_RESULT(s2n_map_add(domain_name_to_cert_map, name, &s2n_map_value));
  130. POSIX_GUARD_RESULT(s2n_map_complete(domain_name_to_cert_map));
  131. } else {
  132. struct certs_by_type *value = (void *) s2n_map_value.data;
  133. if (value->certs[cert_type] == NULL) {
  134. value->certs[cert_type] = cert_key_pair;
  135. } else if (config->cert_tiebreak_cb) {
  136. /* There's an existing certificate for this (domain_name, auth_method).
  137. * Run the application's tiebreaking callback to decide which cert should be used.
  138. * An application may have some context specific logic to resolve ties that are based
  139. * on factors like trust, expiry, etc.
  140. */
  141. struct s2n_cert_chain_and_key *winner = config->cert_tiebreak_cb(
  142. value->certs[cert_type],
  143. cert_key_pair,
  144. name->data,
  145. name->size);
  146. if (winner) {
  147. value->certs[cert_type] = winner;
  148. }
  149. }
  150. }
  151. return 0;
  152. }
  153. static int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
  154. {
  155. uint32_t cn_len = 0;
  156. POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->cn_names, &cn_len));
  157. uint32_t san_len = 0;
  158. POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->san_names, &san_len));
  159. if (san_len == 0) {
  160. for (uint32_t i = 0; i < cn_len; i++) {
  161. struct s2n_blob *cn_name = NULL;
  162. POSIX_GUARD_RESULT(s2n_array_get(cert_key_pair->cn_names, i, (void **) &cn_name));
  163. POSIX_GUARD(s2n_config_update_domain_name_to_cert_map(config, cn_name, cert_key_pair));
  164. }
  165. } else {
  166. for (uint32_t i = 0; i < san_len; i++) {
  167. struct s2n_blob *san_name = NULL;
  168. POSIX_GUARD_RESULT(s2n_array_get(cert_key_pair->san_names, i, (void **) &san_name));
  169. POSIX_GUARD(s2n_config_update_domain_name_to_cert_map(config, san_name, cert_key_pair));
  170. }
  171. }
  172. return 0;
  173. }
  174. struct s2n_config *s2n_fetch_default_config(void)
  175. {
  176. if (s2n_use_default_tls13_config()) {
  177. return &s2n_default_tls13_config;
  178. }
  179. if (s2n_is_in_fips_mode()) {
  180. return &s2n_default_fips_config;
  181. }
  182. return &s2n_default_config;
  183. }
  184. int s2n_config_set_unsafe_for_testing(struct s2n_config *config)
  185. {
  186. POSIX_ENSURE(s2n_in_test(), S2N_ERR_NOT_IN_TEST);
  187. config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
  188. config->check_ocsp = 0;
  189. config->disable_x509_validation = 1;
  190. return S2N_SUCCESS;
  191. }
  192. int s2n_config_defaults_init(void)
  193. {
  194. /* Set up fips defaults */
  195. if (s2n_is_in_fips_mode()) {
  196. POSIX_GUARD(s2n_config_init(&s2n_default_fips_config));
  197. POSIX_GUARD(s2n_config_setup_fips(&s2n_default_fips_config));
  198. POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_fips_config));
  199. } else {
  200. /* Set up default */
  201. POSIX_GUARD(s2n_config_init(&s2n_default_config));
  202. POSIX_GUARD(s2n_config_setup_default(&s2n_default_config));
  203. POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_config));
  204. }
  205. /* Set up TLS 1.3 defaults */
  206. POSIX_GUARD(s2n_config_init(&s2n_default_tls13_config));
  207. POSIX_GUARD(s2n_config_setup_tls13(&s2n_default_tls13_config));
  208. POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_tls13_config));
  209. return S2N_SUCCESS;
  210. }
  211. void s2n_wipe_static_configs(void)
  212. {
  213. s2n_config_cleanup(&s2n_default_fips_config);
  214. s2n_config_cleanup(&s2n_default_config);
  215. s2n_config_cleanup(&s2n_default_tls13_config);
  216. }
  217. int s2n_config_load_system_certs(struct s2n_config *config)
  218. {
  219. POSIX_ENSURE_REF(config);
  220. struct s2n_x509_trust_store *store = &config->trust_store;
  221. POSIX_ENSURE(!store->loaded_system_certs, S2N_ERR_X509_TRUST_STORE);
  222. if (!store->trust_store) {
  223. store->trust_store = X509_STORE_new();
  224. POSIX_ENSURE_REF(store->trust_store);
  225. }
  226. int err_code = X509_STORE_set_default_paths(store->trust_store);
  227. if (!err_code) {
  228. s2n_x509_trust_store_wipe(store);
  229. POSIX_BAIL(S2N_ERR_X509_TRUST_STORE);
  230. }
  231. store->loaded_system_certs = true;
  232. return S2N_SUCCESS;
  233. }
  234. struct s2n_config *s2n_config_new_minimal(void)
  235. {
  236. struct s2n_blob allocator = { 0 };
  237. struct s2n_config *new_config;
  238. PTR_GUARD_POSIX(s2n_alloc(&allocator, sizeof(struct s2n_config)));
  239. PTR_GUARD_POSIX(s2n_blob_zero(&allocator));
  240. new_config = (struct s2n_config *) (void *) allocator.data;
  241. if (s2n_config_init(new_config) != S2N_SUCCESS) {
  242. s2n_free(&allocator);
  243. return NULL;
  244. }
  245. return new_config;
  246. }
  247. struct s2n_config *s2n_config_new(void)
  248. {
  249. struct s2n_config *new_config = s2n_config_new_minimal();
  250. PTR_ENSURE_REF(new_config);
  251. /* For backwards compatibility, s2n_config_new loads system certs by default. */
  252. PTR_GUARD_POSIX(s2n_config_load_system_certs(new_config));
  253. return new_config;
  254. }
  255. static int s2n_config_store_ticket_key_comparator(const void *a, const void *b)
  256. {
  257. if (((const struct s2n_ticket_key *) a)->intro_timestamp >= ((const struct s2n_ticket_key *) b)->intro_timestamp) {
  258. return S2N_GREATER_OR_EQUAL;
  259. } else {
  260. return S2N_LESS_THAN;
  261. }
  262. }
  263. static int s2n_verify_unique_ticket_key_comparator(const void *a, const void *b)
  264. {
  265. return memcmp(a, b, SHA_DIGEST_LENGTH);
  266. }
  267. int s2n_config_init_session_ticket_keys(struct s2n_config *config)
  268. {
  269. if (config->ticket_keys == NULL) {
  270. POSIX_ENSURE_REF(config->ticket_keys = s2n_set_new(sizeof(struct s2n_ticket_key), s2n_config_store_ticket_key_comparator));
  271. }
  272. if (config->ticket_key_hashes == NULL) {
  273. POSIX_ENSURE_REF(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
  274. }
  275. return 0;
  276. }
  277. int s2n_config_free_session_ticket_keys(struct s2n_config *config)
  278. {
  279. if (config->ticket_keys != NULL) {
  280. POSIX_GUARD_RESULT(s2n_set_free_p(&config->ticket_keys));
  281. }
  282. if (config->ticket_key_hashes != NULL) {
  283. POSIX_GUARD_RESULT(s2n_set_free_p(&config->ticket_key_hashes));
  284. }
  285. return 0;
  286. }
  287. int s2n_config_free_cert_chain_and_key(struct s2n_config *config)
  288. {
  289. /* We track certificate ownership on the config itself because a config
  290. * CANNOT use a combination of owned and unowned chains.
  291. * If it does, and the unowned chains are freed before the config is,
  292. * then iterating over the chains to determine which are owned and need to be freed
  293. * will mean also reading the invalid, freed memory of any unowned certificates.
  294. * As of now, some tests free chains before the config, so that pattern may also
  295. * appear in application code.
  296. */
  297. if (config->cert_ownership != S2N_LIB_OWNED) {
  298. return S2N_SUCCESS;
  299. }
  300. /* Free the cert_chain_and_key since the application has no reference
  301. * to it. This is necessary until s2n_config_add_cert_chain_and_key is deprecated. */
  302. for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
  303. s2n_cert_chain_and_key_free(config->default_certs_by_type.certs[i]);
  304. config->default_certs_by_type.certs[i] = NULL;
  305. }
  306. config->cert_ownership = S2N_NOT_OWNED;
  307. return S2N_SUCCESS;
  308. }
  309. int s2n_config_free_dhparams(struct s2n_config *config)
  310. {
  311. if (config->dhparams) {
  312. POSIX_GUARD(s2n_dh_params_free(config->dhparams));
  313. }
  314. POSIX_GUARD(s2n_free_object((uint8_t **) &config->dhparams, sizeof(struct s2n_dh_params)));
  315. return 0;
  316. }
  317. S2N_CLEANUP_RESULT s2n_config_ptr_free(struct s2n_config **config)
  318. {
  319. RESULT_ENSURE_REF(config);
  320. RESULT_GUARD_POSIX(s2n_config_free(*config));
  321. *config = NULL;
  322. return S2N_RESULT_OK;
  323. }
  324. int s2n_config_free(struct s2n_config *config)
  325. {
  326. s2n_config_cleanup(config);
  327. POSIX_GUARD(s2n_free_object((uint8_t **) &config, sizeof(struct s2n_config)));
  328. return 0;
  329. }
  330. int s2n_config_get_client_auth_type(struct s2n_config *config, s2n_cert_auth_type *client_auth_type)
  331. {
  332. POSIX_ENSURE_REF(config);
  333. POSIX_ENSURE_REF(client_auth_type);
  334. *client_auth_type = config->client_cert_auth_type;
  335. return 0;
  336. }
  337. int s2n_config_set_client_auth_type(struct s2n_config *config, s2n_cert_auth_type client_auth_type)
  338. {
  339. POSIX_ENSURE_REF(config);
  340. config->client_cert_auth_type = client_auth_type;
  341. return 0;
  342. }
  343. int s2n_config_set_ct_support_level(struct s2n_config *config, s2n_ct_support_level type)
  344. {
  345. POSIX_ENSURE_REF(config);
  346. config->ct_type = type;
  347. return 0;
  348. }
  349. int s2n_config_set_alert_behavior(struct s2n_config *config, s2n_alert_behavior alert_behavior)
  350. {
  351. POSIX_ENSURE_REF(config);
  352. switch (alert_behavior) {
  353. case S2N_ALERT_FAIL_ON_WARNINGS:
  354. case S2N_ALERT_IGNORE_WARNINGS:
  355. config->alert_behavior = alert_behavior;
  356. break;
  357. default:
  358. POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
  359. }
  360. return 0;
  361. }
  362. int s2n_config_set_verify_host_callback(struct s2n_config *config, s2n_verify_host_fn verify_host_fn, void *data)
  363. {
  364. POSIX_ENSURE_REF(config);
  365. config->verify_host_fn = verify_host_fn;
  366. config->data_for_verify_host = data;
  367. return 0;
  368. }
  369. int s2n_config_set_check_stapled_ocsp_response(struct s2n_config *config, uint8_t check_ocsp)
  370. {
  371. POSIX_ENSURE_REF(config);
  372. S2N_ERROR_IF(check_ocsp && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
  373. config->check_ocsp = check_ocsp;
  374. return 0;
  375. }
  376. int s2n_config_disable_x509_time_verification(struct s2n_config *config)
  377. {
  378. POSIX_ENSURE_REF(config);
  379. config->disable_x509_time_validation = true;
  380. return S2N_SUCCESS;
  381. }
  382. int s2n_config_disable_x509_verification(struct s2n_config *config)
  383. {
  384. POSIX_ENSURE_REF(config);
  385. s2n_x509_trust_store_wipe(&config->trust_store);
  386. config->disable_x509_validation = 1;
  387. return 0;
  388. }
  389. int s2n_config_set_max_cert_chain_depth(struct s2n_config *config, uint16_t max_depth)
  390. {
  391. POSIX_ENSURE_REF(config);
  392. S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
  393. config->max_verify_cert_chain_depth = max_depth;
  394. config->max_verify_cert_chain_depth_set = 1;
  395. return 0;
  396. }
  397. int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type)
  398. {
  399. S2N_ERROR_IF(type == S2N_STATUS_REQUEST_OCSP && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
  400. POSIX_ENSURE_REF(config);
  401. config->ocsp_status_requested_by_user = (type == S2N_STATUS_REQUEST_OCSP);
  402. /* Reset the ocsp_status_requested_by_s2n flag if OCSP status requests were disabled. */
  403. if (type == S2N_STATUS_REQUEST_NONE) {
  404. config->ocsp_status_requested_by_s2n = false;
  405. }
  406. return 0;
  407. }
  408. int s2n_config_wipe_trust_store(struct s2n_config *config)
  409. {
  410. POSIX_ENSURE_REF(config);
  411. s2n_x509_trust_store_wipe(&config->trust_store);
  412. return S2N_SUCCESS;
  413. }
  414. int s2n_config_add_pem_to_trust_store(struct s2n_config *config, const char *pem)
  415. {
  416. POSIX_ENSURE_REF(config);
  417. POSIX_ENSURE_REF(pem);
  418. POSIX_GUARD(s2n_x509_trust_store_add_pem(&config->trust_store, pem));
  419. return 0;
  420. }
  421. int s2n_config_set_verification_ca_location(struct s2n_config *config, const char *ca_pem_filename, const char *ca_dir)
  422. {
  423. POSIX_ENSURE_REF(config);
  424. int err_code = s2n_x509_trust_store_from_ca_file(&config->trust_store, ca_pem_filename, ca_dir);
  425. if (!err_code) {
  426. config->ocsp_status_requested_by_s2n = s2n_x509_ocsp_stapling_supported() ? S2N_STATUS_REQUEST_OCSP : S2N_STATUS_REQUEST_NONE;
  427. }
  428. return err_code;
  429. }
  430. static int s2n_config_add_cert_chain_and_key_impl(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
  431. {
  432. POSIX_ENSURE_REF(config->domain_name_to_cert_map);
  433. POSIX_ENSURE_REF(cert_key_pair);
  434. s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
  435. config->is_rsa_cert_configured |= (cert_type == S2N_PKEY_TYPE_RSA);
  436. POSIX_GUARD(s2n_config_build_domain_name_to_cert_map(config, cert_key_pair));
  437. if (!config->default_certs_are_explicit) {
  438. POSIX_ENSURE(cert_type >= 0, S2N_ERR_CERT_TYPE_UNSUPPORTED);
  439. POSIX_ENSURE(cert_type < S2N_CERT_TYPE_COUNT, S2N_ERR_CERT_TYPE_UNSUPPORTED);
  440. /* Attempt to auto set default based on ordering. ie: first RSA cert is the default, first ECDSA cert is the
  441. * default, etc. */
  442. if (config->default_certs_by_type.certs[cert_type] == NULL) {
  443. config->default_certs_by_type.certs[cert_type] = cert_key_pair;
  444. } else {
  445. /* Because library-owned certificates are tracked and cleaned up via the
  446. * default_certs_by_type mapping, library-owned chains MUST be set as the default
  447. * to avoid a memory leak. If they're not the default, they're not freed.
  448. */
  449. POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED,
  450. S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
  451. }
  452. }
  453. if (s2n_pkey_check_key_exists(cert_key_pair->private_key) != S2N_SUCCESS) {
  454. config->no_signing_key = true;
  455. }
  456. return S2N_SUCCESS;
  457. }
  458. /* Deprecated. Superseded by s2n_config_add_cert_chain_and_key_to_store */
  459. int s2n_config_add_cert_chain_and_key(struct s2n_config *config, const char *cert_chain_pem, const char *private_key_pem)
  460. {
  461. POSIX_ENSURE_REF(config);
  462. POSIX_ENSURE(config->cert_ownership != S2N_APP_OWNED, S2N_ERR_CERT_OWNERSHIP);
  463. DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = s2n_cert_chain_and_key_new(),
  464. s2n_cert_chain_and_key_ptr_free);
  465. POSIX_ENSURE_REF(chain_and_key);
  466. POSIX_GUARD(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem));
  467. POSIX_GUARD(s2n_config_add_cert_chain_and_key_impl(config, chain_and_key));
  468. config->cert_ownership = S2N_LIB_OWNED;
  469. ZERO_TO_DISABLE_DEFER_CLEANUP(chain_and_key);
  470. return S2N_SUCCESS;
  471. }
  472. /* Only used in the Rust bindings. Superseded by s2n_config_add_cert_chain_and_key_to_store */
  473. int s2n_config_add_cert_chain(struct s2n_config *config,
  474. uint8_t *cert_chain_pem, uint32_t cert_chain_pem_size)
  475. {
  476. POSIX_ENSURE_REF(config);
  477. POSIX_ENSURE(config->cert_ownership != S2N_APP_OWNED, S2N_ERR_CERT_OWNERSHIP);
  478. DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = s2n_cert_chain_and_key_new(),
  479. s2n_cert_chain_and_key_ptr_free);
  480. POSIX_ENSURE_REF(chain_and_key);
  481. POSIX_GUARD(s2n_cert_chain_and_key_load_public_pem_bytes(chain_and_key,
  482. cert_chain_pem, cert_chain_pem_size));
  483. POSIX_GUARD(s2n_config_add_cert_chain_and_key_impl(config, chain_and_key));
  484. config->cert_ownership = S2N_LIB_OWNED;
  485. ZERO_TO_DISABLE_DEFER_CLEANUP(chain_and_key);
  486. return S2N_SUCCESS;
  487. }
  488. int s2n_config_add_cert_chain_and_key_to_store(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
  489. {
  490. POSIX_ENSURE_REF(config);
  491. POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
  492. POSIX_ENSURE_REF(cert_key_pair);
  493. POSIX_GUARD(s2n_config_add_cert_chain_and_key_impl(config, cert_key_pair));
  494. config->cert_ownership = S2N_APP_OWNED;
  495. return S2N_SUCCESS;
  496. }
  497. int s2n_config_set_async_pkey_callback(struct s2n_config *config, s2n_async_pkey_fn fn)
  498. {
  499. POSIX_ENSURE_REF(config);
  500. config->async_pkey_cb = fn;
  501. return S2N_SUCCESS;
  502. }
  503. static int s2n_config_clear_default_certificates(struct s2n_config *config)
  504. {
  505. POSIX_ENSURE_REF(config);
  506. /* Clearing library-owned chains would lead to a memory leak.
  507. * See s2n_config_free_cert_chain_and_key.
  508. */
  509. POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
  510. for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
  511. config->default_certs_by_type.certs[i] = NULL;
  512. }
  513. config->cert_ownership = S2N_NOT_OWNED;
  514. return 0;
  515. }
  516. int s2n_config_set_cert_chain_and_key_defaults(struct s2n_config *config,
  517. struct s2n_cert_chain_and_key **cert_key_pairs,
  518. uint32_t num_cert_key_pairs)
  519. {
  520. POSIX_ENSURE_REF(config);
  521. POSIX_ENSURE_REF(cert_key_pairs);
  522. S2N_ERROR_IF(num_cert_key_pairs < 1 || num_cert_key_pairs > S2N_CERT_TYPE_COUNT,
  523. S2N_ERR_NUM_DEFAULT_CERTIFICATES);
  524. /* This method will set application-owned chains, so we must not already be using
  525. * any library owned chains. See s2n_config_free_cert_chain_and_key.
  526. */
  527. POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
  528. /* Validate certs being set before clearing auto-chosen defaults or previously set defaults */
  529. struct certs_by_type new_defaults = { { 0 } };
  530. for (size_t i = 0; i < num_cert_key_pairs; i++) {
  531. POSIX_ENSURE_REF(cert_key_pairs[i]);
  532. s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
  533. S2N_ERROR_IF(new_defaults.certs[cert_type] != NULL, S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
  534. new_defaults.certs[cert_type] = cert_key_pairs[i];
  535. }
  536. POSIX_GUARD(s2n_config_clear_default_certificates(config));
  537. for (size_t i = 0; i < num_cert_key_pairs; i++) {
  538. s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
  539. config->is_rsa_cert_configured |= (cert_type == S2N_PKEY_TYPE_RSA);
  540. config->default_certs_by_type.certs[cert_type] = cert_key_pairs[i];
  541. }
  542. config->default_certs_are_explicit = 1;
  543. config->cert_ownership = S2N_APP_OWNED;
  544. return 0;
  545. }
  546. int s2n_config_add_dhparams(struct s2n_config *config, const char *dhparams_pem)
  547. {
  548. DEFER_CLEANUP(struct s2n_stuffer dhparams_in_stuffer = { 0 }, s2n_stuffer_free);
  549. DEFER_CLEANUP(struct s2n_stuffer dhparams_out_stuffer = { 0 }, s2n_stuffer_free);
  550. struct s2n_blob dhparams_blob = { 0 };
  551. struct s2n_blob mem = { 0 };
  552. /* Allocate the memory for the chain and key struct */
  553. POSIX_GUARD(s2n_alloc(&mem, sizeof(struct s2n_dh_params)));
  554. config->dhparams = (struct s2n_dh_params *) (void *) mem.data;
  555. if (s2n_stuffer_alloc_ro_from_string(&dhparams_in_stuffer, dhparams_pem) != S2N_SUCCESS) {
  556. s2n_free(&mem);
  557. S2N_ERROR_PRESERVE_ERRNO();
  558. }
  559. if (s2n_stuffer_growable_alloc(&dhparams_out_stuffer, strlen(dhparams_pem)) != S2N_SUCCESS) {
  560. s2n_free(&mem);
  561. S2N_ERROR_PRESERVE_ERRNO();
  562. }
  563. /* Convert pem to asn1 and asn1 to the private key */
  564. POSIX_GUARD(s2n_stuffer_dhparams_from_pem(&dhparams_in_stuffer, &dhparams_out_stuffer));
  565. dhparams_blob.size = s2n_stuffer_data_available(&dhparams_out_stuffer);
  566. dhparams_blob.data = s2n_stuffer_raw_read(&dhparams_out_stuffer, dhparams_blob.size);
  567. POSIX_ENSURE_REF(dhparams_blob.data);
  568. POSIX_GUARD(s2n_pkcs3_to_dh_params(config->dhparams, &dhparams_blob));
  569. return 0;
  570. }
  571. int s2n_config_set_wall_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
  572. {
  573. POSIX_ENSURE_REF(clock_fn);
  574. config->wall_clock = clock_fn;
  575. config->sys_clock_ctx = ctx;
  576. return 0;
  577. }
  578. int s2n_config_set_monotonic_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
  579. {
  580. POSIX_ENSURE_REF(clock_fn);
  581. config->monotonic_clock = clock_fn;
  582. config->monotonic_clock_ctx = ctx;
  583. return 0;
  584. }
  585. int s2n_config_set_cache_store_callback(struct s2n_config *config, s2n_cache_store_callback cache_store_callback, void *data)
  586. {
  587. POSIX_ENSURE_REF(cache_store_callback);
  588. config->cache_store = cache_store_callback;
  589. config->cache_store_data = data;
  590. return 0;
  591. }
  592. int s2n_config_set_cache_retrieve_callback(struct s2n_config *config, s2n_cache_retrieve_callback cache_retrieve_callback, void *data)
  593. {
  594. POSIX_ENSURE_REF(cache_retrieve_callback);
  595. config->cache_retrieve = cache_retrieve_callback;
  596. config->cache_retrieve_data = data;
  597. return 0;
  598. }
  599. int s2n_config_set_cache_delete_callback(struct s2n_config *config, s2n_cache_delete_callback cache_delete_callback, void *data)
  600. {
  601. POSIX_ENSURE_REF(cache_delete_callback);
  602. config->cache_delete = cache_delete_callback;
  603. config->cache_delete_data = data;
  604. return 0;
  605. }
  606. int s2n_config_set_extension_data(struct s2n_config *config, s2n_tls_extension_type type, const uint8_t *data, uint32_t length)
  607. {
  608. POSIX_ENSURE_REF(config);
  609. if (s2n_config_get_num_default_certs(config) == 0) {
  610. POSIX_BAIL(S2N_ERR_UPDATING_EXTENSION);
  611. }
  612. struct s2n_cert_chain_and_key *config_chain_and_key = s2n_config_get_single_default_cert(config);
  613. POSIX_ENSURE_REF(config_chain_and_key);
  614. POSIX_ENSURE(config->cert_ownership == S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
  615. switch (type) {
  616. case S2N_EXTENSION_CERTIFICATE_TRANSPARENCY:
  617. POSIX_GUARD(s2n_cert_chain_and_key_set_sct_list(config_chain_and_key, data, length));
  618. break;
  619. case S2N_EXTENSION_OCSP_STAPLING:
  620. POSIX_GUARD(s2n_cert_chain_and_key_set_ocsp_data(config_chain_and_key, data, length));
  621. break;
  622. default:
  623. POSIX_BAIL(S2N_ERR_UNRECOGNIZED_EXTENSION);
  624. }
  625. return 0;
  626. }
  627. int s2n_config_set_client_hello_cb(struct s2n_config *config, s2n_client_hello_fn client_hello_cb, void *ctx)
  628. {
  629. POSIX_ENSURE_REF(config);
  630. config->client_hello_cb = client_hello_cb;
  631. config->client_hello_cb_ctx = ctx;
  632. return 0;
  633. }
  634. int s2n_config_set_client_hello_cb_mode(struct s2n_config *config, s2n_client_hello_cb_mode cb_mode)
  635. {
  636. POSIX_ENSURE_REF(config);
  637. POSIX_ENSURE(cb_mode == S2N_CLIENT_HELLO_CB_BLOCKING || cb_mode == S2N_CLIENT_HELLO_CB_NONBLOCKING, S2N_ERR_INVALID_STATE);
  638. config->client_hello_cb_mode = cb_mode;
  639. return S2N_SUCCESS;
  640. }
  641. int s2n_config_send_max_fragment_length(struct s2n_config *config, s2n_max_frag_len mfl_code)
  642. {
  643. POSIX_ENSURE_REF(config);
  644. S2N_ERROR_IF(mfl_code > S2N_TLS_MAX_FRAG_LEN_4096, S2N_ERR_INVALID_MAX_FRAG_LEN);
  645. config->mfl_code = mfl_code;
  646. return 0;
  647. }
  648. int s2n_config_accept_max_fragment_length(struct s2n_config *config)
  649. {
  650. POSIX_ENSURE_REF(config);
  651. config->accept_mfl = 1;
  652. return 0;
  653. }
  654. int s2n_config_set_session_state_lifetime(struct s2n_config *config,
  655. uint64_t lifetime_in_secs)
  656. {
  657. POSIX_ENSURE_REF(config);
  658. config->session_state_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
  659. return 0;
  660. }
  661. int s2n_config_set_session_tickets_onoff(struct s2n_config *config, uint8_t enabled)
  662. {
  663. POSIX_ENSURE_REF(config);
  664. if (config->use_tickets == enabled) {
  665. return 0;
  666. }
  667. config->use_tickets = enabled;
  668. if (config->initial_tickets_to_send == 0) {
  669. /* Normally initial_tickets_to_send is set via s2n_config_set_initial_ticket_count.
  670. * However, s2n_config_set_initial_ticket_count calls this method.
  671. * So we set initial_tickets_to_send directly to avoid infinite recursion. */
  672. config->initial_tickets_to_send = 1;
  673. }
  674. /* session ticket || session id is enabled */
  675. if (enabled) {
  676. POSIX_GUARD(s2n_config_init_session_ticket_keys(config));
  677. } else if (!config->use_session_cache) {
  678. POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
  679. }
  680. return 0;
  681. }
  682. int s2n_config_set_session_cache_onoff(struct s2n_config *config, uint8_t enabled)
  683. {
  684. POSIX_ENSURE_REF(config);
  685. if (enabled && config->cache_store && config->cache_retrieve && config->cache_delete) {
  686. POSIX_GUARD(s2n_config_init_session_ticket_keys(config));
  687. config->use_session_cache = 1;
  688. } else {
  689. if (!config->use_tickets) {
  690. POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
  691. }
  692. config->use_session_cache = 0;
  693. }
  694. return 0;
  695. }
  696. int s2n_config_set_ticket_encrypt_decrypt_key_lifetime(struct s2n_config *config,
  697. uint64_t lifetime_in_secs)
  698. {
  699. POSIX_ENSURE_REF(config);
  700. config->encrypt_decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
  701. return 0;
  702. }
  703. int s2n_config_set_ticket_decrypt_key_lifetime(struct s2n_config *config,
  704. uint64_t lifetime_in_secs)
  705. {
  706. POSIX_ENSURE_REF(config);
  707. config->decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
  708. return 0;
  709. }
  710. int s2n_config_add_ticket_crypto_key(struct s2n_config *config,
  711. const uint8_t *name, uint32_t name_len,
  712. uint8_t *key, uint32_t key_len,
  713. uint64_t intro_time_in_seconds_from_epoch)
  714. {
  715. POSIX_ENSURE_REF(config);
  716. POSIX_ENSURE_REF(name);
  717. POSIX_ENSURE_REF(key);
  718. /* both session ticket and session cache encryption/decryption can use the same key mechanism */
  719. if (!config->use_tickets && !config->use_session_cache) {
  720. return 0;
  721. }
  722. POSIX_GUARD(s2n_config_wipe_expired_ticket_crypto_keys(config, -1));
  723. POSIX_ENSURE(key_len != 0, S2N_ERR_INVALID_TICKET_KEY_LENGTH);
  724. uint32_t ticket_keys_len = 0;
  725. POSIX_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
  726. POSIX_ENSURE(ticket_keys_len < S2N_MAX_TICKET_KEYS, S2N_ERR_TICKET_KEY_LIMIT);
  727. POSIX_ENSURE(name_len != 0, S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
  728. POSIX_ENSURE(name_len <= S2N_TICKET_KEY_NAME_LEN, S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
  729. /* Copy the name into a zero-padded array. */
  730. /* This ensures that all ticket names are equal in length, as the serialized name is fixed length */
  731. uint8_t name_data[S2N_TICKET_KEY_NAME_LEN] = { 0 };
  732. POSIX_CHECKED_MEMCPY(name_data, name, name_len);
  733. /* ensure the ticket name is not already present */
  734. POSIX_ENSURE(s2n_find_ticket_key(config, name_data) == NULL, S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
  735. uint8_t output_pad[S2N_AES256_KEY_LEN + S2N_TICKET_AAD_IMPLICIT_LEN] = { 0 };
  736. struct s2n_blob out_key = { 0 };
  737. POSIX_GUARD(s2n_blob_init(&out_key, output_pad, s2n_array_len(output_pad)));
  738. struct s2n_blob in_key = { 0 };
  739. POSIX_GUARD(s2n_blob_init(&in_key, key, key_len));
  740. struct s2n_blob salt = { 0 };
  741. POSIX_GUARD(s2n_blob_init(&salt, NULL, 0));
  742. struct s2n_blob info = { 0 };
  743. POSIX_GUARD(s2n_blob_init(&info, NULL, 0));
  744. struct s2n_ticket_key *session_ticket_key = { 0 };
  745. DEFER_CLEANUP(struct s2n_blob allocator = { 0 }, s2n_free);
  746. POSIX_GUARD(s2n_alloc(&allocator, sizeof(struct s2n_ticket_key)));
  747. session_ticket_key = (struct s2n_ticket_key *) (void *) allocator.data;
  748. DEFER_CLEANUP(struct s2n_hmac_state hmac = { 0 }, s2n_hmac_free);
  749. POSIX_GUARD(s2n_hmac_new(&hmac));
  750. POSIX_GUARD(s2n_hkdf(&hmac, S2N_HMAC_SHA256, &salt, &in_key, &info, &out_key));
  751. DEFER_CLEANUP(struct s2n_hash_state hash = { 0 }, s2n_hash_free);
  752. uint8_t hash_output[SHA_DIGEST_LENGTH] = { 0 };
  753. POSIX_GUARD(s2n_hash_new(&hash));
  754. POSIX_GUARD(s2n_hash_init(&hash, S2N_HASH_SHA1));
  755. POSIX_GUARD(s2n_hash_update(&hash, out_key.data, out_key.size));
  756. POSIX_GUARD(s2n_hash_digest(&hash, hash_output, SHA_DIGEST_LENGTH));
  757. POSIX_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
  758. if (ticket_keys_len >= S2N_MAX_TICKET_KEY_HASHES) {
  759. POSIX_GUARD_RESULT(s2n_set_free_p(&config->ticket_key_hashes));
  760. POSIX_ENSURE_REF(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
  761. }
  762. /* Insert hash key into a sorted array at known index */
  763. POSIX_GUARD_RESULT(s2n_set_add(config->ticket_key_hashes, hash_output));
  764. POSIX_CHECKED_MEMCPY(session_ticket_key->key_name, name_data, s2n_array_len(name_data));
  765. POSIX_CHECKED_MEMCPY(session_ticket_key->aes_key, out_key.data, S2N_AES256_KEY_LEN);
  766. out_key.data = output_pad + S2N_AES256_KEY_LEN;
  767. POSIX_CHECKED_MEMCPY(session_ticket_key->implicit_aad, out_key.data, S2N_TICKET_AAD_IMPLICIT_LEN);
  768. if (intro_time_in_seconds_from_epoch == 0) {
  769. uint64_t now = 0;
  770. POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now));
  771. session_ticket_key->intro_timestamp = now;
  772. } else {
  773. session_ticket_key->intro_timestamp = (intro_time_in_seconds_from_epoch * ONE_SEC_IN_NANOS);
  774. }
  775. POSIX_GUARD(s2n_config_store_ticket_key(config, session_ticket_key));
  776. return 0;
  777. }
  778. int s2n_config_set_cert_tiebreak_callback(struct s2n_config *config, s2n_cert_tiebreak_callback cert_tiebreak_cb)
  779. {
  780. config->cert_tiebreak_cb = cert_tiebreak_cb;
  781. return 0;
  782. }
  783. struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config)
  784. {
  785. PTR_ENSURE_REF(config);
  786. struct s2n_cert_chain_and_key *cert = NULL;
  787. for (int i = S2N_CERT_TYPE_COUNT - 1; i >= 0; i--) {
  788. if (config->default_certs_by_type.certs[i] != NULL) {
  789. cert = config->default_certs_by_type.certs[i];
  790. }
  791. }
  792. return cert;
  793. }
  794. int s2n_config_get_num_default_certs(struct s2n_config *config)
  795. {
  796. POSIX_ENSURE_REF(config);
  797. int num_certs = 0;
  798. for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
  799. if (config->default_certs_by_type.certs[i] != NULL) {
  800. num_certs++;
  801. }
  802. }
  803. return num_certs;
  804. }
  805. int s2n_config_enable_cert_req_dss_legacy_compat(struct s2n_config *config)
  806. {
  807. POSIX_ENSURE_REF(config);
  808. config->cert_req_dss_legacy_compat_enabled = 1;
  809. return S2N_SUCCESS;
  810. }
  811. int s2n_config_set_psk_selection_callback(struct s2n_config *config, s2n_psk_selection_callback cb, void *context)
  812. {
  813. POSIX_ENSURE_REF(config);
  814. config->psk_selection_cb = cb;
  815. config->psk_selection_ctx = context;
  816. return S2N_SUCCESS;
  817. }
  818. int s2n_config_set_key_log_cb(struct s2n_config *config, s2n_key_log_fn callback, void *ctx)
  819. {
  820. POSIX_ENSURE_MUT(config);
  821. config->key_log_cb = callback;
  822. config->key_log_ctx = ctx;
  823. return S2N_SUCCESS;
  824. }
  825. int s2n_config_set_async_pkey_validation_mode(struct s2n_config *config, s2n_async_pkey_validation_mode mode)
  826. {
  827. POSIX_ENSURE_REF(config);
  828. switch (mode) {
  829. case S2N_ASYNC_PKEY_VALIDATION_FAST:
  830. case S2N_ASYNC_PKEY_VALIDATION_STRICT:
  831. config->async_pkey_validation_mode = mode;
  832. return S2N_SUCCESS;
  833. }
  834. POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
  835. }
  836. int s2n_config_set_ctx(struct s2n_config *config, void *ctx)
  837. {
  838. POSIX_ENSURE_REF(config);
  839. config->context = ctx;
  840. return S2N_SUCCESS;
  841. }
  842. int s2n_config_get_ctx(struct s2n_config *config, void **ctx)
  843. {
  844. POSIX_ENSURE_REF(config);
  845. POSIX_ENSURE_REF(ctx);
  846. *ctx = config->context;
  847. return S2N_SUCCESS;
  848. }
  849. int s2n_config_set_send_buffer_size(struct s2n_config *config, uint32_t size)
  850. {
  851. POSIX_ENSURE_REF(config);
  852. POSIX_ENSURE(size >= S2N_MIN_SEND_BUFFER_SIZE, S2N_ERR_INVALID_ARGUMENT);
  853. config->send_buffer_size_override = size;
  854. return S2N_SUCCESS;
  855. }
  856. int s2n_config_set_verify_after_sign(struct s2n_config *config, s2n_verify_after_sign mode)
  857. {
  858. POSIX_ENSURE_REF(config);
  859. switch (mode) {
  860. case S2N_VERIFY_AFTER_SIGN_DISABLED:
  861. config->verify_after_sign = false;
  862. break;
  863. case S2N_VERIFY_AFTER_SIGN_ENABLED:
  864. config->verify_after_sign = true;
  865. break;
  866. default:
  867. POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
  868. }
  869. return S2N_SUCCESS;
  870. }
  871. /*
  872. *= https://tools.ietf.org/rfc/rfc5746#5
  873. *# TLS implementations SHOULD provide a mechanism to disable and enable
  874. *# renegotiation.
  875. */
  876. int s2n_config_set_renegotiate_request_cb(struct s2n_config *config, s2n_renegotiate_request_cb cb, void *ctx)
  877. {
  878. POSIX_ENSURE_REF(config);
  879. config->renegotiate_request_cb = cb;
  880. config->renegotiate_request_ctx = ctx;
  881. return S2N_SUCCESS;
  882. }
  883. int s2n_config_set_npn(struct s2n_config *config, bool enable)
  884. {
  885. POSIX_ENSURE_REF(config);
  886. config->npn_supported = enable;
  887. return S2N_SUCCESS;
  888. }
  889. /*
  890. * Wrapper for wall_clock callback. This wrapper will ensure right return of s2n_errno everytime wall_clock
  891. * callback is called.
  892. */
  893. S2N_RESULT s2n_config_wall_clock(struct s2n_config *config, uint64_t *output)
  894. {
  895. RESULT_ENSURE(config->wall_clock(config->sys_clock_ctx, output) >= S2N_SUCCESS, S2N_ERR_CANCELLED);
  896. return S2N_RESULT_OK;
  897. }
  898. int s2n_config_set_crl_lookup_cb(struct s2n_config *config, s2n_crl_lookup_callback cb, void *ctx)
  899. {
  900. POSIX_ENSURE_REF(config);
  901. config->crl_lookup_cb = cb;
  902. config->crl_lookup_ctx = ctx;
  903. return S2N_SUCCESS;
  904. }
  905. int s2n_config_set_recv_multi_record(struct s2n_config *config, bool enabled)
  906. {
  907. POSIX_ENSURE_REF(config);
  908. config->recv_multi_record = enabled;
  909. return S2N_SUCCESS;
  910. }
  911. int s2n_config_set_cert_validation_cb(struct s2n_config *config, s2n_cert_validation_callback cb, void *ctx)
  912. {
  913. POSIX_ENSURE_REF(config);
  914. config->cert_validation_cb = cb;
  915. config->cert_validation_ctx = ctx;
  916. return S2N_SUCCESS;
  917. }