diff --git a/apps/apps.c b/apps/apps.c index 0cdc1ad69bee9b57ff398db4c3a38fcadc4135c9..ac9e3daa5e9e3245a24df81165457e535b820be1 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -1519,19 +1519,44 @@ BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) return(ret); } -int save_serial(char *serialfile, BIGNUM *serial, ASN1_INTEGER **retai) +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai) { - BIO *out; + 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,serialfile) <= 0) + if (BIO_write_filename(out,buf[0]) <= 0) { perror(serialfile); goto err; @@ -1556,6 +1581,76 @@ err: 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; diff --git a/apps/apps.h b/apps/apps.h index 974eb4f1c9ede13648b4b365dd830987aa6a41cd..8a9c4ab0a0541dbf57c61baf0729ff27d782f8fe 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -311,7 +311,8 @@ typedef struct ca_db_st } CA_DB; BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai); -int save_serial(char *serialfile, BIGNUM *serial, ASN1_INTEGER **retai); +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai); +int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix); CA_DB *load_index(char *dbfile, DB_ATTR *dbattr); int index_index(CA_DB *db); int save_index(char *dbfile, char *suffix, CA_DB *db); diff --git a/apps/ca.c b/apps/ca.c index 34b1507aeedda8e11b95ceddc2b2e1462762e61a..618d88b2d0e76bba4497cb0b76e2783bce6e700e 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -1243,21 +1243,7 @@ bad: 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; } @@ -1317,34 +1303,7 @@ bad: 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; diff --git a/apps/x509.c b/apps/x509.c index efb7b0d8b285093ace48503b0cec0f7437841d36..ed9e40574aabbca9ff3d5d07b75fc09ef13566f0 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -1064,7 +1064,7 @@ static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create if (!BN_add_word(serial,1)) { BIO_printf(bio_err,"add_word failure\n"); goto end; } - if (!save_serial(buf, serial, &bs)) goto end; + if (!save_serial(buf, NULL, serial, &bs)) goto end; end: if (buf) OPENSSL_free(buf);