aboutsummaryrefslogtreecommitdiffstats
path: root/apps/req.c
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2001-03-05 11:09:43 +0000
committerBodo Möller <bodo@openssl.org>2001-03-05 11:09:43 +0000
commitbad4058574a110c972616e4b2f629a6268322eb3 (patch)
tree14c74c6c138d8495aeb8593ae1b5205885e05f3a /apps/req.c
parentd8c2adae578d44b6c313e57bc971fa2825b9c399 (diff)
downloadopenssl-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.c209
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);