#include <openssl/ocsp.h>
#include <openssl/pem.h>
-#ifdef OPENSSL_SYS_WINDOWS
-#define strcasecmp _stricmp
-#else
-# ifdef NO_STRINGS_H
- int strcasecmp();
-# else
-# include <strings.h>
-# endif /* NO_STRINGS_H */
-#endif
-
#ifndef W_OK
# ifdef OPENSSL_SYS_VMS
# if defined(__DECC)
#define ENV_NEW_CERTS_DIR "new_certs_dir"
#define ENV_CERTIFICATE "certificate"
#define ENV_SERIAL "serial"
+#define ENV_CRLNUMBER "crlnumber"
#define ENV_CRL "crl"
#define ENV_PRIVATE_KEY "private_key"
#define ENV_RANDFILE "RANDFILE"
" -keyform arg - private key file format (PEM or ENGINE)\n",
" -key arg - key to decode the private key if it is encrypted\n",
" -cert file - The CA certificate\n",
+" -selfsign - sign a certificate with the key associated with it\n",
" -in file - The input PEM encoded certificate request(s)\n",
" -out file - Where to put the output file(s)\n",
" -outdir dir - Where to put output certificates\n",
BIGNUM *serial, char *subj, int email_dn, char *startdate,
char *enddate, long days, int batch, char *ext_sect, CONF *conf,
int verbose, unsigned long certopt, unsigned long nameopt,
- int default_op, int ext_copy);
+ int default_op, int ext_copy, int selfsign);
static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
CA_DB *db, BIGNUM *serial, char *subj, int email_dn,
int email_dn, char *startdate, char *enddate, long days, int batch,
int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
unsigned long certopt, unsigned long nameopt, int default_op,
- int ext_copy);
+ int ext_copy, int selfsign);
static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
static int get_certificate_status(const char *ser_status, CA_DB *db);
static int do_updatedb(CA_DB *db);
char *outfile=NULL;
char *outdir=NULL;
char *serialfile=NULL;
+ char *crlnumberfile=NULL;
char *extensions=NULL;
char *extfile=NULL;
char *subj=NULL;
int rev_type = REV_NONE;
char *rev_arg = NULL;
BIGNUM *serial=NULL;
+ BIGNUM *crlnumber=NULL;
char *startdate=NULL;
char *enddate=NULL;
long days=0;
unsigned long nameopt = 0, certopt = 0;
int default_op = 1;
int ext_copy = EXT_COPY_NONE;
- X509 *x509=NULL;
+ int selfsign = 0;
+ X509 *x509=NULL, *x509p = NULL;
X509 *x=NULL;
BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
char *dbfile=NULL;
if (--argc < 1) goto bad;
certfile= *(++argv);
}
+ else if (strcmp(*argv,"-selfsign") == 0)
+ selfsign=1;
else if (strcmp(*argv,"-in") == 0)
{
if (--argc < 1) goto bad;
p = NCONF_get_string(conf, section, "unique_subject");
if (p)
{
+#ifdef RL_DEBUG
BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
+#endif
switch(*p)
{
case 'f': /* false */
break;
}
}
+#ifdef RL_DEBUG
else
BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
+#endif
+#ifdef RL_DEBUG
BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
db_attr.unique_subject);
+#endif
in=BIO_new(BIO_s_file());
out=BIO_new(BIO_s_file());
}
/*****************************************************************/
- /* we definitely need a public key, so let's get it */
+ /* we definitely need a private key, so let's get it */
if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
section,ENV_PRIVATE_KEY)) == NULL))
/*****************************************************************/
/* we need a certificate */
- if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
- section,ENV_CERTIFICATE)) == NULL))
+ if (!selfsign || spkac_file || ss_cert_file || gencrl)
{
- lookup_fail(section,ENV_CERTIFICATE);
- goto err;
- }
- x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
- "CA certificate");
- if (x509 == NULL)
- goto err;
+ if ((certfile == NULL)
+ && ((certfile=NCONF_get_string(conf,
+ section,ENV_CERTIFICATE)) == NULL))
+ {
+ lookup_fail(section,ENV_CERTIFICATE);
+ goto err;
+ }
+ x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
+ "CA certificate");
+ if (x509 == NULL)
+ goto err;
- if (!X509_check_private_key(x509,pkey))
- {
- BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
- goto err;
+ if (!X509_check_private_key(x509,pkey))
+ {
+ BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
+ goto err;
+ }
}
+ if (!selfsign) x509p = x509;
f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
if (f == NULL)
if (infile != NULL)
{
total++;
- j=certify(&x,infile,pkey,x509,dgst,attribs,db,
+ j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
serial,subj,email_dn,startdate,enddate,days,batch,
extensions,conf,verbose, certopt, nameopt,
- default_op, ext_copy);
+ default_op, ext_copy, selfsign);
if (j < 0) goto err;
if (j > 0)
{
for (i=0; i<argc; i++)
{
total++;
- j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
+ j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
serial,subj,email_dn,startdate,enddate,days,batch,
extensions,conf,verbose, certopt, nameopt,
- default_op, ext_copy);
+ default_op, ext_copy, selfsign);
if (j < 0) goto err;
if (j > 0)
{
BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
- if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5)
- {
- BIO_printf(bio_err,"file name too long\n");
- goto err;
- }
-
- strcpy(buf[0],serialfile);
-
-#ifdef OPENSSL_SYS_VMS
- strcat(buf[0],"-new");
-#else
- strcat(buf[0],".new");
-#endif
-
- if (!save_serial(buf[0],serial,NULL)) goto err;
+ if (!save_serial(serialfile,"new",serial,NULL)) goto err;
if (!save_index(dbfile, "new", db)) goto err;
}
if (sk_X509_num(cert_sk))
{
/* Rename the database and the serial file */
- strncpy(buf[2],serialfile,BSIZE-4);
- buf[2][BSIZE-4]='\0';
-
-#ifdef OPENSSL_SYS_VMS
- strcat(buf[2],"-old");
-#else
- strcat(buf[2],".old");
-#endif
-
- BIO_free(in);
- BIO_free_all(out);
- in=NULL;
- out=NULL;
- if (rename(serialfile,buf[2]) < 0)
- {
- BIO_printf(bio_err,"unable to rename %s to %s\n",
- serialfile,buf[2]);
- perror("reason");
- goto err;
- }
- if (rename(buf[0],serialfile) < 0)
- {
- BIO_printf(bio_err,"unable to rename %s to %s\n",
- buf[0],serialfile);
- perror("reason");
- rename(buf[2],serialfile);
- goto err;
- }
+ if (!rotate_serial(serialfile,"new","old")) goto err;
if (!rotate_index(dbfile,"new","old")) goto err;
}
}
+ if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
+ != NULL)
+ if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"error while loading CRL number\n");
+ goto err;
+ }
+
if (!crldays && !crlhours)
{
if (!NCONF_get_number(conf,section,
/* Add any extensions asked for */
- if (crl_ext)
+ if (crl_ext || crlnumberfile != NULL)
{
X509V3_CTX crlctx;
X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
X509V3_set_nconf(&crlctx, conf);
- if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
- crl_ext, crl)) goto err;
+ if (crl_ext)
+ if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
+ crl_ext, crl)) goto err;
+ if (crlnumberfile != NULL)
+ {
+ tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
+ if (!tmpser) goto err;
+ X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
+ ASN1_INTEGER_free(tmpser);
+ crl_v2 = 1;
+ if (!BN_add_word(crlnumber,1)) goto err;
+ }
}
if (crl_ext || crl_v2)
{
goto err; /* version 2 CRL */
}
+
+ if (crlnumberfile != NULL) /* we have a CRL number that need updating */
+ if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
+
if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
PEM_write_bio_X509_CRL(Sout,crl);
+
+ if (crlnumberfile != NULL) /* Rename the crlnumber file */
+ if (!rotate_serial(crlnumberfile,"new","old")) goto err;
+
}
/*****************************************************************/
if (dorevoke)
BN_free(serial);
free_index(db);
EVP_PKEY_free(pkey);
- X509_free(x509);
+ if (x509) X509_free(x509);
X509_CRL_free(crl);
NCONF_free(conf);
OBJ_cleanup();
BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
long days, int batch, char *ext_sect, CONF *lconf, int verbose,
unsigned long certopt, unsigned long nameopt, int default_op,
- int ext_copy)
+ int ext_copy, int selfsign)
{
X509_REQ *req=NULL;
BIO *in=NULL;
BIO_printf(bio_err,"Check that the request matches the signature\n");
+ if (selfsign && !X509_REQ_check_private_key(req,pkey))
+ {
+ BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
+ ok=0;
+ goto err;
+ }
if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
{
BIO_printf(bio_err,"error unpacking public key\n");
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
- certopt, nameopt, default_op, ext_copy);
+ certopt, nameopt, default_op, ext_copy, selfsign);
err:
if (req != NULL) X509_REQ_free(req);
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
- ext_copy);
+ ext_copy, 0);
err:
if (rreq != NULL) X509_REQ_free(rreq);
int email_dn, char *startdate, char *enddate, long days, int batch,
int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
unsigned long certopt, unsigned long nameopt, int default_op,
- int ext_copy)
+ int ext_copy, int selfsign)
{
X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
ASN1_UTCTIME *tm,*tmptm;
}
/* take a copy of the issuer name before we mess with it. */
- CAname=X509_NAME_dup(x509->cert_info->subject);
+ if (selfsign)
+ CAname=X509_NAME_dup(name);
+ else
+ CAname=X509_NAME_dup(x509->cert_info->subject);
if (CAname == NULL) goto err;
str=str2=NULL;
#ifdef X509_V3
/* Make it an X509 v3 certificate. */
- if (!X509_set_version(x509,2)) goto err;
+ if (!X509_set_version(ret,2)) goto err;
#endif
if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
goto err;
- if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
- goto err;
+ if (selfsign)
+ {
+ if (!X509_set_issuer_name(ret,subject))
+ goto err;
+ }
+ else
+ {
+ if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
+ goto err;
+ }
if (strcmp(startdate,"today") == 0)
X509_gmtime_adj(X509_get_notBefore(ret),0);
ci->extensions = NULL;
/* Initialize the context structure */
- X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
+ if (selfsign)
+ X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
+ else
+ X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
if (extconf)
{
BIO_printf(bio_err,"Certificate is to be certified until ");
ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
- if (days) BIO_printf(bio_err," (%d days)",days);
+ if (days) BIO_printf(bio_err," (%ld days)",days);
BIO_printf(bio_err, "\n");
if (!batch)
EVP_PKEY_free(pktmp);
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
- ext_copy);
+ ext_copy, 0);
err:
if (req != NULL) X509_REQ_free(req);
if (parms != NULL) CONF_free(parms);
return ret;
}
-