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