s2n_crl.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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 "s2n_crl.h"
  16. #include "tls/s2n_connection.h"
  17. struct s2n_crl *s2n_crl_new(void)
  18. {
  19. DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
  20. PTR_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_crl)));
  21. PTR_GUARD_POSIX(s2n_blob_zero(&mem));
  22. struct s2n_crl *crl = (struct s2n_crl *) (void *) mem.data;
  23. ZERO_TO_DISABLE_DEFER_CLEANUP(mem);
  24. return crl;
  25. }
  26. int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len)
  27. {
  28. POSIX_ENSURE_REF(crl);
  29. POSIX_ENSURE(crl->crl == NULL, S2N_ERR_INVALID_ARGUMENT);
  30. struct s2n_blob pem_blob = { 0 };
  31. POSIX_GUARD(s2n_blob_init(&pem_blob, pem, len));
  32. struct s2n_stuffer pem_stuffer = { 0 };
  33. POSIX_GUARD(s2n_stuffer_init(&pem_stuffer, &pem_blob));
  34. POSIX_GUARD(s2n_stuffer_skip_write(&pem_stuffer, pem_blob.size));
  35. DEFER_CLEANUP(struct s2n_stuffer der_out_stuffer = { 0 }, s2n_stuffer_free);
  36. POSIX_GUARD(s2n_stuffer_growable_alloc(&der_out_stuffer, len));
  37. POSIX_GUARD(s2n_stuffer_crl_from_pem(&pem_stuffer, &der_out_stuffer));
  38. uint32_t data_size = s2n_stuffer_data_available(&der_out_stuffer);
  39. const uint8_t *data = s2n_stuffer_raw_read(&der_out_stuffer, data_size);
  40. POSIX_ENSURE_REF(data);
  41. crl->crl = d2i_X509_CRL(NULL, &data, data_size);
  42. POSIX_ENSURE(crl->crl != NULL, S2N_ERR_INVALID_PEM);
  43. return S2N_SUCCESS;
  44. }
  45. int s2n_crl_free(struct s2n_crl **crl)
  46. {
  47. if (crl == NULL) {
  48. return S2N_SUCCESS;
  49. }
  50. if (*crl == NULL) {
  51. return S2N_SUCCESS;
  52. }
  53. if ((*crl)->crl != NULL) {
  54. X509_CRL_free((*crl)->crl);
  55. (*crl)->crl = NULL;
  56. }
  57. POSIX_GUARD(s2n_free_object((uint8_t **) crl, sizeof(struct s2n_crl)));
  58. *crl = NULL;
  59. return S2N_SUCCESS;
  60. }
  61. int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash)
  62. {
  63. POSIX_ENSURE_REF(crl);
  64. POSIX_ENSURE_REF(crl->crl);
  65. POSIX_ENSURE_REF(hash);
  66. X509_NAME *crl_name = X509_CRL_get_issuer(crl->crl);
  67. POSIX_ENSURE_REF(crl_name);
  68. unsigned long temp_hash = X509_NAME_hash(crl_name);
  69. POSIX_ENSURE(temp_hash != 0, S2N_ERR_INTERNAL_LIBCRYPTO_ERROR);
  70. *hash = temp_hash;
  71. return S2N_SUCCESS;
  72. }
  73. int s2n_crl_validate_active(struct s2n_crl *crl)
  74. {
  75. POSIX_ENSURE_REF(crl);
  76. POSIX_ENSURE_REF(crl->crl);
  77. ASN1_TIME *this_update = X509_CRL_get_lastUpdate(crl->crl);
  78. POSIX_ENSURE_REF(this_update);
  79. int ret = X509_cmp_time(this_update, NULL);
  80. POSIX_ENSURE(ret != 0, S2N_ERR_CRL_INVALID_THIS_UPDATE);
  81. POSIX_ENSURE(ret < 0, S2N_ERR_CRL_NOT_YET_VALID);
  82. return S2N_SUCCESS;
  83. }
  84. int s2n_crl_validate_not_expired(struct s2n_crl *crl)
  85. {
  86. POSIX_ENSURE_REF(crl);
  87. POSIX_ENSURE_REF(crl->crl);
  88. ASN1_TIME *next_update = X509_CRL_get_nextUpdate(crl->crl);
  89. if (next_update == NULL) {
  90. /* If the CRL has no nextUpdate field, assume it will never expire */
  91. return S2N_SUCCESS;
  92. }
  93. int ret = X509_cmp_time(next_update, NULL);
  94. POSIX_ENSURE(ret != 0, S2N_ERR_CRL_INVALID_NEXT_UPDATE);
  95. POSIX_ENSURE(ret > 0, S2N_ERR_CRL_EXPIRED);
  96. return S2N_SUCCESS;
  97. }
  98. S2N_RESULT s2n_crl_get_crls_from_lookup_list(struct s2n_x509_validator *validator, STACK_OF(X509_CRL) *crl_stack)
  99. {
  100. RESULT_ENSURE_REF(validator);
  101. RESULT_ENSURE_REF(validator->crl_lookup_list);
  102. RESULT_ENSURE_REF(crl_stack);
  103. uint32_t num_lookups = 0;
  104. RESULT_GUARD(s2n_array_num_elements(validator->crl_lookup_list, &num_lookups));
  105. for (uint32_t i = 0; i < num_lookups; i++) {
  106. struct s2n_crl_lookup *lookup = NULL;
  107. RESULT_GUARD(s2n_array_get(validator->crl_lookup_list, i, (void **) &lookup));
  108. RESULT_ENSURE_REF(lookup);
  109. if (lookup->crl == NULL) {
  110. /* A CRL was intentionally not returned from the callback. Don't add anything to the stack*/
  111. continue;
  112. }
  113. RESULT_ENSURE_REF(lookup->crl->crl);
  114. if (!sk_X509_CRL_push(crl_stack, lookup->crl->crl)) {
  115. RESULT_BAIL(S2N_ERR_INTERNAL_LIBCRYPTO_ERROR);
  116. }
  117. }
  118. return S2N_RESULT_OK;
  119. }
  120. static S2N_RESULT s2n_crl_get_lookup_callback_status(struct s2n_x509_validator *validator, crl_lookup_callback_status *status)
  121. {
  122. RESULT_ENSURE_REF(validator);
  123. RESULT_ENSURE_REF(validator->crl_lookup_list);
  124. uint32_t num_lookups = 0;
  125. RESULT_GUARD(s2n_array_num_elements(validator->crl_lookup_list, &num_lookups));
  126. for (uint32_t i = 0; i < num_lookups; i++) {
  127. struct s2n_crl_lookup *lookup = NULL;
  128. RESULT_GUARD(s2n_array_get(validator->crl_lookup_list, i, (void **) &lookup));
  129. RESULT_ENSURE_REF(lookup);
  130. if (lookup->status == AWAITING_RESPONSE) {
  131. *status = AWAITING_RESPONSE;
  132. return S2N_RESULT_OK;
  133. }
  134. }
  135. *status = FINISHED;
  136. return S2N_RESULT_OK;
  137. }
  138. S2N_RESULT s2n_crl_handle_lookup_callback_result(struct s2n_x509_validator *validator)
  139. {
  140. RESULT_ENSURE_REF(validator);
  141. crl_lookup_callback_status status = 0;
  142. RESULT_GUARD(s2n_crl_get_lookup_callback_status(validator, &status));
  143. switch (status) {
  144. case FINISHED:
  145. validator->state = READY_TO_VERIFY;
  146. return S2N_RESULT_OK;
  147. case AWAITING_RESPONSE:
  148. validator->state = AWAITING_CRL_CALLBACK;
  149. RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED);
  150. default:
  151. RESULT_BAIL(S2N_ERR_INVALID_CERT_STATE);
  152. }
  153. }
  154. S2N_RESULT s2n_crl_invoke_lookup_callbacks(struct s2n_connection *conn, struct s2n_x509_validator *validator)
  155. {
  156. RESULT_ENSURE_REF(validator);
  157. RESULT_ENSURE_REF(validator->cert_chain_from_wire);
  158. int cert_count = sk_X509_num(validator->cert_chain_from_wire);
  159. DEFER_CLEANUP(struct s2n_array *crl_lookup_list = s2n_array_new_with_capacity(sizeof(struct s2n_crl_lookup), cert_count),
  160. s2n_array_free_p);
  161. RESULT_ENSURE_REF(crl_lookup_list);
  162. for (int i = 0; i < cert_count; ++i) {
  163. struct s2n_crl_lookup *lookup = NULL;
  164. RESULT_GUARD(s2n_array_pushback(crl_lookup_list, (void **) &lookup));
  165. X509 *cert = sk_X509_value(validator->cert_chain_from_wire, i);
  166. RESULT_ENSURE_REF(cert);
  167. lookup->cert = cert;
  168. lookup->cert_idx = i;
  169. }
  170. validator->crl_lookup_list = crl_lookup_list;
  171. ZERO_TO_DISABLE_DEFER_CLEANUP(crl_lookup_list);
  172. /* Invoke the crl lookup callbacks after the crl_lookup_list is stored on the validator. This ensures that if a
  173. * callback fails, the memory for all other callbacks that may still be running remains allocated */
  174. uint32_t num_lookups = 0;
  175. RESULT_GUARD(s2n_array_num_elements(validator->crl_lookup_list, &num_lookups));
  176. for (uint32_t i = 0; i < num_lookups; i++) {
  177. struct s2n_crl_lookup *lookup = NULL;
  178. RESULT_GUARD(s2n_array_get(validator->crl_lookup_list, i, (void **) &lookup));
  179. RESULT_ENSURE_REF(lookup);
  180. int result = conn->config->crl_lookup_cb(lookup, conn->config->crl_lookup_ctx);
  181. RESULT_ENSURE(result == S2N_SUCCESS, S2N_ERR_CANCELLED);
  182. }
  183. return S2N_RESULT_OK;
  184. }
  185. int s2n_crl_ossl_verify_callback(int default_ossl_ret, X509_STORE_CTX *ctx)
  186. {
  187. int err = X509_STORE_CTX_get_error(ctx);
  188. switch (err) {
  189. case X509_V_ERR_CRL_NOT_YET_VALID:
  190. case X509_V_ERR_CRL_HAS_EXPIRED:
  191. case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
  192. case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
  193. return 1;
  194. default:
  195. return default_ossl_ret;
  196. }
  197. }
  198. int s2n_crl_lookup_get_cert_issuer_hash(struct s2n_crl_lookup *lookup, uint64_t *hash)
  199. {
  200. POSIX_ENSURE_REF(lookup);
  201. POSIX_ENSURE_REF(lookup->cert);
  202. POSIX_ENSURE_REF(hash);
  203. unsigned long temp_hash = X509_issuer_name_hash(lookup->cert);
  204. POSIX_ENSURE(temp_hash != 0, S2N_ERR_INTERNAL_LIBCRYPTO_ERROR);
  205. *hash = temp_hash;
  206. return S2N_SUCCESS;
  207. }
  208. int s2n_crl_lookup_set(struct s2n_crl_lookup *lookup, struct s2n_crl *crl)
  209. {
  210. POSIX_ENSURE_REF(lookup);
  211. POSIX_ENSURE_REF(crl);
  212. lookup->crl = crl;
  213. lookup->status = FINISHED;
  214. return S2N_SUCCESS;
  215. }
  216. int s2n_crl_lookup_ignore(struct s2n_crl_lookup *lookup)
  217. {
  218. POSIX_ENSURE_REF(lookup);
  219. lookup->crl = NULL;
  220. lookup->status = FINISHED;
  221. return S2N_SUCCESS;
  222. }