Hello,
is there a special reason that openssl ca has only functionality to copy the emailAddress from the subject name to the subjectAltName extension ?
Or would something like the attached patch acceptable ?
This patch extends the syntax of the subjectAltName entry of the config file section with the extensions in the way that the flags "copy" and "move" are recognized for all names.
Additionally it allows to specify the name entry type in the subject name that is moved/copied.
for example: In my local openssl.cnf I have the entry: subjectAltName = DNS:copy:commonName,DNS:mydyndnsorgdomain.dyndns.org
An issued certificate gets 2 subjectAltNames: 1. a copy of the common name (inserted as dnsDomain name) 2. the general dnsDomain name mydyndnsorgdomain.dyndns.org.
This allows me to access the host with the external and the internal host name without the accessing program generating an error message about a mismatching domain name.
Bye
Goetz
-- DMCA: The greed of the few outweighs the freedom of the many
Index: crypto/x509v3/v3_alt.c =================================================================== RCS file: /cvs/openssl/crypto/x509v3/v3_alt.c,v retrieving revision 1.33 diff -u -r1.33 v3_alt.c --- crypto/x509v3/v3_alt.c 27 Dec 2003 14:40:01 -0000 1.33 +++ crypto/x509v3/v3_alt.c 22 Apr 2005 13:52:11 -0000 @@ -63,7 +63,9 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_name(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + GENERAL_NAMES *gens, + const char *type, const char *field, int move_p); static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); @@ -304,6 +306,7 @@ { GENERAL_NAMES *gens = NULL; CONF_VALUE *cnf; + const char *value; int i; if(!(gens = sk_GENERAL_NAME_new_null())) { X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); @@ -311,17 +314,23 @@ } for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { cnf = sk_CONF_VALUE_value(nval, i); - if(!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "copy")) { - if(!copy_email(ctx, gens, 0)) goto err; - } else if(!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "move")) { - if(!copy_email(ctx, gens, 1)) goto err; - } else { - GENERAL_NAME *gen; - if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); + if (cnf->value && cnf->value[0]) { + if (!name_cmp(cnf->value,"copy")) { + value = cnf->value+4; + if (value[0] == '.' || value[0] == ':')value++; + if(!copy_name(method,ctx,gens,cnf->name,value,0)) + goto err; + } else if (!name_cmp(cnf->value,"move")) { + value = cnf->value+4; + if (value[0] == '.') value++; + if(!copy_name(method,ctx,gens,cnf->name,value,1)) + goto err; + } else { + GENERAL_NAME *gen; + if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } } } return gens; @@ -330,44 +339,76 @@ return NULL; } -/* Copy any email addresses in a certificate or request to +/* Copy any fields of given type in a certificate or request to * GENERAL_NAMES */ -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +static int copy_name(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + GENERAL_NAMES *gens, + const char *type, const char *field, int move_p) { X509_NAME *nm; - ASN1_IA5STRING *email = NULL; X509_NAME_ENTRY *ne; - GENERAL_NAME *gen = NULL; + CONF_VALUE cv = { NULL,(char*)type,NULL }; + GENERAL_NAME *gen = NULL; + unsigned char*str = NULL; + int nid = 0; + int len; int i; if(ctx->flags == CTX_TEST) return 1; - if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS); goto err; } - /* Find the subject name */ + /* get the type of name entry to operate on in the DN */ + if (field && field[0]) { + nid = OBJ_txt2nid(field); + if (!nid) { + X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_INVALID_EXTENSION_STRING); + goto err; + } + } + if (!nid) { + if (!name_cmp(type, "email")) nid = NID_pkcs9_emailAddress; +#if 0 + else if(!name_cmp(type, "URI" )) nid = NID_commonName; + else if(!name_cmp(name, "DNS" )) nid = NID_commonName; + else if(!name_cmp(name, "RID" )) nid = NID_commonName; + else if(!name_cmp(name, "IP" )) nid = NID_commonName; +#endif + else nid = NID_commonName; + } + if (!nid) { + X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_INVALID_OBJECT_IDENTIFIER ); + 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 */ + /* Now add any name(s) 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 = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); - if (move_p) - { - X509_NAME_delete_entry(nm, i); - i--; - } - if(!email || !(gen = GENERAL_NAME_new())) { + while((i = X509_NAME_get_index_by_NID(nm,nid, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + if ( ne ) + len = ASN1_STRING_to_UTF8(&str, + X509_NAME_ENTRY_get_data(ne)); + else + len = -1; + cv.value = len >= 0 ? (char *)str : NULL; + if (!cv.value) /* value not found: skip... */ + continue; + gen = v2i_GENERAL_NAME_ex(NULL,method,ctx,&cv,0); + OPENSSL_free(str); + str = NULL; + if (move_p) { + X509_NAME_delete_entry(nm, i); + i--; + } + if(!gen) { X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); goto err; } - gen->d.ia5 = email; - email = NULL; - gen->type = GEN_EMAIL; if(!sk_GENERAL_NAME_push(gens, gen)) { X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); goto err; @@ -375,12 +416,10 @@ gen = NULL; } - return 1; err: GENERAL_NAME_free(gen); - M_ASN1_IA5STRING_free(email); return 0; } Index: crypto/x509v3/v3_utl.c =================================================================== RCS file: /cvs/openssl/crypto/x509v3/v3_utl.c,v retrieving revision 1.31 diff -u -r1.31 v3_utl.c --- crypto/x509v3/v3_utl.c 17 May 2004 19:14:22 -0000 1.31 +++ crypto/x509v3/v3_utl.c 22 Apr 2005 14:09:33 -0000 @@ -455,7 +455,7 @@ len = strlen(cmp); if((ret = strncmp(name, cmp, len))) return ret; c = name[len]; - if(!c || (c=='.')) return 0; + if(!c || (c=='.') || (c==':')) return 0; return 1; }
smime.p7s
Description: S/MIME Cryptographic Signature