2
0

cmp_genm.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /*
  2. * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright Siemens AG 2022
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. #include "cmp_local.h"
  11. #include <openssl/cmp_util.h>
  12. static const X509_VERIFY_PARAM *get0_trustedStore_vpm(const OSSL_CMP_CTX *ctx)
  13. {
  14. const X509_STORE *ts = OSSL_CMP_CTX_get0_trustedStore(ctx);
  15. return ts == NULL ? NULL : X509_STORE_get0_param(ts);
  16. }
  17. static void cert_msg(const char *func, const char *file, int lineno,
  18. OSSL_CMP_severity level, OSSL_CMP_CTX *ctx,
  19. const char *source, X509 *cert, const char *msg)
  20. {
  21. char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
  22. ossl_cmp_print_log(level, ctx, func, file, lineno,
  23. level == OSSL_CMP_LOG_WARNING ? "WARN" : "ERR",
  24. "certificate from '%s' with subject '%s' %s",
  25. source, subj, msg);
  26. OPENSSL_free(subj);
  27. }
  28. /* use |type_CA| -1 (no CA type check) or 0 (must be EE) or 1 (must be CA) */
  29. static int ossl_X509_check(OSSL_CMP_CTX *ctx, const char *source, X509 *cert,
  30. int type_CA, const X509_VERIFY_PARAM *vpm)
  31. {
  32. uint32_t ex_flags = X509_get_extension_flags(cert);
  33. int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert),
  34. X509_get0_notAfter(cert));
  35. int ret = res == 0;
  36. OSSL_CMP_severity level =
  37. vpm == NULL ? OSSL_CMP_LOG_WARNING : OSSL_CMP_LOG_ERR;
  38. if (!ret)
  39. cert_msg(OPENSSL_FUNC, OPENSSL_FILE, OPENSSL_LINE, level, ctx,
  40. source, cert, res > 0 ? "has expired" : "not yet valid");
  41. if (type_CA >= 0 && (ex_flags & EXFLAG_V1) == 0) {
  42. int is_CA = (ex_flags & EXFLAG_CA) != 0;
  43. if ((type_CA != 0) != is_CA) {
  44. cert_msg(OPENSSL_FUNC, OPENSSL_FILE, OPENSSL_LINE, level, ctx,
  45. source, cert,
  46. is_CA ? "is not an EE cert" : "is not a CA cert");
  47. ret = 0;
  48. }
  49. }
  50. return ret;
  51. }
  52. static int ossl_X509_check_all(OSSL_CMP_CTX *ctx, const char *source,
  53. STACK_OF(X509) *certs,
  54. int type_CA, const X509_VERIFY_PARAM *vpm)
  55. {
  56. int i;
  57. int ret = 1;
  58. for (i = 0; i < sk_X509_num(certs /* may be NULL */); i++)
  59. ret = ossl_X509_check(ctx, source,
  60. sk_X509_value(certs, i), type_CA, vpm)
  61. && ret; /* Having 'ret' after the '&&', all certs are checked. */
  62. return ret;
  63. }
  64. static OSSL_CMP_ITAV *get_genm_itav(OSSL_CMP_CTX *ctx,
  65. OSSL_CMP_ITAV *req, /* gets consumed */
  66. int expected, const char *desc)
  67. {
  68. STACK_OF(OSSL_CMP_ITAV) *itavs = NULL;
  69. int i, n;
  70. if (ctx == NULL) {
  71. ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
  72. goto err;
  73. }
  74. if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_unspecified) {
  75. ERR_raise_data(ERR_LIB_CMP, CMP_R_UNCLEAN_CTX,
  76. "client context in unsuitable state; should call CMPclient_reinit() before");
  77. goto err;
  78. }
  79. if (!OSSL_CMP_CTX_push0_genm_ITAV(ctx, req))
  80. goto err;
  81. req = NULL;
  82. itavs = OSSL_CMP_exec_GENM_ses(ctx);
  83. if (itavs == NULL) {
  84. if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_request)
  85. ERR_raise_data(ERR_LIB_CMP, CMP_R_GETTING_GENP,
  86. "with infoType %s", desc);
  87. return NULL;
  88. }
  89. if ((n = sk_OSSL_CMP_ITAV_num(itavs)) <= 0) {
  90. ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_GENP,
  91. "response on genm requesting infoType %s does not include suitable value", desc);
  92. sk_OSSL_CMP_ITAV_free(itavs);
  93. return NULL;
  94. }
  95. if (n > 1)
  96. ossl_cmp_log2(WARN, ctx,
  97. "response on genm contains %d ITAVs; will use the first ITAV with infoType id-it-%s",
  98. n, desc);
  99. for (i = 0; i < n; i++) {
  100. OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_shift(itavs);
  101. ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav);
  102. char name[128] = "genp contains InfoType '";
  103. size_t offset = strlen(name);
  104. if (OBJ_obj2nid(obj) == expected) {
  105. for (i++; i < n; i++)
  106. OSSL_CMP_ITAV_free(sk_OSSL_CMP_ITAV_shift(itavs));
  107. sk_OSSL_CMP_ITAV_free(itavs);
  108. return itav;
  109. }
  110. if (OBJ_obj2txt(name + offset, sizeof(name) - offset, obj, 0) < 0)
  111. strcat(name, "<unknown>");
  112. ossl_cmp_log2(WARN, ctx, "%s' while expecting 'id-it-%s'", name, desc);
  113. OSSL_CMP_ITAV_free(itav);
  114. }
  115. ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_GENP,
  116. "could not find any ITAV for %s", desc);
  117. err:
  118. sk_OSSL_CMP_ITAV_free(itavs);
  119. OSSL_CMP_ITAV_free(req);
  120. return NULL;
  121. }
  122. int OSSL_CMP_get1_caCerts(OSSL_CMP_CTX *ctx, STACK_OF(X509) **out)
  123. {
  124. OSSL_CMP_ITAV *req, *itav;
  125. STACK_OF(X509) *certs = NULL;
  126. int ret = 0;
  127. if (out == NULL) {
  128. ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
  129. return 0;
  130. }
  131. *out = NULL;
  132. if ((req = OSSL_CMP_ITAV_new_caCerts(NULL)) == NULL)
  133. return 0;
  134. if ((itav = get_genm_itav(ctx, req, NID_id_it_caCerts, "caCerts")) == NULL)
  135. return 0;
  136. if (!OSSL_CMP_ITAV_get0_caCerts(itav, &certs))
  137. goto end;
  138. ret = 1;
  139. if (certs == NULL) /* no CA certificate available */
  140. goto end;
  141. if (!ossl_X509_check_all(ctx, "genp", certs, 1 /* CA */,
  142. get0_trustedStore_vpm(ctx))) {
  143. ret = 0;
  144. goto end;
  145. }
  146. *out = sk_X509_new_reserve(NULL, sk_X509_num(certs));
  147. if (!X509_add_certs(*out, certs,
  148. X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) {
  149. sk_X509_pop_free(*out, X509_free);
  150. *out = NULL;
  151. ret = 0;
  152. }
  153. end:
  154. OSSL_CMP_ITAV_free(itav);
  155. return ret;
  156. }
  157. static int selfsigned_verify_cb(int ok, X509_STORE_CTX *store_ctx)
  158. {
  159. if (ok == 0
  160. && X509_STORE_CTX_get_error_depth(store_ctx) == 0
  161. && X509_STORE_CTX_get_error(store_ctx)
  162. == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {
  163. /* in this case, custom chain building */
  164. int i;
  165. STACK_OF(X509) *trust;
  166. STACK_OF(X509) *chain = X509_STORE_CTX_get0_chain(store_ctx);
  167. STACK_OF(X509) *untrusted = X509_STORE_CTX_get0_untrusted(store_ctx);
  168. X509_STORE_CTX_check_issued_fn check_issued =
  169. X509_STORE_CTX_get_check_issued(store_ctx);
  170. X509 *cert = sk_X509_value(chain, 0); /* target cert */
  171. X509 *issuer;
  172. for (i = 0; i < sk_X509_num(untrusted); i++) {
  173. cert = sk_X509_value(untrusted, i);
  174. if (!X509_add_cert(chain, cert, X509_ADD_FLAG_UP_REF))
  175. return 0;
  176. }
  177. trust = X509_STORE_get1_all_certs(X509_STORE_CTX_get0_store(store_ctx));
  178. for (i = 0; i < sk_X509_num(trust); i++) {
  179. issuer = sk_X509_value(trust, i);
  180. if ((*check_issued)(store_ctx, cert, issuer)) {
  181. if (X509_add_cert(chain, cert, X509_ADD_FLAG_UP_REF))
  182. ok = 1;
  183. break;
  184. }
  185. }
  186. sk_X509_pop_free(trust, X509_free);
  187. return ok;
  188. } else {
  189. X509_STORE *ts = X509_STORE_CTX_get0_store(store_ctx);
  190. X509_STORE_CTX_verify_cb verify_cb;
  191. if (ts == NULL || (verify_cb = X509_STORE_get_verify_cb(ts)) == NULL)
  192. return ok;
  193. return (*verify_cb)(ok, store_ctx);
  194. }
  195. }
  196. /* vanilla X509_verify_cert() does not support self-signed certs as target */
  197. static int verify_ss_cert(OSSL_LIB_CTX *libctx, const char *propq,
  198. X509_STORE *ts, STACK_OF(X509) *untrusted,
  199. X509 *target)
  200. {
  201. X509_STORE_CTX *csc = NULL;
  202. int ok = 0;
  203. if (ts == NULL || target == NULL) {
  204. ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER);
  205. return 0;
  206. }
  207. if ((csc = X509_STORE_CTX_new_ex(libctx, propq)) == NULL
  208. || !X509_STORE_CTX_init(csc, ts, target, untrusted))
  209. goto err;
  210. X509_STORE_CTX_set_verify_cb(csc, selfsigned_verify_cb);
  211. ok = X509_verify_cert(csc) > 0;
  212. err:
  213. X509_STORE_CTX_free(csc);
  214. return ok;
  215. }
  216. static int
  217. verify_ss_cert_trans(OSSL_CMP_CTX *ctx, X509 *trusted /* may be NULL */,
  218. X509 *trans /* the only untrusted cert, may be NULL */,
  219. X509 *target, const char *desc)
  220. {
  221. X509_STORE *ts = OSSL_CMP_CTX_get0_trusted(ctx);
  222. STACK_OF(X509) *untrusted = NULL;
  223. int res = 0;
  224. if (trusted != NULL) {
  225. X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts);
  226. if ((ts = X509_STORE_new()) == NULL)
  227. return 0;
  228. if (!X509_STORE_set1_param(ts, vpm)
  229. || !X509_STORE_add_cert(ts, trusted))
  230. goto err;
  231. }
  232. if (trans != NULL
  233. && !ossl_x509_add_cert_new(&untrusted, trans, X509_ADD_FLAG_UP_REF))
  234. goto err;
  235. res = verify_ss_cert(OSSL_CMP_CTX_get0_libctx(ctx),
  236. OSSL_CMP_CTX_get0_propq(ctx),
  237. ts, untrusted, target);
  238. if (!res)
  239. ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_ROOTCAKEYUPDATE,
  240. "failed to validate %s certificate received in genp %s",
  241. desc, trusted == NULL ? "using trust store"
  242. : "with given certificate as trust anchor");
  243. err:
  244. sk_X509_pop_free(untrusted, X509_free);
  245. if (trusted != NULL)
  246. X509_STORE_free(ts);
  247. return res;
  248. }
  249. int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx,
  250. const X509 *oldWithOld, X509 **newWithNew,
  251. X509 **newWithOld, X509 **oldWithNew)
  252. {
  253. X509 *oldWithOld_copy = NULL, *my_newWithOld, *my_oldWithNew;
  254. OSSL_CMP_ITAV *req, *itav;
  255. int res = 0;
  256. if (newWithNew == NULL) {
  257. ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER);
  258. return 0;
  259. }
  260. *newWithNew = NULL;
  261. if ((req = OSSL_CMP_ITAV_new_rootCaCert(oldWithOld)) == NULL)
  262. return 0;
  263. itav = get_genm_itav(ctx, req, NID_id_it_rootCaKeyUpdate, "rootCaKeyUpdate");
  264. if (itav == NULL)
  265. return 0;
  266. if (!OSSL_CMP_ITAV_get0_rootCaKeyUpdate(itav, newWithNew,
  267. &my_newWithOld, &my_oldWithNew))
  268. goto end;
  269. if (*newWithNew == NULL) /* no root CA cert update available */
  270. goto end;
  271. if ((oldWithOld_copy = X509_dup(oldWithOld)) == NULL && oldWithOld != NULL)
  272. goto end;
  273. if (!verify_ss_cert_trans(ctx, oldWithOld_copy, my_newWithOld,
  274. *newWithNew, "newWithNew")) {
  275. ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ROOTCAKEYUPDATE);
  276. goto end;
  277. }
  278. if (oldWithOld != NULL && my_oldWithNew != NULL
  279. && !verify_ss_cert_trans(ctx, *newWithNew, my_oldWithNew,
  280. oldWithOld_copy, "oldWithOld")) {
  281. ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ROOTCAKEYUPDATE);
  282. goto end;
  283. }
  284. if (!X509_up_ref(*newWithNew))
  285. goto end;
  286. if (newWithOld != NULL &&
  287. (*newWithOld = my_newWithOld) != NULL && !X509_up_ref(*newWithOld))
  288. goto free;
  289. if (oldWithNew == NULL ||
  290. (*oldWithNew = my_oldWithNew) == NULL || X509_up_ref(*oldWithNew)) {
  291. res = 1;
  292. goto end;
  293. }
  294. if (newWithOld != NULL)
  295. X509_free(*newWithOld);
  296. free:
  297. X509_free(*newWithNew);
  298. end:
  299. OSSL_CMP_ITAV_free(itav);
  300. X509_free(oldWithOld_copy);
  301. return res;
  302. }