diff options
author | levitte <levitte> | 2003-04-03 16:33:01 +0000 |
---|---|---|
committer | levitte <levitte> | 2003-04-03 16:33:01 +0000 |
commit | 9de7fd0827406c292e80160889bb5bf14a5d2271 (patch) | |
tree | 46d535fac319acf30b3cd92aca49bd7ed58df6e3 /apps/ca.c | |
parent | ae7affd9e90d809dd8ea0a000de819a6413a1e02 (diff) | |
download | openssl-9de7fd0827406c292e80160889bb5bf14a5d2271.tar.gz |
Make it possible to have multiple active certificates with the same
subject.
Diffstat (limited to 'apps/ca.c')
-rw-r--r-- | apps/ca.c | 425 |
1 files changed, 84 insertions, 341 deletions
@@ -143,18 +143,6 @@ #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 */ @@ -211,43 +199,36 @@ extern int EF_ALIGNMENT; #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); @@ -259,11 +240,6 @@ static char *section=NULL; 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 **); @@ -320,14 +296,13 @@ int MAIN(int argc, char **argv) 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; @@ -339,6 +314,7 @@ int MAIN(int argc, char **argv) char *engine = NULL; #endif char *tofree=NULL; + DB_ATTR db_attr; #ifdef EFENCE EF_PROTECT_FREE=1; @@ -659,6 +635,33 @@ bad: 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) + { + BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p); + 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; + } + } + else + BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p); + BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n", + db_attr.unique_subject); in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); @@ -679,17 +682,10 @@ bad: 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", @@ -849,19 +845,13 @@ bad: 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')) { @@ -912,23 +902,13 @@ bad: 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 */ @@ -951,62 +931,9 @@ bad: } 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); @@ -1167,7 +1094,7 @@ bad: 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; @@ -1315,24 +1242,9 @@ bad: strcat(buf[0],".new"); #endif - if (!save_serial(buf[0],serial)) goto err; - - strcpy(buf[1],dbfile); - -#ifdef OPENSSL_SYS_VMS - strcat(buf[1],"-new"); -#else - strcat(buf[1],".new"); -#endif + if (!save_serial(buf[0],serial,NULL)) goto err; - 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) @@ -1419,30 +1331,8 @@ bad: goto err; } - strncpy(buf[2],dbfile,BSIZE-4); - buf[2][BSIZE-4]='\0'; - -#ifdef OPENSSL_SYS_VMS - strcat(buf[2],"-old"); -#else - strcat(buf[2],".old"); -#endif + if (!rotate_index(dbfile,"new","old")) goto err; - 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"); } } @@ -1501,9 +1391,9 @@ bad: 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; @@ -1592,50 +1482,10 @@ bad: 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 - strcat(buf[0],".new"); -#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; - strncpy(buf[1],dbfile,BSIZE-4); - buf[1][BSIZE-4]='\0'; -#ifndef OPENSSL_SYS_VMS - strcat(buf[1],".old"); -#else - strcat(buf[1],"-old"); -#endif - BIO_free(in); - in = NULL; - BIO_free(out); - out = NULL; - 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"); } } @@ -1657,7 +1507,7 @@ err: 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); @@ -1672,106 +1522,8 @@ static void lookup_fail(char *name, char *tag) 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, @@ -1833,7 +1585,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, + 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, @@ -1887,7 +1639,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, 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, @@ -1905,7 +1657,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, 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(); @@ -2142,15 +1894,19 @@ again2: 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", @@ -2384,10 +2140,10 @@ again2: } 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; @@ -2438,7 +2194,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, + 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) @@ -2617,7 +2373,7 @@ static int check_time_format(char *str) 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; @@ -2642,10 +2398,10 @@ static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value) /* 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); @@ -2685,10 +2441,10 @@ static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value) } 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; } @@ -2733,7 +2489,7 @@ 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; @@ -2774,7 +2530,7 @@ static int get_certificate_status(const char *serial, TXT_DB *db) 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", @@ -2821,7 +2577,7 @@ err: 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; @@ -2847,9 +2603,9 @@ static int do_updatedb (TXT_DB *db) 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') { @@ -3337,16 +3093,3 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_G 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; - } |