Dear OpenSSL-Devlopers !
As I have wrote in a mail to openssl-users I would like to add a new
functionality in openssl. As Massimiliano Pala has suggested I send my patch
to this list.
I have attached a patch to enhance the "ca"-application to check "index.txt"
for expired certs and (if found) mark them. The idea is to run
"openssl ca -updatedb" (new switch) periodically by a cron-job to keep
index.txt up-to-date.
The patch is a diff -cb against openssl-SNAP-19990505/apps/ca.c.
Some annotations:
I have basically adapted the revoke-parts in ca.c for my needs. I have added a
new subroutine called "do_updatedb" which does the checking of index.txt. The
routine returns the number of new marked entry�s or -1 for an Malloc-error.
To avoid asking for the pass-phrase for the ca-cert I had to wrap this part
with an if-clause.
The basic problem in checking index.txt was to avoid year 2000 problems:
I use two flags "db_y2k" and "a_y2k". db_y2k is set to 1 if the year part
of the date-entry in index.txt is less or equal 49, otherwise db_y2k is set to
0. Same for a_y2k and the actual date. This implies that 00,01,...,49 are
20xx-years. I hope I have got this right...
Then db_y2k and a_y2k will be compared:
db_y2k > a_y2k => cert is valid
db_y2k < a_y2k => cert is not valid
db_y2k = a_y2k => The dates lay in the same interval. Now it is save to
use the standard "strcmp()"-function to compare the
the date-entry in index.txt and the actual date.
That�s all.
I am not an advanced C-programmer so feel free to change everything
or reject it completely ;-)
Ciao,
Lars <[EMAIL PROTECTED]>
*** openssl-SNAP-19990505/apps/ca.c.orig Sat May 8 16:49:30 1999
--- openssl-SNAP-19990505/apps/ca.c Sat May 8 16:57:56 1999
***************
*** 1,4 ****
! /* apps/ca.c */
/* Copyright (C) 1995-1998 Eric Young ([EMAIL PROTECTED])
* All rights reserved.
*
--- 1,4 ----
! #/* apps/ca.c */
/* Copyright (C) 1995-1998 Eric Young ([EMAIL PROTECTED])
* All rights reserved.
*
***************
*** 147,152 ****
--- 147,153 ----
" -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",
+ " -updatedb - Checks index.txt for expired certificates and mark them\n",
NULL
};
***************
*** 185,190 ****
--- 186,192 ----
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 do_updatedb(TXT_DB *db);
static int check_time_format(char *str);
static LHASH *conf;
static char *key=NULL;
***************
*** 203,208 ****
--- 205,211 ----
int verbose=0;
int gencrl=0;
int dorevoke=0;
+ int doupdatedb=0;
long crldays=0;
long crlhours=0;
long errorline= -1;
***************
*** 369,374 ****
--- 372,381 ----
infile= *(++argv);
dorevoke=1;
}
+ else if (strcmp(*argv,"-updatedb") == 0)
+ {
+ doupdatedb=1;
+ }
else
{
bad:
***************
*** 462,467 ****
--- 469,479 ----
}
/*****************************************************************/
+ /* do not ask for ca key/cert if doupdatedb != 0 because
+ * ca -updatedb intend to run automatically
+ */
+ if ( doupdatedb == 0 )
+ {
/* we definitly need an public key, so lets get it */
if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
***************
*** 522,527 ****
--- 534,540 ----
f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
msie_hack=1;
+ } /* if ( doupdatedb == 0 ) */
/*****************************************************************/
/* lookup where to write new certificates */
***************
*** 1133,1138 ****
--- 1146,1202 ----
}
}
/*****************************************************************/
+ if (doupdatedb)
+ {
+ i = do_updatedb (db);
+ if ( i == -1)
+ {
+ BIO_printf(bio_err,"Malloc failure\n");
+ goto err;
+ }
+ else if ( i == 0 )
+ BIO_printf(bio_err,"No entry's found to mark expired - will not touch
+index.txt\n");
+ else
+ {
+ out = BIO_new (BIO_s_file());
+ if (out == NULL)
+ {
+ ERR_print_errors (bio_err);
+ goto err;
+ }
+
+ strncpy (buf[0],dbfile,BSIZE-4);
+ strcat (buf[0],".new");
+ 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;
+ strncpy (buf[1],dbfile,BSIZE-4);
+ strcat (buf[1],".old");
+ 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,"%d entry's marked as expired\n", i);
+ }
+ }
+
+ /*****************************************************************/
ret=0;
err:
BIO_free(hex);
***************
*** 2159,2161 ****
--- 2223,2280 ----
return(ok);
}
+ static int do_updatedb (TXT_DB *db)
+ {
+ ASN1_UTCTIME *a_tm = NULL;
+ int i, cnt = 0;
+ int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
+ char **rrow, *a_tm_s;
+
+
+ /* get actual time and make a string */
+ a_tm = X509_gmtime_adj( a_tm, 0 );
+ a_tm_s = (char *) Malloc( a_tm->length+1 );
+ if ( a_tm_s == NULL )
+ {
+ cnt = -1;
+ goto err;
+ }
+ memcpy( a_tm_s, a_tm->data, a_tm->length );
+ a_tm_s[a_tm->length] = '\0';
+
+ if ( strncmp( a_tm_s, "49", 2 ) <= 0 )
+ a_y2k = 1;
+ else
+ a_y2k = 0;
+
+ for (i = 0; i < sk_num( db->data ); i++)
+ {
+ rrow = (char **) sk_value( db->data, i );
+ if ( rrow[DB_type][0] == 'V' ) /* ignore entry's that are not valid */
+ {
+ if ( strncmp( rrow[DB_exp_date], "49", 2 ) <= 0 )
+ db_y2k = 1;
+ else
+ db_y2k = 0;
+ if ( db_y2k > a_y2k ) /* db > a => cert is valid */
+ {
+ if ( db_y2k < a_y2k ) /* db < a => cert is expired */
+ {
+ rrow[DB_type][0] = 'E';
+ rrow[DB_type][1] = '\0';
+ cnt++;
+ }
+ else if ( strcmp( rrow[DB_exp_date], a_tm_s ) <= 0 ) /* db = a */
+ {
+ rrow[DB_type][0] = 'E';
+ rrow[DB_type][1] = '\0';
+ cnt++;
+ }
+ }
+ }
+ }
+ err:
+ ASN1_UTCTIME_free( a_tm );
+ Free( a_tm_s );
+ return (cnt);
+ }