verify_extra_test.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <openssl/crypto.h>
  12. #include <openssl/bio.h>
  13. #include <openssl/x509.h>
  14. #include <openssl/pem.h>
  15. #include <openssl/err.h>
  16. #include "testutil.h"
  17. DEFINE_STACK_OF(X509)
  18. static const char *root_f;
  19. static const char *roots_f;
  20. static const char *untrusted_f;
  21. static const char *bad_f;
  22. static const char *req_f;
  23. static X509 *load_cert_from_file(const char *filename)
  24. {
  25. X509 *cert = NULL;
  26. BIO *bio;
  27. bio = BIO_new_file(filename, "r");
  28. if (bio != NULL)
  29. cert = PEM_read_bio_X509(bio, NULL, 0, NULL);
  30. BIO_free(bio);
  31. return cert;
  32. }
  33. static STACK_OF(X509) *load_certs_from_file(const char *filename)
  34. {
  35. STACK_OF(X509) *certs;
  36. BIO *bio;
  37. X509 *x;
  38. bio = BIO_new_file(filename, "r");
  39. if (bio == NULL) {
  40. return NULL;
  41. }
  42. certs = sk_X509_new_null();
  43. if (certs == NULL) {
  44. BIO_free(bio);
  45. return NULL;
  46. }
  47. ERR_set_mark();
  48. do {
  49. x = PEM_read_bio_X509(bio, NULL, 0, NULL);
  50. if (x != NULL && !sk_X509_push(certs, x)) {
  51. sk_X509_pop_free(certs, X509_free);
  52. BIO_free(bio);
  53. return NULL;
  54. } else if (x == NULL) {
  55. /*
  56. * We probably just ran out of certs, so ignore any errors
  57. * generated
  58. */
  59. ERR_pop_to_mark();
  60. }
  61. } while (x != NULL);
  62. BIO_free(bio);
  63. return certs;
  64. }
  65. /*
  66. * Test for CVE-2015-1793 (Alternate Chains Certificate Forgery)
  67. *
  68. * Chain is as follows:
  69. *
  70. * rootCA (self-signed)
  71. * |
  72. * interCA
  73. * |
  74. * subinterCA subinterCA (self-signed)
  75. * | |
  76. * leaf ------------------
  77. * |
  78. * bad
  79. *
  80. * rootCA, interCA, subinterCA, subinterCA (ss) all have CA=TRUE
  81. * leaf and bad have CA=FALSE
  82. *
  83. * subinterCA and subinterCA (ss) have the same subject name and keys
  84. *
  85. * interCA (but not rootCA) and subinterCA (ss) are in the trusted store
  86. * (roots.pem)
  87. * leaf and subinterCA are in the untrusted list (untrusted.pem)
  88. * bad is the certificate being verified (bad.pem)
  89. *
  90. * Versions vulnerable to CVE-2015-1793 will fail to detect that leaf has
  91. * CA=FALSE, and will therefore incorrectly verify bad
  92. *
  93. */
  94. static int test_alt_chains_cert_forgery(void)
  95. {
  96. int ret = 0;
  97. int i;
  98. X509 *x = NULL;
  99. STACK_OF(X509) *untrusted = NULL;
  100. X509_STORE_CTX *sctx = NULL;
  101. X509_STORE *store = NULL;
  102. X509_LOOKUP *lookup = NULL;
  103. store = X509_STORE_new();
  104. if (store == NULL)
  105. goto err;
  106. lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
  107. if (lookup == NULL)
  108. goto err;
  109. if (!X509_LOOKUP_load_file(lookup, roots_f, X509_FILETYPE_PEM))
  110. goto err;
  111. untrusted = load_certs_from_file(untrusted_f);
  112. if ((x = load_cert_from_file(bad_f)) == NULL)
  113. goto err;
  114. sctx = X509_STORE_CTX_new();
  115. if (sctx == NULL)
  116. goto err;
  117. if (!X509_STORE_CTX_init(sctx, store, x, untrusted))
  118. goto err;
  119. i = X509_verify_cert(sctx);
  120. if (i == 0 && X509_STORE_CTX_get_error(sctx) == X509_V_ERR_INVALID_CA) {
  121. /* This is the result we were expecting: Test passed */
  122. ret = 1;
  123. }
  124. err:
  125. X509_STORE_CTX_free(sctx);
  126. X509_free(x);
  127. sk_X509_pop_free(untrusted, X509_free);
  128. X509_STORE_free(store);
  129. return ret;
  130. }
  131. static int test_store_ctx(void)
  132. {
  133. X509_STORE_CTX *sctx = NULL;
  134. X509 *x = NULL;
  135. int testresult = 0, ret;
  136. x = load_cert_from_file(bad_f);
  137. if (x == NULL)
  138. goto err;
  139. sctx = X509_STORE_CTX_new();
  140. if (sctx == NULL)
  141. goto err;
  142. if (!X509_STORE_CTX_init(sctx, NULL, x, NULL))
  143. goto err;
  144. /* Verifying a cert where we have no trusted certs should fail */
  145. ret = X509_verify_cert(sctx);
  146. if (ret == 0) {
  147. /* This is the result we were expecting: Test passed */
  148. testresult = 1;
  149. }
  150. err:
  151. X509_STORE_CTX_free(sctx);
  152. X509_free(x);
  153. return testresult;
  154. }
  155. OPT_TEST_DECLARE_USAGE("roots.pem untrusted.pem bad.pem\n")
  156. static int test_distinguishing_id(void)
  157. {
  158. X509 *x = NULL;
  159. int ret = 0;
  160. ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
  161. char *distid = "this is an ID";
  162. x = load_cert_from_file(bad_f);
  163. if (x == NULL)
  164. goto err;
  165. v = ASN1_OCTET_STRING_new();
  166. if (v == NULL)
  167. goto err;
  168. if (!ASN1_OCTET_STRING_set(v, (unsigned char *)distid,
  169. (int)strlen(distid))) {
  170. ASN1_OCTET_STRING_free(v);
  171. goto err;
  172. }
  173. X509_set0_distinguishing_id(x, v);
  174. v2 = X509_get0_distinguishing_id(x);
  175. if (!TEST_ptr(v2)
  176. || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
  177. goto err;
  178. ret = 1;
  179. err:
  180. X509_free(x);
  181. return ret;
  182. }
  183. static int test_req_distinguishing_id(void)
  184. {
  185. X509_REQ *x = NULL;
  186. BIO *bio = NULL;
  187. int ret = 0;
  188. ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
  189. char *distid = "this is an ID";
  190. bio = BIO_new_file(req_f, "r");
  191. if (bio == NULL)
  192. goto err;
  193. x = PEM_read_bio_X509_REQ(bio, NULL, 0, NULL);
  194. if (x == NULL)
  195. goto err;
  196. v = ASN1_OCTET_STRING_new();
  197. if (v == NULL)
  198. goto err;
  199. if (!ASN1_OCTET_STRING_set(v, (unsigned char *)distid,
  200. (int)strlen(distid))) {
  201. ASN1_OCTET_STRING_free(v);
  202. goto err;
  203. }
  204. X509_REQ_set0_distinguishing_id(x, v);
  205. v2 = X509_REQ_get0_distinguishing_id(x);
  206. if (!TEST_ptr(v2)
  207. || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
  208. goto err;
  209. ret = 1;
  210. err:
  211. X509_REQ_free(x);
  212. BIO_free(bio);
  213. return ret;
  214. }
  215. static int test_self_signed(const char *filename, int expected)
  216. {
  217. X509 *cert;
  218. int ret;
  219. cert = load_cert_from_file(filename); /* may result in NULL */
  220. ret = TEST_int_eq(X509_self_signed(cert, 1), expected);
  221. X509_free(cert);
  222. return ret;
  223. }
  224. static int test_self_signed_good(void)
  225. {
  226. return test_self_signed(root_f, 1);
  227. }
  228. static int test_self_signed_bad(void)
  229. {
  230. return test_self_signed(bad_f, 0);
  231. }
  232. static int test_self_signed_error(void)
  233. {
  234. return test_self_signed("nonexistent file name", -1);
  235. }
  236. int setup_tests(void)
  237. {
  238. if (!test_skip_common_options()) {
  239. TEST_error("Error parsing test options\n");
  240. return 0;
  241. }
  242. if (!TEST_ptr(root_f = test_get_argument(0))
  243. || !TEST_ptr(roots_f = test_get_argument(1))
  244. || !TEST_ptr(untrusted_f = test_get_argument(2))
  245. || !TEST_ptr(bad_f = test_get_argument(3))
  246. || !TEST_ptr(req_f = test_get_argument(4)))
  247. return 0;
  248. ADD_TEST(test_alt_chains_cert_forgery);
  249. ADD_TEST(test_store_ctx);
  250. ADD_TEST(test_distinguishing_id);
  251. ADD_TEST(test_req_distinguishing_id);
  252. ADD_TEST(test_self_signed_good);
  253. ADD_TEST(test_self_signed_bad);
  254. ADD_TEST(test_self_signed_error);
  255. return 1;
  256. }