From 89da653fa62598c29dc29b7e1741985f51172837 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bodo=20M=C3=B6ller?= Date: Thu, 25 Oct 2001 08:25:19 +0000 Subject: [PATCH] Add '-noemailDN' option to 'openssl ca'. This prevents inclusion of the e-mail address in the DN (i.e., it will go into a certificate extension only). The new configuration file option 'email_in_dn = no' has the same effect. Submitted by: Massimiliano Pala madwolf@openca.org --- CHANGES | 6 +++ apps/ca.c | 136 ++++++++++++++++++++++++++++++++++-------------- doc/apps/ca.pod | 24 ++++++++- 3 files changed, 126 insertions(+), 40 deletions(-) diff --git a/CHANGES b/CHANGES index 99d9dd0642..5c6a9fdcdd 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,12 @@ *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7 +) applies to 0.9.7 only + +) Add '-noemailDN' option to 'openssl ca'. This prevents inclusion + of the e-mail address in the DN (i.e., it will go into a certificate + extension only). The new configuration file option 'email_in_dn = no' + has the same effect. + [Massimiliano Pala madwolf@openca.org] + *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when faced with a pathologically small ClientHello fragment that does not contain client_version: Instead of aborting with an error, diff --git a/apps/ca.c b/apps/ca.c index 481bfc77d7..e96d086b45 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -126,6 +126,7 @@ #define ENV_DEFAULT_CRL_DAYS "default_crl_days" #define ENV_DEFAULT_CRL_HOURS "default_crl_hours" #define ENV_DEFAULT_MD "default_md" +#define ENV_DEFAULT_EMAIL_DN "email_in_dn" #define ENV_PRESERVE "preserve" #define ENV_POLICY "policy" #define ENV_EXTENSIONS "x509_extensions" @@ -182,6 +183,7 @@ static char *ca_usage[]={ " -spkac file - File contains DN and signed public key and challenge\n", " -ss_cert file - File contains a self signed cert to sign\n", " -preserveDN - Don't re-order the DN\n", +" -noemailDN - Don't add the EMAIL field into certificate' subject\n", " -batch - Don't ask questions\n", " -msie_hack - msie modifications to handle all those universal strings\n", " -revoke file - Revoke a certificate (given in file)\n", @@ -211,32 +213,32 @@ static BIGNUM *load_serial(char *serialfile); static int save_serial(char *serialfile, BIGNUM *serial); static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db, - BIGNUM *serial, char *subj, char *startdate,char *enddate, - long days, int batch, char *ext_sect, CONF *conf,int verbose, - unsigned long certopt, unsigned long nameopt, int default_op, - int ext_copy); + BIGNUM *serial, char *subj, int email_dn, char *startdate, + char *enddate, long days, int batch, char *ext_sect, CONF *conf, + int verbose, unsigned long certopt, unsigned long nameopt, + int default_op, int ext_copy); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, - TXT_DB *db, BIGNUM *serial, char *subj, char *startdate, - char *enddate, long days, int batch, char *ext_sect, - CONF *conf,int verbose, unsigned long certopt, + TXT_DB *db, BIGNUM *serial, char *subj, int email_dn, + char *startdate, char *enddate, long days, int batch, + char *ext_sect, CONF *conf,int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, ENGINE *e); static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, - TXT_DB *db, BIGNUM *serial,char *subj, char *startdate, - char *enddate, long days, char *ext_sect,CONF *conf, - int verbose, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy); + TXT_DB *db, BIGNUM *serial,char *subj, int email_dn, + char *startdate, char *enddate, long days, char *ext_sect, + CONF *conf, int verbose, unsigned long certopt, + unsigned long nameopt, int default_op, int ext_copy); static int fix_data(int nid, int *type); static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj, - char *startdate, char *enddate, long days, int batch, int verbose, - X509_REQ *req, char *ext_sect, CONF *conf, + int email_dn, char *startdate, char *enddate, long days, int batch, + int verbose, X509_REQ *req, char *ext_sect, CONF *conf, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy); -static X509_NAME *do_subject(char *subject); +static X509_NAME *do_subject(char *subject, int email_dn); static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval); static int get_certificate_status(const char *ser_status, TXT_DB *db); static int do_updatedb(TXT_DB *db); @@ -268,6 +270,7 @@ int MAIN(int argc, char **argv) int total_done=0; int badops=0; int ret=1; + int email_dn=1; int req=0; int verbose=0; int gencrl=0; @@ -294,6 +297,7 @@ int MAIN(int argc, char **argv) char *extensions=NULL; char *extfile=NULL; char *subj=NULL; + char *tmp_email_dn=NULL; char *crl_ext=NULL; int rev_type = REV_NONE; char *rev_arg = NULL; @@ -439,6 +443,8 @@ EF_ALIGNMENT=0; batch=1; else if (strcmp(*argv,"-preserveDN") == 0) preserve=1; + else if (strcmp(*argv,"-noemailDN") == 0) + email_dn=0; else if (strcmp(*argv,"-gencrl") == 0) gencrl=1; else if (strcmp(*argv,"-msie_hack") == 0) @@ -1041,6 +1047,12 @@ bad: lookup_fail(section,ENV_DEFAULT_MD); goto err; } + if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf, + section,ENV_DEFAULT_EMAIL_DN)) != NULL )) + { + if(strcmp(tmp_email_dn,"no") == 0) + email_dn=0; + } if ((dgst=EVP_get_digestbyname(md)) == NULL) { BIO_printf(bio_err,"%s is an unsupported message digest type\n",md); @@ -1159,8 +1171,8 @@ bad: { total++; j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, - serial,subj,startdate,enddate, days,extensions,conf, - verbose, certopt, nameopt, default_op, ext_copy); + serial,subj,email_dn,startdate,enddate,days,extensions, + conf,verbose,certopt,nameopt,default_op,ext_copy); if (j < 0) goto err; if (j > 0) { @@ -1183,7 +1195,7 @@ bad: { total++; j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, - db,serial,subj,startdate,enddate,days,batch, + db,serial,subj,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy, e); if (j < 0) goto err; @@ -1203,7 +1215,7 @@ bad: { total++; j=certify(&x,infile,pkey,x509,dgst,attribs,db, - serial,subj,startdate,enddate,days,batch, + serial,subj,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy); if (j < 0) goto err; @@ -1223,7 +1235,7 @@ bad: { total++; j=certify(&x,argv[i],pkey,x509,dgst,attribs,db, - serial,subj,startdate,enddate,days,batch, + serial,subj,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy); if (j < 0) goto err; @@ -1699,8 +1711,8 @@ err: static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, - BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, - int batch, char *ext_sect, CONF *lconf, int verbose, + BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, + long days, int batch, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) { @@ -1749,8 +1761,8 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, else BIO_printf(bio_err,"Signature ok\n"); - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate, enddate, - days,batch,verbose,req,ext_sect,lconf, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn, + startdate,enddate,days,batch,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, ext_copy); err: @@ -1761,8 +1773,8 @@ err: static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, - BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, - int batch, char *ext_sect, CONF *lconf, int verbose, + BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, + long days, int batch, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, ENGINE *e) { @@ -1803,9 +1815,9 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL) goto err; - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,days, - batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, - ext_copy); + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, + days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, + ext_copy); err: if (rreq != NULL) X509_REQ_free(rreq); @@ -1815,12 +1827,12 @@ err: static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj, - char *startdate, char *enddate, long days, int batch, int verbose, - X509_REQ *req, char *ext_sect, CONF *lconf, + int email_dn, char *startdate, char *enddate, long days, int batch, + int verbose, X509_REQ *req, char *ext_sect, CONF *lconf, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) { - X509_NAME *name=NULL,*CAname=NULL,*subject=NULL; + X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL; ASN1_UTCTIME *tm,*tmptm; ASN1_STRING *str,*str2; ASN1_OBJECT *obj; @@ -1847,7 +1859,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, if (subj) { - X509_NAME *n = do_subject(subj); + X509_NAME *n = do_subject(subj, email_dn); if (!n) { @@ -1861,6 +1873,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, if (default_op) BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n"); + name=X509_REQ_get_subject_name(req); for (i=0; itype=V_ASN1_IA5STRING; } + /* If no EMAIL is wanted in the subject */ + if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn)) + continue; + /* check some things */ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (str->type != V_ASN1_IA5STRING)) @@ -2018,14 +2035,44 @@ again2: if (preserve) { X509_NAME_free(subject); - subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); + /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ + subject=X509_NAME_dup(name); if (subject == NULL) goto err; } if (verbose) BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n"); - row[DB_name]=X509_NAME_oneline(subject,NULL,0); + /* Build the correct Subject if no e-mail is wanted in the subject */ + /* and add it later on because of the method extensions are added (altName) */ + + if (!email_dn) + { + if ((dn_subject=X509_NAME_new()) == NULL) + { + BIO_printf(bio_err,"Memory allocation failure\n"); + goto err; + } + + for (i=0; i B [B<-spkac file>] [B<-ss_cert file>] [B<-preserveDN>] +[B<-noemailDN>] [B<-batch>] [B<-msie_hack>] [B<-extensions section>] @@ -157,6 +158,15 @@ is the same as the request. This is largely for compatibility with the older IE enrollment control which would only accept certificates if their DNs match the order of the request. This is not needed for Xenroll. +=item B<-noemailDN> + +The DN of a certificate can contain the EMAIL field if present in the +request DN, however it is good policy just having the e-mail set into +the altName extension of the certificate. When this option is set the +EMAIL field is removed from the certificate' subject and set only in +the, eventually present, extensions. The B keyword can be +used in the configuration file to enable this behaviour. + =item B<-batch> this sets the batch mode. In this mode no questions will be asked @@ -308,6 +318,12 @@ the same as B<-crlexts>. the same as B<-preserveDN> +=item B + +the same as B<-noemailDN>. If you want the EMAIL field to be removed +from the DN of the certificate simply set this to 'no'. If not present +the default is to allow for the EMAIL filed in the certificate's DN. + =item B the same as B<-msie_hack> @@ -437,6 +453,7 @@ A sample configuration file with the relevant sections for B: default_md = md5 # md to use policy = policy_any # default policy + email_in_dn = no # Don't add the email into cert DN nameopt = default_ca # Subject name display option certopt = default_ca # Certificate display option @@ -518,8 +535,11 @@ exposed at either a command or interface level so a more friendly utility B help a little but not very much. Any fields in a request that are not present in a policy are silently -deleted. This does not happen if the B<-preserveDN> option is used. -The behaviour should be more friendly and configurable. +deleted. This does not happen if the B<-preserveDN> option is used. To +enforce the absence of the EMAIL field within the DN, as suggested by +RFCs, regardless the contents of the request' subject the B<-noemailDN> +option can be used. The behaviour should be more friendly and +configurable. Cancelling some commands by refusing to certify a certificate can create an empty file. -- 2.25.1