diff options
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_alt.c')
-rw-r--r-- | src/lib/libcrypto/x509v3/v3_alt.c | 289 |
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 | |||
65 | static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | 65 | static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); |
66 | static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); | 66 | static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); |
67 | static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); | 67 | static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); |
68 | X509V3_EXT_METHOD v3_alt[] = { | 68 | static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); |
69 | static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); | ||
70 | |||
71 | const 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), |
70 | 0,0,0,0, | 73 | 0,0,0,0, |
71 | 0,0, | 74 | 0,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, | |||
153 | int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) | 171 | int 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 | ||
379 | GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, | 411 | GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, |
380 | CONF_VALUE *cnf) | 412 | CONF_VALUE *cnf) |
381 | { | 413 | { |
382 | char is_string = 0; | 414 | return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); |
383 | int type; | 415 | } |
384 | GENERAL_NAME *gen = NULL; | ||
385 | 416 | ||
386 | char *name, *value; | 417 | GENERAL_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 | ||
388 | name = cnf->name; | 425 | char *name, *value; |
389 | value = cnf->value; | ||
390 | 426 | ||
391 | if(!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 | ||
396 | if(!(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 | ||
401 | if(!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 | ||
442 | if(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 | ||
451 | gen->type = type; | 529 | err: |
530 | GENERAL_NAME_free(gen); | ||
531 | return NULL; | ||
532 | } | ||
452 | 533 | ||
453 | return gen; | 534 | static 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 | ||
455 | err: | 559 | static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) |
456 | GENERAL_NAME_free(gen); | 560 | { |
457 | return 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 | } | ||