diff options
author | Bodo Möller <bodo@openssl.org> | 2001-03-05 11:09:43 +0000 |
---|---|---|
committer | Bodo Möller <bodo@openssl.org> | 2001-03-05 11:09:43 +0000 |
commit | bad4058574a110c972616e4b2f629a6268322eb3 (patch) | |
tree | 14c74c6c138d8495aeb8593ae1b5205885e05f3a /apps/req.c | |
parent | d8c2adae578d44b6c313e57bc971fa2825b9c399 (diff) | |
download | openssl-bad4058574a110c972616e4b2f629a6268322eb3.tar.gz |
New option '-subj arg' for 'openssl req' and 'openssl ca'. This
sets the subject name for a new request or supersedes the
subject name in a given request.
Add options '-batch' and '-verbose' to 'openssl req'.
Submitted by: Massimiliano Pala <madwolf@hackmasters.net>
Reviewed by: Bodo Moeller
Diffstat (limited to 'apps/req.c')
-rw-r--r-- | apps/req.c | 209 |
1 files changed, 171 insertions, 38 deletions
diff --git a/apps/req.c b/apps/req.c index e75d7abf09..5246bbfdee 100644 --- a/apps/req.c +++ b/apps/req.c @@ -111,7 +111,8 @@ * require. This format is wrong */ -static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); +static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,char *dn,int attribs); +static int build_subject(X509_REQ *req, char *subj); static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs); @@ -132,6 +133,7 @@ static char *default_config_file=NULL; static LHASH *config=NULL; #endif static LHASH *req_conf=NULL; +static int batch=0; #define TYPE_RSA 1 #define TYPE_DSA 2 @@ -150,7 +152,7 @@ int MAIN(int argc, char **argv) X509 *x509ss=NULL; X509_REQ *req=NULL; EVP_PKEY *pkey=NULL; - int i,badops=0,newreq=0,newkey= -1,pkey_type=TYPE_RSA; + int i,badops=0,newreq=0,newkey= -1,verbose=0,pkey_type=TYPE_RSA; BIO *in=NULL,*out=NULL; int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM; int nodes=0,kludge=0,newhdr=0,subject=0; @@ -165,6 +167,7 @@ int MAIN(int argc, char **argv) char *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; char *p; + char *subj = NULL; const EVP_MD *md_alg=NULL,*digest=EVP_md5(); #ifndef MONOLITH MS_STATIC char config_name[256]; @@ -321,6 +324,8 @@ int MAIN(int argc, char **argv) newreq=1; } + else if (strcmp(*argv,"-batch") == 0) + batch=1; else if (strcmp(*argv,"-newhdr") == 0) newhdr=1; else if (strcmp(*argv,"-modulus") == 0) @@ -331,6 +336,8 @@ int MAIN(int argc, char **argv) nodes=1; else if (strcmp(*argv,"-noout") == 0) noout=1; + else if (strcmp(*argv,"-verbose") == 0) + verbose=1; else if (strcmp(*argv,"-nameopt") == 0) { if (--argc < 1) goto bad; @@ -346,6 +353,11 @@ int MAIN(int argc, char **argv) kludge=1; else if (strcmp(*argv,"-no-asn1-kludge") == 0) kludge=0; + else if (strcmp(*argv,"-subj") == 0) + { + if (--argc < 1) goto bad; + subj= *(++argv); + } else if (strcmp(*argv,"-days") == 0) { if (--argc < 1) goto bad; @@ -397,8 +409,10 @@ bad: BIO_printf(bio_err," -verify verify signature on REQ\n"); BIO_printf(bio_err," -modulus RSA modulus\n"); BIO_printf(bio_err," -nodes don't encrypt the output key\n"); - BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); - BIO_printf(bio_err," -key file use the private key contained in file\n"); + BIO_printf(bio_err," -engine e use engine e, possibly a hardware device\n"); + BIO_printf(bio_err," -subject output the request's subject\n"); + BIO_printf(bio_err," -passin private key password source\n"); + BIO_printf(bio_err," -key file use the private key contained in file\n"); BIO_printf(bio_err," -keyform arg key file format\n"); BIO_printf(bio_err," -keyout arg file to send the key to\n"); BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); @@ -406,10 +420,11 @@ bad: BIO_printf(bio_err," the random number generator\n"); BIO_printf(bio_err," -newkey rsa:bits generate a new RSA key of 'bits' in size\n"); BIO_printf(bio_err," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n"); - BIO_printf(bio_err," -[digest] Digest to sign with (md5, sha1, md2, mdc2)\n"); BIO_printf(bio_err," -config file request template file.\n"); + BIO_printf(bio_err," -subj arg set or modify request subject\n"); BIO_printf(bio_err," -new new request.\n"); + BIO_printf(bio_err," -batch do not ask anything during request generation\n"); BIO_printf(bio_err," -x509 output a x509 structure instead of a cert. req.\n"); BIO_printf(bio_err," -days number of days a certificate generated by -x509 is valid for.\n"); BIO_printf(bio_err," -set_serial serial number to use for a certificate generated by -x509.\n"); @@ -627,13 +642,13 @@ bad: BIO_printf(bio_err,"unable to load Private key\n"); goto end; } - if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) + if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) { char *randfile = CONF_get_string(req_conf,SECTION,"RANDFILE"); if (randfile == NULL) ERR_clear_error(); app_RAND_load_file(randfile, bio_err, 0); - } + } } if (newreq && (pkey == NULL)) @@ -795,7 +810,8 @@ loop: goto end; } - i=make_REQ(req,pkey,!x509); + i=make_REQ(req,pkey,subj,!x509); + subj=NULL; /* done processing '-subj' option */ if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) { sk_X509_ATTRIBUTE_free(req->req_info->attributes); @@ -839,13 +855,13 @@ loop: /* Add extensions */ if(extensions && !X509V3_EXT_add_conf(req_conf, &ext_ctx, extensions, x509ss)) - { - BIO_printf(bio_err, - "Error Loading extension section %s\n", - extensions); - goto end; - } - + { + BIO_printf(bio_err, + "Error Loading extension section %s\n", + extensions); + goto end; + } + if (!(i=X509_sign(x509ss,pkey,digest))) goto end; } @@ -861,17 +877,46 @@ loop: /* Add extensions */ if(req_exts && !X509V3_EXT_REQ_add_conf(req_conf, &ext_ctx, req_exts, req)) - { - BIO_printf(bio_err, - "Error Loading extension section %s\n", - req_exts); - goto end; - } + { + BIO_printf(bio_err, + "Error Loading extension section %s\n", + req_exts); + goto end; + } if (!(i=X509_REQ_sign(req,pkey,digest))) goto end; } } + if (subj && x509) + { + BIO_printf(bio_err, "Cannot modifiy certificate subject\n"); + goto end; + } + + if (subj && !x509) + { + if (verbose) + { + BIO_printf(bio_err, "Modifying Request's Subject\n"); + print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag); + } + + if (build_subject(req, subj) == 0) + { + BIO_printf(bio_err, "ERROR: cannot modify subject\n"); + ex=1; + goto end; + } + + req->req_info->enc.modified = 1; + + if (verbose) + { + print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag); + } + } + if (verify && !x509) { int tmp=0; @@ -1024,7 +1069,7 @@ end: EXIT(ex); } -static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) +static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int attribs) { int ret=0,i; char no_prompt = 0; @@ -1069,8 +1114,15 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) /* setup version number */ if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */ - if(no_prompt) i = auto_info(req, dn_sk, attr_sk, attribs); - else i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs); + if (no_prompt) + i = auto_info(req, dn_sk, attr_sk, attribs); + else + { + if (subj) + i = build_subject(req, subj); + else + i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs); + } if(!i) goto err; X509_REQ_set_pubkey(req,pkey); @@ -1080,6 +1132,68 @@ err: return(ret); } +static int build_subject(X509_REQ *req, char *subject) + { + X509_NAME *n = NULL; + + int i, nid, ne_num=0; + + char *ne_name = NULL; + char *ne_value = NULL; + + char *tmp = NULL; + char *p[2]; + + char *str_list[256]; + + p[0] = ",/"; + p[1] = "="; + + n = X509_NAME_new(); + + tmp = strtok(subject, p[0]); + while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list))) + { + char *token = tmp; + + while (token[0] == ' ') + token++; + str_list[ne_num] = token; + + tmp = strtok(NULL, p[0]); + ne_num++; + } + + for(i = 0; i < ne_num; i++) + { + ne_name = strtok(str_list[i], p[1]); + ne_value = strtok(NULL, p[1]); + + if ((nid=OBJ_txt2nid(ne_name)) == NID_undef) + { + BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name); + continue; + } + + if (ne_value == NULL) + { + BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name); + continue; + } + + if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0)) + { + X509_NAME_free(n); + return 0; + } + } + + if (!X509_REQ_set_subject_name(req, n)) + return 0; + X509_NAME_free(n); + return 1; +} + static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, @@ -1093,13 +1207,17 @@ static int prompt_info(X509_REQ *req, CONF_VALUE *v; X509_NAME *subj; subj = X509_REQ_get_subject_name(req); - BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); - BIO_printf(bio_err,"into your certificate request.\n"); - BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); - BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n"); - BIO_printf(bio_err,"For some fields there will be a default value,\n"); - BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); - BIO_printf(bio_err,"-----\n"); + + if(!batch) + { + BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); + BIO_printf(bio_err,"into your certificate request.\n"); + BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); + BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n"); + BIO_printf(bio_err,"For some fields there will be a default value,\n"); + BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); + BIO_printf(bio_err,"-----\n"); + } if (sk_CONF_VALUE_num(dn_sk)) @@ -1160,7 +1278,7 @@ start: for (;;) if (attribs) { - if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)) + if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch)) { BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); BIO_printf(bio_err,"to be sent with your certificate request\n"); @@ -1276,9 +1394,9 @@ static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, int i,ret=0; MS_STATIC char buf[1024]; start: - BIO_printf(bio_err,"%s [%s]:",text,def); + if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def); (void)BIO_flush(bio_err); - if (value != NULL) + if(value != NULL) { strcpy(buf,value); strcat(buf,"\n"); @@ -1287,7 +1405,15 @@ start: else { buf[0]='\0'; - fgets(buf,1024,stdin); + if (!batch) + { + fgets(buf,1024,stdin); + } + else + { + buf[0] = '\n'; + buf[1] = '\0'; + } } if (buf[0] == '\0') return(0); @@ -1307,7 +1433,6 @@ start: return(0); } buf[--i]='\0'; - #ifdef CHARSET_EBCDIC ebcdic2ascii(buf, buf, i); #endif @@ -1327,7 +1452,7 @@ static int add_attribute_object(X509_REQ *req, char *text, static char buf[1024]; start: - BIO_printf(bio_err,"%s [%s]:",text,def); + if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def); (void)BIO_flush(bio_err); if (value != NULL) { @@ -1338,7 +1463,15 @@ start: else { buf[0]='\0'; - fgets(buf,1024,stdin); + if (!batch) + { + fgets(buf,1024,stdin); + } + else + { + buf[0] = '\n'; + buf[1] = '\0'; + } } if (buf[0] == '\0') return(0); |