tls_channel_handler.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/io/channel.h>
  6. #include <aws/io/file_utils.h>
  7. #include <aws/io/logging.h>
  8. #include <aws/io/pkcs11.h>
  9. #include <aws/io/private/pem_utils.h>
  10. #include <aws/io/private/tls_channel_handler_shared.h>
  11. #include <aws/io/tls_channel_handler.h>
  12. #define AWS_DEFAULT_TLS_TIMEOUT_MS 10000
  13. #include "./pkcs11_private.h"
  14. #include <aws/common/string.h>
  15. void aws_tls_ctx_options_init_default_client(struct aws_tls_ctx_options *options, struct aws_allocator *allocator) {
  16. AWS_ZERO_STRUCT(*options);
  17. options->allocator = allocator;
  18. options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
  19. options->cipher_pref = AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT;
  20. options->verify_peer = true;
  21. options->max_fragment_size = g_aws_channel_max_fragment_size;
  22. }
  23. void aws_tls_ctx_options_clean_up(struct aws_tls_ctx_options *options) {
  24. aws_byte_buf_clean_up(&options->ca_file);
  25. aws_string_destroy(options->ca_path);
  26. aws_byte_buf_clean_up(&options->certificate);
  27. aws_byte_buf_clean_up_secure(&options->private_key);
  28. #ifdef __APPLE__
  29. aws_byte_buf_clean_up_secure(&options->pkcs12);
  30. aws_byte_buf_clean_up_secure(&options->pkcs12_password);
  31. # if !defined(AWS_OS_IOS)
  32. aws_string_destroy(options->keychain_path);
  33. # endif
  34. #endif
  35. aws_string_destroy(options->alpn_list);
  36. aws_custom_key_op_handler_release(options->custom_key_op_handler);
  37. AWS_ZERO_STRUCT(*options);
  38. }
  39. int aws_tls_ctx_options_init_client_mtls(
  40. struct aws_tls_ctx_options *options,
  41. struct aws_allocator *allocator,
  42. const struct aws_byte_cursor *cert,
  43. const struct aws_byte_cursor *pkey) {
  44. #if !defined(AWS_OS_IOS)
  45. aws_tls_ctx_options_init_default_client(options, allocator);
  46. if (aws_byte_buf_init_copy_from_cursor(&options->certificate, allocator, *cert)) {
  47. goto error;
  48. }
  49. if (aws_sanitize_pem(&options->certificate, allocator)) {
  50. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid certificate. File must contain PEM encoded data");
  51. goto error;
  52. }
  53. if (aws_byte_buf_init_copy_from_cursor(&options->private_key, allocator, *pkey)) {
  54. goto error;
  55. }
  56. if (aws_sanitize_pem(&options->private_key, allocator)) {
  57. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid private key. File must contain PEM encoded data");
  58. goto error;
  59. }
  60. return AWS_OP_SUCCESS;
  61. error:
  62. aws_tls_ctx_options_clean_up(options);
  63. return AWS_OP_ERR;
  64. #else
  65. (void)allocator;
  66. (void)cert;
  67. (void)pkey;
  68. AWS_ZERO_STRUCT(*options);
  69. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: This platform does not support PEM certificates");
  70. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  71. #endif
  72. }
  73. int aws_tls_ctx_options_init_client_mtls_from_path(
  74. struct aws_tls_ctx_options *options,
  75. struct aws_allocator *allocator,
  76. const char *cert_path,
  77. const char *pkey_path) {
  78. #if !defined(AWS_OS_IOS)
  79. aws_tls_ctx_options_init_default_client(options, allocator);
  80. if (aws_byte_buf_init_from_file(&options->certificate, allocator, cert_path)) {
  81. goto error;
  82. }
  83. if (aws_sanitize_pem(&options->certificate, allocator)) {
  84. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid certificate. File must contain PEM encoded data");
  85. goto error;
  86. }
  87. if (aws_byte_buf_init_from_file(&options->private_key, allocator, pkey_path)) {
  88. goto error;
  89. }
  90. if (aws_sanitize_pem(&options->private_key, allocator)) {
  91. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid private key. File must contain PEM encoded data");
  92. goto error;
  93. }
  94. return AWS_OP_SUCCESS;
  95. error:
  96. aws_tls_ctx_options_clean_up(options);
  97. return AWS_OP_ERR;
  98. #else
  99. (void)allocator;
  100. (void)cert_path;
  101. (void)pkey_path;
  102. AWS_ZERO_STRUCT(*options);
  103. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: This platform does not support PEM certificates");
  104. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  105. #endif
  106. }
  107. int aws_tls_ctx_options_init_client_mtls_with_custom_key_operations(
  108. struct aws_tls_ctx_options *options,
  109. struct aws_allocator *allocator,
  110. struct aws_custom_key_op_handler *custom,
  111. const struct aws_byte_cursor *cert_file_contents) {
  112. #if !USE_S2N
  113. (void)options;
  114. (void)allocator;
  115. (void)custom;
  116. (void)cert_file_contents;
  117. AWS_ZERO_STRUCT(*options);
  118. AWS_LOGF_ERROR(
  119. AWS_LS_IO_TLS, "static: This platform does not currently support TLS with custom private key operations.");
  120. return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
  121. #else
  122. aws_tls_ctx_options_init_default_client(options, allocator);
  123. /* on_key_operation is required */
  124. AWS_ASSERT(custom != NULL);
  125. AWS_ASSERT(custom->vtable != NULL);
  126. AWS_ASSERT(custom->vtable->on_key_operation != NULL);
  127. /* Hold a reference to the custom key operation handler so it cannot be destroyed */
  128. options->custom_key_op_handler = aws_custom_key_op_handler_acquire((struct aws_custom_key_op_handler *)custom);
  129. /* Copy the certificate data from the cursor */
  130. AWS_ASSERT(cert_file_contents != NULL);
  131. aws_byte_buf_init_copy_from_cursor(&options->certificate, allocator, *cert_file_contents);
  132. /* Make sure the certificate is set and valid */
  133. if (aws_sanitize_pem(&options->certificate, allocator)) {
  134. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid certificate. File must contain PEM encoded data");
  135. goto error;
  136. }
  137. return AWS_OP_SUCCESS;
  138. error:
  139. aws_tls_ctx_options_clean_up(options);
  140. return AWS_OP_ERR;
  141. #endif /* PLATFORM-SUPPORTS-CUSTOM-KEY-OPERATIONS */
  142. }
  143. int aws_tls_ctx_options_init_client_mtls_with_pkcs11(
  144. struct aws_tls_ctx_options *options,
  145. struct aws_allocator *allocator,
  146. const struct aws_tls_ctx_pkcs11_options *pkcs11_options) {
  147. #if defined(USE_S2N)
  148. struct aws_custom_key_op_handler *pkcs11_handler = aws_pkcs11_tls_op_handler_new(
  149. allocator,
  150. pkcs11_options->pkcs11_lib,
  151. &pkcs11_options->user_pin,
  152. &pkcs11_options->token_label,
  153. &pkcs11_options->private_key_object_label,
  154. pkcs11_options->slot_id);
  155. struct aws_byte_buf tmp_cert_buf;
  156. AWS_ZERO_STRUCT(tmp_cert_buf);
  157. bool success = false;
  158. int custom_key_result = AWS_OP_ERR;
  159. if (pkcs11_handler == NULL) {
  160. aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  161. goto finish;
  162. }
  163. if ((pkcs11_options->cert_file_contents.ptr != NULL) && (pkcs11_options->cert_file_path.ptr != NULL)) {
  164. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Cannot use certificate AND certificate file path, only one can be set");
  165. aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  166. goto finish;
  167. } else if (pkcs11_options->cert_file_contents.ptr != NULL) {
  168. custom_key_result = aws_tls_ctx_options_init_client_mtls_with_custom_key_operations(
  169. options, allocator, pkcs11_handler, &pkcs11_options->cert_file_contents);
  170. success = true;
  171. } else {
  172. struct aws_string *tmp_string = aws_string_new_from_cursor(allocator, &pkcs11_options->cert_file_path);
  173. int op = aws_byte_buf_init_from_file(&tmp_cert_buf, allocator, aws_string_c_str(tmp_string));
  174. aws_string_destroy(tmp_string);
  175. if (op != AWS_OP_SUCCESS) {
  176. goto finish;
  177. }
  178. struct aws_byte_cursor tmp_cursor = aws_byte_cursor_from_buf(&tmp_cert_buf);
  179. custom_key_result = aws_tls_ctx_options_init_client_mtls_with_custom_key_operations(
  180. options, allocator, pkcs11_handler, &tmp_cursor);
  181. success = true;
  182. }
  183. finish:
  184. if (pkcs11_handler != NULL) {
  185. /**
  186. * Calling aws_tls_ctx_options_init_client_mtls_with_custom_key_operations will have this options
  187. * hold a reference to the custom key operations, but creating the TLS operations handler using
  188. * aws_pkcs11_tls_op_handler_set_certificate_data adds a reference too, so we need to release
  189. * this reference so the only thing (currently) holding a reference is the TLS options itself and
  190. * not this function.
  191. */
  192. aws_custom_key_op_handler_release(pkcs11_handler);
  193. }
  194. if (success == false) {
  195. aws_tls_ctx_options_clean_up(options);
  196. }
  197. aws_byte_buf_clean_up(&tmp_cert_buf);
  198. if (success) {
  199. return custom_key_result;
  200. } else {
  201. return AWS_OP_ERR;
  202. }
  203. #else /* Platform does not support S2N */
  204. (void)allocator;
  205. (void)pkcs11_options;
  206. AWS_ZERO_STRUCT(*options);
  207. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: This platform does not currently support TLS with PKCS#11.");
  208. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  209. #endif /* PLATFORM-SUPPORTS-PKCS11-TLS */
  210. }
  211. int aws_tls_ctx_options_set_keychain_path(
  212. struct aws_tls_ctx_options *options,
  213. struct aws_byte_cursor *keychain_path_cursor) {
  214. #if defined(__APPLE__) && !defined(AWS_OS_IOS)
  215. AWS_LOGF_WARN(AWS_LS_IO_TLS, "static: Keychain path is deprecated.");
  216. options->keychain_path = aws_string_new_from_cursor(options->allocator, keychain_path_cursor);
  217. if (!options->keychain_path) {
  218. return AWS_OP_ERR;
  219. }
  220. return AWS_OP_SUCCESS;
  221. #else
  222. (void)options;
  223. (void)keychain_path_cursor;
  224. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Keychain path can only be set on MacOS.");
  225. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  226. #endif
  227. }
  228. int aws_tls_ctx_options_init_client_mtls_from_system_path(
  229. struct aws_tls_ctx_options *options,
  230. struct aws_allocator *allocator,
  231. const char *cert_reg_path) {
  232. #ifdef _WIN32
  233. aws_tls_ctx_options_init_default_client(options, allocator);
  234. options->system_certificate_path = cert_reg_path;
  235. return AWS_OP_SUCCESS;
  236. #else
  237. (void)allocator;
  238. (void)cert_reg_path;
  239. AWS_ZERO_STRUCT(*options);
  240. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: System certificate path can only be set on Windows.");
  241. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  242. #endif
  243. }
  244. int aws_tls_ctx_options_init_default_server_from_system_path(
  245. struct aws_tls_ctx_options *options,
  246. struct aws_allocator *allocator,
  247. const char *cert_reg_path) {
  248. if (aws_tls_ctx_options_init_client_mtls_from_system_path(options, allocator, cert_reg_path)) {
  249. return AWS_OP_ERR;
  250. }
  251. options->verify_peer = false;
  252. return AWS_OP_SUCCESS;
  253. }
  254. int aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(
  255. struct aws_tls_ctx_options *options,
  256. struct aws_allocator *allocator,
  257. const char *pkcs12_path,
  258. const struct aws_byte_cursor *pkcs_pwd) {
  259. #ifdef __APPLE__
  260. aws_tls_ctx_options_init_default_client(options, allocator);
  261. if (aws_byte_buf_init_from_file(&options->pkcs12, allocator, pkcs12_path)) {
  262. return AWS_OP_ERR;
  263. }
  264. if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12_password, allocator, *pkcs_pwd)) {
  265. aws_byte_buf_clean_up_secure(&options->pkcs12);
  266. return AWS_OP_ERR;
  267. }
  268. return AWS_OP_SUCCESS;
  269. #else
  270. (void)allocator;
  271. (void)pkcs12_path;
  272. (void)pkcs_pwd;
  273. AWS_ZERO_STRUCT(*options);
  274. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: This platform does not support PKCS#12 files.");
  275. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  276. #endif
  277. }
  278. int aws_tls_ctx_options_init_client_mtls_pkcs12(
  279. struct aws_tls_ctx_options *options,
  280. struct aws_allocator *allocator,
  281. struct aws_byte_cursor *pkcs12,
  282. struct aws_byte_cursor *pkcs_pwd) {
  283. #ifdef __APPLE__
  284. aws_tls_ctx_options_init_default_client(options, allocator);
  285. if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12, allocator, *pkcs12)) {
  286. return AWS_OP_ERR;
  287. }
  288. if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12_password, allocator, *pkcs_pwd)) {
  289. aws_byte_buf_clean_up_secure(&options->pkcs12);
  290. return AWS_OP_ERR;
  291. }
  292. return AWS_OP_SUCCESS;
  293. #else
  294. (void)allocator;
  295. (void)pkcs12;
  296. (void)pkcs_pwd;
  297. AWS_ZERO_STRUCT(*options);
  298. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: This platform does not support PKCS#12 files.");
  299. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  300. #endif
  301. }
  302. int aws_tls_ctx_options_init_server_pkcs12_from_path(
  303. struct aws_tls_ctx_options *options,
  304. struct aws_allocator *allocator,
  305. const char *pkcs12_path,
  306. struct aws_byte_cursor *pkcs_password) {
  307. if (aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(options, allocator, pkcs12_path, pkcs_password)) {
  308. return AWS_OP_ERR;
  309. }
  310. options->verify_peer = false;
  311. return AWS_OP_SUCCESS;
  312. }
  313. int aws_tls_ctx_options_init_server_pkcs12(
  314. struct aws_tls_ctx_options *options,
  315. struct aws_allocator *allocator,
  316. struct aws_byte_cursor *pkcs12,
  317. struct aws_byte_cursor *pkcs_password) {
  318. if (aws_tls_ctx_options_init_client_mtls_pkcs12(options, allocator, pkcs12, pkcs_password)) {
  319. return AWS_OP_ERR;
  320. }
  321. options->verify_peer = false;
  322. return AWS_OP_SUCCESS;
  323. }
  324. int aws_tls_ctx_options_init_default_server_from_path(
  325. struct aws_tls_ctx_options *options,
  326. struct aws_allocator *allocator,
  327. const char *cert_path,
  328. const char *pkey_path) {
  329. #if !defined(AWS_OS_IOS)
  330. if (aws_tls_ctx_options_init_client_mtls_from_path(options, allocator, cert_path, pkey_path)) {
  331. return AWS_OP_ERR;
  332. }
  333. options->verify_peer = false;
  334. return AWS_OP_SUCCESS;
  335. #else
  336. (void)allocator;
  337. (void)cert_path;
  338. (void)pkey_path;
  339. AWS_ZERO_STRUCT(*options);
  340. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Cannot create a server on this platform.");
  341. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  342. #endif
  343. }
  344. int aws_tls_ctx_options_init_default_server(
  345. struct aws_tls_ctx_options *options,
  346. struct aws_allocator *allocator,
  347. struct aws_byte_cursor *cert,
  348. struct aws_byte_cursor *pkey) {
  349. #if !defined(AWS_OS_IOS)
  350. if (aws_tls_ctx_options_init_client_mtls(options, allocator, cert, pkey)) {
  351. return AWS_OP_ERR;
  352. }
  353. options->verify_peer = false;
  354. return AWS_OP_SUCCESS;
  355. #else
  356. (void)allocator;
  357. (void)cert;
  358. (void)pkey;
  359. AWS_ZERO_STRUCT(*options);
  360. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Cannot create a server on this platform.");
  361. return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
  362. #endif
  363. }
  364. int aws_tls_ctx_options_set_alpn_list(struct aws_tls_ctx_options *options, const char *alpn_list) {
  365. options->alpn_list = aws_string_new_from_c_str(options->allocator, alpn_list);
  366. if (!options->alpn_list) {
  367. return AWS_OP_ERR;
  368. }
  369. return AWS_OP_SUCCESS;
  370. }
  371. void aws_tls_ctx_options_set_verify_peer(struct aws_tls_ctx_options *options, bool verify_peer) {
  372. options->verify_peer = verify_peer;
  373. }
  374. void aws_tls_ctx_options_set_minimum_tls_version(
  375. struct aws_tls_ctx_options *options,
  376. enum aws_tls_versions minimum_tls_version) {
  377. options->minimum_tls_version = minimum_tls_version;
  378. }
  379. void aws_tls_ctx_options_set_tls_cipher_preference(
  380. struct aws_tls_ctx_options *options,
  381. enum aws_tls_cipher_pref cipher_pref) {
  382. options->cipher_pref = cipher_pref;
  383. }
  384. int aws_tls_ctx_options_override_default_trust_store_from_path(
  385. struct aws_tls_ctx_options *options,
  386. const char *ca_path,
  387. const char *ca_file) {
  388. /* Note: on success these are not cleaned up, their data is "moved" into the options struct */
  389. struct aws_string *ca_path_tmp = NULL;
  390. struct aws_byte_buf ca_file_tmp;
  391. AWS_ZERO_STRUCT(ca_file_tmp);
  392. if (ca_path) {
  393. if (options->ca_path) {
  394. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: cannot override trust store multiple times");
  395. aws_raise_error(AWS_ERROR_INVALID_STATE);
  396. goto error;
  397. }
  398. ca_path_tmp = aws_string_new_from_c_str(options->allocator, ca_path);
  399. if (!ca_path_tmp) {
  400. goto error;
  401. }
  402. }
  403. if (ca_file) {
  404. if (aws_tls_options_buf_is_set(&options->ca_file)) {
  405. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: cannot override trust store multiple times");
  406. aws_raise_error(AWS_ERROR_INVALID_STATE);
  407. goto error;
  408. }
  409. if (aws_byte_buf_init_from_file(&ca_file_tmp, options->allocator, ca_file)) {
  410. goto error;
  411. }
  412. if (aws_sanitize_pem(&ca_file_tmp, options->allocator)) {
  413. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid CA file. File must contain PEM encoded data");
  414. goto error;
  415. }
  416. }
  417. /* Success, set new values. (no need to clean up old values, we checked earlier that they were unallocated) */
  418. if (ca_path) {
  419. options->ca_path = ca_path_tmp;
  420. }
  421. if (ca_file) {
  422. options->ca_file = ca_file_tmp;
  423. }
  424. return AWS_OP_SUCCESS;
  425. error:
  426. aws_string_destroy_secure(ca_path_tmp);
  427. aws_byte_buf_clean_up_secure(&ca_file_tmp);
  428. return AWS_OP_ERR;
  429. }
  430. void aws_tls_ctx_options_set_extension_data(struct aws_tls_ctx_options *options, void *extension_data) {
  431. options->ctx_options_extension = extension_data;
  432. }
  433. int aws_tls_ctx_options_override_default_trust_store(
  434. struct aws_tls_ctx_options *options,
  435. const struct aws_byte_cursor *ca_file) {
  436. if (aws_tls_options_buf_is_set(&options->ca_file)) {
  437. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: cannot override trust store multiple times");
  438. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  439. }
  440. if (aws_byte_buf_init_copy_from_cursor(&options->ca_file, options->allocator, *ca_file)) {
  441. goto error;
  442. }
  443. if (aws_sanitize_pem(&options->ca_file, options->allocator)) {
  444. AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid CA file. File must contain PEM encoded data");
  445. goto error;
  446. }
  447. return AWS_OP_SUCCESS;
  448. error:
  449. aws_byte_buf_clean_up_secure(&options->ca_file);
  450. return AWS_OP_ERR;
  451. }
  452. void aws_tls_connection_options_init_from_ctx(
  453. struct aws_tls_connection_options *conn_options,
  454. struct aws_tls_ctx *ctx) {
  455. AWS_ZERO_STRUCT(*conn_options);
  456. /* the assumption here, is that if it was set in the context, we WANT it to be NULL here unless it's different.
  457. * so only set verify peer at this point. */
  458. conn_options->ctx = aws_tls_ctx_acquire(ctx);
  459. conn_options->timeout_ms = AWS_DEFAULT_TLS_TIMEOUT_MS;
  460. }
  461. int aws_tls_connection_options_copy(
  462. struct aws_tls_connection_options *to,
  463. const struct aws_tls_connection_options *from) {
  464. /* clean up the options before copy. */
  465. aws_tls_connection_options_clean_up(to);
  466. /* copy everything copyable over, then override the rest with deep copies. */
  467. *to = *from;
  468. to->ctx = aws_tls_ctx_acquire(from->ctx);
  469. if (from->alpn_list) {
  470. to->alpn_list = aws_string_new_from_string(from->alpn_list->allocator, from->alpn_list);
  471. if (!to->alpn_list) {
  472. return AWS_OP_ERR;
  473. }
  474. }
  475. if (from->server_name) {
  476. to->server_name = aws_string_new_from_string(from->server_name->allocator, from->server_name);
  477. if (!to->server_name) {
  478. aws_string_destroy(to->server_name);
  479. return AWS_OP_ERR;
  480. }
  481. }
  482. return AWS_OP_SUCCESS;
  483. }
  484. void aws_tls_connection_options_clean_up(struct aws_tls_connection_options *connection_options) {
  485. aws_tls_ctx_release(connection_options->ctx);
  486. if (connection_options->alpn_list) {
  487. aws_string_destroy(connection_options->alpn_list);
  488. }
  489. if (connection_options->server_name) {
  490. aws_string_destroy(connection_options->server_name);
  491. }
  492. AWS_ZERO_STRUCT(*connection_options);
  493. }
  494. void aws_tls_connection_options_set_callbacks(
  495. struct aws_tls_connection_options *conn_options,
  496. aws_tls_on_negotiation_result_fn *on_negotiation_result,
  497. aws_tls_on_data_read_fn *on_data_read,
  498. aws_tls_on_error_fn *on_error,
  499. void *user_data) {
  500. conn_options->on_negotiation_result = on_negotiation_result;
  501. conn_options->on_data_read = on_data_read;
  502. conn_options->on_error = on_error;
  503. conn_options->user_data = user_data;
  504. }
  505. int aws_tls_connection_options_set_server_name(
  506. struct aws_tls_connection_options *conn_options,
  507. struct aws_allocator *allocator,
  508. const struct aws_byte_cursor *server_name) {
  509. if (conn_options->server_name != NULL) {
  510. aws_string_destroy(conn_options->server_name);
  511. conn_options->server_name = NULL;
  512. }
  513. conn_options->server_name = aws_string_new_from_cursor(allocator, server_name);
  514. if (!conn_options->server_name) {
  515. return AWS_OP_ERR;
  516. }
  517. return AWS_OP_SUCCESS;
  518. }
  519. int aws_tls_connection_options_set_alpn_list(
  520. struct aws_tls_connection_options *conn_options,
  521. struct aws_allocator *allocator,
  522. const char *alpn_list) {
  523. if (conn_options->alpn_list != NULL) {
  524. aws_string_destroy(conn_options->alpn_list);
  525. conn_options->alpn_list = NULL;
  526. }
  527. conn_options->alpn_list = aws_string_new_from_c_str(allocator, alpn_list);
  528. if (!conn_options->alpn_list) {
  529. return AWS_OP_ERR;
  530. }
  531. return AWS_OP_SUCCESS;
  532. }
  533. #ifdef BYO_CRYPTO
  534. struct aws_tls_ctx *aws_tls_server_ctx_new(struct aws_allocator *alloc, const struct aws_tls_ctx_options *options) {
  535. (void)alloc;
  536. (void)options;
  537. AWS_FATAL_ASSERT(
  538. false &&
  539. "When using BYO_CRYPTO, user is responsible for creating aws_tls_ctx manually. You cannot call this function.");
  540. }
  541. struct aws_tls_ctx *aws_tls_client_ctx_new(struct aws_allocator *alloc, const struct aws_tls_ctx_options *options) {
  542. (void)alloc;
  543. (void)options;
  544. AWS_FATAL_ASSERT(
  545. false &&
  546. "When using BYO_CRYPTO, user is responsible for creating aws_tls_ctx manually. You cannot call this function.");
  547. }
  548. static aws_tls_handler_new_fn *s_client_handler_new = NULL;
  549. static aws_tls_client_handler_start_negotiation_fn *s_start_negotiation_fn = NULL;
  550. static void *s_client_user_data = NULL;
  551. static aws_tls_handler_new_fn *s_server_handler_new = NULL;
  552. static void *s_server_user_data = NULL;
  553. struct aws_channel_handler *aws_tls_client_handler_new(
  554. struct aws_allocator *allocator,
  555. struct aws_tls_connection_options *options,
  556. struct aws_channel_slot *slot) {
  557. AWS_FATAL_ASSERT(
  558. s_client_handler_new &&
  559. "For BYO_CRYPTO, you must call aws_tls_client_handler_new_set_callback() with a non-null value.");
  560. return s_client_handler_new(allocator, options, slot, s_client_user_data);
  561. }
  562. struct aws_channel_handler *aws_tls_server_handler_new(
  563. struct aws_allocator *allocator,
  564. struct aws_tls_connection_options *options,
  565. struct aws_channel_slot *slot) {
  566. AWS_FATAL_ASSERT(
  567. s_client_handler_new &&
  568. "For BYO_CRYPTO, you must call aws_tls_server_handler_new_set_callback() with a non-null value.");
  569. return s_server_handler_new(allocator, options, slot, s_server_user_data);
  570. }
  571. void aws_tls_byo_crypto_set_client_setup_options(const struct aws_tls_byo_crypto_setup_options *options) {
  572. AWS_FATAL_ASSERT(options);
  573. AWS_FATAL_ASSERT(options->new_handler_fn);
  574. AWS_FATAL_ASSERT(options->start_negotiation_fn);
  575. s_client_handler_new = options->new_handler_fn;
  576. s_start_negotiation_fn = options->start_negotiation_fn;
  577. s_client_user_data = options->user_data;
  578. }
  579. void aws_tls_byo_crypto_set_server_setup_options(const struct aws_tls_byo_crypto_setup_options *options) {
  580. AWS_FATAL_ASSERT(options);
  581. AWS_FATAL_ASSERT(options->new_handler_fn);
  582. s_server_handler_new = options->new_handler_fn;
  583. s_server_user_data = options->user_data;
  584. }
  585. int aws_tls_client_handler_start_negotiation(struct aws_channel_handler *handler) {
  586. AWS_FATAL_ASSERT(
  587. s_start_negotiation_fn &&
  588. "For BYO_CRYPTO, you must call aws_tls_client_handler_set_start_negotiation_callback() with a non-null value.");
  589. return s_start_negotiation_fn(handler, s_client_user_data);
  590. }
  591. void aws_tls_init_static_state(struct aws_allocator *alloc) {
  592. (void)alloc;
  593. }
  594. void aws_tls_clean_up_static_state(void) {}
  595. #endif /* BYO_CRYPTO */
  596. int aws_channel_setup_client_tls(
  597. struct aws_channel_slot *right_of_slot,
  598. struct aws_tls_connection_options *tls_options) {
  599. AWS_FATAL_ASSERT(right_of_slot != NULL);
  600. struct aws_channel *channel = right_of_slot->channel;
  601. struct aws_allocator *allocator = right_of_slot->alloc;
  602. struct aws_channel_slot *tls_slot = aws_channel_slot_new(channel);
  603. /* as far as cleanup goes, since this stuff is being added to a channel, the caller will free this memory
  604. when they clean up the channel. */
  605. if (!tls_slot) {
  606. return AWS_OP_ERR;
  607. }
  608. struct aws_channel_handler *tls_handler = aws_tls_client_handler_new(allocator, tls_options, tls_slot);
  609. if (!tls_handler) {
  610. aws_mem_release(allocator, tls_slot);
  611. return AWS_OP_ERR;
  612. }
  613. /*
  614. * From here on out, channel shutdown will handle slot/handler cleanup
  615. */
  616. aws_channel_slot_insert_right(right_of_slot, tls_slot);
  617. AWS_LOGF_TRACE(
  618. AWS_LS_IO_CHANNEL,
  619. "id=%p: Setting up client TLS with handler %p on slot %p",
  620. (void *)channel,
  621. (void *)tls_handler,
  622. (void *)tls_slot);
  623. if (aws_channel_slot_set_handler(tls_slot, tls_handler) != AWS_OP_SUCCESS) {
  624. return AWS_OP_ERR;
  625. }
  626. if (aws_tls_client_handler_start_negotiation(tls_handler) != AWS_OP_SUCCESS) {
  627. return AWS_OP_ERR;
  628. }
  629. return AWS_OP_SUCCESS;
  630. }
  631. struct aws_tls_ctx *aws_tls_ctx_acquire(struct aws_tls_ctx *ctx) {
  632. if (ctx != NULL) {
  633. aws_ref_count_acquire(&ctx->ref_count);
  634. }
  635. return ctx;
  636. }
  637. void aws_tls_ctx_release(struct aws_tls_ctx *ctx) {
  638. if (ctx != NULL) {
  639. aws_ref_count_release(&ctx->ref_count);
  640. }
  641. }
  642. const char *aws_tls_hash_algorithm_str(enum aws_tls_hash_algorithm hash) {
  643. /* clang-format off */
  644. switch (hash) {
  645. case (AWS_TLS_HASH_SHA1): return "SHA1";
  646. case (AWS_TLS_HASH_SHA224): return "SHA224";
  647. case (AWS_TLS_HASH_SHA256): return "SHA256";
  648. case (AWS_TLS_HASH_SHA384): return "SHA384";
  649. case (AWS_TLS_HASH_SHA512): return "SHA512";
  650. default: return "<UNKNOWN HASH ALGORITHM>";
  651. }
  652. /* clang-format on */
  653. }
  654. const char *aws_tls_signature_algorithm_str(enum aws_tls_signature_algorithm signature) {
  655. /* clang-format off */
  656. switch (signature) {
  657. case (AWS_TLS_SIGNATURE_RSA): return "RSA";
  658. case (AWS_TLS_SIGNATURE_ECDSA): return "ECDSA";
  659. default: return "<UNKNOWN SIGNATURE ALGORITHM>";
  660. }
  661. /* clang-format on */
  662. }
  663. const char *aws_tls_key_operation_type_str(enum aws_tls_key_operation_type operation_type) {
  664. /* clang-format off */
  665. switch (operation_type) {
  666. case (AWS_TLS_KEY_OPERATION_SIGN): return "SIGN";
  667. case (AWS_TLS_KEY_OPERATION_DECRYPT): return "DECRYPT";
  668. default: return "<UNKNOWN OPERATION TYPE>";
  669. }
  670. /* clang-format on */
  671. }
  672. #if !USE_S2N
  673. void aws_tls_key_operation_complete(struct aws_tls_key_operation *operation, struct aws_byte_cursor output) {
  674. (void)operation;
  675. (void)output;
  676. }
  677. void aws_tls_key_operation_complete_with_error(struct aws_tls_key_operation *operation, int error_code) {
  678. (void)operation;
  679. (void)error_code;
  680. }
  681. struct aws_byte_cursor aws_tls_key_operation_get_input(const struct aws_tls_key_operation *operation) {
  682. (void)operation;
  683. return aws_byte_cursor_from_array(NULL, 0);
  684. }
  685. enum aws_tls_key_operation_type aws_tls_key_operation_get_type(const struct aws_tls_key_operation *operation) {
  686. (void)operation;
  687. return AWS_TLS_KEY_OPERATION_UNKNOWN;
  688. }
  689. enum aws_tls_signature_algorithm aws_tls_key_operation_get_signature_algorithm(
  690. const struct aws_tls_key_operation *operation) {
  691. (void)operation;
  692. return AWS_TLS_SIGNATURE_UNKNOWN;
  693. }
  694. enum aws_tls_hash_algorithm aws_tls_key_operation_get_digest_algorithm(const struct aws_tls_key_operation *operation) {
  695. (void)operation;
  696. return AWS_TLS_HASH_UNKNOWN;
  697. }
  698. #endif
  699. struct aws_custom_key_op_handler *aws_custom_key_op_handler_acquire(struct aws_custom_key_op_handler *key_op_handler) {
  700. if (key_op_handler != NULL) {
  701. aws_ref_count_acquire(&key_op_handler->ref_count);
  702. }
  703. return key_op_handler;
  704. }
  705. struct aws_custom_key_op_handler *aws_custom_key_op_handler_release(struct aws_custom_key_op_handler *key_op_handler) {
  706. if (key_op_handler != NULL) {
  707. aws_ref_count_release(&key_op_handler->ref_count);
  708. }
  709. return NULL;
  710. }
  711. void aws_custom_key_op_handler_perform_operation(
  712. struct aws_custom_key_op_handler *key_op_handler,
  713. struct aws_tls_key_operation *operation) {
  714. key_op_handler->vtable->on_key_operation(key_op_handler, operation);
  715. }