OLD | NEW |
1 /* v3_crld.c */ | 1 /* v3_crld.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 * project 1999. | 3 * project 1999. |
4 */ | 4 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
11 * | 11 * |
12 * 1. Redistributions of source code must retain the above copyright | 12 * 1. Redistributions of source code must retain the above copyright |
13 * notice, this list of conditions and the following disclaimer. | 13 * notice, this list of conditions and the following disclaimer. |
14 * | 14 * |
15 * 2. Redistributions in binary form must reproduce the above copyright | 15 * 2. Redistributions in binary form must reproduce the above copyright |
16 * notice, this list of conditions and the following disclaimer in | 16 * notice, this list of conditions and the following disclaimer in |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 * | 56 * |
57 */ | 57 */ |
58 | 58 |
59 #include <stdio.h> | 59 #include <stdio.h> |
60 #include "cryptlib.h" | 60 #include "cryptlib.h" |
61 #include <openssl/conf.h> | 61 #include <openssl/conf.h> |
62 #include <openssl/asn1.h> | 62 #include <openssl/asn1.h> |
63 #include <openssl/asn1t.h> | 63 #include <openssl/asn1t.h> |
64 #include <openssl/x509v3.h> | 64 #include <openssl/x509v3.h> |
65 | 65 |
66 static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, | 66 static void *v2i_crld(const X509V3_EXT_METHOD *method, |
67 » » STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *extlist); | 67 » » X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); |
68 static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, | 68 static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, |
69 » » » » X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | 69 » » int indent); |
70 | 70 |
71 const X509V3_EXT_METHOD v3_crld = { | 71 const X509V3_EXT_METHOD v3_crld = |
72 NID_crl_distribution_points, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(CRL_DIST_POINTS
), | 72 » { |
73 0,0,0,0, | 73 » NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), |
74 0,0, | 74 » 0,0,0,0, |
75 (X509V3_EXT_I2V)i2v_crld, | 75 » 0,0, |
76 (X509V3_EXT_V2I)v2i_crld, | 76 » 0, |
77 0,0, | 77 » v2i_crld, |
78 NULL | 78 » i2r_crldp,0, |
| 79 » NULL |
| 80 » }; |
| 81 |
| 82 const X509V3_EXT_METHOD v3_freshest_crl = |
| 83 » { |
| 84 » NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), |
| 85 » 0,0,0,0, |
| 86 » 0,0, |
| 87 » 0, |
| 88 » v2i_crld, |
| 89 » i2r_crldp,0, |
| 90 » NULL |
| 91 » }; |
| 92 |
| 93 static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect) |
| 94 » { |
| 95 » STACK_OF(CONF_VALUE) *gnsect; |
| 96 » STACK_OF(GENERAL_NAME) *gens; |
| 97 » if (*sect == '@') |
| 98 » » gnsect = X509V3_get_section(ctx, sect + 1); |
| 99 » else |
| 100 » » gnsect = X509V3_parse_list(sect); |
| 101 » if (!gnsect) |
| 102 » » { |
| 103 » » X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, |
| 104 » » » » » » X509V3_R_SECTION_NOT_FOUND); |
| 105 » » return NULL; |
| 106 » » } |
| 107 » gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); |
| 108 » if (*sect == '@') |
| 109 » » X509V3_section_free(ctx, gnsect); |
| 110 » else |
| 111 » » sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); |
| 112 » return gens; |
| 113 » } |
| 114 |
| 115 static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, |
| 116 » » » » » » » CONF_VALUE *cnf) |
| 117 » { |
| 118 » STACK_OF(GENERAL_NAME) *fnm = NULL; |
| 119 » STACK_OF(X509_NAME_ENTRY) *rnm = NULL; |
| 120 » if (!strncmp(cnf->name, "fullname", 9)) |
| 121 » » { |
| 122 » » fnm = gnames_from_sectname(ctx, cnf->value); |
| 123 » » if (!fnm) |
| 124 » » » goto err; |
| 125 » » } |
| 126 » else if (!strcmp(cnf->name, "relativename")) |
| 127 » » { |
| 128 » » int ret; |
| 129 » » STACK_OF(CONF_VALUE) *dnsect; |
| 130 » » X509_NAME *nm; |
| 131 » » nm = X509_NAME_new(); |
| 132 » » if (!nm) |
| 133 » » » return -1; |
| 134 » » dnsect = X509V3_get_section(ctx, cnf->value); |
| 135 » » if (!dnsect) |
| 136 » » » { |
| 137 » » » X509V3err(X509V3_F_SET_DIST_POINT_NAME, |
| 138 » » » » » » X509V3_R_SECTION_NOT_FOUND); |
| 139 » » » return -1; |
| 140 » » » } |
| 141 » » ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); |
| 142 » » X509V3_section_free(ctx, dnsect); |
| 143 » » rnm = nm->entries; |
| 144 » » nm->entries = NULL; |
| 145 » » X509_NAME_free(nm); |
| 146 » » if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) |
| 147 » » » goto err; |
| 148 » » /* Since its a name fragment can't have more than one |
| 149 » » * RDNSequence |
| 150 » » */ |
| 151 » » if (sk_X509_NAME_ENTRY_value(rnm, |
| 152 » » » » sk_X509_NAME_ENTRY_num(rnm) - 1)->set) |
| 153 » » » { |
| 154 » » » X509V3err(X509V3_F_SET_DIST_POINT_NAME, |
| 155 » » » » » » X509V3_R_INVALID_MULTIPLE_RDNS); |
| 156 » » » goto err; |
| 157 » » » } |
| 158 » » } |
| 159 » else |
| 160 » » return 0; |
| 161 |
| 162 » if (*pdp) |
| 163 » » { |
| 164 » » X509V3err(X509V3_F_SET_DIST_POINT_NAME, |
| 165 » » » » » » X509V3_R_DISTPOINT_ALREADY_SET); |
| 166 » » goto err; |
| 167 » » } |
| 168 |
| 169 » *pdp = DIST_POINT_NAME_new(); |
| 170 » if (!*pdp) |
| 171 » » goto err; |
| 172 » if (fnm) |
| 173 » » { |
| 174 » » (*pdp)->type = 0; |
| 175 » » (*pdp)->name.fullname = fnm; |
| 176 » » } |
| 177 » else |
| 178 » » { |
| 179 » » (*pdp)->type = 1; |
| 180 » » (*pdp)->name.relativename = rnm; |
| 181 » » } |
| 182 |
| 183 » return 1; |
| 184 » » |
| 185 » err: |
| 186 » if (fnm) |
| 187 » » sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); |
| 188 » if (rnm) |
| 189 » » sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); |
| 190 » return -1; |
| 191 » } |
| 192 |
| 193 static const BIT_STRING_BITNAME reason_flags[] = { |
| 194 {0, "Unused", "unused"}, |
| 195 {1, "Key Compromise", "keyCompromise"}, |
| 196 {2, "CA Compromise", "CACompromise"}, |
| 197 {3, "Affiliation Changed", "affiliationChanged"}, |
| 198 {4, "Superseded", "superseded"}, |
| 199 {5, "Cessation Of Operation", "cessationOfOperation"}, |
| 200 {6, "Certificate Hold", "certificateHold"}, |
| 201 {7, "Privilege Withdrawn", "privilegeWithdrawn"}, |
| 202 {8, "AA Compromise", "AACompromise"}, |
| 203 {-1, NULL, NULL} |
79 }; | 204 }; |
80 | 205 |
81 static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, | 206 static int set_reasons(ASN1_BIT_STRING **preas, char *value) |
82 » » » STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *exts) | 207 » { |
83 { | 208 » STACK_OF(CONF_VALUE) *rsk = NULL; |
84 » DIST_POINT *point; | 209 » const BIT_STRING_BITNAME *pbn; |
| 210 » const char *bnam; |
| 211 » int i, ret = 0; |
| 212 » rsk = X509V3_parse_list(value); |
| 213 » if (!rsk) |
| 214 » » return 0; |
| 215 » if (*preas) |
| 216 » » return 0; |
| 217 » for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) |
| 218 » » { |
| 219 » » bnam = sk_CONF_VALUE_value(rsk, i)->name; |
| 220 » » if (!*preas) |
| 221 » » » { |
| 222 » » » *preas = ASN1_BIT_STRING_new(); |
| 223 » » » if (!*preas) |
| 224 » » » » goto err; |
| 225 » » » } |
| 226 » » for (pbn = reason_flags; pbn->lname; pbn++) |
| 227 » » » { |
| 228 » » » if (!strcmp(pbn->sname, bnam)) |
| 229 » » » » { |
| 230 » » » » if (!ASN1_BIT_STRING_set_bit(*preas, |
| 231 » » » » » » » pbn->bitnum, 1)) |
| 232 » » » » » goto err; |
| 233 » » » » break; |
| 234 » » » » } |
| 235 » » » } |
| 236 » » if (!pbn->lname) |
| 237 » » » goto err; |
| 238 » » } |
| 239 » ret = 1; |
| 240 |
| 241 » err: |
| 242 » sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); |
| 243 » return ret; |
| 244 » } |
| 245 |
| 246 static int print_reasons(BIO *out, const char *rname, |
| 247 » » » ASN1_BIT_STRING *rflags, int indent) |
| 248 » { |
| 249 » int first = 1; |
| 250 » const BIT_STRING_BITNAME *pbn; |
| 251 » BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); |
| 252 » for (pbn = reason_flags; pbn->lname; pbn++) |
| 253 » » { |
| 254 » » if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) |
| 255 » » » { |
| 256 » » » if (first) |
| 257 » » » » first = 0; |
| 258 » » » else |
| 259 » » » » BIO_puts(out, ", "); |
| 260 » » » BIO_puts(out, pbn->lname); |
| 261 » » » } |
| 262 » » } |
| 263 » if (first) |
| 264 » » BIO_puts(out, "<EMPTY>\n"); |
| 265 » else |
| 266 » » BIO_puts(out, "\n"); |
| 267 » return 1; |
| 268 » } |
| 269 |
| 270 static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, |
| 271 » » » » » » STACK_OF(CONF_VALUE) *nval) |
| 272 » { |
85 int i; | 273 int i; |
86 » for(i = 0; i < sk_DIST_POINT_num(crld); i++) { | 274 » CONF_VALUE *cnf; |
87 » » point = sk_DIST_POINT_value(crld, i); | 275 » DIST_POINT *point = NULL; |
88 » » if(point->distpoint) { | 276 » point = DIST_POINT_new(); |
89 » » » if(point->distpoint->type == 0) | 277 » if (!point) |
90 » » » » exts = i2v_GENERAL_NAMES(NULL, | 278 » » goto err; |
91 » » » » » point->distpoint->name.fullname, exts); | 279 » for(i = 0; i < sk_CONF_VALUE_num(nval); i++) |
92 » » else X509V3_add_value("RelativeName","<UNSUPPORTED>", &e
xts); | 280 » » { |
93 » » } | 281 » » int ret; |
94 » » if(point->reasons) | 282 » » cnf = sk_CONF_VALUE_value(nval, i); |
95 » » » X509V3_add_value("reasons","<UNSUPPORTED>", &exts); | 283 » » ret = set_dist_point_name(&point->distpoint, ctx, cnf); |
96 » » if(point->CRLissuer) | 284 » » if (ret > 0) |
97 » » » X509V3_add_value("CRLissuer","<UNSUPPORTED>", &exts); | 285 » » » continue; |
98 » } | 286 » » if (ret < 0) |
99 » return exts; | 287 » » » goto err; |
100 } | 288 » » if (!strcmp(cnf->name, "reasons")) |
101 | 289 » » » { |
102 static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, | 290 » » » if (!set_reasons(&point->reasons, cnf->value)) |
103 » » » » X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | 291 » » » » goto err; |
104 { | 292 » » » } |
| 293 » » else if (!strcmp(cnf->name, "CRLissuer")) |
| 294 » » » { |
| 295 » » » point->CRLissuer = |
| 296 » » » » gnames_from_sectname(ctx, cnf->value); |
| 297 » » » if (!point->CRLissuer) |
| 298 » » » » goto err; |
| 299 » » » } |
| 300 » » } |
| 301 |
| 302 » return point; |
| 303 » » » |
| 304 |
| 305 » err: |
| 306 » if (point) |
| 307 » » DIST_POINT_free(point); |
| 308 » return NULL; |
| 309 » } |
| 310 |
| 311 static void *v2i_crld(const X509V3_EXT_METHOD *method, |
| 312 » » X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) |
| 313 » { |
105 STACK_OF(DIST_POINT) *crld = NULL; | 314 STACK_OF(DIST_POINT) *crld = NULL; |
106 GENERAL_NAMES *gens = NULL; | 315 GENERAL_NAMES *gens = NULL; |
107 GENERAL_NAME *gen = NULL; | 316 GENERAL_NAME *gen = NULL; |
108 CONF_VALUE *cnf; | 317 CONF_VALUE *cnf; |
109 int i; | 318 int i; |
110 if(!(crld = sk_DIST_POINT_new_null())) goto merr; | 319 if(!(crld = sk_DIST_POINT_new_null())) goto merr; |
111 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | 320 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
112 DIST_POINT *point; | 321 DIST_POINT *point; |
113 cnf = sk_CONF_VALUE_value(nval, i); | 322 cnf = sk_CONF_VALUE_value(nval, i); |
114 » » if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; | 323 » » if (!cnf->value) |
115 » » if(!(gens = GENERAL_NAMES_new())) goto merr; | 324 » » » { |
116 » » if(!sk_GENERAL_NAME_push(gens, gen)) goto merr; | 325 » » » STACK_OF(CONF_VALUE) *dpsect; |
117 » » gen = NULL; | 326 » » » dpsect = X509V3_get_section(ctx, cnf->name); |
118 » » if(!(point = DIST_POINT_new())) goto merr; | 327 » » » if (!dpsect) |
119 » » if(!sk_DIST_POINT_push(crld, point)) { | 328 » » » » goto err; |
120 » » » DIST_POINT_free(point); | 329 » » » point = crldp_from_section(ctx, dpsect); |
121 » » » goto merr; | 330 » » » X509V3_section_free(ctx, dpsect); |
122 » » } | 331 » » » if (!point) |
123 » » if(!(point->distpoint = DIST_POINT_NAME_new())) goto merr; | 332 » » » » goto err; |
124 » » point->distpoint->name.fullname = gens; | 333 » » » if(!sk_DIST_POINT_push(crld, point)) |
125 » » point->distpoint->type = 0; | 334 » » » » { |
126 » » gens = NULL; | 335 » » » » DIST_POINT_free(point); |
| 336 » » » » goto merr; |
| 337 » » » » } |
| 338 » » » } |
| 339 » » else |
| 340 » » » { |
| 341 » » » if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) |
| 342 » » » » goto err; |
| 343 » » » if(!(gens = GENERAL_NAMES_new())) |
| 344 » » » » goto merr; |
| 345 » » » if(!sk_GENERAL_NAME_push(gens, gen)) |
| 346 » » » » goto merr; |
| 347 » » » gen = NULL; |
| 348 » » » if(!(point = DIST_POINT_new())) |
| 349 » » » » goto merr; |
| 350 » » » if(!sk_DIST_POINT_push(crld, point)) |
| 351 » » » » { |
| 352 » » » » DIST_POINT_free(point); |
| 353 » » » » goto merr; |
| 354 » » » » } |
| 355 » » » if(!(point->distpoint = DIST_POINT_NAME_new())) |
| 356 » » » » goto merr; |
| 357 » » » point->distpoint->name.fullname = gens; |
| 358 » » » point->distpoint->type = 0; |
| 359 » » » gens = NULL; |
| 360 » » » } |
127 } | 361 } |
128 return crld; | 362 return crld; |
129 | 363 |
130 merr: | 364 merr: |
131 X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE); | 365 X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE); |
132 err: | 366 err: |
133 GENERAL_NAME_free(gen); | 367 GENERAL_NAME_free(gen); |
134 GENERAL_NAMES_free(gens); | 368 GENERAL_NAMES_free(gens); |
135 sk_DIST_POINT_pop_free(crld, DIST_POINT_free); | 369 sk_DIST_POINT_pop_free(crld, DIST_POINT_free); |
136 return NULL; | 370 return NULL; |
137 } | 371 } |
138 | 372 |
139 IMPLEMENT_STACK_OF(DIST_POINT) | 373 IMPLEMENT_STACK_OF(DIST_POINT) |
140 IMPLEMENT_ASN1_SET_OF(DIST_POINT) | 374 IMPLEMENT_ASN1_SET_OF(DIST_POINT) |
141 | 375 |
| 376 static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
| 377 void *exarg) |
| 378 { |
| 379 DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; |
142 | 380 |
143 ASN1_CHOICE(DIST_POINT_NAME) = { | 381 » switch(operation) |
| 382 » » { |
| 383 » » case ASN1_OP_NEW_POST: |
| 384 » » dpn->dpname = NULL; |
| 385 » » break; |
| 386 |
| 387 » » case ASN1_OP_FREE_POST: |
| 388 » » if (dpn->dpname) |
| 389 » » » X509_NAME_free(dpn->dpname); |
| 390 » » break; |
| 391 » » } |
| 392 » return 1; |
| 393 » } |
| 394 |
| 395 |
| 396 ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { |
144 ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), | 397 ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), |
145 ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) | 398 ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) |
146 } ASN1_CHOICE_END(DIST_POINT_NAME) | 399 } ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) |
| 400 |
147 | 401 |
148 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) | 402 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) |
149 | 403 |
150 ASN1_SEQUENCE(DIST_POINT) = { | 404 ASN1_SEQUENCE(DIST_POINT) = { |
151 ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), | 405 ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), |
152 ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), | 406 ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), |
153 ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) | 407 ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) |
154 } ASN1_SEQUENCE_END(DIST_POINT) | 408 } ASN1_SEQUENCE_END(DIST_POINT) |
155 | 409 |
156 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) | 410 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) |
157 | 411 |
158 ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = | 412 ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = |
159 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, D
IST_POINT) | 413 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, D
IST_POINT) |
160 ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) | 414 ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) |
161 | 415 |
162 IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) | 416 IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) |
| 417 |
| 418 ASN1_SEQUENCE(ISSUING_DIST_POINT) = { |
| 419 ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), |
| 420 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), |
| 421 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), |
| 422 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), |
| 423 ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), |
| 424 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) |
| 425 } ASN1_SEQUENCE_END(ISSUING_DIST_POINT) |
| 426 |
| 427 IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) |
| 428 |
| 429 static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, |
| 430 int indent); |
| 431 static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, |
| 432 STACK_OF(CONF_VALUE) *nval); |
| 433 |
| 434 const X509V3_EXT_METHOD v3_idp = |
| 435 { |
| 436 NID_issuing_distribution_point, X509V3_EXT_MULTILINE, |
| 437 ASN1_ITEM_ref(ISSUING_DIST_POINT), |
| 438 0,0,0,0, |
| 439 0,0, |
| 440 0, |
| 441 v2i_idp, |
| 442 i2r_idp,0, |
| 443 NULL |
| 444 }; |
| 445 |
| 446 static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, |
| 447 STACK_OF(CONF_VALUE) *nval) |
| 448 { |
| 449 ISSUING_DIST_POINT *idp = NULL; |
| 450 CONF_VALUE *cnf; |
| 451 char *name, *val; |
| 452 int i, ret; |
| 453 idp = ISSUING_DIST_POINT_new(); |
| 454 if (!idp) |
| 455 goto merr; |
| 456 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) |
| 457 { |
| 458 cnf = sk_CONF_VALUE_value(nval, i); |
| 459 name = cnf->name; |
| 460 val = cnf->value; |
| 461 ret = set_dist_point_name(&idp->distpoint, ctx, cnf); |
| 462 if (ret > 0) |
| 463 continue; |
| 464 if (ret < 0) |
| 465 goto err; |
| 466 if (!strcmp(name, "onlyuser")) |
| 467 { |
| 468 if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) |
| 469 goto err; |
| 470 } |
| 471 else if (!strcmp(name, "onlyCA")) |
| 472 { |
| 473 if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) |
| 474 goto err; |
| 475 } |
| 476 else if (!strcmp(name, "onlyAA")) |
| 477 { |
| 478 if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) |
| 479 goto err; |
| 480 } |
| 481 else if (!strcmp(name, "indirectCRL")) |
| 482 { |
| 483 if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) |
| 484 goto err; |
| 485 } |
| 486 else if (!strcmp(name, "onlysomereasons")) |
| 487 { |
| 488 if (!set_reasons(&idp->onlysomereasons, val)) |
| 489 goto err; |
| 490 } |
| 491 else |
| 492 { |
| 493 X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); |
| 494 X509V3_conf_err(cnf); |
| 495 goto err; |
| 496 } |
| 497 } |
| 498 return idp; |
| 499 |
| 500 merr: |
| 501 X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE); |
| 502 err: |
| 503 ISSUING_DIST_POINT_free(idp); |
| 504 return NULL; |
| 505 } |
| 506 |
| 507 static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) |
| 508 { |
| 509 int i; |
| 510 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) |
| 511 { |
| 512 BIO_printf(out, "%*s", indent + 2, ""); |
| 513 GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); |
| 514 BIO_puts(out, "\n"); |
| 515 } |
| 516 return 1; |
| 517 } |
| 518 |
| 519 static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) |
| 520 { |
| 521 if (dpn->type == 0) |
| 522 { |
| 523 BIO_printf(out, "%*sFull Name:\n", indent, ""); |
| 524 print_gens(out, dpn->name.fullname, indent); |
| 525 } |
| 526 else |
| 527 { |
| 528 X509_NAME ntmp; |
| 529 ntmp.entries = dpn->name.relativename; |
| 530 BIO_printf(out, "%*sRelative Name:\n%*s", |
| 531 indent, "", indent + 2, ""); |
| 532 X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); |
| 533 BIO_puts(out, "\n"); |
| 534 } |
| 535 return 1; |
| 536 } |
| 537 |
| 538 static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, |
| 539 int indent) |
| 540 { |
| 541 ISSUING_DIST_POINT *idp = pidp; |
| 542 if (idp->distpoint) |
| 543 print_distpoint(out, idp->distpoint, indent); |
| 544 if (idp->onlyuser > 0) |
| 545 BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); |
| 546 if (idp->onlyCA > 0) |
| 547 BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); |
| 548 if (idp->indirectCRL > 0) |
| 549 BIO_printf(out, "%*sIndirect CRL\n", indent, ""); |
| 550 if (idp->onlysomereasons) |
| 551 print_reasons(out, "Only Some Reasons", |
| 552 idp->onlysomereasons, indent); |
| 553 if (idp->onlyattr > 0) |
| 554 BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); |
| 555 if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) |
| 556 && (idp->indirectCRL <= 0) && !idp->onlysomereasons |
| 557 && (idp->onlyattr <= 0)) |
| 558 BIO_printf(out, "%*s<EMPTY>\n", indent, ""); |
| 559 |
| 560 return 1; |
| 561 } |
| 562 |
| 563 static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, |
| 564 int indent) |
| 565 { |
| 566 STACK_OF(DIST_POINT) *crld = pcrldp; |
| 567 DIST_POINT *point; |
| 568 int i; |
| 569 for(i = 0; i < sk_DIST_POINT_num(crld); i++) |
| 570 { |
| 571 BIO_puts(out, "\n"); |
| 572 point = sk_DIST_POINT_value(crld, i); |
| 573 if(point->distpoint) |
| 574 print_distpoint(out, point->distpoint, indent); |
| 575 if(point->reasons) |
| 576 print_reasons(out, "Reasons", point->reasons, |
| 577 indent); |
| 578 if(point->CRLissuer) |
| 579 { |
| 580 BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); |
| 581 print_gens(out, point->CRLissuer, indent); |
| 582 } |
| 583 } |
| 584 return 1; |
| 585 } |
| 586 |
| 587 int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) |
| 588 { |
| 589 int i; |
| 590 STACK_OF(X509_NAME_ENTRY) *frag; |
| 591 X509_NAME_ENTRY *ne; |
| 592 if (!dpn || (dpn->type != 1)) |
| 593 return 1; |
| 594 frag = dpn->name.relativename; |
| 595 dpn->dpname = X509_NAME_dup(iname); |
| 596 if (!dpn->dpname) |
| 597 return 0; |
| 598 for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) |
| 599 { |
| 600 ne = sk_X509_NAME_ENTRY_value(frag, i); |
| 601 if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) |
| 602 { |
| 603 X509_NAME_free(dpn->dpname); |
| 604 dpn->dpname = NULL; |
| 605 return 0; |
| 606 } |
| 607 } |
| 608 /* generate cached encoding of name */ |
| 609 if (i2d_X509_NAME(dpn->dpname, NULL) < 0) |
| 610 { |
| 611 X509_NAME_free(dpn->dpname); |
| 612 dpn->dpname = NULL; |
| 613 return 0; |
| 614 } |
| 615 return 1; |
| 616 } |
OLD | NEW |