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
This commit is contained in:
parent
d8c2adae57
commit
bad4058574
10
CHANGES
10
CHANGES
@ -3,6 +3,16 @@
|
||||
|
||||
Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
|
||||
|
||||
*) 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. Formats that can be parsed are
|
||||
'CN=Some Name, OU=myOU, C=IT'
|
||||
and
|
||||
'CN=Some Name/OU=myOU/C=IT'.
|
||||
|
||||
Add options '-batch' and '-verbose' to 'openssl req'.
|
||||
[Massimiliano Pala <madwolf@hackmasters.net>]
|
||||
|
||||
*) Introduce the possibility to access global variables through
|
||||
functions on platform were that's the best way to handle exporting
|
||||
global variables in shared libraries. To enable this functionality,
|
||||
|
126
apps/ca.c
126
apps/ca.c
@ -183,6 +183,7 @@ static char *ca_usage[]={
|
||||
" -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",
|
||||
" -subj arg - Use arg instead of request's subject\n",
|
||||
" -extensions .. - Extension section (override value in config file)\n",
|
||||
" -extfile file - Configuration file with X509v3 extentions to add\n",
|
||||
" -crlexts .. - CRL extension section (override value in config file)\n",
|
||||
@ -208,24 +209,25 @@ 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 *startdate,char *enddate, int days,
|
||||
int batch, char *ext_sect, LHASH *conf,int verbose);
|
||||
BIGNUM *serial, char *subj, char *startdate,char *enddate,
|
||||
int days, int batch, char *ext_sect, LHASH *conf,int verbose);
|
||||
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 *startdate,
|
||||
TXT_DB *db, BIGNUM *serial, char *subj, char *startdate,
|
||||
char *enddate, int days, int batch, char *ext_sect,
|
||||
LHASH *conf,int verbose);
|
||||
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 *startdate,
|
||||
TXT_DB *db, BIGNUM *serial,char *subj, char *startdate,
|
||||
char *enddate, int days, char *ext_sect,LHASH *conf,
|
||||
int verbose);
|
||||
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,
|
||||
STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
|
||||
char *startdate, char *enddate, int days, int batch, int verbose,
|
||||
X509_REQ *req, char *ext_sect, LHASH *conf);
|
||||
static X509_NAME *do_subject(char *subject);
|
||||
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);
|
||||
@ -280,6 +282,7 @@ int MAIN(int argc, char **argv)
|
||||
char *serialfile=NULL;
|
||||
char *extensions=NULL;
|
||||
char *extfile=NULL;
|
||||
char *subj=NULL;
|
||||
char *crl_ext=NULL;
|
||||
int rev_type = REV_NONE;
|
||||
char *rev_arg = NULL;
|
||||
@ -343,6 +346,12 @@ EF_ALIGNMENT=0;
|
||||
if (--argc < 1) goto bad;
|
||||
section= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-subj") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
subj= *(++argv);
|
||||
/* preserve=1; */
|
||||
}
|
||||
else if (strcmp(*argv,"-startdate") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
@ -719,7 +728,7 @@ bad:
|
||||
lookup_fail(section,ENV_CERTIFICATE);
|
||||
goto err;
|
||||
}
|
||||
if (BIO_read_filename(in,certfile) <= 0)
|
||||
if (BIO_read_filename(in,certfile) <= 0)
|
||||
{
|
||||
perror(certfile);
|
||||
BIO_printf(bio_err,"trying to load CA certificate\n");
|
||||
@ -771,7 +780,7 @@ bad:
|
||||
C routines to convert the directory syntax to Unixly, and give
|
||||
that to access(). However, time's too short to do that just
|
||||
now.
|
||||
*/
|
||||
*/
|
||||
if (access(outdir,R_OK|W_OK|X_OK) != 0)
|
||||
{
|
||||
BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
|
||||
@ -902,9 +911,9 @@ bad:
|
||||
{
|
||||
BIO_printf(bio_err,"Malloc failure\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else if (i == 0)
|
||||
{
|
||||
{
|
||||
if (verbose) BIO_printf(bio_err,
|
||||
"No entries found to mark expired\n");
|
||||
}
|
||||
@ -987,7 +996,7 @@ bad:
|
||||
/* We can have sections in the ext file */
|
||||
if (!extensions && !(extensions = CONF_get_string(extconf, "default", "extensions")))
|
||||
extensions = "default";
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
if (req || gencrl)
|
||||
@ -1138,7 +1147,7 @@ bad:
|
||||
{
|
||||
total++;
|
||||
j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
|
||||
serial,startdate,enddate, days,extensions,conf,
|
||||
serial,subj,startdate,enddate, days,extensions,conf,
|
||||
verbose);
|
||||
if (j < 0) goto err;
|
||||
if (j > 0)
|
||||
@ -1162,7 +1171,7 @@ bad:
|
||||
{
|
||||
total++;
|
||||
j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
|
||||
db,serial,startdate,enddate,days,batch,
|
||||
db,serial,subj,startdate,enddate,days,batch,
|
||||
extensions,conf,verbose);
|
||||
if (j < 0) goto err;
|
||||
if (j > 0)
|
||||
@ -1181,7 +1190,7 @@ bad:
|
||||
{
|
||||
total++;
|
||||
j=certify(&x,infile,pkey,x509,dgst,attribs,db,
|
||||
serial,startdate,enddate,days,batch,
|
||||
serial,subj,startdate,enddate,days,batch,
|
||||
extensions,conf,verbose);
|
||||
if (j < 0) goto err;
|
||||
if (j > 0)
|
||||
@ -1200,7 +1209,7 @@ bad:
|
||||
{
|
||||
total++;
|
||||
j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
|
||||
serial,startdate,enddate,days,batch,
|
||||
serial,subj,startdate,enddate,days,batch,
|
||||
extensions,conf,verbose);
|
||||
if (j < 0) goto err;
|
||||
if (j > 0)
|
||||
@ -1674,7 +1683,7 @@ 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 *startdate, char *enddate, int days,
|
||||
BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
|
||||
int batch, char *ext_sect, LHASH *lconf, int verbose)
|
||||
{
|
||||
X509_REQ *req=NULL;
|
||||
@ -1722,7 +1731,7 @@ 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,startdate, enddate,
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate, enddate,
|
||||
days,batch,verbose,req,ext_sect,lconf);
|
||||
|
||||
err:
|
||||
@ -1733,7 +1742,7 @@ 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 *startdate, char *enddate, int days,
|
||||
BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
|
||||
int batch, char *ext_sect, LHASH *lconf, int verbose)
|
||||
{
|
||||
X509 *req=NULL;
|
||||
@ -1784,7 +1793,7 @@ 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,startdate,enddate,days,
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,days,
|
||||
batch,verbose,rreq,ext_sect,lconf);
|
||||
|
||||
err:
|
||||
@ -1795,7 +1804,7 @@ 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,
|
||||
STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
|
||||
char *startdate, char *enddate, int days, int batch, int verbose,
|
||||
X509_REQ *req, char *ext_sect, LHASH *lconf)
|
||||
{
|
||||
@ -1824,7 +1833,21 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
|
||||
for (i=0; i<DB_NUMBER; i++)
|
||||
row[i]=NULL;
|
||||
|
||||
BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
|
||||
if (subj)
|
||||
{
|
||||
X509_NAME *n = do_subject(subj);
|
||||
|
||||
if (!n)
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto err;
|
||||
}
|
||||
X509_REQ_set_subject_name(req,n);
|
||||
req->req_info->enc.modified = 1;
|
||||
X509_NAME_free(n);
|
||||
}
|
||||
|
||||
BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
|
||||
name=X509_REQ_get_subject_name(req);
|
||||
for (i=0; i<X509_NAME_entry_count(name); i++)
|
||||
{
|
||||
@ -2288,7 +2311,7 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
|
||||
|
||||
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 *startdate, char *enddate, int days,
|
||||
BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
|
||||
char *ext_sect, LHASH *lconf, int verbose)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *sk=NULL;
|
||||
@ -2423,7 +2446,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
|
||||
X509_REQ_set_pubkey(req,pktmp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,
|
||||
days,1,verbose,req,ext_sect,lconf);
|
||||
err:
|
||||
if (req != NULL) X509_REQ_free(req);
|
||||
@ -2973,3 +2996,62 @@ int make_revoked(X509_REVOKED *rev, char *str)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static X509_NAME *do_subject(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 NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
209
apps/req.c
209
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);
|
||||
|
@ -119,8 +119,15 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
|
||||
ret->modified=1;
|
||||
*val = (ASN1_VALUE *)ret;
|
||||
return 1;
|
||||
memerr:
|
||||
|
||||
memerr:
|
||||
ASN1err(ASN1_F_X509_NAME_NEW, ERR_R_MALLOC_FAILURE);
|
||||
if (ret)
|
||||
{
|
||||
if (ret->entries)
|
||||
sk_X509_NAME_ENTRY_free(ret->entries);
|
||||
OPENSSL_free(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ B<openssl> B<ca>
|
||||
[B<-name section>]
|
||||
[B<-gencrl>]
|
||||
[B<-revoke file>]
|
||||
[B<-subj arg>]
|
||||
[B<-crldays days>]
|
||||
[B<-crlhours hours>]
|
||||
[B<-crlexts section>]
|
||||
@ -105,6 +106,7 @@ the 'ps' utility) this option should be used with caution.
|
||||
|
||||
the key password source. For more information about the format of B<arg>
|
||||
see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
|
||||
|
||||
=item B<-verbose>
|
||||
|
||||
this prints extra details about the operations being performed.
|
||||
@ -197,6 +199,10 @@ the number of hours before the next CRL is due.
|
||||
|
||||
a filename containing a certificate to revoke.
|
||||
|
||||
=item B<-subj arg>
|
||||
|
||||
supersedes subject name given in the request
|
||||
|
||||
=item B<-crlexts section>
|
||||
|
||||
the section of the configuration file containing CRL extensions to
|
||||
|
@ -28,12 +28,15 @@ B<openssl> B<req>
|
||||
[B<-keyout filename>]
|
||||
[B<-[md5|sha1|md2|mdc2]>]
|
||||
[B<-config filename>]
|
||||
[B<-subj arg>]
|
||||
[B<-x509>]
|
||||
[B<-days n>]
|
||||
[B<-asn1-kludge>]
|
||||
[B<-newhdr>]
|
||||
[B<-extensions section>]
|
||||
[B<-reqexts section>]
|
||||
[B<-batch>]
|
||||
[B<-verbose>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@ -154,6 +157,11 @@ this allows an alternative configuration file to be specified,
|
||||
this overrides the compile time filename or any specified in
|
||||
the B<OPENSSL_CONF> environment variable.
|
||||
|
||||
=item B<-subj arg>
|
||||
|
||||
sets subject name for new request or supersedes the subject name
|
||||
when processing a request.
|
||||
|
||||
=item B<-x509>
|
||||
|
||||
this option outputs a self signed certificate instead of a certificate
|
||||
@ -196,6 +204,14 @@ It should be noted that very few CAs still require the use of this option.
|
||||
Adds the word B<NEW> to the PEM file header and footer lines on the outputed
|
||||
request. Some software (Netscape certificate server) and some CAs need this.
|
||||
|
||||
=item B<-batch>
|
||||
|
||||
non-interactive mode.
|
||||
|
||||
=item B<-verbose>
|
||||
|
||||
print extra details about the operations being performed.
|
||||
|
||||
=back
|
||||
|
||||
=head1 CONFIGURATION FILE FORMAT
|
||||
|
Loading…
x
Reference in New Issue
Block a user