summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3/v3_alt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_alt.c')
-rw-r--r--src/lib/libcrypto/x509v3/v3_alt.c289
1 files changed, 206 insertions, 83 deletions
diff --git a/src/lib/libcrypto/x509v3/v3_alt.c b/src/lib/libcrypto/x509v3/v3_alt.c
index 58b935a3b6..bb2f5bc54e 100644
--- a/src/lib/libcrypto/x509v3/v3_alt.c
+++ b/src/lib/libcrypto/x509v3/v3_alt.c
@@ -1,9 +1,9 @@
1/* v3_alt.c */ 1/* v3_alt.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999. 3 * project.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2003 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
@@ -65,7 +65,10 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx
65static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 65static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
66static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); 66static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
67static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); 67static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
68X509V3_EXT_METHOD v3_alt[] = { 68static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
69static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
70
71const X509V3_EXT_METHOD v3_alt[] = {
69{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 72{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
700,0,0,0, 730,0,0,0,
710,0, 740,0,
@@ -98,7 +101,8 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
98 GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) 101 GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
99{ 102{
100 unsigned char *p; 103 unsigned char *p;
101 char oline[256]; 104 char oline[256], htmp[5];
105 int i;
102 switch (gen->type) 106 switch (gen->type)
103 { 107 {
104 case GEN_OTHERNAME: 108 case GEN_OTHERNAME:
@@ -132,13 +136,27 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
132 136
133 case GEN_IPADD: 137 case GEN_IPADD:
134 p = gen->d.ip->data; 138 p = gen->d.ip->data;
135 /* BUG: doesn't support IPV6 */ 139 if(gen->d.ip->length == 4)
136 if(gen->d.ip->length != 4) { 140 BIO_snprintf(oline, sizeof oline,
141 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
142 else if(gen->d.ip->length == 16)
143 {
144 oline[0] = 0;
145 for (i = 0; i < 8; i++)
146 {
147 BIO_snprintf(htmp, sizeof htmp,
148 "%X", p[0] << 8 | p[1]);
149 p += 2;
150 strcat(oline, htmp);
151 if (i != 7)
152 strcat(oline, ":");
153 }
154 }
155 else
156 {
137 X509V3_add_value("IP Address","<invalid>", &ret); 157 X509V3_add_value("IP Address","<invalid>", &ret);
138 break; 158 break;
139 } 159 }
140 BIO_snprintf(oline, sizeof oline,
141 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
142 X509V3_add_value("IP Address",oline, &ret); 160 X509V3_add_value("IP Address",oline, &ret);
143 break; 161 break;
144 162
@@ -153,6 +171,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
153int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) 171int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
154{ 172{
155 unsigned char *p; 173 unsigned char *p;
174 int i;
156 switch (gen->type) 175 switch (gen->type)
157 { 176 {
158 case GEN_OTHERNAME: 177 case GEN_OTHERNAME:
@@ -187,12 +206,24 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
187 206
188 case GEN_IPADD: 207 case GEN_IPADD:
189 p = gen->d.ip->data; 208 p = gen->d.ip->data;
190 /* BUG: doesn't support IPV6 */ 209 if(gen->d.ip->length == 4)
191 if(gen->d.ip->length != 4) { 210 BIO_printf(out, "IP Address:%d.%d.%d.%d",
211 p[0], p[1], p[2], p[3]);
212 else if(gen->d.ip->length == 16)
213 {
214 BIO_printf(out, "IP Address");
215 for (i = 0; i < 8; i++)
216 {
217 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
218 p += 2;
219 }
220 BIO_puts(out, "\n");
221 }
222 else
223 {
192 BIO_printf(out,"IP Address:<invalid>"); 224 BIO_printf(out,"IP Address:<invalid>");
193 break; 225 break;
194 } 226 }
195 BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
196 break; 227 break;
197 228
198 case GEN_RID: 229 case GEN_RID:
@@ -210,7 +241,7 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
210 CONF_VALUE *cnf; 241 CONF_VALUE *cnf;
211 int i; 242 int i;
212 if(!(gens = sk_GENERAL_NAME_new_null())) { 243 if(!(gens = sk_GENERAL_NAME_new_null())) {
213 X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); 244 X509V3err(X509V3_F_V2I_ISSUER_ALT,ERR_R_MALLOC_FAILURE);
214 return NULL; 245 return NULL;
215 } 246 }
216 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 247 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -275,7 +306,7 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
275 CONF_VALUE *cnf; 306 CONF_VALUE *cnf;
276 int i; 307 int i;
277 if(!(gens = sk_GENERAL_NAME_new_null())) { 308 if(!(gens = sk_GENERAL_NAME_new_null())) {
278 X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); 309 X509V3err(X509V3_F_V2I_SUBJECT_ALT,ERR_R_MALLOC_FAILURE);
279 return NULL; 310 return NULL;
280 } 311 }
281 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 312 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -310,7 +341,8 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
310 X509_NAME_ENTRY *ne; 341 X509_NAME_ENTRY *ne;
311 GENERAL_NAME *gen = NULL; 342 GENERAL_NAME *gen = NULL;
312 int i; 343 int i;
313 if(ctx->flags == CTX_TEST) return 1; 344 if(ctx != NULL && ctx->flags == CTX_TEST)
345 return 1;
314 if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { 346 if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
315 X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS); 347 X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS);
316 goto err; 348 goto err;
@@ -378,81 +410,172 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
378 410
379GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 411GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
380 CONF_VALUE *cnf) 412 CONF_VALUE *cnf)
381{ 413 {
382char is_string = 0; 414 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
383int type; 415 }
384GENERAL_NAME *gen = NULL;
385 416
386char *name, *value; 417GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
418 X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
419 CONF_VALUE *cnf, int is_nc)
420 {
421 char is_string = 0;
422 int type;
423 GENERAL_NAME *gen = NULL;
387 424
388name = cnf->name; 425 char *name, *value;
389value = cnf->value;
390 426
391if(!value) { 427 name = cnf->name;
392 X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_MISSING_VALUE); 428 value = cnf->value;
393 return NULL;
394}
395 429
396if(!(gen = GENERAL_NAME_new())) { 430 if(!value)
397 X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); 431 {
398 return NULL; 432 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE);
399} 433 return NULL;
434 }
400 435
401if(!name_cmp(name, "email")) { 436 if (out)
402 is_string = 1; 437 gen = out;
403 type = GEN_EMAIL; 438 else
404} else if(!name_cmp(name, "URI")) { 439 {
405 is_string = 1; 440 gen = GENERAL_NAME_new();
406 type = GEN_URI; 441 if(gen == NULL)
407} else if(!name_cmp(name, "DNS")) { 442 {
408 is_string = 1; 443 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE);
409 type = GEN_DNS; 444 return NULL;
410} else if(!name_cmp(name, "RID")) { 445 }
411 ASN1_OBJECT *obj; 446 }
412 if(!(obj = OBJ_txt2obj(value,0))) { 447
413 X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_OBJECT); 448 if(!name_cmp(name, "email"))
414 ERR_add_error_data(2, "value=", value); 449 {
415 goto err; 450 is_string = 1;
416 } 451 type = GEN_EMAIL;
417 gen->d.rid = obj; 452 }
418 type = GEN_RID; 453 else if(!name_cmp(name, "URI"))
419} else if(!name_cmp(name, "IP")) { 454 {
420 int i1,i2,i3,i4; 455 is_string = 1;
421 unsigned char ip[4]; 456 type = GEN_URI;
422 if((sscanf(value, "%d.%d.%d.%d",&i1,&i2,&i3,&i4) != 4) || 457 }
423 (i1 < 0) || (i1 > 255) || (i2 < 0) || (i2 > 255) || 458 else if(!name_cmp(name, "DNS"))
424 (i3 < 0) || (i3 > 255) || (i4 < 0) || (i4 > 255) ) { 459 {
425 X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS); 460 is_string = 1;
426 ERR_add_error_data(2, "value=", value); 461 type = GEN_DNS;
462 }
463 else if(!name_cmp(name, "RID"))
464 {
465 ASN1_OBJECT *obj;
466 if(!(obj = OBJ_txt2obj(value,0)))
467 {
468 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_OBJECT);
469 ERR_add_error_data(2, "value=", value);
470 goto err;
471 }
472 gen->d.rid = obj;
473 type = GEN_RID;
474 }
475 else if(!name_cmp(name, "IP"))
476 {
477 if (is_nc)
478 gen->d.ip = a2i_IPADDRESS_NC(value);
479 else
480 gen->d.ip = a2i_IPADDRESS(value);
481 if(gen->d.ip == NULL)
482 {
483 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_IP_ADDRESS);
484 ERR_add_error_data(2, "value=", value);
485 goto err;
486 }
487 type = GEN_IPADD;
488 }
489 else if(!name_cmp(name, "dirName"))
490 {
491 type = GEN_DIRNAME;
492 if (!do_dirname(gen, value, ctx))
493 {
494 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_DIRNAME_ERROR);
495 goto err;
496 }
497 }
498 else if(!name_cmp(name, "otherName"))
499 {
500 if (!do_othername(gen, value, ctx))
501 {
502 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_OTHERNAME_ERROR);
503 goto err;
504 }
505 type = GEN_OTHERNAME;
506 }
507 else
508 {
509 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
510 ERR_add_error_data(2, "name=", name);
427 goto err; 511 goto err;
428 } 512 }
429 ip[0] = i1; ip[1] = i2 ; ip[2] = i3 ; ip[3] = i4; 513
430 if(!(gen->d.ip = M_ASN1_OCTET_STRING_new()) || 514 if(is_string)
431 !ASN1_STRING_set(gen->d.ip, ip, 4)) { 515 {
432 X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); 516 if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
517 !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
518 strlen(value)))
519 {
520 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE);
433 goto err; 521 goto err;
434 } 522 }
435 type = GEN_IPADD; 523 }
436} else {
437 X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_OPTION);
438 ERR_add_error_data(2, "name=", name);
439 goto err;
440}
441 524
442if(is_string) { 525 gen->type = type;
443 if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || 526
444 !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, 527 return gen;
445 strlen(value))) {
446 X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
447 goto err;
448 }
449}
450 528
451gen->type = type; 529 err:
530 GENERAL_NAME_free(gen);
531 return NULL;
532 }
452 533
453return gen; 534static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
535 {
536 char *objtmp = NULL, *p;
537 int objlen;
538 if (!(p = strchr(value, ';')))
539 return 0;
540 if (!(gen->d.otherName = OTHERNAME_new()))
541 return 0;
542 /* Free this up because we will overwrite it.
543 * no need to free type_id because it is static
544 */
545 ASN1_TYPE_free(gen->d.otherName->value);
546 if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
547 return 0;
548 objlen = p - value;
549 objtmp = OPENSSL_malloc(objlen + 1);
550 strncpy(objtmp, value, objlen);
551 objtmp[objlen] = 0;
552 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
553 OPENSSL_free(objtmp);
554 if (!gen->d.otherName->type_id)
555 return 0;
556 return 1;
557 }
454 558
455err: 559static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
456GENERAL_NAME_free(gen); 560 {
457return NULL; 561 int ret;
458} 562 STACK_OF(CONF_VALUE) *sk;
563 X509_NAME *nm;
564 if (!(nm = X509_NAME_new()))
565 return 0;
566 sk = X509V3_get_section(ctx, value);
567 if (!sk)
568 {
569 X509V3err(X509V3_F_DO_DIRNAME,X509V3_R_SECTION_NOT_FOUND);
570 ERR_add_error_data(2, "section=", value);
571 X509_NAME_free(nm);
572 return 0;
573 }
574 /* FIXME: should allow other character types... */
575 ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
576 if (!ret)
577 X509_NAME_free(nm);
578 gen->d.dirn = nm;
579
580 return ret;
581 }