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 #include <stdio.h>
59 #include <string.h>
60
61 #include <openssl/conf.h>
62 #include <openssl/err.h>
63 #include <openssl/mem.h>
64 #include <openssl/obj.h>
65 #include <openssl/x509v3.h>
66
67 #include "internal.h"
68
69
70 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
71 X509V3_CTX *ctx,
72 STACK_OF(CONF_VALUE) *nval);
73 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
74 X509V3_CTX *ctx,
75 STACK_OF(CONF_VALUE) *nval);
76 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
77 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
78 static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
79 static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
80
81 const X509V3_EXT_METHOD v3_alt[] = {
82 {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
83 0, 0, 0, 0,
84 0, 0,
85 (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
86 (X509V3_EXT_V2I)v2i_subject_alt,
87 NULL, NULL, NULL},
88
89 {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
90 0, 0, 0, 0,
91 0, 0,
92 (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
93 (X509V3_EXT_V2I)v2i_issuer_alt,
94 NULL, NULL, NULL},
95
96 {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
97 0, 0, 0, 0,
98 0, 0,
99 (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
100 NULL, NULL, NULL, NULL},
101 };
102
STACK_OF(CONF_VALUE)103 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
104 GENERAL_NAMES *gens,
105 STACK_OF(CONF_VALUE) *ret)
106 {
107 int ret_was_null = ret == NULL;
108 for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
109 GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
110 STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret);
111 if (tmp == NULL) {
112 if (ret_was_null) {
113 sk_CONF_VALUE_pop_free(ret, X509V3_conf_free);
114 }
115 return NULL;
116 }
117 ret = tmp;
118 }
119 if (!ret)
120 return sk_CONF_VALUE_new_null();
121 return ret;
122 }
123
STACK_OF(CONF_VALUE)124 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
125 GENERAL_NAME *gen,
126 STACK_OF(CONF_VALUE) *ret)
127 {
128 /* Note the error-handling for this function relies on there being at most
129 * one |X509V3_add_value| call. If there were two and the second failed, we
130 * would need to sometimes free the first call's result. */
131 unsigned char *p;
132 char oline[256], htmp[5];
133 int i;
134 switch (gen->type) {
135 case GEN_OTHERNAME:
136 if (!X509V3_add_value("othername", "<unsupported>", &ret))
137 return NULL;
138 break;
139
140 case GEN_X400:
141 if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
142 return NULL;
143 break;
144
145 case GEN_EDIPARTY:
146 if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
147 return NULL;
148 break;
149
150 case GEN_EMAIL:
151 if (!x509V3_add_value_asn1_string("email", gen->d.ia5, &ret))
152 return NULL;
153 break;
154
155 case GEN_DNS:
156 if (!x509V3_add_value_asn1_string("DNS", gen->d.ia5, &ret))
157 return NULL;
158 break;
159
160 case GEN_URI:
161 if (!x509V3_add_value_asn1_string("URI", gen->d.ia5, &ret))
162 return NULL;
163 break;
164
165 case GEN_DIRNAME:
166 if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL
167 || !X509V3_add_value("DirName", oline, &ret))
168 return NULL;
169 break;
170
171 case GEN_IPADD:
172 p = gen->d.ip->data;
173 if (gen->d.ip->length == 4)
174 BIO_snprintf(oline, sizeof oline,
175 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
176 else if (gen->d.ip->length == 16) {
177 oline[0] = 0;
178 for (i = 0; i < 8; i++) {
179 BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
180 p += 2;
181 OPENSSL_strlcat(oline, htmp, sizeof(oline));
182 if (i != 7)
183 OPENSSL_strlcat(oline, ":", sizeof(oline));
184 }
185 } else {
186 if (!X509V3_add_value("IP Address", "<invalid>", &ret))
187 return NULL;
188 break;
189 }
190 if (!X509V3_add_value("IP Address", oline, &ret))
191 return NULL;
192 break;
193
194 case GEN_RID:
195 i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
196 if (!X509V3_add_value("Registered ID", oline, &ret))
197 return NULL;
198 break;
199 }
200 return ret;
201 }
202
GENERAL_NAME_print(BIO * out,GENERAL_NAME * gen)203 int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
204 {
205 unsigned char *p;
206 int i;
207 switch (gen->type) {
208 case GEN_OTHERNAME:
209 BIO_printf(out, "othername:<unsupported>");
210 break;
211
212 case GEN_X400:
213 BIO_printf(out, "X400Name:<unsupported>");
214 break;
215
216 case GEN_EDIPARTY:
217 /* Maybe fix this: it is supported now */
218 BIO_printf(out, "EdiPartyName:<unsupported>");
219 break;
220
221 case GEN_EMAIL:
222 BIO_printf(out, "email:");
223 ASN1_STRING_print(out, gen->d.ia5);
224 break;
225
226 case GEN_DNS:
227 BIO_printf(out, "DNS:");
228 ASN1_STRING_print(out, gen->d.ia5);
229 break;
230
231 case GEN_URI:
232 BIO_printf(out, "URI:");
233 ASN1_STRING_print(out, gen->d.ia5);
234 break;
235
236 case GEN_DIRNAME:
237 BIO_printf(out, "DirName: ");
238 X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
239 break;
240
241 case GEN_IPADD:
242 p = gen->d.ip->data;
243 if (gen->d.ip->length == 4)
244 BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
245 else if (gen->d.ip->length == 16) {
246 BIO_printf(out, "IP Address");
247 for (i = 0; i < 8; i++) {
248 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
249 p += 2;
250 }
251 BIO_puts(out, "\n");
252 } else {
253 BIO_printf(out, "IP Address:<invalid>");
254 break;
255 }
256 break;
257
258 case GEN_RID:
259 BIO_printf(out, "Registered ID");
260 i2a_ASN1_OBJECT(out, gen->d.rid);
261 break;
262 }
263 return 1;
264 }
265
v2i_issuer_alt(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)266 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
267 X509V3_CTX *ctx,
268 STACK_OF(CONF_VALUE) *nval)
269 {
270 GENERAL_NAMES *gens = NULL;
271 CONF_VALUE *cnf;
272 size_t i;
273 if (!(gens = sk_GENERAL_NAME_new_null())) {
274 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
275 return NULL;
276 }
277 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
278 cnf = sk_CONF_VALUE_value(nval, i);
279 if (!x509v3_name_cmp(cnf->name, "issuer") && cnf->value &&
280 !strcmp(cnf->value, "copy")) {
281 if (!copy_issuer(ctx, gens))
282 goto err;
283 } else {
284 GENERAL_NAME *gen;
285 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
286 goto err;
287 sk_GENERAL_NAME_push(gens, gen);
288 }
289 }
290 return gens;
291 err:
292 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
293 return NULL;
294 }
295
296 /* Append subject altname of issuer to issuer alt name of subject */
297
copy_issuer(X509V3_CTX * ctx,GENERAL_NAMES * gens)298 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
299 {
300 if (ctx && (ctx->flags == CTX_TEST))
301 return 1;
302 if (!ctx || !ctx->issuer_cert) {
303 OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
304 return 0;
305 }
306 int i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
307 if (i < 0)
308 return 1;
309
310 int ret = 0;
311 GENERAL_NAMES *ialt = NULL;
312 X509_EXTENSION *ext;
313 if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
314 !(ialt = X509V3_EXT_d2i(ext))) {
315 OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
316 goto err;
317 }
318
319 for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
320 GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j);
321 if (!sk_GENERAL_NAME_push(gens, gen)) {
322 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
323 goto err;
324 }
325 /* Ownership of |gen| has moved from |ialt| to |gens|. */
326 sk_GENERAL_NAME_set(ialt, j, NULL);
327 }
328
329 ret = 1;
330
331 err:
332 GENERAL_NAMES_free(ialt);
333 return ret;
334 }
335
v2i_subject_alt(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)336 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
337 X509V3_CTX *ctx,
338 STACK_OF(CONF_VALUE) *nval)
339 {
340 GENERAL_NAMES *gens = NULL;
341 CONF_VALUE *cnf;
342 size_t i;
343 if (!(gens = sk_GENERAL_NAME_new_null())) {
344 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
345 return NULL;
346 }
347 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
348 cnf = sk_CONF_VALUE_value(nval, i);
349 if (!x509v3_name_cmp(cnf->name, "email") && cnf->value &&
350 !strcmp(cnf->value, "copy")) {
351 if (!copy_email(ctx, gens, 0))
352 goto err;
353 } else if (!x509v3_name_cmp(cnf->name, "email") && cnf->value &&
354 !strcmp(cnf->value, "move")) {
355 if (!copy_email(ctx, gens, 1))
356 goto err;
357 } else {
358 GENERAL_NAME *gen;
359 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
360 goto err;
361 sk_GENERAL_NAME_push(gens, gen);
362 }
363 }
364 return gens;
365 err:
366 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
367 return NULL;
368 }
369
370 /*
371 * Copy any email addresses in a certificate or request to GENERAL_NAMES
372 */
373
copy_email(X509V3_CTX * ctx,GENERAL_NAMES * gens,int move_p)374 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
375 {
376 X509_NAME *nm;
377 ASN1_IA5STRING *email = NULL;
378 X509_NAME_ENTRY *ne;
379 GENERAL_NAME *gen = NULL;
380 int i;
381 if (ctx != NULL && ctx->flags == CTX_TEST)
382 return 1;
383 if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
384 OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
385 goto err;
386 }
387 /* Find the subject name */
388 if (ctx->subject_cert)
389 nm = X509_get_subject_name(ctx->subject_cert);
390 else
391 nm = X509_REQ_get_subject_name(ctx->subject_req);
392
393 /* Now add any email address(es) to STACK */
394 i = -1;
395 while ((i = X509_NAME_get_index_by_NID(nm,
396 NID_pkcs9_emailAddress, i)) >= 0) {
397 ne = X509_NAME_get_entry(nm, i);
398 email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
399 if (move_p) {
400 X509_NAME_delete_entry(nm, i);
401 X509_NAME_ENTRY_free(ne);
402 i--;
403 }
404 if (!email || !(gen = GENERAL_NAME_new())) {
405 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
406 goto err;
407 }
408 gen->d.ia5 = email;
409 email = NULL;
410 gen->type = GEN_EMAIL;
411 if (!sk_GENERAL_NAME_push(gens, gen)) {
412 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
413 goto err;
414 }
415 gen = NULL;
416 }
417
418 return 1;
419
420 err:
421 GENERAL_NAME_free(gen);
422 ASN1_IA5STRING_free(email);
423 return 0;
424
425 }
426
v2i_GENERAL_NAMES(const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)427 GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
428 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
429 {
430 GENERAL_NAME *gen;
431 GENERAL_NAMES *gens = NULL;
432 CONF_VALUE *cnf;
433 size_t i;
434 if (!(gens = sk_GENERAL_NAME_new_null())) {
435 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
436 return NULL;
437 }
438 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
439 cnf = sk_CONF_VALUE_value(nval, i);
440 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
441 goto err;
442 sk_GENERAL_NAME_push(gens, gen);
443 }
444 return gens;
445 err:
446 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
447 return NULL;
448 }
449
v2i_GENERAL_NAME(const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,CONF_VALUE * cnf)450 GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
451 X509V3_CTX *ctx, CONF_VALUE *cnf)
452 {
453 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
454 }
455
a2i_GENERAL_NAME(GENERAL_NAME * out,const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,int gen_type,const char * value,int is_nc)456 GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
457 const X509V3_EXT_METHOD *method,
458 X509V3_CTX *ctx, int gen_type,
459 const char *value, int is_nc)
460 {
461 char is_string = 0;
462 GENERAL_NAME *gen = NULL;
463
464 if (!value) {
465 OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
466 return NULL;
467 }
468
469 if (out)
470 gen = out;
471 else {
472 gen = GENERAL_NAME_new();
473 if (gen == NULL) {
474 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
475 return NULL;
476 }
477 }
478
479 switch (gen_type) {
480 case GEN_URI:
481 case GEN_EMAIL:
482 case GEN_DNS:
483 is_string = 1;
484 break;
485
486 case GEN_RID:
487 {
488 ASN1_OBJECT *obj;
489 if (!(obj = OBJ_txt2obj(value, 0))) {
490 OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
491 ERR_add_error_data(2, "value=", value);
492 goto err;
493 }
494 gen->d.rid = obj;
495 }
496 break;
497
498 case GEN_IPADD:
499 if (is_nc)
500 gen->d.ip = a2i_IPADDRESS_NC(value);
501 else
502 gen->d.ip = a2i_IPADDRESS(value);
503 if (gen->d.ip == NULL) {
504 OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
505 ERR_add_error_data(2, "value=", value);
506 goto err;
507 }
508 break;
509
510 case GEN_DIRNAME:
511 if (!do_dirname(gen, value, ctx)) {
512 OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
513 goto err;
514 }
515 break;
516
517 case GEN_OTHERNAME:
518 if (!do_othername(gen, value, ctx)) {
519 OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
520 goto err;
521 }
522 break;
523 default:
524 OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
525 goto err;
526 }
527
528 if (is_string) {
529 if (!(gen->d.ia5 = ASN1_IA5STRING_new()) ||
530 !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
531 strlen(value))) {
532 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
533 goto err;
534 }
535 }
536
537 gen->type = gen_type;
538
539 return gen;
540
541 err:
542 if (!out)
543 GENERAL_NAME_free(gen);
544 return NULL;
545 }
546
v2i_GENERAL_NAME_ex(GENERAL_NAME * out,const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,CONF_VALUE * cnf,int is_nc)547 GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
548 const X509V3_EXT_METHOD *method,
549 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
550 {
551 int type;
552
553 char *name, *value;
554
555 name = cnf->name;
556 value = cnf->value;
557
558 if (!value) {
559 OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
560 return NULL;
561 }
562
563 if (!x509v3_name_cmp(name, "email"))
564 type = GEN_EMAIL;
565 else if (!x509v3_name_cmp(name, "URI"))
566 type = GEN_URI;
567 else if (!x509v3_name_cmp(name, "DNS"))
568 type = GEN_DNS;
569 else if (!x509v3_name_cmp(name, "RID"))
570 type = GEN_RID;
571 else if (!x509v3_name_cmp(name, "IP"))
572 type = GEN_IPADD;
573 else if (!x509v3_name_cmp(name, "dirName"))
574 type = GEN_DIRNAME;
575 else if (!x509v3_name_cmp(name, "otherName"))
576 type = GEN_OTHERNAME;
577 else {
578 OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
579 ERR_add_error_data(2, "name=", name);
580 return NULL;
581 }
582
583 return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
584
585 }
586
do_othername(GENERAL_NAME * gen,const char * value,X509V3_CTX * ctx)587 static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
588 {
589 char *objtmp = NULL;
590 const char *p;
591 int objlen;
592 if (!(p = strchr(value, ';')))
593 return 0;
594 if (!(gen->d.otherName = OTHERNAME_new()))
595 return 0;
596 /*
597 * Free this up because we will overwrite it. no need to free type_id
598 * because it is static
599 */
600 ASN1_TYPE_free(gen->d.otherName->value);
601 if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
602 return 0;
603 objlen = p - value;
604 objtmp = OPENSSL_malloc(objlen + 1);
605 if (objtmp == NULL)
606 return 0;
607 OPENSSL_strlcpy(objtmp, value, objlen + 1);
608 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
609 OPENSSL_free(objtmp);
610 if (!gen->d.otherName->type_id)
611 return 0;
612 return 1;
613 }
614
do_dirname(GENERAL_NAME * gen,const char * value,X509V3_CTX * ctx)615 static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
616 {
617 int ret = 0;
618 STACK_OF(CONF_VALUE) *sk = NULL;
619 X509_NAME *nm = X509_NAME_new();
620 if (nm == NULL)
621 goto err;
622 sk = X509V3_get_section(ctx, value);
623 if (sk == NULL) {
624 OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
625 ERR_add_error_data(2, "section=", value);
626 goto err;
627 }
628 /* FIXME: should allow other character types... */
629 if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
630 goto err;
631 gen->d.dirn = nm;
632 ret = 1;
633
634 err:
635 if (!ret)
636 X509_NAME_free(nm);
637 X509V3_section_free(ctx, sk);
638 return ret;
639 }
640