From aa066b9e6e44297a00e641e200bf48b5728ae5c3 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 21 Feb 1999 01:46:45 +0000 Subject: Add more functionality to issuer alt name and subject alt name. New options to include email addresses from DN and copy details from issuer certificate. Include examples in openssl.cnf, update Win32 ordinals. --- crypto/x509v3/v3_alt.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 2 deletions(-) (limited to 'crypto/x509v3/v3_alt.c') diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c index 0e8211b007..76f1b633c5 100644 --- a/crypto/x509v3/v3_alt.c +++ b/crypto/x509v3/v3_alt.c @@ -65,6 +65,18 @@ #include #include "x509v3.h" +#ifndef NOPROTO +STACK *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval); +STACK *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval); +static int copy_email(X509V3_CTX *ctx, STACK *gens); +static int copy_issuer(X509V3_CTX *ctx, STACK *gens); +#else +STACK *v2i_issuer_alt(); +STACK *v2i_subject_alt(); +static int copy_email(); +static int copy_issuer(); +#endif + X509V3_EXT_METHOD v3_alt[] = { { NID_subject_alt_name, 0, (X509V3_EXT_NEW)GENERAL_NAMES_new, @@ -73,7 +85,7 @@ GENERAL_NAMES_free, i2d_GENERAL_NAMES, NULL, NULL, (X509V3_EXT_I2V)i2v_GENERAL_NAMES, -(X509V3_EXT_V2I)v2i_GENERAL_NAMES, +(X509V3_EXT_V2I)v2i_subject_alt, NULL, NULL}, { NID_issuer_alt_name, 0, (X509V3_EXT_NEW)GENERAL_NAMES_new, @@ -82,7 +94,7 @@ GENERAL_NAMES_free, i2d_GENERAL_NAMES, NULL, NULL, (X509V3_EXT_I2V)i2v_GENERAL_NAMES, -(X509V3_EXT_V2I)v2i_GENERAL_NAMES, +(X509V3_EXT_V2I)v2i_issuer_alt, NULL, NULL}, EXT_END }; @@ -158,6 +170,157 @@ STACK *ret; return ret; } +STACK *v2i_issuer_alt(method, ctx, nval) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +STACK *nval; +{ + STACK *gens = NULL; + CONF_VALUE *cnf; + int i; + if(!(gens = sk_new(NULL))) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); + return NULL; + } + for(i = 0; i < sk_num(nval); i++) { + cnf = (CONF_VALUE *)sk_value(nval, i); + if(!name_cmp(cnf->name, "issuer") && cnf->value && + !strcmp(cnf->value, "copy")) { + if(!copy_issuer(ctx, gens)) goto err; + } else { + GENERAL_NAME *gen; + if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_push(gens, (char *)gen); + } + } + return gens; + err: + sk_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Append subject altname of issuer to issuer alt name of subject */ + +static int copy_issuer(ctx, gens) +X509V3_CTX *ctx; +STACK *gens; +{ + STACK *ialt; + char *gen; + X509_EXTENSION *ext; + int i; + if(ctx && (ctx->flags == CTX_TEST)) return 1; + if(!ctx || !ctx->issuer_cert) { + X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS); + goto err; + } + i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if(i < 0) return 1; + if(!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = (STACK *) X509V3_EXT_d2i(ext)) ) { + X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for(i = 0; i < sk_num(ialt); i++) { + gen = sk_value(ialt, i); + if(!sk_push(gens, gen)) { + X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_free(ialt); + + return 1; + + err: + return 0; + +} + +STACK *v2i_subject_alt(method, ctx, nval) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +STACK *nval; +{ + STACK *gens = NULL; + CONF_VALUE *cnf; + int i; + if(!(gens = sk_new(NULL))) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); + return NULL; + } + for(i = 0; i < sk_num(nval); i++) { + cnf = (CONF_VALUE *)sk_value(nval, i); + if(!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if(!copy_email(ctx, gens)) goto err; + } else { + GENERAL_NAME *gen; + if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_push(gens, (char *)gen); + } + } + return gens; + err: + sk_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Copy any email addresses in a certificate or request to + * GENERAL_NAMES + */ + +static int copy_email(ctx, gens) +X509V3_CTX *ctx; +STACK *gens; +{ + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + if(ctx->flags == CTX_TEST) return 1; + if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + /* Find the subject name */ + if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert); + else nm = X509_REQ_get_subject_name(ctx->subject_req); + + /* Now add any email address(es) to STACK */ + i = -1; + while((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) > 0) { + ne = X509_NAME_get_entry(nm, i); + email = ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if(!email || !(gen = GENERAL_NAME_new())) { + X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if(!sk_push(gens, (char *)gen)) { + X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + + return 1; + + err: + GENERAL_NAME_free(gen); + ASN1_IA5STRING_free(email); + return 0; + +} + STACK *v2i_GENERAL_NAMES(method, ctx, nval) X509V3_EXT_METHOD *method; X509V3_CTX *ctx; @@ -196,6 +359,11 @@ char *name, *value; name = cnf->name; value = cnf->value; +if(!value) { + X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_MISSING_VALUE); + return NULL; +} + if(!(gen = GENERAL_NAME_new())) { X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); return NULL; -- cgit v1.2.3