s2n_resume.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  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_resume.h"
  16. #include <math.h>
  17. #include <sys/param.h>
  18. #include "api/s2n.h"
  19. #include "error/s2n_errno.h"
  20. #include "stuffer/s2n_stuffer.h"
  21. #include "tls/s2n_cipher_suites.h"
  22. #include "tls/s2n_connection.h"
  23. #include "tls/s2n_crypto.h"
  24. #include "tls/s2n_tls.h"
  25. #include "utils/s2n_blob.h"
  26. #include "utils/s2n_random.h"
  27. #include "utils/s2n_safety.h"
  28. #include "utils/s2n_set.h"
  29. int s2n_allowed_to_cache_connection(struct s2n_connection *conn)
  30. {
  31. /* We're unable to cache connections with a Client Cert since we currently don't serialize the Client Cert,
  32. * which means that callers won't have access to the Client's Cert if the connection is resumed. */
  33. if (s2n_connection_is_client_auth_enabled(conn)) {
  34. return 0;
  35. }
  36. struct s2n_config *config = conn->config;
  37. POSIX_ENSURE_REF(config);
  38. return config->use_session_cache;
  39. }
  40. /* If a protocol version is required before the actual_protocol_version
  41. * is negotiated, we should fall back to resume_protocol_version if available.
  42. *
  43. * This covers the case where the application requests a ticket / session state
  44. * before a NewSessionTicket message has been sent or received. Historically,
  45. * in that case we return the ticket / session state already set for the connection.
  46. * resume_protocol_version represents the protocol version of that existing ticket / state.
  47. */
  48. static uint8_t s2n_resume_protocol_version(struct s2n_connection *conn)
  49. {
  50. if (!IS_NEGOTIATED(conn) && conn->resume_protocol_version) {
  51. return conn->resume_protocol_version;
  52. } else {
  53. return conn->actual_protocol_version;
  54. }
  55. }
  56. static int s2n_tls12_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
  57. {
  58. POSIX_ENSURE_REF(to);
  59. POSIX_ENSURE_REF(conn);
  60. POSIX_ENSURE_REF(conn->secure);
  61. uint64_t now;
  62. S2N_ERROR_IF(s2n_stuffer_space_remaining(to) < S2N_TLS12_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_IS_FULL);
  63. /* Get the time */
  64. POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now));
  65. /* Write the entry */
  66. POSIX_GUARD(s2n_stuffer_write_uint8(to, S2N_SERIALIZED_FORMAT_TLS12_V3));
  67. POSIX_GUARD(s2n_stuffer_write_uint8(to, s2n_resume_protocol_version(conn)));
  68. POSIX_GUARD(s2n_stuffer_write_bytes(to, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
  69. POSIX_GUARD(s2n_stuffer_write_uint64(to, now));
  70. POSIX_GUARD(s2n_stuffer_write_bytes(to, conn->secrets.version.tls12.master_secret, S2N_TLS_SECRET_LEN));
  71. POSIX_GUARD(s2n_stuffer_write_uint8(to, conn->ems_negotiated));
  72. return S2N_SUCCESS;
  73. }
  74. static S2N_RESULT s2n_tls13_serialize_keying_material_expiration(struct s2n_connection *conn,
  75. uint64_t now, struct s2n_stuffer *out)
  76. {
  77. RESULT_ENSURE_REF(conn);
  78. RESULT_ENSURE_REF(out);
  79. if (conn->mode != S2N_SERVER) {
  80. return S2N_RESULT_OK;
  81. }
  82. uint64_t expiration_timestamp = now + (conn->server_keying_material_lifetime * (uint64_t) ONE_SEC_IN_NANOS);
  83. struct s2n_psk *chosen_psk = conn->psk_params.chosen_psk;
  84. if (chosen_psk && chosen_psk->type == S2N_PSK_TYPE_RESUMPTION) {
  85. expiration_timestamp = MIN(chosen_psk->keying_material_expiration, expiration_timestamp);
  86. }
  87. RESULT_GUARD_POSIX(s2n_stuffer_write_uint64(out, expiration_timestamp));
  88. return S2N_RESULT_OK;
  89. }
  90. static S2N_RESULT s2n_tls13_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *out)
  91. {
  92. RESULT_ENSURE_REF(out);
  93. RESULT_ENSURE_REF(conn);
  94. RESULT_ENSURE_REF(conn->secure);
  95. uint64_t current_time = 0;
  96. struct s2n_ticket_fields *ticket_fields = &conn->tls13_ticket_fields;
  97. /* Get the time */
  98. RESULT_GUARD(s2n_config_wall_clock(conn->config, &current_time));
  99. RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, S2N_SERIALIZED_FORMAT_TLS13_V1));
  100. RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, conn->actual_protocol_version));
  101. RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
  102. RESULT_GUARD_POSIX(s2n_stuffer_write_uint64(out, current_time));
  103. RESULT_GUARD_POSIX(s2n_stuffer_write_uint32(out, ticket_fields->ticket_age_add));
  104. RESULT_ENSURE_INCLUSIVE_RANGE(1, ticket_fields->session_secret.size, UINT8_MAX);
  105. RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, ticket_fields->session_secret.size));
  106. RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, ticket_fields->session_secret.data, ticket_fields->session_secret.size));
  107. RESULT_GUARD(s2n_tls13_serialize_keying_material_expiration(conn, current_time, out));
  108. uint32_t server_max_early_data = 0;
  109. RESULT_GUARD(s2n_early_data_get_server_max_size(conn, &server_max_early_data));
  110. RESULT_GUARD_POSIX(s2n_stuffer_write_uint32(out, server_max_early_data));
  111. if (server_max_early_data > 0) {
  112. uint8_t application_protocol_len = strlen(conn->application_protocol);
  113. RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, application_protocol_len));
  114. RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, (uint8_t *) conn->application_protocol, application_protocol_len));
  115. RESULT_GUARD_POSIX(s2n_stuffer_write_uint16(out, conn->server_early_data_context.size));
  116. RESULT_GUARD_POSIX(s2n_stuffer_write(out, &conn->server_early_data_context));
  117. }
  118. return S2N_RESULT_OK;
  119. }
  120. static S2N_RESULT s2n_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *out)
  121. {
  122. if (s2n_resume_protocol_version(conn) < S2N_TLS13) {
  123. RESULT_GUARD_POSIX(s2n_tls12_serialize_resumption_state(conn, out));
  124. } else {
  125. RESULT_GUARD(s2n_tls13_serialize_resumption_state(conn, out));
  126. }
  127. return S2N_RESULT_OK;
  128. }
  129. static int s2n_tls12_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
  130. {
  131. POSIX_ENSURE_REF(conn);
  132. POSIX_ENSURE_REF(conn->secure);
  133. uint8_t protocol_version = 0;
  134. uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
  135. S2N_ERROR_IF(s2n_stuffer_data_available(from) < S2N_TLS12_STATE_SIZE_IN_BYTES - sizeof(uint8_t), S2N_ERR_STUFFER_OUT_OF_DATA);
  136. POSIX_GUARD(s2n_stuffer_read_uint8(from, &protocol_version));
  137. S2N_ERROR_IF(protocol_version != conn->actual_protocol_version, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  138. POSIX_GUARD(s2n_stuffer_read_bytes(from, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN));
  139. S2N_ERROR_IF(memcmp(conn->secure->cipher_suite->iana_value, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN), S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  140. uint64_t now;
  141. POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now));
  142. uint64_t then;
  143. POSIX_GUARD(s2n_stuffer_read_uint64(from, &then));
  144. S2N_ERROR_IF(then > now, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  145. S2N_ERROR_IF(now - then > conn->config->session_state_lifetime_in_nanos, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  146. POSIX_GUARD(s2n_stuffer_read_bytes(from, conn->secrets.version.tls12.master_secret, S2N_TLS_SECRET_LEN));
  147. if (s2n_stuffer_data_available(from)) {
  148. uint8_t ems_negotiated = 0;
  149. POSIX_GUARD(s2n_stuffer_read_uint8(from, &ems_negotiated));
  150. /**
  151. *= https://tools.ietf.org/rfc/rfc7627#section-5.3
  152. *# o If the original session did not use the "extended_master_secret"
  153. *# extension but the new ClientHello contains the extension, then the
  154. *# server MUST NOT perform the abbreviated handshake. Instead, it
  155. *# SHOULD continue with a full handshake (as described in
  156. *# Section 5.2) to negotiate a new session.
  157. *#
  158. *# o If the original session used the "extended_master_secret"
  159. *# extension but the new ClientHello does not contain it, the server
  160. *# MUST abort the abbreviated handshake.
  161. **/
  162. if (conn->ems_negotiated != ems_negotiated) {
  163. /* The session ticket needs to have the same EMS state as the current session. If it doesn't
  164. * have the same state, the current session takes the state of the session ticket and errors.
  165. * If the deserialization process errors, we will use this state in a few extra checks
  166. * to determine if we can fallback to a full handshake.
  167. */
  168. conn->ems_negotiated = ems_negotiated;
  169. POSIX_BAIL(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  170. }
  171. }
  172. return S2N_SUCCESS;
  173. }
  174. static int s2n_client_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
  175. {
  176. /* Serialize session ticket */
  177. if (conn->config->use_tickets && conn->client_ticket.size > 0) {
  178. POSIX_GUARD(s2n_stuffer_write_uint8(to, S2N_STATE_WITH_SESSION_TICKET));
  179. POSIX_GUARD(s2n_stuffer_write_uint16(to, conn->client_ticket.size));
  180. POSIX_GUARD(s2n_stuffer_write(to, &conn->client_ticket));
  181. } else {
  182. /* Serialize session id */
  183. POSIX_ENSURE_LT(conn->actual_protocol_version, S2N_TLS13);
  184. POSIX_GUARD(s2n_stuffer_write_uint8(to, S2N_STATE_WITH_SESSION_ID));
  185. POSIX_GUARD(s2n_stuffer_write_uint8(to, conn->session_id_len));
  186. POSIX_GUARD(s2n_stuffer_write_bytes(to, conn->session_id, conn->session_id_len));
  187. }
  188. /* Serialize session state */
  189. POSIX_GUARD_RESULT(s2n_serialize_resumption_state(conn, to));
  190. return 0;
  191. }
  192. static S2N_RESULT s2n_tls12_client_deserialize_session_state(struct s2n_connection *conn,
  193. struct s2n_blob *ticket, struct s2n_stuffer *from)
  194. {
  195. RESULT_ENSURE_REF(conn);
  196. RESULT_ENSURE_REF(from);
  197. /* Operate on a copy of the connection to avoid mutating the connection on
  198. * failure. We have tests in s2n_resume_test.c that prove this level of copy
  199. * is sufficient.
  200. */
  201. struct s2n_crypto_parameters *secure = conn->secure;
  202. RESULT_ENSURE_REF(secure);
  203. struct s2n_connection temp_conn = *conn;
  204. struct s2n_crypto_parameters temp_secure = *secure;
  205. temp_conn.secure = &temp_secure;
  206. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(from, &temp_conn.resume_protocol_version));
  207. uint8_t *cipher_suite_wire = s2n_stuffer_raw_read(from, S2N_TLS_CIPHER_SUITE_LEN);
  208. RESULT_ENSURE_REF(cipher_suite_wire);
  209. RESULT_GUARD_POSIX(s2n_set_cipher_as_client(&temp_conn, cipher_suite_wire));
  210. uint64_t then = 0;
  211. RESULT_GUARD_POSIX(s2n_stuffer_read_uint64(from, &then));
  212. RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(from, temp_conn.secrets.version.tls12.master_secret,
  213. S2N_TLS_SECRET_LEN));
  214. if (s2n_stuffer_data_available(from)) {
  215. uint8_t ems_negotiated = 0;
  216. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(from, &ems_negotiated));
  217. temp_conn.ems_negotiated = ems_negotiated;
  218. }
  219. DEFER_CLEANUP(struct s2n_blob client_ticket = { 0 }, s2n_free);
  220. if (ticket) {
  221. RESULT_GUARD_POSIX(s2n_dup(ticket, &client_ticket));
  222. }
  223. /* Finally, actually update the connection */
  224. RESULT_GUARD_POSIX(s2n_free(&conn->client_ticket));
  225. *secure = temp_secure;
  226. *conn = temp_conn;
  227. conn->secure = secure;
  228. conn->client_ticket = client_ticket;
  229. ZERO_TO_DISABLE_DEFER_CLEANUP(client_ticket);
  230. return S2N_RESULT_OK;
  231. }
  232. static S2N_RESULT s2n_validate_ticket_age(uint64_t current_time, uint64_t ticket_issue_time)
  233. {
  234. RESULT_ENSURE(current_time >= ticket_issue_time, S2N_ERR_INVALID_SESSION_TICKET);
  235. uint64_t ticket_age_in_nanos = current_time - ticket_issue_time;
  236. uint64_t ticket_age_in_sec = ticket_age_in_nanos / ONE_SEC_IN_NANOS;
  237. RESULT_ENSURE(ticket_age_in_sec <= ONE_WEEK_IN_SEC, S2N_ERR_INVALID_SESSION_TICKET);
  238. return S2N_RESULT_OK;
  239. }
  240. static S2N_RESULT s2n_tls13_deserialize_session_state(struct s2n_connection *conn, struct s2n_blob *psk_identity, struct s2n_stuffer *from)
  241. {
  242. RESULT_ENSURE_REF(conn);
  243. RESULT_ENSURE_REF(psk_identity);
  244. RESULT_ENSURE_REF(from);
  245. DEFER_CLEANUP(struct s2n_psk psk = { 0 }, s2n_psk_wipe);
  246. RESULT_GUARD(s2n_psk_init(&psk, S2N_PSK_TYPE_RESUMPTION));
  247. RESULT_GUARD_POSIX(s2n_psk_set_identity(&psk, psk_identity->data, psk_identity->size));
  248. uint8_t protocol_version = 0;
  249. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(from, &protocol_version));
  250. RESULT_ENSURE_GTE(protocol_version, S2N_TLS13);
  251. uint8_t iana_id[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
  252. RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(from, iana_id, S2N_TLS_CIPHER_SUITE_LEN));
  253. struct s2n_cipher_suite *cipher_suite = NULL;
  254. RESULT_GUARD(s2n_cipher_suite_from_iana(iana_id, sizeof(iana_id), &cipher_suite));
  255. RESULT_ENSURE_REF(cipher_suite);
  256. psk.hmac_alg = cipher_suite->prf_alg;
  257. RESULT_GUARD_POSIX(s2n_stuffer_read_uint64(from, &psk.ticket_issue_time));
  258. /**
  259. *= https://tools.ietf.org/rfc/rfc8446#section-4.6.1
  260. *# Clients MUST NOT cache
  261. *# tickets for longer than 7 days, regardless of the ticket_lifetime,
  262. *# and MAY delete tickets earlier based on local policy.
  263. */
  264. uint64_t current_time = 0;
  265. RESULT_GUARD(s2n_config_wall_clock(conn->config, &current_time));
  266. RESULT_GUARD(s2n_validate_ticket_age(current_time, psk.ticket_issue_time));
  267. RESULT_GUARD_POSIX(s2n_stuffer_read_uint32(from, &psk.ticket_age_add));
  268. uint8_t secret_len = 0;
  269. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(from, &secret_len));
  270. RESULT_ENSURE_LTE(secret_len, S2N_TLS_SECRET_LEN);
  271. uint8_t *secret_data = s2n_stuffer_raw_read(from, secret_len);
  272. RESULT_ENSURE_REF(secret_data);
  273. RESULT_GUARD_POSIX(s2n_psk_set_secret(&psk, secret_data, secret_len));
  274. if (conn->mode == S2N_SERVER) {
  275. RESULT_GUARD_POSIX(s2n_stuffer_read_uint64(from, &psk.keying_material_expiration));
  276. RESULT_ENSURE(psk.keying_material_expiration > current_time, S2N_ERR_KEYING_MATERIAL_EXPIRED);
  277. }
  278. uint32_t max_early_data_size = 0;
  279. RESULT_GUARD_POSIX(s2n_stuffer_read_uint32(from, &max_early_data_size));
  280. if (max_early_data_size > 0) {
  281. RESULT_GUARD_POSIX(s2n_psk_configure_early_data(&psk, max_early_data_size,
  282. iana_id[0], iana_id[1]));
  283. uint8_t app_proto_size = 0;
  284. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(from, &app_proto_size));
  285. uint8_t *app_proto_data = s2n_stuffer_raw_read(from, app_proto_size);
  286. RESULT_ENSURE_REF(app_proto_data);
  287. RESULT_GUARD_POSIX(s2n_psk_set_application_protocol(&psk, app_proto_data, app_proto_size));
  288. uint16_t early_data_context_size = 0;
  289. RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(from, &early_data_context_size));
  290. uint8_t *early_data_context_data = s2n_stuffer_raw_read(from, early_data_context_size);
  291. RESULT_ENSURE_REF(early_data_context_data);
  292. RESULT_GUARD_POSIX(s2n_psk_set_early_data_context(&psk, early_data_context_data, early_data_context_size));
  293. }
  294. /* Make sure that this connection is configured for resumption PSKs, not external PSKs */
  295. RESULT_GUARD(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_RESUMPTION));
  296. /* Remove all previously-set PSKs. To keep the session ticket API behavior consistent
  297. * across protocol versions, we currently only support setting a single resumption PSK. */
  298. RESULT_GUARD(s2n_psk_parameters_wipe(&conn->psk_params));
  299. RESULT_GUARD_POSIX(s2n_connection_append_psk(conn, &psk));
  300. return S2N_RESULT_OK;
  301. }
  302. S2N_RESULT s2n_deserialize_resumption_state(struct s2n_connection *conn,
  303. struct s2n_blob *ticket, struct s2n_stuffer *from)
  304. {
  305. RESULT_ENSURE_REF(conn);
  306. RESULT_ENSURE_REF(from);
  307. uint8_t format = 0;
  308. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(from, &format));
  309. if (format == S2N_SERIALIZED_FORMAT_TLS12_V3) {
  310. if (conn->mode == S2N_SERVER) {
  311. RESULT_GUARD_POSIX(s2n_tls12_deserialize_resumption_state(conn, from));
  312. } else {
  313. RESULT_GUARD(s2n_tls12_client_deserialize_session_state(conn, ticket, from));
  314. }
  315. } else if (format == S2N_SERIALIZED_FORMAT_TLS13_V1) {
  316. RESULT_GUARD(s2n_tls13_deserialize_session_state(conn, ticket, from));
  317. } else {
  318. RESULT_BAIL(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  319. }
  320. conn->set_session = true;
  321. return S2N_RESULT_OK;
  322. }
  323. static int s2n_client_deserialize_with_session_id(struct s2n_connection *conn, struct s2n_stuffer *from)
  324. {
  325. uint8_t session_id_len;
  326. POSIX_GUARD(s2n_stuffer_read_uint8(from, &session_id_len));
  327. if (session_id_len == 0 || session_id_len > S2N_TLS_SESSION_ID_MAX_LEN
  328. || session_id_len > s2n_stuffer_data_available(from)) {
  329. POSIX_BAIL(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  330. }
  331. conn->session_id_len = session_id_len;
  332. POSIX_GUARD(s2n_stuffer_read_bytes(from, conn->session_id, session_id_len));
  333. POSIX_GUARD_RESULT(s2n_deserialize_resumption_state(conn, NULL, from));
  334. return 0;
  335. }
  336. static int s2n_client_deserialize_with_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *from)
  337. {
  338. uint16_t session_ticket_len = 0;
  339. POSIX_GUARD(s2n_stuffer_read_uint16(from, &session_ticket_len));
  340. if (session_ticket_len == 0 || session_ticket_len > s2n_stuffer_data_available(from)) {
  341. POSIX_BAIL(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  342. }
  343. struct s2n_blob session_ticket = { 0 };
  344. uint8_t *session_ticket_bytes = s2n_stuffer_raw_read(from, session_ticket_len);
  345. POSIX_ENSURE_REF(session_ticket_bytes);
  346. POSIX_GUARD(s2n_blob_init(&session_ticket, session_ticket_bytes, session_ticket_len));
  347. POSIX_GUARD_RESULT(s2n_deserialize_resumption_state(conn, &session_ticket, from));
  348. return 0;
  349. }
  350. static int s2n_client_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
  351. {
  352. uint8_t format;
  353. POSIX_GUARD(s2n_stuffer_read_uint8(from, &format));
  354. switch (format) {
  355. case S2N_STATE_WITH_SESSION_ID:
  356. POSIX_GUARD(s2n_client_deserialize_with_session_id(conn, from));
  357. break;
  358. case S2N_STATE_WITH_SESSION_TICKET:
  359. POSIX_GUARD(s2n_client_deserialize_with_session_ticket(conn, from));
  360. break;
  361. default:
  362. POSIX_BAIL(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
  363. }
  364. return 0;
  365. }
  366. int s2n_resume_from_cache(struct s2n_connection *conn)
  367. {
  368. S2N_ERROR_IF(conn->session_id_len == 0, S2N_ERR_SESSION_ID_TOO_SHORT);
  369. S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_SESSION_ID_TOO_LONG);
  370. uint8_t data[S2N_TLS12_TICKET_SIZE_IN_BYTES] = { 0 };
  371. struct s2n_blob entry = { 0 };
  372. POSIX_GUARD(s2n_blob_init(&entry, data, S2N_TLS12_TICKET_SIZE_IN_BYTES));
  373. uint64_t size = entry.size;
  374. int result = conn->config->cache_retrieve(conn, conn->config->cache_retrieve_data, conn->session_id, conn->session_id_len, entry.data, &size);
  375. if (result == S2N_CALLBACK_BLOCKED) {
  376. POSIX_BAIL(S2N_ERR_ASYNC_BLOCKED);
  377. }
  378. POSIX_ENSURE(result >= S2N_SUCCESS, S2N_ERR_CANCELLED);
  379. S2N_ERROR_IF(size != entry.size, S2N_ERR_SIZE_MISMATCH);
  380. struct s2n_stuffer from = { 0 };
  381. POSIX_GUARD(s2n_stuffer_init(&from, &entry));
  382. POSIX_GUARD(s2n_stuffer_write(&from, &entry));
  383. POSIX_GUARD(s2n_decrypt_session_cache(conn, &from));
  384. return 0;
  385. }
  386. S2N_RESULT s2n_store_to_cache(struct s2n_connection *conn)
  387. {
  388. uint8_t data[S2N_TLS12_TICKET_SIZE_IN_BYTES] = { 0 };
  389. struct s2n_blob entry = { 0 };
  390. RESULT_GUARD_POSIX(s2n_blob_init(&entry, data, S2N_TLS12_TICKET_SIZE_IN_BYTES));
  391. struct s2n_stuffer to = { 0 };
  392. /* session_id_len should always be >0 since either the Client provided a SessionId or the Server generated a new
  393. * one for the Client */
  394. RESULT_ENSURE(conn->session_id_len > 0, S2N_ERR_SESSION_ID_TOO_SHORT);
  395. RESULT_ENSURE(conn->session_id_len <= S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_SESSION_ID_TOO_LONG);
  396. RESULT_GUARD_POSIX(s2n_stuffer_init(&to, &entry));
  397. RESULT_GUARD_POSIX(s2n_encrypt_session_cache(conn, &to));
  398. /* Store to the cache */
  399. conn->config->cache_store(conn, conn->config->cache_store_data, S2N_TLS_SESSION_CACHE_TTL, conn->session_id, conn->session_id_len, entry.data, entry.size);
  400. return S2N_RESULT_OK;
  401. }
  402. int s2n_connection_set_session(struct s2n_connection *conn, const uint8_t *session, size_t length)
  403. {
  404. POSIX_ENSURE_REF(conn);
  405. POSIX_ENSURE_REF(session);
  406. DEFER_CLEANUP(struct s2n_blob session_data = { 0 }, s2n_free);
  407. POSIX_GUARD(s2n_alloc(&session_data, length));
  408. POSIX_CHECKED_MEMCPY(session_data.data, session, length);
  409. struct s2n_stuffer from = { 0 };
  410. POSIX_GUARD(s2n_stuffer_init(&from, &session_data));
  411. POSIX_GUARD(s2n_stuffer_write(&from, &session_data));
  412. POSIX_GUARD(s2n_client_deserialize_resumption_state(conn, &from));
  413. return 0;
  414. }
  415. int s2n_connection_get_session(struct s2n_connection *conn, uint8_t *session, size_t max_length)
  416. {
  417. POSIX_ENSURE_REF(conn);
  418. POSIX_ENSURE_REF(session);
  419. const int len = s2n_connection_get_session_length(conn);
  420. POSIX_GUARD(len);
  421. if (len == 0) {
  422. return 0;
  423. }
  424. POSIX_ENSURE((size_t) len <= max_length, S2N_ERR_SERIALIZED_SESSION_STATE_TOO_LONG);
  425. struct s2n_blob serialized_data = { 0 };
  426. POSIX_GUARD(s2n_blob_init(&serialized_data, session, len));
  427. POSIX_GUARD(s2n_blob_zero(&serialized_data));
  428. struct s2n_stuffer to = { 0 };
  429. POSIX_GUARD(s2n_stuffer_init(&to, &serialized_data));
  430. POSIX_GUARD(s2n_client_serialize_resumption_state(conn, &to));
  431. return len;
  432. }
  433. int s2n_connection_get_session_ticket_lifetime_hint(struct s2n_connection *conn)
  434. {
  435. POSIX_ENSURE_REF(conn);
  436. S2N_ERROR_IF(!(conn->config->use_tickets && conn->client_ticket.size > 0), S2N_ERR_SESSION_TICKET_NOT_SUPPORTED);
  437. /* Session resumption using session ticket */
  438. return conn->ticket_lifetime_hint;
  439. }
  440. S2N_RESULT s2n_connection_get_session_state_size(struct s2n_connection *conn, size_t *state_size)
  441. {
  442. RESULT_ENSURE_REF(conn);
  443. RESULT_ENSURE_REF(conn->secure);
  444. RESULT_ENSURE_REF(state_size);
  445. if (s2n_resume_protocol_version(conn) < S2N_TLS13) {
  446. *state_size = S2N_TLS12_STATE_SIZE_IN_BYTES;
  447. return S2N_RESULT_OK;
  448. }
  449. *state_size = S2N_TLS13_FIXED_STATE_SIZE;
  450. uint8_t secret_size = 0;
  451. RESULT_ENSURE_REF(conn->secure->cipher_suite);
  452. RESULT_GUARD_POSIX(s2n_hmac_digest_size(conn->secure->cipher_suite->prf_alg, &secret_size));
  453. *state_size += secret_size;
  454. uint32_t server_max_early_data = 0;
  455. RESULT_GUARD(s2n_early_data_get_server_max_size(conn, &server_max_early_data));
  456. if (server_max_early_data > 0) {
  457. *state_size += S2N_TLS13_FIXED_EARLY_DATA_STATE_SIZE
  458. + strlen(conn->application_protocol)
  459. + conn->server_early_data_context.size;
  460. }
  461. return S2N_RESULT_OK;
  462. }
  463. static S2N_RESULT s2n_connection_get_session_length_impl(struct s2n_connection *conn, size_t *length)
  464. {
  465. RESULT_ENSURE_REF(conn);
  466. RESULT_ENSURE_REF(conn->config);
  467. RESULT_ENSURE_REF(length);
  468. *length = 0;
  469. if (conn->config->use_tickets && conn->client_ticket.size > 0) {
  470. size_t session_state_size = 0;
  471. RESULT_GUARD(s2n_connection_get_session_state_size(conn, &session_state_size));
  472. *length = S2N_STATE_FORMAT_LEN + S2N_SESSION_TICKET_SIZE_LEN + conn->client_ticket.size + session_state_size;
  473. } else if (conn->session_id_len > 0 && conn->actual_protocol_version < S2N_TLS13) {
  474. *length = S2N_STATE_FORMAT_LEN + sizeof(conn->session_id_len) + conn->session_id_len + S2N_TLS12_STATE_SIZE_IN_BYTES;
  475. }
  476. return S2N_RESULT_OK;
  477. }
  478. int s2n_connection_get_session_length(struct s2n_connection *conn)
  479. {
  480. size_t length = 0;
  481. if (s2n_result_is_ok(s2n_connection_get_session_length_impl(conn, &length))) {
  482. return length;
  483. }
  484. return 0;
  485. }
  486. int s2n_connection_is_session_resumed(struct s2n_connection *conn)
  487. {
  488. return conn && IS_RESUMPTION_HANDSHAKE(conn)
  489. && (conn->actual_protocol_version < S2N_TLS13 || conn->psk_params.type == S2N_PSK_TYPE_RESUMPTION);
  490. }
  491. int s2n_connection_is_ocsp_stapled(struct s2n_connection *conn)
  492. {
  493. POSIX_ENSURE_REF(conn);
  494. if (conn->actual_protocol_version >= S2N_TLS13) {
  495. return (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn));
  496. } else {
  497. return IS_OCSP_STAPLED(conn);
  498. }
  499. }
  500. int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config)
  501. {
  502. uint64_t now;
  503. struct s2n_ticket_key *ticket_key = NULL;
  504. POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now));
  505. POSIX_ENSURE_REF(config->ticket_keys);
  506. uint32_t ticket_keys_len = 0;
  507. POSIX_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
  508. for (uint32_t i = ticket_keys_len; i > 0; i--) {
  509. uint32_t idx = i - 1;
  510. POSIX_GUARD_RESULT(s2n_set_get(config->ticket_keys, idx, (void **) &ticket_key));
  511. uint64_t key_intro_time = ticket_key->intro_timestamp;
  512. if (key_intro_time < now
  513. && now < key_intro_time + config->encrypt_decrypt_key_lifetime_in_nanos) {
  514. return 1;
  515. }
  516. }
  517. return 0;
  518. }
  519. /* This function is used in s2n_get_ticket_encrypt_decrypt_key to compute the weight
  520. * of the keys and to choose a single key from all of the encrypt-decrypt keys.
  521. * Higher the weight of the key, higher the probability of being picked.
  522. */
  523. int s2n_compute_weight_of_encrypt_decrypt_keys(struct s2n_config *config,
  524. uint8_t *encrypt_decrypt_keys_index,
  525. uint8_t num_encrypt_decrypt_keys,
  526. uint64_t now)
  527. {
  528. double total_weight = 0;
  529. struct s2n_ticket_key_weight ticket_keys_weight[S2N_MAX_TICKET_KEYS];
  530. struct s2n_ticket_key *ticket_key = NULL;
  531. /* Compute weight of encrypt-decrypt keys */
  532. for (int i = 0; i < num_encrypt_decrypt_keys; i++) {
  533. POSIX_GUARD_RESULT(s2n_set_get(config->ticket_keys, encrypt_decrypt_keys_index[i], (void **) &ticket_key));
  534. uint64_t key_intro_time = ticket_key->intro_timestamp;
  535. uint64_t key_encryption_peak_time = key_intro_time + (config->encrypt_decrypt_key_lifetime_in_nanos / 2);
  536. /* The % of encryption using this key is linearly increasing */
  537. if (now < key_encryption_peak_time) {
  538. ticket_keys_weight[i].key_weight = now - key_intro_time;
  539. } else {
  540. /* The % of encryption using this key is linearly decreasing */
  541. ticket_keys_weight[i].key_weight = (config->encrypt_decrypt_key_lifetime_in_nanos / 2) - (now - key_encryption_peak_time);
  542. }
  543. ticket_keys_weight[i].key_index = encrypt_decrypt_keys_index[i];
  544. total_weight += ticket_keys_weight[i].key_weight;
  545. }
  546. /* Pick a random number in [0, 1). Using 53 bits (IEEE 754 double-precision floats). */
  547. uint64_t random_int = 0;
  548. POSIX_GUARD_RESULT(s2n_public_random(pow(2, 53), &random_int));
  549. double random = (double) random_int / (double) pow(2, 53);
  550. /* Compute cumulative weight of encrypt-decrypt keys */
  551. for (int i = 0; i < num_encrypt_decrypt_keys; i++) {
  552. ticket_keys_weight[i].key_weight = ticket_keys_weight[i].key_weight / total_weight;
  553. if (i > 0) {
  554. ticket_keys_weight[i].key_weight += ticket_keys_weight[i - 1].key_weight;
  555. }
  556. if (ticket_keys_weight[i].key_weight > random) {
  557. return ticket_keys_weight[i].key_index;
  558. }
  559. }
  560. POSIX_BAIL(S2N_ERR_ENCRYPT_DECRYPT_KEY_SELECTION_FAILED);
  561. }
  562. /* This function is used in s2n_encrypt_session_ticket in order for s2n to
  563. * choose a key in encrypt-decrypt state from all of the keys added to config
  564. */
  565. struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *config)
  566. {
  567. uint8_t num_encrypt_decrypt_keys = 0;
  568. uint8_t encrypt_decrypt_keys_index[S2N_MAX_TICKET_KEYS] = { 0 };
  569. struct s2n_ticket_key *ticket_key = NULL;
  570. uint64_t now;
  571. PTR_GUARD_RESULT(s2n_config_wall_clock(config, &now));
  572. PTR_ENSURE_REF(config->ticket_keys);
  573. uint32_t ticket_keys_len = 0;
  574. PTR_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
  575. for (uint32_t i = ticket_keys_len; i > 0; i--) {
  576. uint32_t idx = i - 1;
  577. PTR_GUARD_RESULT(s2n_set_get(config->ticket_keys, idx, (void **) &ticket_key));
  578. uint64_t key_intro_time = ticket_key->intro_timestamp;
  579. if (key_intro_time < now
  580. && now < key_intro_time + config->encrypt_decrypt_key_lifetime_in_nanos) {
  581. encrypt_decrypt_keys_index[num_encrypt_decrypt_keys] = idx;
  582. num_encrypt_decrypt_keys++;
  583. }
  584. }
  585. if (num_encrypt_decrypt_keys == 0) {
  586. PTR_BAIL(S2N_ERR_NO_TICKET_ENCRYPT_DECRYPT_KEY);
  587. }
  588. if (num_encrypt_decrypt_keys == 1) {
  589. PTR_GUARD_RESULT(s2n_set_get(config->ticket_keys, encrypt_decrypt_keys_index[0], (void **) &ticket_key));
  590. return ticket_key;
  591. }
  592. int8_t idx;
  593. PTR_GUARD_POSIX(idx = s2n_compute_weight_of_encrypt_decrypt_keys(config, encrypt_decrypt_keys_index, num_encrypt_decrypt_keys, now));
  594. PTR_GUARD_RESULT(s2n_set_get(config->ticket_keys, idx, (void **) &ticket_key));
  595. return ticket_key;
  596. }
  597. /* This function is used in s2n_decrypt_session_ticket in order for s2n to
  598. * find the matching key that was used for encryption.
  599. */
  600. struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint8_t name[S2N_TICKET_KEY_NAME_LEN])
  601. {
  602. uint64_t now;
  603. struct s2n_ticket_key *ticket_key = NULL;
  604. PTR_GUARD_RESULT(s2n_config_wall_clock(config, &now));
  605. PTR_ENSURE_REF(config->ticket_keys);
  606. uint32_t ticket_keys_len = 0;
  607. PTR_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
  608. for (uint32_t i = 0; i < ticket_keys_len; i++) {
  609. PTR_GUARD_RESULT(s2n_set_get(config->ticket_keys, i, (void **) &ticket_key));
  610. if (memcmp(ticket_key->key_name, name, S2N_TICKET_KEY_NAME_LEN) == 0) {
  611. /* Check to see if the key has expired */
  612. if (now >= ticket_key->intro_timestamp
  613. + config->encrypt_decrypt_key_lifetime_in_nanos
  614. + config->decrypt_key_lifetime_in_nanos) {
  615. s2n_config_wipe_expired_ticket_crypto_keys(config, i);
  616. return NULL;
  617. }
  618. return ticket_key;
  619. }
  620. }
  621. return NULL;
  622. }
  623. int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *to)
  624. {
  625. struct s2n_ticket_key *key;
  626. struct s2n_session_key aes_ticket_key = { 0 };
  627. struct s2n_blob aes_key_blob = { 0 };
  628. uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
  629. struct s2n_blob iv = { 0 };
  630. POSIX_GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
  631. uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
  632. struct s2n_blob aad_blob = { 0 };
  633. POSIX_GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
  634. struct s2n_stuffer aad = { 0 };
  635. key = s2n_get_ticket_encrypt_decrypt_key(conn->config);
  636. /* No keys loaded by the user or the keys are either in decrypt-only or expired state */
  637. S2N_ERROR_IF(!key, S2N_ERR_NO_TICKET_ENCRYPT_DECRYPT_KEY);
  638. POSIX_GUARD(s2n_stuffer_write_bytes(to, key->key_name, S2N_TICKET_KEY_NAME_LEN));
  639. POSIX_GUARD_RESULT(s2n_get_public_random_data(&iv));
  640. POSIX_GUARD(s2n_stuffer_write(to, &iv));
  641. POSIX_GUARD(s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN));
  642. POSIX_GUARD(s2n_session_key_alloc(&aes_ticket_key));
  643. POSIX_GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
  644. POSIX_GUARD(s2n_aes256_gcm.set_encryption_key(&aes_ticket_key, &aes_key_blob));
  645. POSIX_GUARD(s2n_stuffer_init(&aad, &aad_blob));
  646. POSIX_GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
  647. POSIX_GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
  648. uint32_t plaintext_header_size = s2n_stuffer_data_available(to);
  649. POSIX_GUARD_RESULT(s2n_serialize_resumption_state(conn, to));
  650. POSIX_GUARD(s2n_stuffer_skip_write(to, S2N_TLS_GCM_TAG_LEN));
  651. struct s2n_blob state_blob = { 0 };
  652. struct s2n_stuffer copy_for_encryption = *to;
  653. POSIX_GUARD(s2n_stuffer_skip_read(&copy_for_encryption, plaintext_header_size));
  654. uint32_t state_blob_size = s2n_stuffer_data_available(&copy_for_encryption);
  655. uint8_t *state_blob_data = s2n_stuffer_raw_read(&copy_for_encryption, state_blob_size);
  656. POSIX_ENSURE_REF(state_blob_data);
  657. POSIX_GUARD(s2n_blob_init(&state_blob, state_blob_data, state_blob_size));
  658. POSIX_GUARD(s2n_aes256_gcm.io.aead.encrypt(&aes_ticket_key, &iv, &aad_blob, &state_blob, &state_blob));
  659. POSIX_GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key));
  660. POSIX_GUARD(s2n_session_key_free(&aes_ticket_key));
  661. return 0;
  662. }
  663. int s2n_decrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *from)
  664. {
  665. struct s2n_ticket_key *key;
  666. DEFER_CLEANUP(struct s2n_session_key aes_ticket_key = { 0 }, s2n_session_key_free);
  667. struct s2n_blob aes_key_blob = { 0 };
  668. uint8_t key_name[S2N_TICKET_KEY_NAME_LEN] = { 0 };
  669. uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
  670. struct s2n_blob iv = { 0 };
  671. POSIX_GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
  672. uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
  673. struct s2n_blob aad_blob = { 0 };
  674. POSIX_GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
  675. struct s2n_stuffer aad = { 0 };
  676. POSIX_GUARD(s2n_stuffer_read_bytes(from, key_name, s2n_array_len(key_name)));
  677. key = s2n_find_ticket_key(conn->config, key_name);
  678. /* Key has expired; do full handshake with New Session Ticket (NST) */
  679. S2N_ERROR_IF(!key, S2N_ERR_KEY_USED_IN_SESSION_TICKET_NOT_FOUND);
  680. POSIX_GUARD(s2n_stuffer_read(from, &iv));
  681. s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN);
  682. POSIX_GUARD(s2n_session_key_alloc(&aes_ticket_key));
  683. POSIX_GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
  684. POSIX_GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob));
  685. POSIX_GUARD(s2n_stuffer_init(&aad, &aad_blob));
  686. POSIX_GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
  687. POSIX_GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
  688. struct s2n_blob en_blob = { 0 };
  689. uint32_t en_blob_size = s2n_stuffer_data_available(from);
  690. uint8_t *en_blob_data = s2n_stuffer_raw_read(from, en_blob_size);
  691. POSIX_ENSURE_REF(en_blob_data);
  692. POSIX_GUARD(s2n_blob_init(&en_blob, en_blob_data, en_blob_size));
  693. POSIX_GUARD(s2n_aes256_gcm.io.aead.decrypt(&aes_ticket_key, &iv, &aad_blob, &en_blob, &en_blob));
  694. struct s2n_blob state_blob = { 0 };
  695. uint32_t state_blob_size = en_blob_size - S2N_TLS_GCM_TAG_LEN;
  696. POSIX_GUARD(s2n_blob_init(&state_blob, en_blob.data, state_blob_size));
  697. struct s2n_stuffer state_stuffer = { 0 };
  698. POSIX_GUARD(s2n_stuffer_init(&state_stuffer, &state_blob));
  699. POSIX_GUARD(s2n_stuffer_skip_write(&state_stuffer, state_blob_size));
  700. POSIX_GUARD_RESULT(s2n_deserialize_resumption_state(conn, &from->blob, &state_stuffer));
  701. uint64_t now;
  702. POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now));
  703. /* If the key is in decrypt-only state, then a new key is assigned
  704. * for the ticket.
  705. */
  706. if (now >= key->intro_timestamp + conn->config->encrypt_decrypt_key_lifetime_in_nanos) {
  707. /* Check if a key in encrypt-decrypt state is available */
  708. if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
  709. conn->session_ticket_status = S2N_NEW_TICKET;
  710. POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
  711. return S2N_SUCCESS;
  712. }
  713. }
  714. return S2N_SUCCESS;
  715. }
  716. int s2n_encrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *to)
  717. {
  718. return s2n_encrypt_session_ticket(conn, to);
  719. }
  720. int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *from)
  721. {
  722. struct s2n_ticket_key *key;
  723. struct s2n_session_key aes_ticket_key = { 0 };
  724. struct s2n_blob aes_key_blob = { 0 };
  725. uint8_t key_name[S2N_TICKET_KEY_NAME_LEN] = { 0 };
  726. uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
  727. struct s2n_blob iv = { 0 };
  728. POSIX_GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
  729. uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
  730. struct s2n_blob aad_blob = { 0 };
  731. POSIX_GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
  732. struct s2n_stuffer aad = { 0 };
  733. uint8_t s_data[S2N_TLS12_STATE_SIZE_IN_BYTES] = { 0 };
  734. struct s2n_blob state_blob = { 0 };
  735. POSIX_GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
  736. struct s2n_stuffer state = { 0 };
  737. uint8_t en_data[S2N_TLS12_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = { 0 };
  738. struct s2n_blob en_blob = { 0 };
  739. POSIX_GUARD(s2n_blob_init(&en_blob, en_data, sizeof(en_data)));
  740. POSIX_GUARD(s2n_stuffer_read_bytes(from, key_name, s2n_array_len(key_name)));
  741. key = s2n_find_ticket_key(conn->config, key_name);
  742. /* Key has expired; do full handshake with New Session Ticket (NST) */
  743. POSIX_ENSURE(key != NULL, S2N_ERR_KEY_USED_IN_SESSION_TICKET_NOT_FOUND);
  744. POSIX_GUARD(s2n_stuffer_read(from, &iv));
  745. s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN);
  746. POSIX_GUARD(s2n_session_key_alloc(&aes_ticket_key));
  747. POSIX_GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
  748. POSIX_GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob));
  749. POSIX_GUARD(s2n_stuffer_init(&aad, &aad_blob));
  750. POSIX_GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
  751. POSIX_GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
  752. POSIX_GUARD(s2n_stuffer_read(from, &en_blob));
  753. POSIX_GUARD(s2n_aes256_gcm.io.aead.decrypt(&aes_ticket_key, &iv, &aad_blob, &en_blob, &en_blob));
  754. POSIX_GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key));
  755. POSIX_GUARD(s2n_session_key_free(&aes_ticket_key));
  756. POSIX_GUARD(s2n_stuffer_init(&state, &state_blob));
  757. POSIX_GUARD(s2n_stuffer_write_bytes(&state, en_data, S2N_TLS12_STATE_SIZE_IN_BYTES));
  758. POSIX_GUARD_RESULT(s2n_deserialize_resumption_state(conn, NULL, &state));
  759. return 0;
  760. }
  761. /* This function is used to remove all or just one expired key from server config */
  762. int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t expired_key_index)
  763. {
  764. int num_of_expired_keys = 0;
  765. int expired_keys_index[S2N_MAX_TICKET_KEYS];
  766. struct s2n_ticket_key *ticket_key = NULL;
  767. if (expired_key_index != -1) {
  768. expired_keys_index[num_of_expired_keys] = expired_key_index;
  769. num_of_expired_keys++;
  770. goto end;
  771. }
  772. uint64_t now;
  773. POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now));
  774. POSIX_ENSURE_REF(config->ticket_keys);
  775. uint32_t ticket_keys_len = 0;
  776. POSIX_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
  777. for (uint32_t i = 0; i < ticket_keys_len; i++) {
  778. POSIX_GUARD_RESULT(s2n_set_get(config->ticket_keys, i, (void **) &ticket_key));
  779. if (now >= ticket_key->intro_timestamp
  780. + config->encrypt_decrypt_key_lifetime_in_nanos
  781. + config->decrypt_key_lifetime_in_nanos) {
  782. expired_keys_index[num_of_expired_keys] = i;
  783. num_of_expired_keys++;
  784. }
  785. }
  786. end:
  787. for (int j = 0; j < num_of_expired_keys; j++) {
  788. POSIX_GUARD_RESULT(s2n_set_remove(config->ticket_keys, expired_keys_index[j] - j));
  789. }
  790. return 0;
  791. }
  792. int s2n_config_store_ticket_key(struct s2n_config *config, struct s2n_ticket_key *key)
  793. {
  794. /* Keys are stored from oldest to newest */
  795. POSIX_GUARD_RESULT(s2n_set_add(config->ticket_keys, key));
  796. return S2N_SUCCESS;
  797. }
  798. int s2n_config_set_initial_ticket_count(struct s2n_config *config, uint8_t num)
  799. {
  800. POSIX_ENSURE_REF(config);
  801. config->initial_tickets_to_send = num;
  802. POSIX_GUARD(s2n_config_set_session_tickets_onoff(config, true));
  803. return S2N_SUCCESS;
  804. }
  805. int s2n_connection_add_new_tickets_to_send(struct s2n_connection *conn, uint8_t num)
  806. {
  807. POSIX_ENSURE_REF(conn);
  808. POSIX_GUARD_RESULT(s2n_psk_validate_keying_material(conn));
  809. uint32_t out = conn->tickets_to_send + num;
  810. POSIX_ENSURE(out <= UINT16_MAX, S2N_ERR_INTEGER_OVERFLOW);
  811. conn->tickets_to_send = out;
  812. return S2N_SUCCESS;
  813. }
  814. int s2n_connection_get_tickets_sent(struct s2n_connection *conn, uint16_t *num)
  815. {
  816. POSIX_ENSURE_REF(conn);
  817. POSIX_ENSURE_REF(num);
  818. POSIX_ENSURE(conn->mode == S2N_SERVER, S2N_ERR_CLIENT_MODE);
  819. *num = conn->tickets_sent;
  820. return S2N_SUCCESS;
  821. }
  822. int s2n_connection_set_server_keying_material_lifetime(struct s2n_connection *conn, uint32_t lifetime_in_secs)
  823. {
  824. POSIX_ENSURE_REF(conn);
  825. conn->server_keying_material_lifetime = lifetime_in_secs;
  826. return S2N_SUCCESS;
  827. }
  828. int s2n_config_set_session_ticket_cb(struct s2n_config *config, s2n_session_ticket_fn callback, void *ctx)
  829. {
  830. POSIX_ENSURE_MUT(config);
  831. config->session_ticket_cb = callback;
  832. config->session_ticket_ctx = ctx;
  833. return S2N_SUCCESS;
  834. }
  835. int s2n_session_ticket_get_data_len(struct s2n_session_ticket *ticket, size_t *data_len)
  836. {
  837. POSIX_ENSURE_REF(ticket);
  838. POSIX_ENSURE_MUT(data_len);
  839. *data_len = ticket->ticket_data.size;
  840. return S2N_SUCCESS;
  841. }
  842. int s2n_session_ticket_get_data(struct s2n_session_ticket *ticket, size_t max_data_len, uint8_t *data)
  843. {
  844. POSIX_ENSURE_REF(ticket);
  845. POSIX_ENSURE_MUT(data);
  846. POSIX_ENSURE(ticket->ticket_data.size <= max_data_len, S2N_ERR_SERIALIZED_SESSION_STATE_TOO_LONG);
  847. POSIX_CHECKED_MEMCPY(data, ticket->ticket_data.data, ticket->ticket_data.size);
  848. return S2N_SUCCESS;
  849. }
  850. int s2n_session_ticket_get_lifetime(struct s2n_session_ticket *ticket, uint32_t *session_lifetime)
  851. {
  852. POSIX_ENSURE_REF(ticket);
  853. POSIX_ENSURE_REF(session_lifetime);
  854. *session_lifetime = ticket->session_lifetime;
  855. return S2N_SUCCESS;
  856. }