Line data Source code
1 : /* v3_alt.c */
2 : /*
3 : * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 : * project.
5 : */
6 : /* ====================================================================
7 : * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : *
13 : * 1. Redistributions of source code must retain the above copyright
14 : * notice, this list of conditions and the following disclaimer.
15 : *
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in
18 : * the documentation and/or other materials provided with the
19 : * distribution.
20 : *
21 : * 3. All advertising materials mentioning features or use of this
22 : * software must display the following acknowledgment:
23 : * "This product includes software developed by the OpenSSL Project
24 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 : *
26 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 : * endorse or promote products derived from this software without
28 : * prior written permission. For written permission, please contact
29 : * licensing@OpenSSL.org.
30 : *
31 : * 5. Products derived from this software may not be called "OpenSSL"
32 : * nor may "OpenSSL" appear in their names without prior written
33 : * permission of the OpenSSL Project.
34 : *
35 : * 6. Redistributions of any form whatsoever must retain the following
36 : * acknowledgment:
37 : * "This product includes software developed by the OpenSSL Project
38 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 : *
40 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 : * OF THE POSSIBILITY OF SUCH DAMAGE.
52 : * ====================================================================
53 : *
54 : * This product includes cryptographic software written by Eric Young
55 : * (eay@cryptsoft.com). This product includes software written by Tim
56 : * Hudson (tjh@cryptsoft.com).
57 : *
58 : */
59 :
60 : #include <stdio.h>
61 : #include "cryptlib.h"
62 : #include <openssl/conf.h>
63 : #include <openssl/x509v3.h>
64 :
65 : static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
66 : X509V3_CTX *ctx,
67 : STACK_OF(CONF_VALUE) *nval);
68 : static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
69 : X509V3_CTX *ctx,
70 : STACK_OF(CONF_VALUE) *nval);
71 : static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
72 : static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
73 : static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
74 : static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
75 :
76 : const X509V3_EXT_METHOD v3_alt[] = {
77 : {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
78 : 0, 0, 0, 0,
79 : 0, 0,
80 : (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
81 : (X509V3_EXT_V2I)v2i_subject_alt,
82 : NULL, NULL, NULL},
83 :
84 : {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
85 : 0, 0, 0, 0,
86 : 0, 0,
87 : (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
88 : (X509V3_EXT_V2I)v2i_issuer_alt,
89 : NULL, NULL, NULL},
90 :
91 : {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
92 : 0, 0, 0, 0,
93 : 0, 0,
94 : (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
95 : NULL, NULL, NULL, NULL},
96 : };
97 :
98 0 : STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
99 : GENERAL_NAMES *gens,
100 : STACK_OF(CONF_VALUE) *ret)
101 : {
102 : int i;
103 : GENERAL_NAME *gen;
104 0 : for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
105 0 : gen = sk_GENERAL_NAME_value(gens, i);
106 0 : ret = i2v_GENERAL_NAME(method, gen, ret);
107 : }
108 0 : if (!ret)
109 0 : return sk_CONF_VALUE_new_null();
110 : return ret;
111 : }
112 :
113 0 : STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
114 : GENERAL_NAME *gen,
115 : STACK_OF(CONF_VALUE) *ret)
116 : {
117 : unsigned char *p;
118 : char oline[256], htmp[5];
119 : int i;
120 0 : switch (gen->type) {
121 : case GEN_OTHERNAME:
122 0 : X509V3_add_value("othername", "<unsupported>", &ret);
123 0 : break;
124 :
125 : case GEN_X400:
126 0 : X509V3_add_value("X400Name", "<unsupported>", &ret);
127 0 : break;
128 :
129 : case GEN_EDIPARTY:
130 0 : X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
131 0 : break;
132 :
133 : case GEN_EMAIL:
134 0 : X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
135 0 : break;
136 :
137 : case GEN_DNS:
138 0 : X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
139 0 : break;
140 :
141 : case GEN_URI:
142 0 : X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
143 0 : break;
144 :
145 : case GEN_DIRNAME:
146 0 : X509_NAME_oneline(gen->d.dirn, oline, 256);
147 0 : X509V3_add_value("DirName", oline, &ret);
148 0 : break;
149 :
150 : case GEN_IPADD:
151 0 : p = gen->d.ip->data;
152 0 : if (gen->d.ip->length == 4)
153 0 : BIO_snprintf(oline, sizeof oline,
154 0 : "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
155 0 : else if (gen->d.ip->length == 16) {
156 0 : oline[0] = 0;
157 0 : for (i = 0; i < 8; i++) {
158 0 : BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
159 0 : p += 2;
160 : strcat(oline, htmp);
161 0 : if (i != 7)
162 : strcat(oline, ":");
163 : }
164 : } else {
165 0 : X509V3_add_value("IP Address", "<invalid>", &ret);
166 0 : break;
167 : }
168 0 : X509V3_add_value("IP Address", oline, &ret);
169 0 : break;
170 :
171 : case GEN_RID:
172 0 : i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
173 0 : X509V3_add_value("Registered ID", oline, &ret);
174 0 : break;
175 : }
176 0 : return ret;
177 : }
178 :
179 0 : int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
180 : {
181 : unsigned char *p;
182 : int i;
183 0 : switch (gen->type) {
184 : case GEN_OTHERNAME:
185 0 : BIO_printf(out, "othername:<unsupported>");
186 0 : break;
187 :
188 : case GEN_X400:
189 0 : BIO_printf(out, "X400Name:<unsupported>");
190 0 : break;
191 :
192 : case GEN_EDIPARTY:
193 : /* Maybe fix this: it is supported now */
194 0 : BIO_printf(out, "EdiPartyName:<unsupported>");
195 0 : break;
196 :
197 : case GEN_EMAIL:
198 0 : BIO_printf(out, "email:%s", gen->d.ia5->data);
199 0 : break;
200 :
201 : case GEN_DNS:
202 0 : BIO_printf(out, "DNS:%s", gen->d.ia5->data);
203 0 : break;
204 :
205 : case GEN_URI:
206 0 : BIO_printf(out, "URI:%s", gen->d.ia5->data);
207 0 : break;
208 :
209 : case GEN_DIRNAME:
210 0 : BIO_printf(out, "DirName: ");
211 0 : X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
212 0 : break;
213 :
214 : case GEN_IPADD:
215 0 : p = gen->d.ip->data;
216 0 : if (gen->d.ip->length == 4)
217 0 : BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
218 0 : else if (gen->d.ip->length == 16) {
219 0 : BIO_printf(out, "IP Address");
220 0 : for (i = 0; i < 8; i++) {
221 0 : BIO_printf(out, ":%X", p[0] << 8 | p[1]);
222 0 : p += 2;
223 : }
224 0 : BIO_puts(out, "\n");
225 : } else {
226 0 : BIO_printf(out, "IP Address:<invalid>");
227 0 : break;
228 : }
229 : break;
230 :
231 : case GEN_RID:
232 0 : BIO_printf(out, "Registered ID");
233 0 : i2a_ASN1_OBJECT(out, gen->d.rid);
234 0 : break;
235 : }
236 0 : return 1;
237 : }
238 :
239 0 : static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
240 : X509V3_CTX *ctx,
241 : STACK_OF(CONF_VALUE) *nval)
242 : {
243 : GENERAL_NAMES *gens = NULL;
244 : CONF_VALUE *cnf;
245 : int i;
246 0 : if (!(gens = sk_GENERAL_NAME_new_null())) {
247 0 : X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
248 0 : return NULL;
249 : }
250 0 : for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
251 0 : cnf = sk_CONF_VALUE_value(nval, i);
252 0 : if (!name_cmp(cnf->name, "issuer") && cnf->value &&
253 0 : !strcmp(cnf->value, "copy")) {
254 0 : if (!copy_issuer(ctx, gens))
255 : goto err;
256 : } else {
257 : GENERAL_NAME *gen;
258 0 : if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
259 : goto err;
260 0 : sk_GENERAL_NAME_push(gens, gen);
261 : }
262 : }
263 : return gens;
264 : err:
265 0 : sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
266 0 : return NULL;
267 : }
268 :
269 : /* Append subject altname of issuer to issuer alt name of subject */
270 :
271 0 : static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
272 : {
273 : GENERAL_NAMES *ialt;
274 : GENERAL_NAME *gen;
275 : X509_EXTENSION *ext;
276 : int i;
277 0 : if (ctx && (ctx->flags == CTX_TEST))
278 : return 1;
279 0 : if (!ctx || !ctx->issuer_cert) {
280 0 : X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS);
281 0 : goto err;
282 : }
283 0 : i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
284 0 : if (i < 0)
285 : return 1;
286 0 : if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
287 : !(ialt = X509V3_EXT_d2i(ext))) {
288 0 : X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR);
289 0 : goto err;
290 : }
291 :
292 0 : for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
293 0 : gen = sk_GENERAL_NAME_value(ialt, i);
294 0 : if (!sk_GENERAL_NAME_push(gens, gen)) {
295 0 : X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
296 0 : goto err;
297 : }
298 : }
299 0 : sk_GENERAL_NAME_free(ialt);
300 :
301 0 : return 1;
302 :
303 : err:
304 : return 0;
305 :
306 : }
307 :
308 0 : static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
309 : X509V3_CTX *ctx,
310 : STACK_OF(CONF_VALUE) *nval)
311 : {
312 : GENERAL_NAMES *gens = NULL;
313 : CONF_VALUE *cnf;
314 : int i;
315 0 : if (!(gens = sk_GENERAL_NAME_new_null())) {
316 0 : X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
317 0 : return NULL;
318 : }
319 0 : for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
320 0 : cnf = sk_CONF_VALUE_value(nval, i);
321 0 : if (!name_cmp(cnf->name, "email") && cnf->value &&
322 0 : !strcmp(cnf->value, "copy")) {
323 0 : if (!copy_email(ctx, gens, 0))
324 : goto err;
325 0 : } else if (!name_cmp(cnf->name, "email") && cnf->value &&
326 0 : !strcmp(cnf->value, "move")) {
327 0 : if (!copy_email(ctx, gens, 1))
328 : goto err;
329 : } else {
330 : GENERAL_NAME *gen;
331 0 : if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
332 : goto err;
333 0 : sk_GENERAL_NAME_push(gens, gen);
334 : }
335 : }
336 : return gens;
337 : err:
338 0 : sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
339 0 : return NULL;
340 : }
341 :
342 : /*
343 : * Copy any email addresses in a certificate or request to GENERAL_NAMES
344 : */
345 :
346 0 : static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
347 : {
348 : X509_NAME *nm;
349 : ASN1_IA5STRING *email = NULL;
350 : X509_NAME_ENTRY *ne;
351 : GENERAL_NAME *gen = NULL;
352 : int i;
353 0 : if (ctx != NULL && ctx->flags == CTX_TEST)
354 : return 1;
355 0 : if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
356 0 : X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS);
357 0 : goto err;
358 : }
359 : /* Find the subject name */
360 0 : if (ctx->subject_cert)
361 0 : nm = X509_get_subject_name(ctx->subject_cert);
362 : else
363 0 : nm = X509_REQ_get_subject_name(ctx->subject_req);
364 :
365 : /* Now add any email address(es) to STACK */
366 : i = -1;
367 0 : while ((i = X509_NAME_get_index_by_NID(nm,
368 : NID_pkcs9_emailAddress, i)) >= 0) {
369 0 : ne = X509_NAME_get_entry(nm, i);
370 0 : email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
371 0 : if (move_p) {
372 0 : X509_NAME_delete_entry(nm, i);
373 0 : X509_NAME_ENTRY_free(ne);
374 0 : i--;
375 : }
376 0 : if (!email || !(gen = GENERAL_NAME_new())) {
377 0 : X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
378 0 : goto err;
379 : }
380 0 : gen->d.ia5 = email;
381 : email = NULL;
382 0 : gen->type = GEN_EMAIL;
383 0 : if (!sk_GENERAL_NAME_push(gens, gen)) {
384 0 : X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
385 0 : goto err;
386 : }
387 : gen = NULL;
388 : }
389 :
390 : return 1;
391 :
392 : err:
393 0 : GENERAL_NAME_free(gen);
394 0 : M_ASN1_IA5STRING_free(email);
395 0 : return 0;
396 :
397 : }
398 :
399 0 : GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
400 : X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
401 : {
402 : GENERAL_NAME *gen;
403 : GENERAL_NAMES *gens = NULL;
404 : CONF_VALUE *cnf;
405 : int i;
406 0 : if (!(gens = sk_GENERAL_NAME_new_null())) {
407 0 : X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
408 0 : return NULL;
409 : }
410 0 : for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
411 0 : cnf = sk_CONF_VALUE_value(nval, i);
412 0 : if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
413 : goto err;
414 0 : sk_GENERAL_NAME_push(gens, gen);
415 : }
416 : return gens;
417 : err:
418 0 : sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
419 0 : return NULL;
420 : }
421 :
422 0 : GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
423 : X509V3_CTX *ctx, CONF_VALUE *cnf)
424 : {
425 0 : return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
426 : }
427 :
428 0 : GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
429 : const X509V3_EXT_METHOD *method,
430 : X509V3_CTX *ctx, int gen_type, char *value,
431 : int is_nc)
432 : {
433 : char is_string = 0;
434 : GENERAL_NAME *gen = NULL;
435 :
436 0 : if (!value) {
437 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE);
438 0 : return NULL;
439 : }
440 :
441 0 : if (out)
442 : gen = out;
443 : else {
444 0 : gen = GENERAL_NAME_new();
445 0 : if (gen == NULL) {
446 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
447 0 : return NULL;
448 : }
449 : }
450 :
451 0 : switch (gen_type) {
452 : case GEN_URI:
453 : case GEN_EMAIL:
454 : case GEN_DNS:
455 : is_string = 1;
456 : break;
457 :
458 : case GEN_RID:
459 : {
460 : ASN1_OBJECT *obj;
461 0 : if (!(obj = OBJ_txt2obj(value, 0))) {
462 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT);
463 0 : ERR_add_error_data(2, "value=", value);
464 0 : goto err;
465 : }
466 0 : gen->d.rid = obj;
467 : }
468 0 : break;
469 :
470 : case GEN_IPADD:
471 0 : if (is_nc)
472 0 : gen->d.ip = a2i_IPADDRESS_NC(value);
473 : else
474 0 : gen->d.ip = a2i_IPADDRESS(value);
475 0 : if (gen->d.ip == NULL) {
476 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
477 0 : ERR_add_error_data(2, "value=", value);
478 0 : goto err;
479 : }
480 : break;
481 :
482 : case GEN_DIRNAME:
483 0 : if (!do_dirname(gen, value, ctx)) {
484 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
485 0 : goto err;
486 : }
487 : break;
488 :
489 : case GEN_OTHERNAME:
490 0 : if (!do_othername(gen, value, ctx)) {
491 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
492 0 : goto err;
493 : }
494 : break;
495 : default:
496 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
497 0 : goto err;
498 : }
499 :
500 0 : if (is_string) {
501 0 : if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
502 0 : !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
503 0 : strlen(value))) {
504 0 : X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
505 0 : goto err;
506 : }
507 : }
508 :
509 0 : gen->type = gen_type;
510 :
511 0 : return gen;
512 :
513 : err:
514 0 : if (!out)
515 0 : GENERAL_NAME_free(gen);
516 : return NULL;
517 : }
518 :
519 0 : GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
520 : const X509V3_EXT_METHOD *method,
521 : X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
522 : {
523 : int type;
524 :
525 : char *name, *value;
526 :
527 0 : name = cnf->name;
528 0 : value = cnf->value;
529 :
530 0 : if (!value) {
531 0 : X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE);
532 0 : return NULL;
533 : }
534 :
535 0 : if (!name_cmp(name, "email"))
536 : type = GEN_EMAIL;
537 0 : else if (!name_cmp(name, "URI"))
538 : type = GEN_URI;
539 0 : else if (!name_cmp(name, "DNS"))
540 : type = GEN_DNS;
541 0 : else if (!name_cmp(name, "RID"))
542 : type = GEN_RID;
543 0 : else if (!name_cmp(name, "IP"))
544 : type = GEN_IPADD;
545 0 : else if (!name_cmp(name, "dirName"))
546 : type = GEN_DIRNAME;
547 0 : else if (!name_cmp(name, "otherName"))
548 : type = GEN_OTHERNAME;
549 : else {
550 0 : X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION);
551 0 : ERR_add_error_data(2, "name=", name);
552 0 : return NULL;
553 : }
554 :
555 0 : return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
556 :
557 : }
558 :
559 0 : static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
560 : {
561 : char *objtmp = NULL, *p;
562 : int objlen;
563 0 : if (!(p = strchr(value, ';')))
564 : return 0;
565 0 : if (!(gen->d.otherName = OTHERNAME_new()))
566 : return 0;
567 : /*
568 : * Free this up because we will overwrite it. no need to free type_id
569 : * because it is static
570 : */
571 0 : ASN1_TYPE_free(gen->d.otherName->value);
572 0 : if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
573 : return 0;
574 0 : objlen = p - value;
575 0 : objtmp = OPENSSL_malloc(objlen + 1);
576 0 : strncpy(objtmp, value, objlen);
577 0 : objtmp[objlen] = 0;
578 0 : gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
579 0 : OPENSSL_free(objtmp);
580 0 : if (!gen->d.otherName->type_id)
581 : return 0;
582 : return 1;
583 : }
584 :
585 0 : static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
586 : {
587 : int ret = 0;
588 : STACK_OF(CONF_VALUE) *sk = NULL;
589 : X509_NAME *nm = NULL;
590 0 : if (!(nm = X509_NAME_new()))
591 : goto err;
592 0 : sk = X509V3_get_section(ctx, value);
593 0 : if (!sk) {
594 0 : X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
595 0 : ERR_add_error_data(2, "section=", value);
596 : goto err;
597 : }
598 : /* FIXME: should allow other character types... */
599 0 : ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
600 0 : if (!ret)
601 : goto err;
602 0 : gen->d.dirn = nm;
603 :
604 : err:
605 0 : if (ret == 0)
606 0 : X509_NAME_free(nm);
607 0 : X509V3_section_free(ctx, sk);
608 0 : return ret;
609 : }
|