return p;
}
+
+static unsigned long index_serial_hash(const char **a)
+ {
+ const char *n;
+
+ n=a[DB_serial];
+ while (*n == '0') n++;
+ return(lh_strhash(n));
+ }
+
+static int index_serial_cmp(const char **a, const char **b)
+ {
+ const char *aa,*bb;
+
+ for (aa=a[DB_serial]; *aa == '0'; aa++);
+ for (bb=b[DB_serial]; *bb == '0'; bb++);
+ return(strcmp(aa,bb));
+ }
+
+static int index_name_qual(char **a)
+ { return(a[0][0] == 'V'); }
+
+static unsigned long index_name_hash(const char **a)
+ { return(lh_strhash(a[DB_name])); }
+
+int index_name_cmp(const char **a, const char **b)
+ { return(strcmp(a[DB_name],
+ b[DB_name])); }
+
+static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
+static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
+static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
+static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
+
+#undef BSIZE
+#define BSIZE 256
+
+BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
+ {
+ BIO *in=NULL;
+ BIGNUM *ret=NULL;
+ MS_STATIC char buf[1024];
+ ASN1_INTEGER *ai=NULL;
+
+ ai=ASN1_INTEGER_new();
+ if (ai == NULL) goto err;
+
+ if ((in=BIO_new(BIO_s_file())) == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ if (BIO_read_filename(in,serialfile) <= 0)
+ {
+ if (!create)
+ {
+ perror(serialfile);
+ goto err;
+ }
+ else
+ {
+ ASN1_INTEGER_set(ai,1);
+ ret=BN_new();
+ if (ret == NULL)
+ BIO_printf(bio_err, "Out of memory\n");
+ else
+ BN_one(ret);
+ }
+ }
+ else
+ {
+ if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
+ {
+ BIO_printf(bio_err,"unable to load number from %s\n",
+ serialfile);
+ goto err;
+ }
+ ret=ASN1_INTEGER_to_BN(ai,NULL);
+ if (ret == NULL)
+ {
+ BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
+ goto err;
+ }
+ }
+
+ if (ret && retai)
+ {
+ *retai = ai;
+ ai = NULL;
+ }
+ err:
+ if (in != NULL) BIO_free(in);
+ if (ai != NULL) ASN1_INTEGER_free(ai);
+ return(ret);
+ }
+
+int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai)
+ {
+ char buf[1][BSIZE];
+ BIO *out = NULL;
+ int ret=0;
+ ASN1_INTEGER *ai=NULL;
+ int j;
+
+ if (suffix == NULL)
+ j = strlen(serialfile);
+ else
+ j = strlen(serialfile) + strlen(suffix) + 1;
+ if (j >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+ if (suffix == NULL)
+ BUF_strlcpy(buf[0], serialfile, BSIZE);
+ else
+ {
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
+#endif
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
+#endif
+ out=BIO_new(BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ if (BIO_write_filename(out,buf[0]) <= 0)
+ {
+ perror(serialfile);
+ goto err;
+ }
+
+ if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
+ {
+ BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
+ goto err;
+ }
+ i2a_ASN1_INTEGER(out,ai);
+ BIO_puts(out,"\n");
+ ret=1;
+ if (retai)
+ {
+ *retai = ai;
+ ai = NULL;
+ }
+err:
+ if (out != NULL) BIO_free_all(out);
+ if (ai != NULL) ASN1_INTEGER_free(ai);
+ return(ret);
+ }
+
+int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
+ {
+ char buf[5][BSIZE];
+ int i,j;
+ struct stat sb;
+
+ i = strlen(serialfile) + strlen(old_suffix);
+ j = strlen(serialfile) + strlen(new_suffix);
+ if (i > j) j = i;
+ if (j + 1 >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
+ serialfile, new_suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
+ serialfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
+ serialfile, old_suffix);
+#else
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
+ serialfile, old_suffix);
+#endif
+ if (stat(serialfile,&sb) < 0)
+ {
+ if (errno != ENOENT
+#ifdef ENOTDIR
+ && errno != ENOTDIR)
+#endif
+ goto err;
+ }
+ else
+ {
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ serialfile, buf[1]);
+#endif
+ if (rename(serialfile,buf[1]) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ serialfile, buf[1]);
+ perror("reason");
+ goto err;
+ }
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[0],serialfile);
+#endif
+ if (rename(buf[0],serialfile) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[0],serialfile);
+ perror("reason");
+ rename(buf[1],serialfile);
+ goto err;
+ }
+ return 1;
+ err:
+ return 0;
+ }
+
+CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
+ {
+ CA_DB *retdb = NULL;
+ TXT_DB *tmpdb = NULL;
+ BIO *in = BIO_new(BIO_s_file());
+ CONF *dbattr_conf = NULL;
+ char buf[1][BSIZE];
+ long errorline= -1;
+
+ if (in == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ if (BIO_read_filename(in,dbfile) <= 0)
+ {
+ perror(dbfile);
+ BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
+ goto err;
+ }
+ if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
+ {
+ if (tmpdb != NULL) TXT_DB_free(tmpdb);
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
+#else
+ BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
+#endif
+ dbattr_conf = NCONF_new(NULL);
+ if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
+ {
+ if (errorline > 0)
+ {
+ BIO_printf(bio_err,
+ "error on line %ld of db attribute file '%s'\n"
+ ,errorline,buf[0]);
+ goto err;
+ }
+ else
+ {
+ NCONF_free(dbattr_conf);
+ dbattr_conf = NULL;
+ }
+ }
+
+ if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
+ {
+ fprintf(stderr, "Out of memory\n");
+ goto err;
+ }
+
+ retdb->db = tmpdb;
+ tmpdb = NULL;
+ if (db_attr)
+ retdb->attributes = *db_attr;
+ else
+ {
+ retdb->attributes.unique_subject = 1;
+ }
+
+ if (dbattr_conf)
+ {
+ char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
+ if (p)
+ {
+ BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
+ switch(*p)
+ {
+ case 'f': /* false */
+ case 'F': /* FALSE */
+ case 'n': /* no */
+ case 'N': /* NO */
+ retdb->attributes.unique_subject = 0;
+ break;
+ case 't': /* true */
+ case 'T': /* TRUE */
+ case 'y': /* yes */
+ case 'Y': /* YES */
+ default:
+ retdb->attributes.unique_subject = 1;
+ break;
+ }
+ }
+ }
+
+ err:
+ if (dbattr_conf) NCONF_free(dbattr_conf);
+ if (tmpdb) TXT_DB_free(tmpdb);
+ if (in) BIO_free_all(in);
+ return retdb;
+ }
+
+int index_index(CA_DB *db)
+ {
+ if (!TXT_DB_create_index(db->db, DB_serial, NULL,
+ LHASH_HASH_FN(index_serial_hash),
+ LHASH_COMP_FN(index_serial_cmp)))
+ {
+ BIO_printf(bio_err,
+ "error creating serial number index:(%ld,%ld,%ld)\n",
+ db->db->error,db->db->arg1,db->db->arg2);
+ return 0;
+ }
+
+ if (db->attributes.unique_subject
+ && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
+ LHASH_HASH_FN(index_name_hash),
+ LHASH_COMP_FN(index_name_cmp)))
+ {
+ BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
+ db->db->error,db->db->arg1,db->db->arg2);
+ return 0;
+ }
+ return 1;
+ }
+
+int save_index(char *dbfile, char *suffix, CA_DB *db)
+ {
+ char buf[3][BSIZE];
+ BIO *out = BIO_new(BIO_s_file());
+ int j;
+
+ if (out == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+ j = strlen(dbfile) + strlen(suffix);
+ if (j + 6 >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
+#else
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
+#else
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
+#endif
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
+#endif
+ if (BIO_write_filename(out,buf[0]) <= 0)
+ {
+ perror(dbfile);
+ BIO_printf(bio_err,"unable to open '%s'\n", dbfile);
+ goto err;
+ }
+ j=TXT_DB_write(out,db->db);
+ if (j <= 0) goto err;
+
+ BIO_free(out);
+
+ out = BIO_new(BIO_s_file());
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
+#endif
+ if (BIO_write_filename(out,buf[1]) <= 0)
+ {
+ perror(buf[2]);
+ BIO_printf(bio_err,"unable to open '%s'\n", buf[2]);
+ goto err;
+ }
+ BIO_printf(out,"unique_subject = %s\n",
+ db->attributes.unique_subject ? "yes" : "no");
+ BIO_free(out);
+
+ return 1;
+ err:
+ return 0;
+ }
+
+int rotate_index(char *dbfile, char *new_suffix, char *old_suffix)
+ {
+ char buf[5][BSIZE];
+ int i,j;
+ struct stat sb;
+
+ i = strlen(dbfile) + strlen(old_suffix);
+ j = strlen(dbfile) + strlen(new_suffix);
+ if (i > j) j = i;
+ if (j + 6 >= BSIZE)
+ {
+ BIO_printf(bio_err,"file name too long\n");
+ goto err;
+ }
+
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
+#else
+ j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s",
+ dbfile, new_suffix);
+#else
+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s",
+ dbfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
+ dbfile, new_suffix);
+#else
+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
+ dbfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
+ dbfile, old_suffix);
+#else
+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
+ dbfile, old_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+ j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s",
+ dbfile, old_suffix);
+#else
+ j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
+ dbfile, old_suffix);
+#endif
+ if (stat(dbfile,&sb) < 0)
+ {
+ if (errno != ENOENT
+#ifdef ENOTDIR
+ && errno != ENOTDIR)
+#endif
+ goto err;
+ }
+ else
+ {
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ dbfile, buf[1]);
+#endif
+ if (rename(dbfile,buf[1]) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ dbfile, buf[1]);
+ perror("reason");
+ goto err;
+ }
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[0],dbfile);
+#endif
+ if (rename(buf[0],dbfile) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[0],dbfile);
+ perror("reason");
+ rename(buf[1],dbfile);
+ goto err;
+ }
+ if (stat(buf[4],&sb) < 0)
+ {
+ if (errno != ENOENT
+#ifdef ENOTDIR
+ && errno != ENOTDIR)
+#endif
+ goto err;
+ }
+ else
+ {
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[4],buf[3]);
+#endif
+ if (rename(buf[4],buf[3]) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[4], buf[3]);
+ perror("reason");
+ rename(dbfile,buf[0]);
+ rename(buf[1],dbfile);
+ goto err;
+ }
+ }
+#ifdef RL_DEBUG
+ BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+ buf[2],buf[4]);
+#endif
+ if (rename(buf[2],buf[4]) < 0)
+ {
+ BIO_printf(bio_err,
+ "unable to rename %s to %s\n",
+ buf[2],buf[4]);
+ perror("reason");
+ rename(buf[3],buf[4]);
+ rename(dbfile,buf[0]);
+ rename(buf[1],dbfile);
+ goto err;
+ }
+ return 1;
+ err:
+ return 0;
+ }
+
+void free_index(CA_DB *db)
+ {
+ TXT_DB_free(db->db);
+ OPENSSL_free(db);
+ }
#define ENV_DATABASE "database"
-#define DB_type 0
-#define DB_exp_date 1
-#define DB_rev_date 2
-#define DB_serial 3 /* index - unique */
-#define DB_file 4
-#define DB_name 5 /* index - unique for active */
-#define DB_NUMBER 6
-
-#define DB_TYPE_REV 'R'
-#define DB_TYPE_EXP 'E'
-#define DB_TYPE_VAL 'V'
-
/* Additional revocation information types */
#define REV_NONE 0 /* No addditional information */
#endif
static void lookup_fail(char *name,char *tag);
-static unsigned long index_serial_hash(const char **a);
-static int index_serial_cmp(const char **a, const char **b);
-static unsigned long index_name_hash(const char **a);
-static int index_name_qual(char **a);
-static int index_name_cmp(const char **a,const char **b);
-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,
+ const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
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);
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 *subj, int email_dn,
+ CA_DB *db, 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,
ENGINE *e);
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 *subj, int email_dn,
+ CA_DB *db, BIGNUM *serial,char *subj, int email_dn,
char *startdate, char *enddate, long days, char *ext_sect,
CONF *conf, int verbose, unsigned long certopt,
unsigned long nameopt, int default_op, int ext_copy);
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,char *subj,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,
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);
-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);
+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);
static int check_time_format(char *str);
char *make_revocation_str(int rev_type, char *rev_arg);
int make_revoked(X509_REVOKED *rev, char *str);
static int preserve=0;
static int msie_hack=0;
-static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
-static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
-static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
-static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
-
int MAIN(int, char **);
X509 *x=NULL;
BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
char *dbfile=NULL;
- TXT_DB *db=NULL;
+ CA_DB *db=NULL;
X509_CRL *crl=NULL;
X509_REVOKED *r=NULL;
ASN1_TIME *tmptm;
ASN1_INTEGER *tmpser;
char **pp,*p,*f;
int i,j;
- long l;
const EVP_MD *dgst=NULL;
STACK_OF(CONF_VALUE) *attribs=NULL;
STACK_OF(X509) *cert_sk=NULL;
char *engine = NULL;
#endif
char *tofree=NULL;
+ DB_ATTR db_attr;
#ifdef EFENCE
EF_PROTECT_FREE=1;
if (randfile == NULL)
ERR_clear_error();
app_RAND_load_file(randfile, bio_err, 0);
+
+ db_attr.unique_subject = 1;
+ 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 */
+ case 'F': /* FALSE */
+ case 'n': /* no */
+ case 'N': /* NO */
+ db_attr.unique_subject = 0;
+ break;
+ case 't': /* true */
+ case 'T': /* TRUE */
+ case 'y': /* yes */
+ case 'Y': /* YES */
+ default:
+ db_attr.unique_subject = 1;
+ 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());
lookup_fail(section,ENV_DATABASE);
goto err;
}
- if (BIO_read_filename(in,dbfile) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
- goto err;
- }
- db=TXT_DB_read(in,DB_NUMBER);
+ db = load_index(dbfile,&db_attr);
if (db == NULL) goto err;
- if (!make_serial_index(db))
- goto err;
+ if (!index_index(db)) goto err;
if (get_certificate_status(ser_status,db) != 1)
BIO_printf(bio_err,"Error verifying serial %s!\n",
lookup_fail(section,ENV_DATABASE);
goto err;
}
- if (BIO_read_filename(in,dbfile) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
- goto err;
- }
- db=TXT_DB_read(in,DB_NUMBER);
+ db = load_index(dbfile, &db_attr);
if (db == NULL) goto err;
/* Lets check some fields */
- for (i=0; i<sk_num(db->data); i++)
+ for (i=0; i<sk_num(db->db->data); i++)
{
- pp=(char **)sk_value(db->data,i);
+ pp=(char **)sk_value(db->db->data,i);
if ((pp[DB_type][0] != DB_TYPE_REV) &&
(pp[DB_rev_date][0] != '\0'))
{
out = BIO_push(tmpbio, out);
}
#endif
- TXT_DB_write(out,db);
+ TXT_DB_write(out,db->db);
BIO_printf(bio_err,"%d entries loaded from the database\n",
- db->data->num);
+ db->db->data->num);
BIO_printf(bio_err,"generating index\n");
}
- if (!make_serial_index(db))
- goto err;
-
- if (!TXT_DB_create_index(db, DB_name, index_name_qual,
- LHASH_HASH_FN(index_name_hash),
- LHASH_COMP_FN(index_name_cmp)))
- {
- BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
- db->error,db->arg1,db->arg2);
- goto err;
- }
+ if (!index_index(db)) goto err;
/*****************************************************************/
/* Update the db file for expired certificates */
}
else
{
- out = BIO_new(BIO_s_file());
- if (out == NULL)
- {
- ERR_print_errors(bio_err);
- goto err;
- }
-
-#ifndef OPENSSL_SYS_VMS
- j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
-#else
- j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile);
-#endif
- if (j < 0 || j >= sizeof buf[0])
- {
- BIO_printf(bio_err, "file name too long\n");
- goto err;
- }
- if (BIO_write_filename(out,buf[0]) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",
- dbfile);
- goto err;
- }
- j=TXT_DB_write(out,db);
- if (j <= 0) goto err;
-
- BIO_free(out);
- out = NULL;
-#ifndef OPENSSL_SYS_VMS
- j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
-#else
- j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile);
-#endif
- if (j < 0 || j >= sizeof buf[1])
- {
- BIO_printf(bio_err, "file name too long\n");
- goto err;
- }
- if (rename(dbfile,buf[1]) < 0)
- {
- BIO_printf(bio_err,
- "unable to rename %s to %s\n",
- dbfile, buf[1]);
- perror("reason");
- goto err;
- }
- if (rename(buf[0],dbfile) < 0)
- {
- BIO_printf(bio_err,
- "unable to rename %s to %s\n",
- buf[0],dbfile);
- perror("reason");
- rename(buf[1],dbfile);
- goto err;
- }
+ if (!save_index(dbfile,"new",db)) goto err;
+
+ if (!rotate_index(dbfile,"new","old")) goto err;
if (verbose) BIO_printf(bio_err,
"Done. %d entries marked as expired\n",i);
goto err;
}
- if ((serial=load_serial(serialfile)) == NULL)
+ if ((serial=load_serial(serialfile, 0, NULL)) == NULL)
{
BIO_printf(bio_err,"error while loading serial number\n");
goto err;
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);
+ if (!save_serial(serialfile,"new",serial,NULL)) goto err;
-#ifdef OPENSSL_SYS_VMS
- strcat(buf[0],"-new");
-#else
- BUF_strlcat(buf[0],".new",sizeof(buf[0]));
-#endif
-
- if (!save_serial(buf[0],serial)) goto err;
-
- strcpy(buf[1],dbfile);
-
-#ifdef OPENSSL_SYS_VMS
- strcat(buf[1],"-new");
-#else
- BUF_strlcat(buf[1],".new",sizeof(buf[1]));
-#endif
-
- if (BIO_write_filename(out,buf[1]) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
- goto err;
- }
- l=TXT_DB_write(out,db);
- if (l <= 0) goto err;
+ if (!save_index(dbfile, "new", db)) goto err;
}
if (verbose)
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
- BUF_strlcat(buf[2],".old",sizeof(buf[2]));
-#endif
+ if (!rotate_serial(serialfile,"new","old")) goto err;
- 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_index(dbfile,"new","old")) goto err;
- strncpy(buf[2],dbfile,BSIZE-4);
- buf[2][BSIZE-4]='\0';
-
-#ifdef OPENSSL_SYS_VMS
- strcat(buf[2],"-old");
-#else
- BUF_strlcat(buf[2],".old",sizeof(buf[2]));
-#endif
-
- if (rename(dbfile,buf[2]) < 0)
- {
- BIO_printf(bio_err,"unable to rename %s to %s\n",
- dbfile,buf[2]);
- perror("reason");
- goto err;
- }
- if (rename(buf[1],dbfile) < 0)
- {
- BIO_printf(bio_err,"unable to rename %s to %s\n",
- buf[1],dbfile);
- perror("reason");
- rename(buf[2],dbfile);
- goto err;
- }
BIO_printf(bio_err,"Data Base Updated\n");
}
}
ASN1_TIME_free(tmptm);
- for (i=0; i<sk_num(db->data); i++)
+ for (i=0; i<sk_num(db->db->data); i++)
{
- pp=(char **)sk_value(db->data,i);
+ pp=(char **)sk_value(db->db->data,i);
if (pp[DB_type][0] == DB_TYPE_REV)
{
if ((r=X509_REVOKED_new()) == NULL) goto err;
if (j <= 0) goto err;
X509_free(revcert);
- if(strlen(dbfile) > BSIZE-5)
- {
- BIO_printf(bio_err,"filename too long\n");
- goto err;
- }
+ if (!save_index(dbfile, "new", db)) goto err;
+
+ if (!rotate_index(dbfile, "new", "old")) goto err;
- strcpy(buf[0],dbfile);
-#ifndef OPENSSL_SYS_VMS
- BUF_strlcat(buf[0],".new",sizeof(buf[0]));
-#else
- strcat(buf[0],"-new");
-#endif
- if (BIO_write_filename(out,buf[0]) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
- goto err;
- }
- j=TXT_DB_write(out,db);
- if (j <= 0) goto err;
- BIO_free_all(out);
- out = NULL;
- BIO_free_all(in);
- in = NULL;
- strncpy(buf[1],dbfile,BSIZE-4);
- buf[1][BSIZE-4]='\0';
-#ifndef OPENSSL_SYS_VMS
- BUF_strlcat(buf[1],".old",sizeof(buf[1]));
-#else
- strcat(buf[1],"-old");
-#endif
- if (rename(dbfile,buf[1]) < 0)
- {
- BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
- perror("reason");
- goto err;
- }
- if (rename(buf[0],dbfile) < 0)
- {
- BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
- perror("reason");
- rename(buf[1],dbfile);
- goto err;
- }
BIO_printf(bio_err,"Data Base Updated\n");
}
}
if (free_key && key)
OPENSSL_free(key);
BN_free(serial);
- TXT_DB_free(db);
+ free_index(db);
EVP_PKEY_free(pkey);
X509_free(x509);
X509_CRL_free(crl);
BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
}
-static unsigned long index_serial_hash(const char **a)
- {
- const char *n;
-
- n=a[DB_serial];
- while (*n == '0') n++;
- return(lh_strhash(n));
- }
-
-static int index_serial_cmp(const char **a, const char **b)
- {
- const char *aa,*bb;
-
- for (aa=a[DB_serial]; *aa == '0'; aa++);
- for (bb=b[DB_serial]; *bb == '0'; bb++);
- return(strcmp(aa,bb));
- }
-
-static unsigned long index_name_hash(const char **a)
- { return(lh_strhash(a[DB_name])); }
-
-static int index_name_qual(char **a)
- { return(a[0][0] == 'V'); }
-
-static int index_name_cmp(const char **a, const char **b)
- { return(strcmp(a[DB_name],
- b[DB_name])); }
-
-static BIGNUM *load_serial(char *serialfile)
- {
- BIO *in=NULL;
- BIGNUM *ret=NULL;
- MS_STATIC char buf[1024];
- ASN1_INTEGER *ai=NULL;
-
- if ((in=BIO_new(BIO_s_file())) == NULL)
- {
- ERR_print_errors(bio_err);
- goto err;
- }
-
- if (BIO_read_filename(in,serialfile) <= 0)
- {
- perror(serialfile);
- goto err;
- }
- ai=ASN1_INTEGER_new();
- if (ai == NULL) goto err;
- if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
- {
- BIO_printf(bio_err,"unable to load number from %s\n",
- serialfile);
- goto err;
- }
- ret=ASN1_INTEGER_to_BN(ai,NULL);
- if (ret == NULL)
- {
- BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
- goto err;
- }
-err:
- if (in != NULL) BIO_free(in);
- if (ai != NULL) ASN1_INTEGER_free(ai);
- return(ret);
- }
-
-static int save_serial(char *serialfile, BIGNUM *serial)
- {
- BIO *out;
- int ret=0;
- ASN1_INTEGER *ai=NULL;
-
- out=BIO_new(BIO_s_file());
- if (out == NULL)
- {
- ERR_print_errors(bio_err);
- goto err;
- }
- if (BIO_write_filename(out,serialfile) <= 0)
- {
- perror(serialfile);
- goto err;
- }
-
- if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
- {
- BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
- goto err;
- }
- i2a_ASN1_INTEGER(out,ai);
- BIO_puts(out,"\n");
- ret=1;
-err:
- if (out != NULL) BIO_free_all(out);
- if (ai != NULL) ASN1_INTEGER_free(ai);
- return(ret);
- }
-
static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
- const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
+ const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
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,
}
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,
+ const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
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,
}
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, char *subj,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
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 ok= -1,i,j,last,nid;
char *p;
CONF_VALUE *cv;
- char *row[DB_NUMBER],**rrow,**irow=NULL;
+ char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
char buf[25];
tmptm=ASN1_UTCTIME_new();
goto err;
}
- rrow=TXT_DB_get_by_index(db,DB_name,row);
- if (rrow != NULL)
+ if (db->attributes.unique_subject)
{
- BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
- row[DB_name]);
+ rrow=TXT_DB_get_by_index(db->db,DB_name,row);
+ if (rrow != NULL)
+ {
+ BIO_printf(bio_err,
+ "ERROR:There is already a certificate for %s\n",
+ row[DB_name]);
+ }
}
- else
+ if (rrow == NULL)
{
- rrow=TXT_DB_get_by_index(db,DB_serial,row);
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
if (rrow != NULL)
{
BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
}
irow[DB_NUMBER]=NULL;
- if (!TXT_DB_insert(db,irow))
+ if (!TXT_DB_insert(db->db,irow))
{
BIO_printf(bio_err,"failed to update database\n");
- BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
+ BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
goto err;
}
ok=1;
}
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,
+ const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
unsigned long nameopt, int default_op, int ext_copy)
return(ASN1_UTCTIME_check(&tm));
}
-static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
+static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
{
ASN1_UTCTIME *tm=NULL;
char *row[DB_NUMBER],**rrow,**irow;
/* We have to lookup by serial number because name lookup
* skips revoked certs
*/
- rrow=TXT_DB_get_by_index(db,DB_serial,row);
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
if (rrow == NULL)
{
- BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
+ BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
/* We now just add it to the database */
row[DB_type]=(char *)OPENSSL_malloc(2);
}
irow[DB_NUMBER]=NULL;
- if (!TXT_DB_insert(db,irow))
+ if (!TXT_DB_insert(db->db,irow))
{
BIO_printf(bio_err,"failed to update database\n");
- BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
+ BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
goto err;
}
return(ok);
}
-static int get_certificate_status(const char *serial, TXT_DB *db)
+static int get_certificate_status(const char *serial, CA_DB *db)
{
char *row[DB_NUMBER],**rrow;
int ok=-1,i;
ok=1;
/* Search for the certificate */
- rrow=TXT_DB_get_by_index(db,DB_serial,row);
+ rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
if (rrow == NULL)
{
BIO_printf(bio_err,"Serial %s not present in db.\n",
return(ok);
}
-static int do_updatedb (TXT_DB *db)
+static int do_updatedb (CA_DB *db)
{
ASN1_UTCTIME *a_tm = NULL;
int i, cnt = 0;
else
a_y2k = 0;
- for (i = 0; i < sk_num(db->data); i++)
+ for (i = 0; i < sk_num(db->db->data); i++)
{
- rrow = (char **) sk_value(db->data, i);
+ rrow = (char **) sk_value(db->db->data, i);
if (rrow[DB_type][0] == 'V')
{
return ret;
}
-int make_serial_index(TXT_DB *db)
- {
- if (!TXT_DB_create_index(db, DB_serial, NULL,
- LHASH_HASH_FN(index_serial_hash),
- LHASH_COMP_FN(index_serial_cmp)))
- {
- BIO_printf(bio_err,
- "error creating serial number index:(%ld,%ld,%ld)\n",
- db->error,db->arg1,db->arg2);
- return 0;
- }
- return 1;
- }