s2n_certificate.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  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. #ifndef _GNU_SOURCE
  16. #define _GNU_SOURCE
  17. #endif
  18. #include "crypto/s2n_certificate.h"
  19. #include <openssl/pem.h>
  20. #include <openssl/x509v3.h>
  21. #include <string.h>
  22. #include <strings.h>
  23. #include "api/s2n.h"
  24. #include "crypto/s2n_openssl_x509.h"
  25. #include "tls/extensions/s2n_extension_list.h"
  26. #include "tls/s2n_connection.h"
  27. #include "utils/s2n_array.h"
  28. #include "utils/s2n_mem.h"
  29. #include "utils/s2n_safety.h"
  30. int s2n_cert_set_cert_type(struct s2n_cert *cert, s2n_pkey_type pkey_type)
  31. {
  32. POSIX_ENSURE_REF(cert);
  33. cert->pkey_type = pkey_type;
  34. POSIX_GUARD(s2n_pkey_setup_for_type(&cert->public_key, pkey_type));
  35. return 0;
  36. }
  37. int s2n_create_cert_chain_from_stuffer(struct s2n_cert_chain *cert_chain_out, struct s2n_stuffer *chain_in_stuffer)
  38. {
  39. DEFER_CLEANUP(struct s2n_stuffer cert_out_stuffer = { 0 }, s2n_stuffer_free);
  40. POSIX_GUARD(s2n_stuffer_growable_alloc(&cert_out_stuffer, 2048));
  41. struct s2n_cert **insert = &cert_chain_out->head;
  42. uint32_t chain_size = 0;
  43. do {
  44. struct s2n_cert *new_node = NULL;
  45. if (s2n_stuffer_certificate_from_pem(chain_in_stuffer, &cert_out_stuffer) < 0) {
  46. if (chain_size == 0) {
  47. POSIX_BAIL(S2N_ERR_NO_CERTIFICATE_IN_PEM);
  48. }
  49. break;
  50. }
  51. struct s2n_blob mem = { 0 };
  52. POSIX_GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert)));
  53. new_node = (struct s2n_cert *) (void *) mem.data;
  54. if (s2n_alloc(&new_node->raw, s2n_stuffer_data_available(&cert_out_stuffer)) != S2N_SUCCESS) {
  55. POSIX_GUARD(s2n_free(&mem));
  56. S2N_ERROR_PRESERVE_ERRNO();
  57. }
  58. if (s2n_stuffer_read(&cert_out_stuffer, &new_node->raw) != S2N_SUCCESS) {
  59. POSIX_GUARD(s2n_free(&mem));
  60. S2N_ERROR_PRESERVE_ERRNO();
  61. }
  62. /* Additional 3 bytes for the length field in the protocol */
  63. chain_size += new_node->raw.size + 3;
  64. new_node->next = NULL;
  65. *insert = new_node;
  66. insert = &new_node->next;
  67. } while (s2n_stuffer_data_available(chain_in_stuffer));
  68. /* Leftover data at this point means one of two things:
  69. * A bug in s2n's PEM parsing OR a malformed PEM in the user's chain.
  70. * Be conservative and fail instead of using a partial chain.
  71. */
  72. S2N_ERROR_IF(s2n_stuffer_data_available(chain_in_stuffer) > 0, S2N_ERR_INVALID_PEM);
  73. cert_chain_out->chain_size = chain_size;
  74. return 0;
  75. }
  76. int s2n_cert_chain_and_key_set_cert_chain_from_stuffer(struct s2n_cert_chain_and_key *cert_and_key, struct s2n_stuffer *chain_in_stuffer)
  77. {
  78. return s2n_create_cert_chain_from_stuffer(cert_and_key->cert_chain, chain_in_stuffer);
  79. }
  80. int s2n_cert_chain_and_key_set_cert_chain_bytes(struct s2n_cert_chain_and_key *cert_and_key, uint8_t *cert_chain_pem, uint32_t cert_chain_len)
  81. {
  82. DEFER_CLEANUP(struct s2n_stuffer chain_in_stuffer = { 0 }, s2n_stuffer_free);
  83. POSIX_GUARD(s2n_stuffer_init_ro_from_string(&chain_in_stuffer, cert_chain_pem, cert_chain_len));
  84. POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_from_stuffer(cert_and_key, &chain_in_stuffer));
  85. return S2N_SUCCESS;
  86. }
  87. int s2n_cert_chain_and_key_set_cert_chain(struct s2n_cert_chain_and_key *cert_and_key, const char *cert_chain_pem)
  88. {
  89. DEFER_CLEANUP(struct s2n_stuffer chain_in_stuffer = { 0 }, s2n_stuffer_free);
  90. /* Turn the chain into a stuffer */
  91. POSIX_GUARD(s2n_stuffer_alloc_ro_from_string(&chain_in_stuffer, cert_chain_pem));
  92. POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_from_stuffer(cert_and_key, &chain_in_stuffer));
  93. return S2N_SUCCESS;
  94. }
  95. int s2n_cert_chain_and_key_set_private_key_from_stuffer(struct s2n_cert_chain_and_key *cert_and_key,
  96. struct s2n_stuffer *key_in_stuffer, struct s2n_stuffer *key_out_stuffer)
  97. {
  98. struct s2n_blob key_blob = { 0 };
  99. POSIX_GUARD(s2n_pkey_zero_init(cert_and_key->private_key));
  100. /* Convert pem to asn1 and asn1 to the private key. Handles both PKCS#1 and PKCS#8 formats */
  101. int type = 0;
  102. POSIX_GUARD(s2n_stuffer_private_key_from_pem(key_in_stuffer, key_out_stuffer, &type));
  103. key_blob.size = s2n_stuffer_data_available(key_out_stuffer);
  104. key_blob.data = s2n_stuffer_raw_read(key_out_stuffer, key_blob.size);
  105. POSIX_ENSURE_REF(key_blob.data);
  106. POSIX_GUARD(s2n_asn1der_to_private_key(cert_and_key->private_key, &key_blob, type));
  107. return S2N_SUCCESS;
  108. }
  109. int s2n_cert_chain_and_key_set_private_key_bytes(struct s2n_cert_chain_and_key *cert_and_key, uint8_t *private_key_pem, uint32_t private_key_len)
  110. {
  111. DEFER_CLEANUP(struct s2n_stuffer key_in_stuffer = { 0 }, s2n_stuffer_free);
  112. DEFER_CLEANUP(struct s2n_stuffer key_out_stuffer = { 0 }, s2n_stuffer_free);
  113. /* Put the private key pem in a stuffer */
  114. POSIX_GUARD(s2n_stuffer_init_ro_from_string(&key_in_stuffer, private_key_pem, private_key_len));
  115. POSIX_GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, private_key_len));
  116. POSIX_GUARD(s2n_cert_chain_and_key_set_private_key_from_stuffer(cert_and_key, &key_in_stuffer, &key_out_stuffer));
  117. return S2N_SUCCESS;
  118. }
  119. int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem)
  120. {
  121. POSIX_ENSURE_REF(private_key_pem);
  122. DEFER_CLEANUP(struct s2n_stuffer key_in_stuffer = { 0 }, s2n_stuffer_free);
  123. DEFER_CLEANUP(struct s2n_stuffer key_out_stuffer = { 0 }, s2n_stuffer_free);
  124. /* Put the private key pem in a stuffer */
  125. POSIX_GUARD(s2n_stuffer_alloc_ro_from_string(&key_in_stuffer, private_key_pem));
  126. POSIX_GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, strlen(private_key_pem)));
  127. POSIX_GUARD(s2n_cert_chain_and_key_set_private_key_from_stuffer(cert_and_key, &key_in_stuffer, &key_out_stuffer));
  128. return S2N_SUCCESS;
  129. }
  130. int s2n_cert_chain_and_key_set_ocsp_data(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length)
  131. {
  132. POSIX_ENSURE_REF(chain_and_key);
  133. POSIX_GUARD(s2n_free(&chain_and_key->ocsp_status));
  134. if (data && length) {
  135. POSIX_GUARD(s2n_alloc(&chain_and_key->ocsp_status, length));
  136. POSIX_CHECKED_MEMCPY(chain_and_key->ocsp_status.data, data, length);
  137. }
  138. return 0;
  139. }
  140. int s2n_cert_chain_and_key_set_sct_list(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length)
  141. {
  142. POSIX_ENSURE_REF(chain_and_key);
  143. POSIX_GUARD(s2n_free(&chain_and_key->sct_list));
  144. if (data && length) {
  145. POSIX_GUARD(s2n_alloc(&chain_and_key->sct_list, length));
  146. POSIX_CHECKED_MEMCPY(chain_and_key->sct_list.data, data, length);
  147. }
  148. return 0;
  149. }
  150. struct s2n_cert_chain_and_key *s2n_cert_chain_and_key_new(void)
  151. {
  152. DEFER_CLEANUP(struct s2n_blob chain_and_key_mem = { 0 }, s2n_free);
  153. PTR_GUARD_POSIX(s2n_alloc(&chain_and_key_mem, sizeof(struct s2n_cert_chain_and_key)));
  154. PTR_GUARD_POSIX(s2n_blob_zero(&chain_and_key_mem));
  155. DEFER_CLEANUP(struct s2n_blob cert_chain_mem = { 0 }, s2n_free);
  156. PTR_GUARD_POSIX(s2n_alloc(&cert_chain_mem, sizeof(struct s2n_cert_chain)));
  157. PTR_GUARD_POSIX(s2n_blob_zero(&cert_chain_mem));
  158. DEFER_CLEANUP(struct s2n_blob pkey_mem = { 0 }, s2n_free);
  159. PTR_GUARD_POSIX(s2n_alloc(&pkey_mem, sizeof(s2n_cert_private_key)));
  160. PTR_GUARD_POSIX(s2n_blob_zero(&pkey_mem));
  161. DEFER_CLEANUP(struct s2n_array *cn_names = NULL, s2n_array_free_p);
  162. cn_names = s2n_array_new(sizeof(struct s2n_blob));
  163. PTR_ENSURE_REF(cn_names);
  164. DEFER_CLEANUP(struct s2n_array *san_names = NULL, s2n_array_free_p);
  165. san_names = s2n_array_new(sizeof(struct s2n_blob));
  166. PTR_ENSURE_REF(san_names);
  167. struct s2n_cert_chain_and_key *chain_and_key = (struct s2n_cert_chain_and_key *) (void *) chain_and_key_mem.data;
  168. chain_and_key->cert_chain = (struct s2n_cert_chain *) (void *) cert_chain_mem.data;
  169. chain_and_key->private_key = (s2n_cert_private_key *) (void *) pkey_mem.data;
  170. chain_and_key->cn_names = cn_names;
  171. chain_and_key->san_names = san_names;
  172. ZERO_TO_DISABLE_DEFER_CLEANUP(chain_and_key_mem);
  173. ZERO_TO_DISABLE_DEFER_CLEANUP(cert_chain_mem);
  174. ZERO_TO_DISABLE_DEFER_CLEANUP(pkey_mem);
  175. ZERO_TO_DISABLE_DEFER_CLEANUP(cn_names);
  176. ZERO_TO_DISABLE_DEFER_CLEANUP(san_names);
  177. return chain_and_key;
  178. }
  179. DEFINE_POINTER_CLEANUP_FUNC(GENERAL_NAMES *, GENERAL_NAMES_free);
  180. int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert)
  181. {
  182. POSIX_ENSURE_REF(chain_and_key->san_names);
  183. DEFER_CLEANUP(GENERAL_NAMES *san_names = X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL), GENERAL_NAMES_free_pointer);
  184. if (san_names == NULL) {
  185. /* No SAN extension */
  186. return 0;
  187. }
  188. const int num_san_names = sk_GENERAL_NAME_num(san_names);
  189. for (int i = 0; i < num_san_names; i++) {
  190. GENERAL_NAME *san_name = sk_GENERAL_NAME_value(san_names, i);
  191. if (!san_name) {
  192. continue;
  193. }
  194. if (san_name->type == GEN_DNS) {
  195. /* Decoding isn't necessary here since a DNS SAN name is ASCII(type V_ASN1_IA5STRING) */
  196. unsigned char *san_str = san_name->d.dNSName->data;
  197. const size_t san_str_len = san_name->d.dNSName->length;
  198. struct s2n_blob *san_blob = NULL;
  199. POSIX_GUARD_RESULT(s2n_array_pushback(chain_and_key->san_names, (void **) &san_blob));
  200. if (!san_blob) {
  201. POSIX_BAIL(S2N_ERR_NULL_SANS);
  202. }
  203. if (s2n_alloc(san_blob, san_str_len)) {
  204. S2N_ERROR_PRESERVE_ERRNO();
  205. }
  206. POSIX_CHECKED_MEMCPY(san_blob->data, san_str, san_str_len);
  207. san_blob->size = san_str_len;
  208. /* normalize san_blob to lowercase */
  209. POSIX_GUARD(s2n_blob_char_to_lower(san_blob));
  210. }
  211. }
  212. return 0;
  213. }
  214. /* Parse CN names from the Subject of the leaf certificate. Technically there can by multiple CNs
  215. * in the Subject but practically very few certificates in the wild will have more than one CN.
  216. * Since the data for this certificate is coming from the application and not from an untrusted
  217. * source, we will try our best to parse all of the CNs.
  218. *
  219. * A recent CAB thread proposed removing support for multiple CNs:
  220. * https://cabforum.org/pipermail/public/2016-April/007242.html
  221. */
  222. DEFINE_POINTER_CLEANUP_FUNC(unsigned char *, OPENSSL_free);
  223. int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert)
  224. {
  225. POSIX_ENSURE_REF(chain_and_key->cn_names);
  226. X509_NAME *subject = X509_get_subject_name(x509_cert);
  227. if (!subject) {
  228. return 0;
  229. }
  230. int lastpos = -1;
  231. while ((lastpos = X509_NAME_get_index_by_NID(subject, NID_commonName, lastpos)) >= 0) {
  232. X509_NAME_ENTRY *name_entry = X509_NAME_get_entry(subject, lastpos);
  233. if (!name_entry) {
  234. continue;
  235. }
  236. ASN1_STRING *asn1_str = X509_NAME_ENTRY_get_data(name_entry);
  237. if (!asn1_str) {
  238. continue;
  239. }
  240. /* We need to try and decode the CN since it may be encoded as unicode with a
  241. * direct ASCII equivalent. Any non ASCII bytes in the string will fail later when we
  242. * actually compare hostnames.
  243. *
  244. * `ASN1_STRING_to_UTF8` allocates in both the success case and in the zero return case, but
  245. * not in the failure case (negative return value). Therefore, we use `ZERO_TO_DISABLE_DEFER_CLEANUP`
  246. * in the failure case to prevent double-freeing `utf8_str`. For the zero and success cases, `utf8_str`
  247. * will be freed by the `DEFER_CLEANUP`.
  248. */
  249. DEFER_CLEANUP(unsigned char *utf8_str, OPENSSL_free_pointer);
  250. const int utf8_out_len = ASN1_STRING_to_UTF8(&utf8_str, asn1_str);
  251. if (utf8_out_len < 0) {
  252. /* On failure, ASN1_STRING_to_UTF8 does not allocate any memory */
  253. ZERO_TO_DISABLE_DEFER_CLEANUP(utf8_str);
  254. continue;
  255. } else if (utf8_out_len == 0) {
  256. /* We still need to free memory for this case, so let the DEFER_CLEANUP free it
  257. * see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7521 and
  258. * https://security.archlinux.org/CVE-2017-7521
  259. */
  260. } else {
  261. struct s2n_blob *cn_name = NULL;
  262. POSIX_GUARD_RESULT(s2n_array_pushback(chain_and_key->cn_names, (void **) &cn_name));
  263. if (cn_name == NULL) {
  264. POSIX_BAIL(S2N_ERR_NULL_CN_NAME);
  265. }
  266. if (s2n_alloc(cn_name, utf8_out_len) < 0) {
  267. S2N_ERROR_PRESERVE_ERRNO();
  268. }
  269. POSIX_CHECKED_MEMCPY(cn_name->data, utf8_str, utf8_out_len);
  270. cn_name->size = utf8_out_len;
  271. /* normalize cn_name to lowercase */
  272. POSIX_GUARD(s2n_blob_char_to_lower(cn_name));
  273. }
  274. }
  275. return 0;
  276. }
  277. static int s2n_cert_chain_and_key_set_names(struct s2n_cert_chain_and_key *chain_and_key, struct s2n_blob *leaf_bytes)
  278. {
  279. const unsigned char *leaf_der = leaf_bytes->data;
  280. X509 *cert = d2i_X509(NULL, &leaf_der, leaf_bytes->size);
  281. if (!cert) {
  282. POSIX_BAIL(S2N_ERR_INVALID_PEM);
  283. }
  284. POSIX_GUARD(s2n_cert_chain_and_key_load_sans(chain_and_key, cert));
  285. /* For current use cases, we *could* avoid populating the common names if any sans were loaded in
  286. * s2n_cert_chain_and_key_load_sans. Let's unconditionally populate this field to avoid surprises
  287. * in the future.
  288. */
  289. POSIX_GUARD(s2n_cert_chain_and_key_load_cns(chain_and_key, cert));
  290. X509_free(cert);
  291. return 0;
  292. }
  293. int s2n_cert_chain_and_key_load(struct s2n_cert_chain_and_key *chain_and_key)
  294. {
  295. POSIX_ENSURE_REF(chain_and_key);
  296. POSIX_ENSURE_REF(chain_and_key->cert_chain);
  297. POSIX_ENSURE_REF(chain_and_key->cert_chain->head);
  298. POSIX_ENSURE_REF(chain_and_key->private_key);
  299. struct s2n_cert *head = chain_and_key->cert_chain->head;
  300. /* Parse the leaf cert for the public key and certificate type */
  301. DEFER_CLEANUP(struct s2n_pkey public_key = { 0 }, s2n_pkey_free);
  302. s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN;
  303. POSIX_GUARD(s2n_asn1der_to_public_key_and_type(&public_key, &pkey_type, &head->raw));
  304. POSIX_ENSURE(pkey_type != S2N_PKEY_TYPE_UNKNOWN, S2N_ERR_CERT_TYPE_UNSUPPORTED);
  305. POSIX_GUARD(s2n_cert_set_cert_type(head, pkey_type));
  306. /* Validate the leaf cert's public key matches the provided private key */
  307. if (s2n_pkey_check_key_exists(chain_and_key->private_key) == S2N_SUCCESS) {
  308. POSIX_GUARD(s2n_pkey_match(&public_key, chain_and_key->private_key));
  309. }
  310. /* Populate name information from the SAN/CN for the leaf certificate */
  311. POSIX_GUARD(s2n_cert_chain_and_key_set_names(chain_and_key, &head->raw));
  312. /* Populate ec curve libcrypto nid */
  313. if (pkey_type == S2N_PKEY_TYPE_ECDSA) {
  314. int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(public_key.key.ecdsa_key.ec_key));
  315. POSIX_ENSURE(nid > 0, S2N_ERR_CERT_TYPE_UNSUPPORTED);
  316. POSIX_ENSURE(nid < UINT16_MAX, S2N_ERR_CERT_TYPE_UNSUPPORTED);
  317. head->ec_curve_nid = nid;
  318. }
  319. return S2N_SUCCESS;
  320. }
  321. int s2n_cert_chain_and_key_load_pem(struct s2n_cert_chain_and_key *chain_and_key, const char *chain_pem, const char *private_key_pem)
  322. {
  323. POSIX_ENSURE_REF(chain_and_key);
  324. POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain(chain_and_key, chain_pem));
  325. POSIX_GUARD(s2n_cert_chain_and_key_set_private_key(chain_and_key, private_key_pem));
  326. POSIX_GUARD(s2n_cert_chain_and_key_load(chain_and_key));
  327. return S2N_SUCCESS;
  328. }
  329. int s2n_cert_chain_and_key_load_public_pem_bytes(struct s2n_cert_chain_and_key *chain_and_key, uint8_t *chain_pem, uint32_t chain_pem_len)
  330. {
  331. POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_bytes(chain_and_key, chain_pem, chain_pem_len));
  332. POSIX_GUARD(s2n_cert_chain_and_key_load(chain_and_key));
  333. return S2N_SUCCESS;
  334. }
  335. int s2n_cert_chain_and_key_load_pem_bytes(struct s2n_cert_chain_and_key *chain_and_key, uint8_t *chain_pem,
  336. uint32_t chain_pem_len, uint8_t *private_key_pem, uint32_t private_key_pem_len)
  337. {
  338. POSIX_ENSURE_REF(chain_and_key);
  339. POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_bytes(chain_and_key, chain_pem, chain_pem_len));
  340. POSIX_GUARD(s2n_cert_chain_and_key_set_private_key_bytes(chain_and_key, private_key_pem, private_key_pem_len));
  341. POSIX_GUARD(s2n_cert_chain_and_key_load(chain_and_key));
  342. return S2N_SUCCESS;
  343. }
  344. S2N_CLEANUP_RESULT s2n_cert_chain_and_key_ptr_free(struct s2n_cert_chain_and_key **cert_and_key)
  345. {
  346. RESULT_ENSURE_REF(cert_and_key);
  347. RESULT_GUARD_POSIX(s2n_cert_chain_and_key_free(*cert_and_key));
  348. *cert_and_key = NULL;
  349. return S2N_RESULT_OK;
  350. }
  351. int s2n_cert_chain_and_key_free(struct s2n_cert_chain_and_key *cert_and_key)
  352. {
  353. if (cert_and_key == NULL) {
  354. return 0;
  355. }
  356. /* Walk the chain and free the certs */
  357. if (cert_and_key->cert_chain) {
  358. struct s2n_cert *node = cert_and_key->cert_chain->head;
  359. while (node) {
  360. /* Free the cert */
  361. POSIX_GUARD(s2n_free(&node->raw));
  362. /* update head so it won't point to freed memory */
  363. cert_and_key->cert_chain->head = node->next;
  364. /* Free the node */
  365. POSIX_GUARD(s2n_free_object((uint8_t **) &node, sizeof(struct s2n_cert)));
  366. node = cert_and_key->cert_chain->head;
  367. }
  368. POSIX_GUARD(s2n_free_object((uint8_t **) &cert_and_key->cert_chain, sizeof(struct s2n_cert_chain)));
  369. }
  370. if (cert_and_key->private_key) {
  371. POSIX_GUARD(s2n_pkey_free(cert_and_key->private_key));
  372. POSIX_GUARD(s2n_free_object((uint8_t **) &cert_and_key->private_key, sizeof(s2n_cert_private_key)));
  373. }
  374. uint32_t len = 0;
  375. if (cert_and_key->san_names) {
  376. POSIX_GUARD_RESULT(s2n_array_num_elements(cert_and_key->san_names, &len));
  377. for (uint32_t i = 0; i < len; i++) {
  378. struct s2n_blob *san_name = NULL;
  379. POSIX_GUARD_RESULT(s2n_array_get(cert_and_key->san_names, i, (void **) &san_name));
  380. POSIX_GUARD(s2n_free(san_name));
  381. }
  382. POSIX_GUARD_RESULT(s2n_array_free(cert_and_key->san_names));
  383. cert_and_key->san_names = NULL;
  384. }
  385. if (cert_and_key->cn_names) {
  386. POSIX_GUARD_RESULT(s2n_array_num_elements(cert_and_key->cn_names, &len));
  387. for (uint32_t i = 0; i < len; i++) {
  388. struct s2n_blob *cn_name = NULL;
  389. POSIX_GUARD_RESULT(s2n_array_get(cert_and_key->cn_names, i, (void **) &cn_name));
  390. POSIX_GUARD(s2n_free(cn_name));
  391. }
  392. POSIX_GUARD_RESULT(s2n_array_free(cert_and_key->cn_names));
  393. cert_and_key->cn_names = NULL;
  394. }
  395. POSIX_GUARD(s2n_free(&cert_and_key->ocsp_status));
  396. POSIX_GUARD(s2n_free(&cert_and_key->sct_list));
  397. POSIX_GUARD(s2n_free_object((uint8_t **) &cert_and_key, sizeof(struct s2n_cert_chain_and_key)));
  398. return 0;
  399. }
  400. int s2n_cert_chain_free(struct s2n_cert_chain *cert_chain)
  401. {
  402. /* Walk the chain and free the certs/nodes allocated prior to failure */
  403. if (cert_chain) {
  404. struct s2n_cert *node = cert_chain->head;
  405. while (node) {
  406. /* Free the cert */
  407. POSIX_GUARD(s2n_free(&node->raw));
  408. /* update head so it won't point to freed memory */
  409. cert_chain->head = node->next;
  410. /* Free the node */
  411. POSIX_GUARD(s2n_free_object((uint8_t **) &node, sizeof(struct s2n_cert)));
  412. node = cert_chain->head;
  413. }
  414. }
  415. return S2N_SUCCESS;
  416. }
  417. int s2n_send_cert_chain(struct s2n_connection *conn, struct s2n_stuffer *out, struct s2n_cert_chain_and_key *chain_and_key)
  418. {
  419. POSIX_ENSURE_REF(conn);
  420. POSIX_ENSURE_REF(out);
  421. POSIX_ENSURE_REF(chain_and_key);
  422. struct s2n_cert_chain *chain = chain_and_key->cert_chain;
  423. POSIX_ENSURE_REF(chain);
  424. struct s2n_cert *cur_cert = chain->head;
  425. POSIX_ENSURE_REF(cur_cert);
  426. struct s2n_stuffer_reservation cert_chain_size = { 0 };
  427. POSIX_GUARD(s2n_stuffer_reserve_uint24(out, &cert_chain_size));
  428. /* Send certs and extensions (in TLS 1.3) */
  429. bool first_entry = true;
  430. while (cur_cert) {
  431. POSIX_ENSURE_REF(cur_cert);
  432. POSIX_GUARD(s2n_stuffer_write_uint24(out, cur_cert->raw.size));
  433. POSIX_GUARD(s2n_stuffer_write_bytes(out, cur_cert->raw.data, cur_cert->raw.size));
  434. /* According to https://tools.ietf.org/html/rfc8446#section-4.4.2,
  435. * If an extension applies to the entire chain, it SHOULD be included in
  436. * the first CertificateEntry.
  437. * While the spec allow extensions to be included in other certificate
  438. * entries, only the first matter to use here */
  439. if (conn->actual_protocol_version >= S2N_TLS13) {
  440. if (first_entry) {
  441. POSIX_GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CERTIFICATE, conn, out));
  442. first_entry = false;
  443. } else {
  444. POSIX_GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_EMPTY, conn, out));
  445. }
  446. }
  447. cur_cert = cur_cert->next;
  448. }
  449. POSIX_GUARD(s2n_stuffer_write_vector_size(&cert_chain_size));
  450. return 0;
  451. }
  452. int s2n_send_empty_cert_chain(struct s2n_stuffer *out)
  453. {
  454. POSIX_ENSURE_REF(out);
  455. POSIX_GUARD(s2n_stuffer_write_uint24(out, 0));
  456. return 0;
  457. }
  458. static int s2n_does_cert_san_match_hostname(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
  459. {
  460. POSIX_ENSURE_REF(chain_and_key);
  461. POSIX_ENSURE_REF(dns_name);
  462. struct s2n_array *san_names = chain_and_key->san_names;
  463. uint32_t len = 0;
  464. POSIX_GUARD_RESULT(s2n_array_num_elements(san_names, &len));
  465. for (uint32_t i = 0; i < len; i++) {
  466. struct s2n_blob *san_name = NULL;
  467. POSIX_GUARD_RESULT(s2n_array_get(san_names, i, (void **) &san_name));
  468. POSIX_ENSURE_REF(san_name);
  469. if ((dns_name->size == san_name->size) && (strncasecmp((const char *) dns_name->data, (const char *) san_name->data, dns_name->size) == 0)) {
  470. return 1;
  471. }
  472. }
  473. return 0;
  474. }
  475. static int s2n_does_cert_cn_match_hostname(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
  476. {
  477. POSIX_ENSURE_REF(chain_and_key);
  478. POSIX_ENSURE_REF(dns_name);
  479. struct s2n_array *cn_names = chain_and_key->cn_names;
  480. uint32_t len = 0;
  481. POSIX_GUARD_RESULT(s2n_array_num_elements(cn_names, &len));
  482. for (uint32_t i = 0; i < len; i++) {
  483. struct s2n_blob *cn_name = NULL;
  484. POSIX_GUARD_RESULT(s2n_array_get(cn_names, i, (void **) &cn_name));
  485. POSIX_ENSURE_REF(cn_name);
  486. if ((dns_name->size == cn_name->size) && (strncasecmp((const char *) dns_name->data, (const char *) cn_name->data, dns_name->size) == 0)) {
  487. return 1;
  488. }
  489. }
  490. return 0;
  491. }
  492. int s2n_cert_chain_and_key_matches_dns_name(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
  493. {
  494. uint32_t len = 0;
  495. POSIX_GUARD_RESULT(s2n_array_num_elements(chain_and_key->san_names, &len));
  496. if (len > 0) {
  497. if (s2n_does_cert_san_match_hostname(chain_and_key, dns_name)) {
  498. return 1;
  499. }
  500. } else {
  501. /* Per https://tools.ietf.org/html/rfc6125#section-6.4.4 we only will
  502. * consider the CN for matching if no valid DNS entries are provided
  503. * in a SAN.
  504. */
  505. if (s2n_does_cert_cn_match_hostname(chain_and_key, dns_name)) {
  506. return 1;
  507. }
  508. }
  509. return 0;
  510. }
  511. int s2n_cert_chain_and_key_set_ctx(struct s2n_cert_chain_and_key *cert_and_key, void *ctx)
  512. {
  513. cert_and_key->context = ctx;
  514. return 0;
  515. }
  516. void *s2n_cert_chain_and_key_get_ctx(struct s2n_cert_chain_and_key *cert_and_key)
  517. {
  518. return cert_and_key->context;
  519. }
  520. s2n_pkey_type s2n_cert_chain_and_key_get_pkey_type(struct s2n_cert_chain_and_key *chain_and_key)
  521. {
  522. if (chain_and_key == NULL
  523. || chain_and_key->cert_chain == NULL
  524. || chain_and_key->cert_chain->head == NULL) {
  525. return S2N_PKEY_TYPE_UNKNOWN;
  526. }
  527. return chain_and_key->cert_chain->head->pkey_type;
  528. }
  529. s2n_cert_private_key *s2n_cert_chain_and_key_get_private_key(struct s2n_cert_chain_and_key *chain_and_key)
  530. {
  531. PTR_ENSURE_REF(chain_and_key);
  532. return chain_and_key->private_key;
  533. }
  534. int s2n_cert_chain_get_length(const struct s2n_cert_chain_and_key *chain_and_key, uint32_t *cert_length)
  535. {
  536. POSIX_ENSURE_REF(chain_and_key);
  537. POSIX_ENSURE_REF(cert_length);
  538. struct s2n_cert *head_cert = chain_and_key->cert_chain->head;
  539. POSIX_ENSURE_REF(head_cert);
  540. *cert_length = 1;
  541. struct s2n_cert *next_cert = head_cert->next;
  542. while (next_cert != NULL) {
  543. *cert_length += 1;
  544. next_cert = next_cert->next;
  545. }
  546. return S2N_SUCCESS;
  547. }
  548. int s2n_cert_chain_get_cert(const struct s2n_cert_chain_and_key *chain_and_key, struct s2n_cert **out_cert,
  549. const uint32_t cert_idx)
  550. {
  551. POSIX_ENSURE_REF(chain_and_key);
  552. POSIX_ENSURE_REF(out_cert);
  553. struct s2n_cert *cur_cert = chain_and_key->cert_chain->head;
  554. POSIX_ENSURE_REF(cur_cert);
  555. uint32_t counter = 0;
  556. struct s2n_cert *next_cert = cur_cert->next;
  557. while ((next_cert != NULL) && (counter < cert_idx)) {
  558. cur_cert = next_cert;
  559. next_cert = next_cert->next;
  560. counter++;
  561. }
  562. POSIX_ENSURE(counter == cert_idx, S2N_ERR_NO_CERT_FOUND);
  563. POSIX_ENSURE(cur_cert != NULL, S2N_ERR_NO_CERT_FOUND);
  564. *out_cert = cur_cert;
  565. return S2N_SUCCESS;
  566. }
  567. int s2n_cert_get_der(const struct s2n_cert *cert, const uint8_t **out_cert_der, uint32_t *cert_length)
  568. {
  569. POSIX_ENSURE_REF(cert);
  570. POSIX_ENSURE_REF(out_cert_der);
  571. POSIX_ENSURE_REF(cert_length);
  572. *cert_length = cert->raw.size;
  573. *out_cert_der = cert->raw.data;
  574. return S2N_SUCCESS;
  575. }
  576. static int s2n_asn1_obj_free(ASN1_OBJECT **data)
  577. {
  578. if (*data != NULL) {
  579. ASN1_OBJECT_free(*data);
  580. }
  581. return S2N_SUCCESS;
  582. }
  583. static int s2n_asn1_string_free(ASN1_STRING **data)
  584. {
  585. if (*data != NULL) {
  586. ASN1_STRING_free(*data);
  587. }
  588. return S2N_SUCCESS;
  589. }
  590. static int s2n_utf8_string_from_extension_data(const uint8_t *extension_data, uint32_t extension_len, uint8_t *out_data, uint32_t *out_len)
  591. {
  592. DEFER_CLEANUP(ASN1_STRING *asn1_str = NULL, s2n_asn1_string_free);
  593. /* Note that d2i_ASN1_UTF8STRING increments *der_in to the byte following the parsed data.
  594. * Using a temporary variable is mandatory to prevent memory free-ing errors.
  595. * Ref to the warning section here for more information:
  596. * https://www.openssl.org/docs/man1.1.0/man3/d2i_ASN1_UTF8STRING.html.
  597. */
  598. const uint8_t *asn1_str_data = extension_data;
  599. asn1_str = d2i_ASN1_UTF8STRING(NULL, (const unsigned char **) (void *) &asn1_str_data, extension_len);
  600. POSIX_ENSURE(asn1_str != NULL, S2N_ERR_INVALID_X509_EXTENSION_TYPE);
  601. /* ASN1_STRING_type() returns the type of `asn1_str`, using standard constants such as V_ASN1_OCTET_STRING.
  602. * Ref: https://www.openssl.org/docs/man1.1.0/man3/ASN1_STRING_type.html.
  603. */
  604. int type = ASN1_STRING_type(asn1_str);
  605. POSIX_ENSURE(type == V_ASN1_UTF8STRING, S2N_ERR_INVALID_X509_EXTENSION_TYPE);
  606. int len = ASN1_STRING_length(asn1_str);
  607. if (out_data != NULL) {
  608. POSIX_ENSURE((int64_t) *out_len >= (int64_t) len, S2N_ERR_INSUFFICIENT_MEM_SIZE);
  609. /* ASN1_STRING_data() returns an internal pointer to the data.
  610. * Since this is an internal pointer it should not be freed or modified in any way.
  611. * Ref: https://www.openssl.org/docs/man1.0.2/man3/ASN1_STRING_data.html.
  612. */
  613. unsigned char *internal_data = ASN1_STRING_data(asn1_str);
  614. POSIX_ENSURE_REF(internal_data);
  615. POSIX_CHECKED_MEMCPY(out_data, internal_data, len);
  616. }
  617. *out_len = len;
  618. return S2N_SUCCESS;
  619. }
  620. int s2n_cert_get_utf8_string_from_extension_data_length(const uint8_t *extension_data, uint32_t extension_len, uint32_t *utf8_str_len)
  621. {
  622. POSIX_ENSURE_REF(extension_data);
  623. POSIX_ENSURE_GT(extension_len, 0);
  624. POSIX_ENSURE_REF(utf8_str_len);
  625. POSIX_GUARD(s2n_utf8_string_from_extension_data(extension_data, extension_len, NULL, utf8_str_len));
  626. return S2N_SUCCESS;
  627. }
  628. int s2n_cert_get_utf8_string_from_extension_data(const uint8_t *extension_data, uint32_t extension_len, uint8_t *out_data, uint32_t *out_len)
  629. {
  630. POSIX_ENSURE_REF(extension_data);
  631. POSIX_ENSURE_GT(extension_len, 0);
  632. POSIX_ENSURE_REF(out_data);
  633. POSIX_ENSURE_REF(out_len);
  634. POSIX_GUARD(s2n_utf8_string_from_extension_data(extension_data, extension_len, out_data, out_len));
  635. return S2N_SUCCESS;
  636. }
  637. static int s2n_parse_x509_extension(struct s2n_cert *cert, const uint8_t *oid,
  638. uint8_t *ext_value, uint32_t *ext_value_len, bool *critical)
  639. {
  640. POSIX_ENSURE_REF(cert->raw.data);
  641. /* Obtain the openssl x509 cert from the ASN1 DER certificate input.
  642. * Note that d2i_X509 increments *der_in to the byte following the parsed data.
  643. * Using a temporary variable is mandatory to prevent memory free-ing errors.
  644. * Ref to the warning section here for more information:
  645. * https://www.openssl.org/docs/man1.1.0/man3/d2i_X509.html.
  646. */
  647. uint8_t *der_in = cert->raw.data;
  648. DEFER_CLEANUP(X509 *x509_cert = d2i_X509(NULL, (const unsigned char **) (void *) &der_in, cert->raw.size),
  649. X509_free_pointer);
  650. POSIX_ENSURE_REF(x509_cert);
  651. /* Retrieve the number of x509 extensions present in the certificate
  652. * X509_get_ext_count returns the number of extensions in the x509 certificate.
  653. * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_get_ext_count.html.
  654. */
  655. int ext_count_value = X509_get_ext_count(x509_cert);
  656. POSIX_ENSURE_GT(ext_count_value, 0);
  657. size_t ext_count = (size_t) ext_count_value;
  658. /* OBJ_txt2obj() converts the input text string into an ASN1_OBJECT structure.
  659. * If no_name is 0 then long names and short names will be interpreted as well as numerical forms.
  660. * If no_name is 1 only the numerical form is acceptable.
  661. * Ref: https://www.openssl.org/docs/man1.1.0/man3/OBJ_txt2obj.html.
  662. */
  663. DEFER_CLEANUP(ASN1_OBJECT *asn1_obj_in = OBJ_txt2obj((const char *) oid, 0), s2n_asn1_obj_free);
  664. POSIX_ENSURE_REF(asn1_obj_in);
  665. for (size_t loc = 0; loc < ext_count; loc++) {
  666. ASN1_OCTET_STRING *asn1_str = NULL;
  667. bool match_found = false;
  668. /* Retrieve the x509 extension at location loc.
  669. * X509_get_ext() retrieves extension loc from x.
  670. * The index loc can take any value from 0 to X509_get_ext_count(x) - 1.
  671. * The returned extension is an internal pointer which must not be freed up by the application.
  672. * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_get_ext.html.
  673. */
  674. X509_EXTENSION *x509_ext = X509_get_ext(x509_cert, loc);
  675. POSIX_ENSURE_REF(x509_ext);
  676. /* Retrieve the extension object/OID/extnId.
  677. * X509_EXTENSION_get_object() returns the extension type of `x509_ext` as an ASN1_OBJECT pointer.
  678. * The returned pointer is an internal value which must not be freed up.
  679. * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_object.html.
  680. */
  681. ASN1_OBJECT *asn1_obj = X509_EXTENSION_get_object(x509_ext);
  682. POSIX_ENSURE_REF(asn1_obj);
  683. /* OBJ_cmp() compares two ASN1_OBJECT objects. If the two are identical 0 is returned.
  684. * Ref: https://www.openssl.org/docs/man1.1.0/man3/OBJ_cmp.html.
  685. */
  686. match_found = (0 == OBJ_cmp(asn1_obj_in, asn1_obj));
  687. /* If match found, retrieve the corresponding OID value for the x509 extension */
  688. if (match_found) {
  689. /* X509_EXTENSION_get_data() returns the data of extension `x509_ext`.
  690. * The returned pointer is an internal value which must not be freed up.
  691. * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_data.html.
  692. */
  693. asn1_str = X509_EXTENSION_get_data(x509_ext);
  694. /* ASN1_STRING_length() returns the length of the content of `asn1_str`.
  695. * Ref: https://www.openssl.org/docs/man1.1.0/man3/ASN1_STRING_length.html.
  696. */
  697. int len = ASN1_STRING_length(asn1_str);
  698. if (ext_value != NULL) {
  699. POSIX_ENSURE_GTE(len, 0);
  700. POSIX_ENSURE(*ext_value_len >= (uint32_t) len, S2N_ERR_INSUFFICIENT_MEM_SIZE);
  701. /* ASN1_STRING_data() returns an internal pointer to the data.
  702. * Since this is an internal pointer it should not be freed or modified in any way.
  703. * Ref: https://www.openssl.org/docs/man1.0.2/man3/ASN1_STRING_data.html.
  704. */
  705. unsigned char *internal_data = ASN1_STRING_data(asn1_str);
  706. POSIX_ENSURE_REF(internal_data);
  707. POSIX_CHECKED_MEMCPY(ext_value, internal_data, len);
  708. }
  709. if (critical != NULL) {
  710. /* Retrieve the x509 extension's critical value.
  711. * X509_EXTENSION_get_critical() returns the criticality of extension `x509_ext`,
  712. * it returns 1 for critical and 0 for non-critical.
  713. * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_critical.html.
  714. */
  715. *critical = X509_EXTENSION_get_critical(x509_ext);
  716. }
  717. *ext_value_len = len;
  718. return S2N_SUCCESS;
  719. }
  720. }
  721. POSIX_BAIL(S2N_ERR_X509_EXTENSION_VALUE_NOT_FOUND);
  722. }
  723. int s2n_cert_get_x509_extension_value_length(struct s2n_cert *cert, const uint8_t *oid, uint32_t *ext_value_len)
  724. {
  725. POSIX_ENSURE_REF(cert);
  726. POSIX_ENSURE_REF(oid);
  727. POSIX_ENSURE_REF(ext_value_len);
  728. POSIX_GUARD(s2n_parse_x509_extension(cert, oid, NULL, ext_value_len, NULL));
  729. return S2N_SUCCESS;
  730. }
  731. int s2n_cert_get_x509_extension_value(struct s2n_cert *cert, const uint8_t *oid,
  732. uint8_t *ext_value, uint32_t *ext_value_len, bool *critical)
  733. {
  734. POSIX_ENSURE_REF(cert);
  735. POSIX_ENSURE_REF(oid);
  736. POSIX_ENSURE_REF(ext_value);
  737. POSIX_ENSURE_REF(ext_value_len);
  738. POSIX_ENSURE_REF(critical);
  739. POSIX_GUARD(s2n_parse_x509_extension(cert, oid, ext_value, ext_value_len, critical));
  740. return S2N_SUCCESS;
  741. }