v3_crld.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /*
  2. * Copyright 1999-2024 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 "internal/cryptlib.h"
  11. #include <openssl/conf.h>
  12. #include <openssl/asn1.h>
  13. #include <openssl/asn1t.h>
  14. #include <openssl/x509v3.h>
  15. #include "crypto/x509.h"
  16. #include "ext_dat.h"
  17. #include "x509_local.h"
  18. static void *v2i_crld(const X509V3_EXT_METHOD *method,
  19. X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
  20. static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
  21. int indent);
  22. const X509V3_EXT_METHOD ossl_v3_crld = {
  23. NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
  24. 0, 0, 0, 0,
  25. 0, 0,
  26. 0,
  27. v2i_crld,
  28. i2r_crldp, 0,
  29. NULL
  30. };
  31. const X509V3_EXT_METHOD ossl_v3_freshest_crl = {
  32. NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
  33. 0, 0, 0, 0,
  34. 0, 0,
  35. 0,
  36. v2i_crld,
  37. i2r_crldp, 0,
  38. NULL
  39. };
  40. static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx,
  41. char *sect)
  42. {
  43. STACK_OF(CONF_VALUE) *gnsect;
  44. STACK_OF(GENERAL_NAME) *gens;
  45. if (*sect == '@')
  46. gnsect = X509V3_get_section(ctx, sect + 1);
  47. else
  48. gnsect = X509V3_parse_list(sect);
  49. if (!gnsect) {
  50. ERR_raise(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND);
  51. return NULL;
  52. }
  53. gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
  54. if (*sect == '@')
  55. X509V3_section_free(ctx, gnsect);
  56. else
  57. sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
  58. return gens;
  59. }
  60. static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
  61. CONF_VALUE *cnf)
  62. {
  63. STACK_OF(GENERAL_NAME) *fnm = NULL;
  64. STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
  65. if (cnf->value == NULL) {
  66. ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE);
  67. goto err;
  68. }
  69. if (HAS_PREFIX(cnf->name, "fullname")) {
  70. fnm = gnames_from_sectname(ctx, cnf->value);
  71. if (!fnm)
  72. goto err;
  73. } else if (strcmp(cnf->name, "relativename") == 0) {
  74. int ret;
  75. STACK_OF(CONF_VALUE) *dnsect;
  76. X509_NAME *nm;
  77. nm = X509_NAME_new();
  78. if (nm == NULL)
  79. return -1;
  80. dnsect = X509V3_get_section(ctx, cnf->value);
  81. if (!dnsect) {
  82. X509_NAME_free(nm);
  83. ERR_raise(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND);
  84. return -1;
  85. }
  86. ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
  87. X509V3_section_free(ctx, dnsect);
  88. rnm = nm->entries;
  89. nm->entries = NULL;
  90. X509_NAME_free(nm);
  91. if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
  92. goto err;
  93. /*
  94. * Since its a name fragment can't have more than one RDNSequence
  95. */
  96. if (sk_X509_NAME_ENTRY_value(rnm,
  97. sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
  98. ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
  99. goto err;
  100. }
  101. } else
  102. return 0;
  103. if (*pdp) {
  104. ERR_raise(ERR_LIB_X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
  105. goto err;
  106. }
  107. *pdp = DIST_POINT_NAME_new();
  108. if (*pdp == NULL)
  109. goto err;
  110. if (fnm) {
  111. (*pdp)->type = 0;
  112. (*pdp)->name.fullname = fnm;
  113. } else {
  114. (*pdp)->type = 1;
  115. (*pdp)->name.relativename = rnm;
  116. }
  117. return 1;
  118. err:
  119. sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
  120. sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
  121. return -1;
  122. }
  123. static const BIT_STRING_BITNAME reason_flags[] = {
  124. {0, "Unused", "unused"},
  125. {1, "Key Compromise", "keyCompromise"},
  126. {2, "CA Compromise", "CACompromise"},
  127. {3, "Affiliation Changed", "affiliationChanged"},
  128. {4, "Superseded", "superseded"},
  129. {5, "Cessation Of Operation", "cessationOfOperation"},
  130. {6, "Certificate Hold", "certificateHold"},
  131. {7, "Privilege Withdrawn", "privilegeWithdrawn"},
  132. {8, "AA Compromise", "AACompromise"},
  133. {-1, NULL, NULL}
  134. };
  135. static int set_reasons(ASN1_BIT_STRING **preas, char *value)
  136. {
  137. STACK_OF(CONF_VALUE) *rsk = NULL;
  138. const BIT_STRING_BITNAME *pbn;
  139. const char *bnam;
  140. int i, ret = 0;
  141. rsk = X509V3_parse_list(value);
  142. if (rsk == NULL)
  143. return 0;
  144. if (*preas != NULL)
  145. goto err;
  146. for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
  147. bnam = sk_CONF_VALUE_value(rsk, i)->name;
  148. if (*preas == NULL) {
  149. *preas = ASN1_BIT_STRING_new();
  150. if (*preas == NULL)
  151. goto err;
  152. }
  153. for (pbn = reason_flags; pbn->lname; pbn++) {
  154. if (strcmp(pbn->sname, bnam) == 0) {
  155. if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1))
  156. goto err;
  157. break;
  158. }
  159. }
  160. if (pbn->lname == NULL)
  161. goto err;
  162. }
  163. ret = 1;
  164. err:
  165. sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
  166. return ret;
  167. }
  168. static int print_reasons(BIO *out, const char *rname,
  169. ASN1_BIT_STRING *rflags, int indent)
  170. {
  171. int first = 1;
  172. const BIT_STRING_BITNAME *pbn;
  173. BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
  174. for (pbn = reason_flags; pbn->lname; pbn++) {
  175. if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
  176. if (first)
  177. first = 0;
  178. else
  179. BIO_puts(out, ", ");
  180. BIO_puts(out, pbn->lname);
  181. }
  182. }
  183. if (first)
  184. BIO_puts(out, "<EMPTY>\n");
  185. else
  186. BIO_puts(out, "\n");
  187. return 1;
  188. }
  189. static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
  190. STACK_OF(CONF_VALUE) *nval)
  191. {
  192. int i;
  193. CONF_VALUE *cnf;
  194. DIST_POINT *point = DIST_POINT_new();
  195. if (point == NULL)
  196. goto err;
  197. for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
  198. int ret;
  199. cnf = sk_CONF_VALUE_value(nval, i);
  200. ret = set_dist_point_name(&point->distpoint, ctx, cnf);
  201. if (ret > 0)
  202. continue;
  203. if (ret < 0)
  204. goto err;
  205. if (strcmp(cnf->name, "reasons") == 0) {
  206. if (!set_reasons(&point->reasons, cnf->value))
  207. goto err;
  208. } else if (strcmp(cnf->name, "CRLissuer") == 0) {
  209. point->CRLissuer = gnames_from_sectname(ctx, cnf->value);
  210. if (point->CRLissuer == NULL)
  211. goto err;
  212. }
  213. }
  214. return point;
  215. err:
  216. DIST_POINT_free(point);
  217. return NULL;
  218. }
  219. static void *v2i_crld(const X509V3_EXT_METHOD *method,
  220. X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
  221. {
  222. STACK_OF(DIST_POINT) *crld;
  223. GENERAL_NAMES *gens = NULL;
  224. GENERAL_NAME *gen = NULL;
  225. CONF_VALUE *cnf;
  226. const int num = sk_CONF_VALUE_num(nval);
  227. int i;
  228. crld = sk_DIST_POINT_new_reserve(NULL, num);
  229. if (crld == NULL) {
  230. ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB);
  231. goto err;
  232. }
  233. for (i = 0; i < num; i++) {
  234. DIST_POINT *point;
  235. cnf = sk_CONF_VALUE_value(nval, i);
  236. if (cnf->value == NULL) {
  237. STACK_OF(CONF_VALUE) *dpsect;
  238. dpsect = X509V3_get_section(ctx, cnf->name);
  239. if (!dpsect)
  240. goto err;
  241. point = crldp_from_section(ctx, dpsect);
  242. X509V3_section_free(ctx, dpsect);
  243. if (point == NULL)
  244. goto err;
  245. sk_DIST_POINT_push(crld, point); /* no failure as it was reserved */
  246. } else {
  247. if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
  248. goto err;
  249. if ((gens = GENERAL_NAMES_new()) == NULL) {
  250. ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
  251. goto err;
  252. }
  253. if (!sk_GENERAL_NAME_push(gens, gen)) {
  254. ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB);
  255. goto err;
  256. }
  257. gen = NULL;
  258. if ((point = DIST_POINT_new()) == NULL) {
  259. ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
  260. goto err;
  261. }
  262. sk_DIST_POINT_push(crld, point); /* no failure as it was reserved */
  263. if ((point->distpoint = DIST_POINT_NAME_new()) == NULL) {
  264. ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
  265. goto err;
  266. }
  267. point->distpoint->name.fullname = gens;
  268. point->distpoint->type = 0;
  269. gens = NULL;
  270. }
  271. }
  272. return crld;
  273. err:
  274. GENERAL_NAME_free(gen);
  275. GENERAL_NAMES_free(gens);
  276. sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
  277. return NULL;
  278. }
  279. static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
  280. void *exarg)
  281. {
  282. DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
  283. switch (operation) {
  284. case ASN1_OP_NEW_POST:
  285. dpn->dpname = NULL;
  286. break;
  287. case ASN1_OP_FREE_POST:
  288. X509_NAME_free(dpn->dpname);
  289. break;
  290. }
  291. return 1;
  292. }
  293. ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
  294. ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
  295. ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
  296. } ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
  297. IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
  298. ASN1_SEQUENCE(DIST_POINT) = {
  299. ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
  300. ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
  301. ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
  302. } ASN1_SEQUENCE_END(DIST_POINT)
  303. IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
  304. ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
  305. ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
  306. ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
  307. IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
  308. ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
  309. ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
  310. ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
  311. ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
  312. ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
  313. ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
  314. ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
  315. } ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
  316. IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
  317. static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
  318. int indent);
  319. static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
  320. STACK_OF(CONF_VALUE) *nval);
  321. const X509V3_EXT_METHOD ossl_v3_idp = {
  322. NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
  323. ASN1_ITEM_ref(ISSUING_DIST_POINT),
  324. 0, 0, 0, 0,
  325. 0, 0,
  326. 0,
  327. v2i_idp,
  328. i2r_idp, 0,
  329. NULL
  330. };
  331. static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
  332. STACK_OF(CONF_VALUE) *nval)
  333. {
  334. ISSUING_DIST_POINT *idp = NULL;
  335. CONF_VALUE *cnf;
  336. char *name, *val;
  337. int i, ret;
  338. idp = ISSUING_DIST_POINT_new();
  339. if (idp == NULL) {
  340. ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
  341. goto err;
  342. }
  343. for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
  344. cnf = sk_CONF_VALUE_value(nval, i);
  345. name = cnf->name;
  346. val = cnf->value;
  347. ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
  348. if (ret > 0)
  349. continue;
  350. if (ret < 0)
  351. goto err;
  352. if (strcmp(name, "onlyuser") == 0) {
  353. if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
  354. goto err;
  355. } else if (strcmp(name, "onlyCA") == 0) {
  356. if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
  357. goto err;
  358. } else if (strcmp(name, "onlyAA") == 0) {
  359. if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
  360. goto err;
  361. } else if (strcmp(name, "indirectCRL") == 0) {
  362. if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
  363. goto err;
  364. } else if (strcmp(name, "onlysomereasons") == 0) {
  365. if (!set_reasons(&idp->onlysomereasons, val))
  366. goto err;
  367. } else {
  368. ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NAME);
  369. X509V3_conf_add_error_name_value(cnf);
  370. goto err;
  371. }
  372. }
  373. return idp;
  374. err:
  375. ISSUING_DIST_POINT_free(idp);
  376. return NULL;
  377. }
  378. static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
  379. {
  380. int i;
  381. for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
  382. if (i > 0)
  383. BIO_puts(out, "\n");
  384. BIO_printf(out, "%*s", indent + 2, "");
  385. GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
  386. }
  387. return 1;
  388. }
  389. static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
  390. {
  391. if (dpn->type == 0) {
  392. BIO_printf(out, "%*sFull Name:\n", indent, "");
  393. print_gens(out, dpn->name.fullname, indent);
  394. } else {
  395. X509_NAME ntmp;
  396. ntmp.entries = dpn->name.relativename;
  397. BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, "");
  398. X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
  399. BIO_puts(out, "\n");
  400. }
  401. return 1;
  402. }
  403. static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
  404. int indent)
  405. {
  406. ISSUING_DIST_POINT *idp = pidp;
  407. if (idp->distpoint)
  408. print_distpoint(out, idp->distpoint, indent);
  409. if (idp->onlyuser > 0)
  410. BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
  411. if (idp->onlyCA > 0)
  412. BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
  413. if (idp->indirectCRL > 0)
  414. BIO_printf(out, "%*sIndirect CRL\n", indent, "");
  415. if (idp->onlysomereasons)
  416. print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent);
  417. if (idp->onlyattr > 0)
  418. BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
  419. if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
  420. && (idp->indirectCRL <= 0) && !idp->onlysomereasons
  421. && (idp->onlyattr <= 0))
  422. BIO_printf(out, "%*s<EMPTY>\n", indent, "");
  423. return 1;
  424. }
  425. static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
  426. int indent)
  427. {
  428. STACK_OF(DIST_POINT) *crld = pcrldp;
  429. DIST_POINT *point;
  430. int i;
  431. for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
  432. if (i > 0)
  433. BIO_puts(out, "\n");
  434. point = sk_DIST_POINT_value(crld, i);
  435. if (point->distpoint)
  436. print_distpoint(out, point->distpoint, indent);
  437. if (point->reasons)
  438. print_reasons(out, "Reasons", point->reasons, indent);
  439. if (point->CRLissuer) {
  440. BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
  441. print_gens(out, point->CRLissuer, indent);
  442. }
  443. }
  444. return 1;
  445. }
  446. /* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */
  447. int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname)
  448. {
  449. int i;
  450. STACK_OF(X509_NAME_ENTRY) *frag;
  451. X509_NAME_ENTRY *ne;
  452. if (dpn == NULL || dpn->type != 1)
  453. return 1;
  454. frag = dpn->name.relativename;
  455. X509_NAME_free(dpn->dpname); /* just in case it was already set */
  456. dpn->dpname = X509_NAME_dup(iname);
  457. if (dpn->dpname == NULL)
  458. return 0;
  459. for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
  460. ne = sk_X509_NAME_ENTRY_value(frag, i);
  461. if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
  462. goto err;
  463. }
  464. /* generate cached encoding of name */
  465. if (i2d_X509_NAME(dpn->dpname, NULL) >= 0)
  466. return 1;
  467. err:
  468. X509_NAME_free(dpn->dpname);
  469. dpn->dpname = NULL;
  470. return 0;
  471. }