Commit bad40585 authored by Bodo Möller's avatar Bodo Möller
Browse files

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
parent d8c2adae
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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,
+104 −22
Original line number Diff line number Diff line
@@ -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;
@@ -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;
	}
+171 −38
Original line number Diff line number Diff line
@@ -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,7 +409,9 @@ 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," -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");
@@ -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");
@@ -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);
@@ -872,6 +888,35 @@ loop:
			}
		}

	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,6 +1207,9 @@ static int prompt_info(X509_REQ *req,
	CONF_VALUE *v;
	X509_NAME *subj;
	subj = X509_REQ_get_subject_name(req);

	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");
@@ -1100,6 +1217,7 @@ static int prompt_info(X509_REQ *req,
		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,7 +1394,7 @@ 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)
		{
@@ -1287,8 +1405,16 @@ start:
	else
		{
		buf[0]='\0';
		if (!batch)
			{
			fgets(buf,1024,stdin);
			}
		else
			{
			buf[0] = '\n';
			buf[1] = '\0';
			}
		}

	if (buf[0] == '\0') return(0);
	else if (buf[0] == '\n')
@@ -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,8 +1463,16 @@ start:
	else
		{
		buf[0]='\0';
		if (!batch)
			{
			fgets(buf,1024,stdin);
			}
		else
			{
			buf[0] = '\n';
			buf[1] = '\0';
			}
		}

	if (buf[0] == '\0') return(0);
	else if (buf[0] == '\n')
+8 −1
Original line number Diff line number Diff line
@@ -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:
	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;
}

+6 −0
Original line number Diff line number Diff line
@@ -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
Loading