#define ENV_RANDFILE "RANDFILE"
#define ENV_DEFAULT_DAYS "default_days"
#define ENV_DEFAULT_STARTDATE "default_startdate"
+#define ENV_DEFAULT_ENDDATE "default_enddate"
#define ENV_DEFAULT_CRL_DAYS "default_crl_days"
#define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
#define ENV_DEFAULT_MD "default_md"
" -gencrl - Generate a new CRL\n",
" -crldays days - Days is when the next CRL is due\n",
" -crlhours hours - Hours is when the next CRL is due\n",
+" -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
+" -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
" -days arg - number of days to certify the certificate for\n",
" -md arg - md to use, one of md2, md5, sha or sha1\n",
" -policy arg - The CA 'policy' to support\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",
+" -extensions .. - Extension section (override value in config file)\n",
+" -crlexts .. - CRL extension section (override value in config file)\n",
NULL
};
static int add_oid_section(LHASH *conf);
static void lookup_fail(char *name,char *tag);
-static int MS_CALLBACK key_callback(char *buf,int len,int verify);
+static int MS_CALLBACK key_callback(char *buf,int len,int verify,void *u);
static unsigned long index_serial_hash(char **a);
static int index_serial_cmp(char **a, char **b);
static unsigned long index_name_hash(char **a);
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 *policy,TXT_DB *db,BIGNUM *serial,
- char *startdate,int days,int batch,char *ext_sect,
- LHASH *conf,int verbose);
+ 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);
static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
- const EVP_MD *dgst,STACK *policy,TXT_DB *db,
- BIGNUM *serial,char *startdate,int days,int batch,
- char *ext_sect, LHASH *conf,int verbose);
+ 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);
static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
- const EVP_MD *dgst,STACK *policy,TXT_DB *db,
- BIGNUM *serial,char *startdate,int days,
- char *ext_sect,LHASH *conf,int verbose);
+ const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
+ TXT_DB *db, BIGNUM *serial,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);
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
- STACK *policy, TXT_DB *db, BIGNUM *serial, char *startdate,
- int days, int batch, int verbose, X509_REQ *req, char *ext_sect,
- LHASH *conf);
+ STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
+ char *startdate, char *enddate, int days, int batch, int verbose,
+ X509_REQ *req, char *ext_sect, LHASH *conf);
static int do_revoke(X509 *x509, TXT_DB *db);
static int check_time_format(char *str);
-static LHASH *conf;
+static LHASH *conf=NULL;
static char *key=NULL;
static char *section=NULL;
char *crl_ext=NULL;
BIGNUM *serial=NULL;
char *startdate=NULL;
+ char *enddate=NULL;
int days=0;
int batch=0;
X509 *x509=NULL;
int i,j;
long l;
const EVP_MD *dgst=NULL;
- STACK *attribs=NULL;
+ STACK_OF(CONF_VALUE) *attribs=NULL;
STACK *cert_sk=NULL;
BIO *hex=NULL;
#undef BSIZE
apps_startup();
+ conf = NULL;
+ key = NULL;
+ section = NULL;
+
X509V3_add_standard_extensions();
preserve=0;
+ msie_hack=0;
if (bio_err == NULL)
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
if (--argc < 1) goto bad;
startdate= *(++argv);
}
+ else if (strcmp(*argv,"-enddate") == 0)
+ {
+ if (--argc < 1) goto bad;
+ enddate= *(++argv);
+ }
else if (strcmp(*argv,"-days") == 0)
{
if (--argc < 1) goto bad;
infile= *(++argv);
dorevoke=1;
}
+ else if (strcmp(*argv,"-extensions") == 0)
+ {
+ if (--argc < 1) goto bad;
+ extensions= *(++argv);
+ }
+ else if (strcmp(*argv,"-crlexts") == 0)
+ {
+ if (--argc < 1) goto bad;
+ crl_ext= *(++argv);
+ }
else
{
bad:
goto err;
}
if (key == NULL)
- pkey=PEM_read_bio_PrivateKey(in,NULL,NULL);
+ pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL);
else
{
- pkey=PEM_read_bio_PrivateKey(in,NULL,key_callback);
+ pkey=PEM_read_bio_PrivateKey(in,NULL,key_callback,NULL);
memset(key,0,strlen(key));
}
if (pkey == NULL)
BIO_printf(bio_err,"trying to load CA certificate\n");
goto err;
}
- x509=PEM_read_bio_X509(in,NULL,NULL);
+ x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
if (x509 == NULL)
{
BIO_printf(bio_err,"unable to load CA certificate\n");
lookup_fail(section,ENV_SERIAL);
goto err;
}
-
- extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
+ if(!extensions)
+ extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
if(extensions) {
/* Check syntax of file */
X509V3_CTX ctx;
if (startdate == NULL)
{
- startdate=(char *)CONF_get_string(conf,section,
+ startdate=CONF_get_string(conf,section,
ENV_DEFAULT_STARTDATE);
- if (startdate == NULL)
- startdate="today";
- else
- {
- if (!ASN1_UTCTIME_set_string(NULL,startdate))
- {
- BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSS\n");
- goto err;
- }
- }
+ }
+ if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
+ {
+ BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
+ goto err;
+ }
+ if (startdate == NULL) startdate="today";
+
+ if (enddate == NULL)
+ {
+ enddate=CONF_get_string(conf,section,
+ ENV_DEFAULT_ENDDATE);
+ }
+ if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
+ {
+ BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
+ goto err;
}
if (days == 0)
days=(int)CONF_get_number(conf,section,
ENV_DEFAULT_DAYS);
}
- if (days == 0)
+ if (!enddate && (days == 0))
{
BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
goto err;
{
total++;
j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
- serial,startdate,days,extensions,conf,verbose);
+ serial,startdate,enddate, days,extensions,conf,
+ verbose);
if (j < 0) goto err;
if (j > 0)
{
{
total++;
j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
- db,serial,startdate,days,batch,
+ db,serial,startdate,enddate,days,batch,
extensions,conf,verbose);
if (j < 0) goto err;
if (j > 0)
{
total++;
j=certify(&x,infile,pkey,x509,dgst,attribs,db,
- serial,startdate,days,batch,
+ serial,startdate,enddate,days,batch,
extensions,conf,verbose);
if (j < 0) goto err;
if (j > 0)
{
total++;
j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
- serial,startdate,days,batch,
+ serial,startdate,enddate,days,batch,
extensions,conf,verbose);
if (j < 0) goto err;
if (j > 0)
/*****************************************************************/
if (gencrl)
{
- crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
+ if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
if(crl_ext) {
/* Check syntax of file */
X509V3_CTX ctx;
BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
goto err;
}
- x509=PEM_read_bio_X509(in,NULL,NULL);
+ x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
if (x509 == NULL)
{
BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
}
-static int MS_CALLBACK key_callback(char *buf, int len, int verify)
+static int MS_CALLBACK key_callback(char *buf, int len, int verify, void *u)
{
int i;
}
static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
- const EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial,
- char *startdate, int days, int batch, char *ext_sect, LHASH *lconf,
- int verbose)
+ 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 *lconf, int verbose)
{
X509_REQ *req=NULL;
BIO *in=NULL;
perror(infile);
goto err;
}
- if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL)) == NULL)
+ if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
{
BIO_printf(bio_err,"Error reading certificate request in %s\n",
infile);
else
BIO_printf(bio_err,"Signature ok\n");
- ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,
+ ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
days,batch,verbose,req,ext_sect,lconf);
err:
}
static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
- const EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial,
- char *startdate, int days, int batch, char *ext_sect, LHASH *lconf,
- int verbose)
-
+ 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 *lconf, int verbose)
{
X509 *req=NULL;
X509_REQ *rreq=NULL;
perror(infile);
goto err;
}
- if ((req=PEM_read_bio_X509(in,NULL,NULL)) == NULL)
+ if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
{
BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
goto err;
if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
goto err;
- ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,days,
+ ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
batch,verbose,rreq,ext_sect,lconf);
err:
}
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
- STACK *policy, TXT_DB *db, BIGNUM *serial, char *startdate, int days,
- int batch, int verbose, X509_REQ *req, char *ext_sect, LHASH *lconf)
+ STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
+ char *startdate, char *enddate, int days, int batch, int verbose,
+ X509_REQ *req, char *ext_sect, LHASH *lconf)
{
X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
ASN1_UTCTIME *tm,*tmptm;
if (CAname == NULL) goto err;
str=str2=NULL;
- for (i=0; i<sk_num(policy); i++)
+ for (i=0; i<sk_CONF_VALUE_num(policy); i++)
{
- cv=(CONF_VALUE *)sk_value(policy,i); /* get the object id */
+ cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
{
BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
BIO_printf(bio_err,"Certificate is to be certified until ");
if (strcmp(startdate,"today") == 0)
- {
X509_gmtime_adj(X509_get_notBefore(ret),0);
+ else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
+
+ if (enddate == NULL)
X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
- }
- else
- {
- /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
- ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
- }
+ else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
+
ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
- BIO_printf(bio_err," (%d days)\n",days);
+ if(days) BIO_printf(bio_err," (%d days)",days);
+ BIO_printf(bio_err, "\n");
if (!X509_set_subject_name(ret,subject)) goto err;
}
static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
- const EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial,
- char *startdate, int days, char *ext_sect, LHASH *lconf, int verbose)
+ const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
+ BIGNUM *serial, char *startdate, char *enddate, int days,
+ char *ext_sect, LHASH *lconf, int verbose)
{
- STACK *sk=NULL;
+ STACK_OF(CONF_VALUE) *sk=NULL;
LHASH *parms=NULL;
X509_REQ *req=NULL;
CONF_VALUE *cv=NULL;
NETSCAPE_SPKI *spki = NULL;
- unsigned char *spki_der = NULL,*p;
X509_REQ_INFO *ri;
char *type,*buf;
EVP_PKEY *pktmp=NULL;
}
sk=CONF_get_section(parms, "default");
- if (sk_num(sk) == 0)
+ if (sk_CONF_VALUE_num(sk) == 0)
{
BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
CONF_free(parms);
for (i = 0; ; i++)
{
- if ((int)sk_num(sk) <= i) break;
+ if (sk_CONF_VALUE_num(sk) <= i) break;
- cv=(CONF_VALUE *)sk_value(sk,i);
+ cv=sk_CONF_VALUE_value(sk,i);
type=cv->name;
- buf=cv->value;
+ /* Skip past any leading X. X: X, etc to allow for
+ * multiple instances
+ */
+ for(buf = cv->name; *buf ; buf++)
+ if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
+ buf++;
+ if(*buf) type = buf;
+ break;
+ }
+ buf=cv->value;
if ((nid=OBJ_txt2nid(type)) == NID_undef)
{
if (strcmp(type, "SPKAC") == 0)
{
- spki_der=(unsigned char *)Malloc(
- strlen(cv->value)+1);
- if (spki_der == NULL)
- {
- BIO_printf(bio_err,"Malloc failure\n");
- goto err;
- }
- j = EVP_DecodeBlock(spki_der, (unsigned char *)cv->value,
- strlen(cv->value));
- if (j <= 0)
- {
- BIO_printf(bio_err, "Can't b64 decode SPKAC structure\n");
- goto err;
- }
-
- p=spki_der;
- spki = d2i_NETSCAPE_SPKI(&spki, &p, j);
- Free(spki_der);
- spki_der = NULL;
+ spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
if (spki == NULL)
{
BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
- if ((pktmp=X509_PUBKEY_get(spki->spkac->pubkey)) == NULL)
+ if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
{
BIO_printf(bio_err,"error unpacking SPKAC public key\n");
goto err;
X509_REQ_set_pubkey(req,pktmp);
EVP_PKEY_free(pktmp);
- ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,
+ ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
days,1,verbose,req,ext_sect,lconf);
err:
if (req != NULL) X509_REQ_free(req);
if (parms != NULL) CONF_free(parms);
- if (spki_der != NULL) Free(spki_der);
if (spki != NULL) NETSCAPE_SPKI_free(spki);
if (ne != NULL) X509_NAME_ENTRY_free(ne);
static int add_oid_section(LHASH *hconf)
{
char *p;
- STACK *sktmp;
+ STACK_OF(CONF_VALUE) *sktmp;
CONF_VALUE *cnf;
int i;
if(!(p=CONF_get_string(hconf,NULL,"oid_section"))) return 1;
BIO_printf(bio_err, "problem loading oid section %s\n", p);
return 0;
}
- for(i = 0; i < sk_num(sktmp); i++) {
- cnf = (CONF_VALUE *)sk_value(sktmp, i);
+ for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+ cnf = sk_CONF_VALUE_value(sktmp, i);
if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
BIO_printf(bio_err, "problem creating object %s=%s\n",
cnf->name, cnf->value);