]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
d2e9e320 | 2 | * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. |
142fcca8 | 3 | * |
d2e9e320 RS |
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 | |
142fcca8 DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
b39fc560 | 11 | #include "internal/cryptlib.h" |
ec577822 BM |
12 | #include <openssl/conf.h> |
13 | #include <openssl/x509v3.h> | |
df2ee0e2 | 14 | #include "ext_dat.h" |
142fcca8 | 15 | |
0f113f3e MC |
16 | static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, |
17 | X509V3_CTX *ctx, | |
18 | STACK_OF(CONF_VALUE) *nval); | |
19 | static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, | |
20 | X509V3_CTX *ctx, | |
21 | STACK_OF(CONF_VALUE) *nval); | |
c9fd77e9 | 22 | static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); |
9d6b1ce6 | 23 | static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); |
c8f717fe F |
24 | static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); |
25 | static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); | |
9ea1b878 | 26 | |
4b68cb41 | 27 | const X509V3_EXT_METHOD v3_alt[3] = { |
0f113f3e MC |
28 | {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), |
29 | 0, 0, 0, 0, | |
30 | 0, 0, | |
31 | (X509V3_EXT_I2V) i2v_GENERAL_NAMES, | |
32 | (X509V3_EXT_V2I)v2i_subject_alt, | |
33 | NULL, NULL, NULL}, | |
34 | ||
35 | {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), | |
36 | 0, 0, 0, 0, | |
37 | 0, 0, | |
38 | (X509V3_EXT_I2V) i2v_GENERAL_NAMES, | |
39 | (X509V3_EXT_V2I)v2i_issuer_alt, | |
40 | NULL, NULL, NULL}, | |
41 | ||
42 | {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), | |
43 | 0, 0, 0, 0, | |
44 | 0, 0, | |
45 | (X509V3_EXT_I2V) i2v_GENERAL_NAMES, | |
46 | NULL, NULL, NULL, NULL}, | |
142fcca8 DSH |
47 | }; |
48 | ||
ba404b5e | 49 | STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, |
0f113f3e MC |
50 | GENERAL_NAMES *gens, |
51 | STACK_OF(CONF_VALUE) *ret) | |
142fcca8 | 52 | { |
0f113f3e MC |
53 | int i; |
54 | GENERAL_NAME *gen; | |
55 | for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { | |
56 | gen = sk_GENERAL_NAME_value(gens, i); | |
57 | ret = i2v_GENERAL_NAME(method, gen, ret); | |
58 | } | |
59 | if (!ret) | |
60 | return sk_CONF_VALUE_new_null(); | |
61 | return ret; | |
d08d8da4 DSH |
62 | } |
63 | ||
ba404b5e | 64 | STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, |
0f113f3e MC |
65 | GENERAL_NAME *gen, |
66 | STACK_OF(CONF_VALUE) *ret) | |
d08d8da4 | 67 | { |
0f113f3e MC |
68 | unsigned char *p; |
69 | char oline[256], htmp[5]; | |
70 | int i; | |
71 | switch (gen->type) { | |
72 | case GEN_OTHERNAME: | |
75a3e392 MC |
73 | if (!X509V3_add_value("othername", "<unsupported>", &ret)) |
74 | return NULL; | |
0f113f3e MC |
75 | break; |
76 | ||
77 | case GEN_X400: | |
75a3e392 MC |
78 | if (!X509V3_add_value("X400Name", "<unsupported>", &ret)) |
79 | return NULL; | |
0f113f3e MC |
80 | break; |
81 | ||
82 | case GEN_EDIPARTY: | |
75a3e392 MC |
83 | if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret)) |
84 | return NULL; | |
0f113f3e MC |
85 | break; |
86 | ||
87 | case GEN_EMAIL: | |
75a3e392 MC |
88 | if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) |
89 | return NULL; | |
0f113f3e MC |
90 | break; |
91 | ||
92 | case GEN_DNS: | |
75a3e392 MC |
93 | if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) |
94 | return NULL; | |
0f113f3e MC |
95 | break; |
96 | ||
97 | case GEN_URI: | |
75a3e392 MC |
98 | if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) |
99 | return NULL; | |
0f113f3e MC |
100 | break; |
101 | ||
102 | case GEN_DIRNAME: | |
75a3e392 MC |
103 | if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL |
104 | || !X509V3_add_value("DirName", oline, &ret)) | |
105 | return NULL; | |
0f113f3e MC |
106 | break; |
107 | ||
108 | case GEN_IPADD: | |
109 | p = gen->d.ip->data; | |
110 | if (gen->d.ip->length == 4) | |
111 | BIO_snprintf(oline, sizeof oline, | |
112 | "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); | |
113 | else if (gen->d.ip->length == 16) { | |
114 | oline[0] = 0; | |
115 | for (i = 0; i < 8; i++) { | |
116 | BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); | |
117 | p += 2; | |
118 | strcat(oline, htmp); | |
119 | if (i != 7) | |
120 | strcat(oline, ":"); | |
121 | } | |
122 | } else { | |
75a3e392 MC |
123 | if (!X509V3_add_value("IP Address", "<invalid>", &ret)) |
124 | return NULL; | |
0f113f3e MC |
125 | break; |
126 | } | |
75a3e392 MC |
127 | if (!X509V3_add_value("IP Address", oline, &ret)) |
128 | return NULL; | |
0f113f3e MC |
129 | break; |
130 | ||
131 | case GEN_RID: | |
132 | i2t_ASN1_OBJECT(oline, 256, gen->d.rid); | |
75a3e392 MC |
133 | if (!X509V3_add_value("Registered ID", oline, &ret)) |
134 | return NULL; | |
0f113f3e MC |
135 | break; |
136 | } | |
137 | return ret; | |
2c15d426 DSH |
138 | } |
139 | ||
140 | int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) | |
141 | { | |
0f113f3e MC |
142 | unsigned char *p; |
143 | int i; | |
144 | switch (gen->type) { | |
145 | case GEN_OTHERNAME: | |
146 | BIO_printf(out, "othername:<unsupported>"); | |
147 | break; | |
148 | ||
149 | case GEN_X400: | |
150 | BIO_printf(out, "X400Name:<unsupported>"); | |
151 | break; | |
152 | ||
153 | case GEN_EDIPARTY: | |
154 | /* Maybe fix this: it is supported now */ | |
155 | BIO_printf(out, "EdiPartyName:<unsupported>"); | |
156 | break; | |
157 | ||
158 | case GEN_EMAIL: | |
159 | BIO_printf(out, "email:%s", gen->d.ia5->data); | |
160 | break; | |
161 | ||
162 | case GEN_DNS: | |
163 | BIO_printf(out, "DNS:%s", gen->d.ia5->data); | |
164 | break; | |
165 | ||
166 | case GEN_URI: | |
167 | BIO_printf(out, "URI:%s", gen->d.ia5->data); | |
168 | break; | |
169 | ||
170 | case GEN_DIRNAME: | |
ca1cb0d4 | 171 | BIO_printf(out, "DirName:"); |
0f113f3e MC |
172 | X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); |
173 | break; | |
174 | ||
175 | case GEN_IPADD: | |
176 | p = gen->d.ip->data; | |
177 | if (gen->d.ip->length == 4) | |
178 | BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); | |
179 | else if (gen->d.ip->length == 16) { | |
180 | BIO_printf(out, "IP Address"); | |
181 | for (i = 0; i < 8; i++) { | |
182 | BIO_printf(out, ":%X", p[0] << 8 | p[1]); | |
183 | p += 2; | |
184 | } | |
185 | BIO_puts(out, "\n"); | |
186 | } else { | |
187 | BIO_printf(out, "IP Address:<invalid>"); | |
188 | break; | |
189 | } | |
190 | break; | |
191 | ||
192 | case GEN_RID: | |
ca1cb0d4 | 193 | BIO_printf(out, "Registered ID:"); |
0f113f3e MC |
194 | i2a_ASN1_OBJECT(out, gen->d.rid); |
195 | break; | |
196 | } | |
197 | return 1; | |
142fcca8 DSH |
198 | } |
199 | ||
9d6b1ce6 | 200 | static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, |
0f113f3e MC |
201 | X509V3_CTX *ctx, |
202 | STACK_OF(CONF_VALUE) *nval) | |
aa066b9e | 203 | { |
0f113f3e MC |
204 | GENERAL_NAMES *gens = NULL; |
205 | CONF_VALUE *cnf; | |
206 | int i; | |
75ebbd9a RS |
207 | |
208 | if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { | |
0f113f3e MC |
209 | X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); |
210 | return NULL; | |
211 | } | |
212 | for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { | |
213 | cnf = sk_CONF_VALUE_value(nval, i); | |
86885c28 RS |
214 | if (!name_cmp(cnf->name, "issuer") |
215 | && cnf->value && strcmp(cnf->value, "copy") == 0) { | |
0f113f3e MC |
216 | if (!copy_issuer(ctx, gens)) |
217 | goto err; | |
218 | } else { | |
219 | GENERAL_NAME *gen; | |
75ebbd9a | 220 | if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) |
0f113f3e MC |
221 | goto err; |
222 | sk_GENERAL_NAME_push(gens, gen); | |
223 | } | |
224 | } | |
225 | return gens; | |
226 | err: | |
227 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | |
228 | return NULL; | |
aa066b9e DSH |
229 | } |
230 | ||
231 | /* Append subject altname of issuer to issuer alt name of subject */ | |
232 | ||
9d6b1ce6 | 233 | static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) |
aa066b9e | 234 | { |
0f113f3e MC |
235 | GENERAL_NAMES *ialt; |
236 | GENERAL_NAME *gen; | |
237 | X509_EXTENSION *ext; | |
238 | int i; | |
75ebbd9a | 239 | |
0f113f3e MC |
240 | if (ctx && (ctx->flags == CTX_TEST)) |
241 | return 1; | |
242 | if (!ctx || !ctx->issuer_cert) { | |
243 | X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); | |
244 | goto err; | |
245 | } | |
246 | i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); | |
247 | if (i < 0) | |
248 | return 1; | |
75ebbd9a RS |
249 | if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL |
250 | || (ialt = X509V3_EXT_d2i(ext)) == NULL) { | |
0f113f3e MC |
251 | X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); |
252 | goto err; | |
253 | } | |
254 | ||
255 | for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { | |
256 | gen = sk_GENERAL_NAME_value(ialt, i); | |
257 | if (!sk_GENERAL_NAME_push(gens, gen)) { | |
258 | X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); | |
259 | goto err; | |
260 | } | |
261 | } | |
262 | sk_GENERAL_NAME_free(ialt); | |
263 | ||
264 | return 1; | |
265 | ||
266 | err: | |
267 | return 0; | |
268 | ||
aa066b9e DSH |
269 | } |
270 | ||
9d6b1ce6 | 271 | static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, |
0f113f3e MC |
272 | X509V3_CTX *ctx, |
273 | STACK_OF(CONF_VALUE) *nval) | |
aa066b9e | 274 | { |
0f113f3e MC |
275 | GENERAL_NAMES *gens = NULL; |
276 | CONF_VALUE *cnf; | |
277 | int i; | |
75ebbd9a RS |
278 | |
279 | if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { | |
0f113f3e MC |
280 | X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); |
281 | return NULL; | |
282 | } | |
283 | for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { | |
284 | cnf = sk_CONF_VALUE_value(nval, i); | |
86885c28 RS |
285 | if (!name_cmp(cnf->name, "email") |
286 | && cnf->value && strcmp(cnf->value, "copy") == 0) { | |
0f113f3e MC |
287 | if (!copy_email(ctx, gens, 0)) |
288 | goto err; | |
86885c28 RS |
289 | } else if (!name_cmp(cnf->name, "email") |
290 | && cnf->value && strcmp(cnf->value, "move") == 0) { | |
0f113f3e MC |
291 | if (!copy_email(ctx, gens, 1)) |
292 | goto err; | |
293 | } else { | |
294 | GENERAL_NAME *gen; | |
75ebbd9a | 295 | if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) |
0f113f3e MC |
296 | goto err; |
297 | sk_GENERAL_NAME_push(gens, gen); | |
298 | } | |
299 | } | |
300 | return gens; | |
301 | err: | |
302 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | |
303 | return NULL; | |
aa066b9e DSH |
304 | } |
305 | ||
0f113f3e MC |
306 | /* |
307 | * Copy any email addresses in a certificate or request to GENERAL_NAMES | |
aa066b9e DSH |
308 | */ |
309 | ||
c9fd77e9 | 310 | static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) |
aa066b9e | 311 | { |
0f113f3e MC |
312 | X509_NAME *nm; |
313 | ASN1_IA5STRING *email = NULL; | |
314 | X509_NAME_ENTRY *ne; | |
315 | GENERAL_NAME *gen = NULL; | |
d2a56999 F |
316 | int i = -1; |
317 | ||
0f113f3e MC |
318 | if (ctx != NULL && ctx->flags == CTX_TEST) |
319 | return 1; | |
d2a56999 F |
320 | if (ctx == NULL |
321 | || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { | |
0f113f3e MC |
322 | X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); |
323 | goto err; | |
324 | } | |
325 | /* Find the subject name */ | |
326 | if (ctx->subject_cert) | |
327 | nm = X509_get_subject_name(ctx->subject_cert); | |
328 | else | |
329 | nm = X509_REQ_get_subject_name(ctx->subject_req); | |
330 | ||
331 | /* Now add any email address(es) to STACK */ | |
0f113f3e MC |
332 | while ((i = X509_NAME_get_index_by_NID(nm, |
333 | NID_pkcs9_emailAddress, i)) >= 0) { | |
334 | ne = X509_NAME_get_entry(nm, i); | |
f422a514 | 335 | email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); |
0f113f3e MC |
336 | if (move_p) { |
337 | X509_NAME_delete_entry(nm, i); | |
338 | X509_NAME_ENTRY_free(ne); | |
339 | i--; | |
340 | } | |
75ebbd9a | 341 | if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) { |
0f113f3e MC |
342 | X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); |
343 | goto err; | |
344 | } | |
345 | gen->d.ia5 = email; | |
346 | email = NULL; | |
347 | gen->type = GEN_EMAIL; | |
348 | if (!sk_GENERAL_NAME_push(gens, gen)) { | |
349 | X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); | |
350 | goto err; | |
351 | } | |
352 | gen = NULL; | |
353 | } | |
354 | ||
355 | return 1; | |
356 | ||
357 | err: | |
358 | GENERAL_NAME_free(gen); | |
f422a514 | 359 | ASN1_IA5STRING_free(email); |
0f113f3e MC |
360 | return 0; |
361 | ||
aa066b9e DSH |
362 | } |
363 | ||
babb3798 | 364 | GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, |
0f113f3e | 365 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) |
d08d8da4 | 366 | { |
0f113f3e MC |
367 | GENERAL_NAME *gen; |
368 | GENERAL_NAMES *gens = NULL; | |
369 | CONF_VALUE *cnf; | |
370 | int i; | |
75ebbd9a RS |
371 | |
372 | if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { | |
0f113f3e MC |
373 | X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); |
374 | return NULL; | |
375 | } | |
376 | for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { | |
377 | cnf = sk_CONF_VALUE_value(nval, i); | |
75ebbd9a | 378 | if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) |
0f113f3e MC |
379 | goto err; |
380 | sk_GENERAL_NAME_push(gens, gen); | |
381 | } | |
382 | return gens; | |
383 | err: | |
384 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | |
385 | return NULL; | |
d08d8da4 DSH |
386 | } |
387 | ||
0f113f3e MC |
388 | GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, |
389 | X509V3_CTX *ctx, CONF_VALUE *cnf) | |
390 | { | |
391 | return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); | |
392 | } | |
d08d8da4 | 393 | |
be86c7fc | 394 | GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, |
0f113f3e | 395 | const X509V3_EXT_METHOD *method, |
c8f717fe | 396 | X509V3_CTX *ctx, int gen_type, const char *value, |
0f113f3e MC |
397 | int is_nc) |
398 | { | |
399 | char is_string = 0; | |
400 | GENERAL_NAME *gen = NULL; | |
401 | ||
402 | if (!value) { | |
403 | X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); | |
404 | return NULL; | |
405 | } | |
406 | ||
407 | if (out) | |
408 | gen = out; | |
409 | else { | |
410 | gen = GENERAL_NAME_new(); | |
411 | if (gen == NULL) { | |
412 | X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); | |
413 | return NULL; | |
414 | } | |
415 | } | |
416 | ||
417 | switch (gen_type) { | |
418 | case GEN_URI: | |
419 | case GEN_EMAIL: | |
420 | case GEN_DNS: | |
421 | is_string = 1; | |
422 | break; | |
423 | ||
424 | case GEN_RID: | |
425 | { | |
426 | ASN1_OBJECT *obj; | |
75ebbd9a | 427 | if ((obj = OBJ_txt2obj(value, 0)) == NULL) { |
0f113f3e MC |
428 | X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); |
429 | ERR_add_error_data(2, "value=", value); | |
430 | goto err; | |
431 | } | |
432 | gen->d.rid = obj; | |
433 | } | |
434 | break; | |
435 | ||
436 | case GEN_IPADD: | |
437 | if (is_nc) | |
438 | gen->d.ip = a2i_IPADDRESS_NC(value); | |
439 | else | |
440 | gen->d.ip = a2i_IPADDRESS(value); | |
441 | if (gen->d.ip == NULL) { | |
442 | X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); | |
443 | ERR_add_error_data(2, "value=", value); | |
444 | goto err; | |
445 | } | |
446 | break; | |
447 | ||
448 | case GEN_DIRNAME: | |
449 | if (!do_dirname(gen, value, ctx)) { | |
450 | X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); | |
451 | goto err; | |
452 | } | |
453 | break; | |
454 | ||
455 | case GEN_OTHERNAME: | |
456 | if (!do_othername(gen, value, ctx)) { | |
457 | X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); | |
458 | goto err; | |
459 | } | |
460 | break; | |
461 | default: | |
462 | X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); | |
463 | goto err; | |
464 | } | |
465 | ||
466 | if (is_string) { | |
75ebbd9a | 467 | if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || |
0f113f3e MC |
468 | !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, |
469 | strlen(value))) { | |
470 | X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); | |
471 | goto err; | |
472 | } | |
473 | } | |
474 | ||
475 | gen->type = gen_type; | |
476 | ||
477 | return gen; | |
478 | ||
479 | err: | |
480 | if (!out) | |
481 | GENERAL_NAME_free(gen); | |
482 | return NULL; | |
483 | } | |
9ea1b878 | 484 | |
be86c7fc | 485 | GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, |
0f113f3e MC |
486 | const X509V3_EXT_METHOD *method, |
487 | X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) | |
488 | { | |
489 | int type; | |
490 | ||
491 | char *name, *value; | |
492 | ||
493 | name = cnf->name; | |
494 | value = cnf->value; | |
495 | ||
496 | if (!value) { | |
497 | X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); | |
498 | return NULL; | |
499 | } | |
500 | ||
501 | if (!name_cmp(name, "email")) | |
502 | type = GEN_EMAIL; | |
503 | else if (!name_cmp(name, "URI")) | |
504 | type = GEN_URI; | |
505 | else if (!name_cmp(name, "DNS")) | |
506 | type = GEN_DNS; | |
507 | else if (!name_cmp(name, "RID")) | |
508 | type = GEN_RID; | |
509 | else if (!name_cmp(name, "IP")) | |
510 | type = GEN_IPADD; | |
511 | else if (!name_cmp(name, "dirName")) | |
512 | type = GEN_DIRNAME; | |
513 | else if (!name_cmp(name, "otherName")) | |
514 | type = GEN_OTHERNAME; | |
515 | else { | |
516 | X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); | |
517 | ERR_add_error_data(2, "name=", name); | |
518 | return NULL; | |
519 | } | |
520 | ||
521 | return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); | |
522 | ||
523 | } | |
be86c7fc | 524 | |
c8f717fe | 525 | static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) |
0f113f3e MC |
526 | { |
527 | char *objtmp = NULL, *p; | |
528 | int objlen; | |
75ebbd9a RS |
529 | |
530 | if ((p = strchr(value, ';')) == NULL) | |
0f113f3e | 531 | return 0; |
75ebbd9a | 532 | if ((gen->d.otherName = OTHERNAME_new()) == NULL) |
0f113f3e MC |
533 | return 0; |
534 | /* | |
535 | * Free this up because we will overwrite it. no need to free type_id | |
536 | * because it is static | |
537 | */ | |
538 | ASN1_TYPE_free(gen->d.otherName->value); | |
75ebbd9a | 539 | if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL) |
0f113f3e MC |
540 | return 0; |
541 | objlen = p - value; | |
5e04cfde | 542 | objtmp = OPENSSL_strndup(value, objlen); |
0f113f3e MC |
543 | if (objtmp == NULL) |
544 | return 0; | |
0f113f3e MC |
545 | gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); |
546 | OPENSSL_free(objtmp); | |
547 | if (!gen->d.otherName->type_id) | |
548 | return 0; | |
549 | return 1; | |
550 | } | |
f0dc08e6 | 551 | |
c8f717fe | 552 | static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) |
0f113f3e | 553 | { |
8ec5c5dd KR |
554 | int ret = 0; |
555 | STACK_OF(CONF_VALUE) *sk = NULL; | |
75ebbd9a RS |
556 | X509_NAME *nm; |
557 | ||
558 | if ((nm = X509_NAME_new()) == NULL) | |
8ec5c5dd | 559 | goto err; |
0f113f3e MC |
560 | sk = X509V3_get_section(ctx, value); |
561 | if (!sk) { | |
562 | X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); | |
563 | ERR_add_error_data(2, "section=", value); | |
8ec5c5dd | 564 | goto err; |
0f113f3e MC |
565 | } |
566 | /* FIXME: should allow other character types... */ | |
567 | ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); | |
568 | if (!ret) | |
8ec5c5dd | 569 | goto err; |
0f113f3e | 570 | gen->d.dirn = nm; |
0f113f3e | 571 | |
8ec5c5dd KR |
572 | err: |
573 | if (ret == 0) | |
574 | X509_NAME_free(nm); | |
575 | X509V3_section_free(ctx, sk); | |
0f113f3e MC |
576 | return ret; |
577 | } |