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