Ok...
I had to work some time on the code to get it working but it seems
to be all ok, now.The new patch will add the -status and the -updatedb
switches to the ca application.
Please try to include the patch in the 0.9.3 version.
See you on the bit Stream,
Massimiliano Pala ([EMAIL PROTECTED])
P.S.: I forgot the patch ... sorry! Here it is!
--- ca.c Mon May 10 14:51:06 1999
+++ ca-patched.c Mon May 10 14:50:57 1999
@@ -1,4 +1,4 @@
-/* apps/ca.c */
+#/* apps/ca.c */
/* Copyright (C) 1995-1998 Eric Young ([EMAIL PROTECTED])
* All rights reserved.
*
@@ -61,6 +61,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "apps.h"
@@ -147,6 +148,8 @@
" -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",
+" -status serial - Shows certificate' status given the serial number\n",
+" -updatedb - Checks index.txt for expired certificates and mark them\n",
NULL
};
@@ -185,6 +188,8 @@
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 get_certificate_status(char *ser_status, 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,6 +208,7 @@
int verbose=0;
int gencrl=0;
int dorevoke=0;
+ int doupdatedb=0;
long crldays=0;
long crlhours=0;
long errorline= -1;
@@ -214,6 +220,7 @@
char *infile=NULL;
char *spkac_file=NULL;
char *ss_cert_file=NULL;
+ char *ser_status=NULL;
EVP_PKEY *pkey=NULL;
int output_der = 0;
char *outfile=NULL;
@@ -369,6 +376,15 @@
infile= *(++argv);
dorevoke=1;
}
+ else if (strcmp(*argv,"-status") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ser_status= *(++argv);
+ }
+ else if (strcmp(*argv,"-updatedb") == 0)
+ {
+ doupdatedb=1;
+ }
else
{
bad:
@@ -464,6 +480,150 @@
}
/*****************************************************************/
+ /* we need to load the database file */
+ if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+ {
+ 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);
+ if (db == NULL) goto err;
+
+ /* Lets check some fields */
+ for (i=0; i<sk_num(db->data); i++)
+ {
+ pp=(char **)sk_value(db->data,i);
+ if ((pp[DB_type][0] != DB_TYPE_REV) &&
+ (pp[DB_rev_date][0] != '\0'))
+ {
+ BIO_printf(bio_err,"entry %d: not revoked yet, but has a
+revocation date\n",i+1);
+ goto err;
+ }
+ if ((pp[DB_type][0] == DB_TYPE_REV) &&
+ !check_time_format(pp[DB_rev_date]))
+ {
+ BIO_printf(bio_err,"entry %d: invalid revocation date\n",
+ i+1);
+ goto err;
+ }
+ if (!check_time_format(pp[DB_exp_date]))
+ {
+ BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
+ goto err;
+ }
+ p=pp[DB_serial];
+ j=strlen(p);
+ if ((j&1) || (j < 2))
+ {
+ BIO_printf(bio_err,"entry %d: bad serial number length
+(%d)\n",i+1,j);
+ goto err;
+ }
+ while (*p)
+ {
+ if (!( ((*p >= '0') && (*p <= '9')) ||
+ ((*p >= 'A') && (*p <= 'F')) ||
+ ((*p >= 'a') && (*p <= 'f'))) )
+ {
+ BIO_printf(bio_err,"entry %d: bad serial number
+characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
+ goto err;
+ }
+ p++;
+ }
+ }
+ if (verbose)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
+ TXT_DB_write(out,db);
+ BIO_printf(bio_err,"%d entries loaded from the database\n",
+ db->data->num);
+ BIO_printf(bio_err,"generating indexs\n");
+ }
+
+ if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
+ index_serial_cmp))
+ {
+ BIO_printf(bio_err,"error creating serial number
+index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
+ goto err;
+ }
+
+ if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
+ index_name_cmp))
+ {
+ BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
+ db->error,db->arg1,db->arg2);
+ goto err;
+ }
+
+ /*****************************************************************/
+ /* if the certificate status is required we give it */
+ if (ser_status)
+ {
+ if( get_certificate_status(ser_status,db) != 1)
+ BIO_printf(bio_err,"Error verifying serial %s!\n",
+ ser_status);
+ goto err;
+ }
+
+ /*****************************************************************/
+ /* Update the db file for expired certificates */
+ 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);
+ }
+ goto err;
+ }
+
+ /*****************************************************************/
/* we definitly need an public key, so lets get it */
if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
@@ -558,86 +718,6 @@
}
}
- /*****************************************************************/
- /* we need to load the database file */
- if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
- {
- 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);
- if (db == NULL) goto err;
-
- /* Lets check some fields */
- for (i=0; i<sk_num(db->data); i++)
- {
- pp=(char **)sk_value(db->data,i);
- if ((pp[DB_type][0] != DB_TYPE_REV) &&
- (pp[DB_rev_date][0] != '\0'))
- {
- BIO_printf(bio_err,"entry %d: not revoked yet, but has a
revocation date\n",i+1);
- goto err;
- }
- if ((pp[DB_type][0] == DB_TYPE_REV) &&
- !check_time_format(pp[DB_rev_date]))
- {
- BIO_printf(bio_err,"entry %d: invalid revocation date\n",
- i+1);
- goto err;
- }
- if (!check_time_format(pp[DB_exp_date]))
- {
- BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
- goto err;
- }
- p=pp[DB_serial];
- j=strlen(p);
- if ((j&1) || (j < 2))
- {
- BIO_printf(bio_err,"entry %d: bad serial number length
(%d)\n",i+1,j);
- goto err;
- }
- while (*p)
- {
- if (!( ((*p >= '0') && (*p <= '9')) ||
- ((*p >= 'A') && (*p <= 'F')) ||
- ((*p >= 'a') && (*p <= 'f'))) )
- {
- BIO_printf(bio_err,"entry %d: bad serial number
characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
- goto err;
- }
- p++;
- }
- }
- if (verbose)
- {
- BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
- TXT_DB_write(out,db);
- BIO_printf(bio_err,"%d entries loaded from the database\n",
- db->data->num);
- BIO_printf(bio_err,"generating indexs\n");
- }
-
- if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
- index_serial_cmp))
- {
- BIO_printf(bio_err,"error creating serial number
index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
- goto err;
- }
-
- if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
- index_name_cmp))
- {
- BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
- db->error,db->arg1,db->arg2);
- goto err;
- }
/*****************************************************************/
if (req || gencrl)
@@ -1134,6 +1214,7 @@
BIO_printf(bio_err,"Data Base Updated\n");
}
}
+
/*****************************************************************/
ret=0;
err:
@@ -2161,3 +2242,135 @@
return(ok);
}
+static int get_certificate_status ( char *serial, TXT_DB *db )
+{
+ char *row[DB_NUMBER],**rrow;
+ int ok=-1,i;
+
+ /* Free Resources */
+ for (i=0; i<DB_NUMBER; i++)
+ row[i]=NULL;
+ /* Malloc needed char spaces */
+ row[DB_serial]=( char * ) Malloc ( strlen(serial) +1);
+ if (row[DB_serial] == NULL)
+ {
+ BIO_printf(bio_err,"Malloc failure\n");
+ goto err;
+ }
+
+ /* Copy String from serial to row[DB_serial] */
+ memcpy( row[DB_serial], serial, strlen(serial));
+ row[DB_serial][strlen(serial)]='\0';
+
+ /* Make it Upper Case */
+ for( i=0; row[DB_serial][i] != '\0'; i++ )
+ row[DB_serial][i] = (char) toupper( row[DB_serial][i] );
+
+ ok=1;
+
+ /* Search for the certificate */
+ rrow=TXT_DB_get_by_index(db,DB_serial,row);
+ if (rrow == NULL)
+ {
+ BIO_printf(bio_err,"Serial %s not present in db.\n",
+ row[DB_serial]);
+ ok=-1;
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='V')
+ {
+ BIO_printf(bio_err,"STATUS: Valid (%c)\n",
+ rrow[DB_type][0]);
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='R')
+ {
+ BIO_printf(bio_err,"STATUS: Revoked (%c)\n",
+ rrow[DB_type][0]);
+ goto err;
+ }
+ else if (rrow[DB_type][0]=='E')
+ {
+ BIO_printf(bio_err,"STATUS: Expired (%c)\n",
+ rrow[DB_type][0]);
+ goto err;
+ }
+ else
+ {
+ BIO_printf(bio_err,"ERROR: Unknown status (%c).\n",
+ rrow[DB_type][0]);
+ ok=-1;
+ }
+err:
+ for (i=0; i<DB_NUMBER; i++)
+ {
+ if ((row[i] != NULL) && (row[i] != serial) )
+ Free(row[i]);
+ }
+ 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;
+
+ /* mdified by madwolf */
+ a_tm = ASN1_UTCTIME_new();
+
+ /* 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 )
+ {
+ /* all on the same y2k side */
+ if ( strcmp( rrow[DB_exp_date], a_tm_s ) <= 0 )
+ {
+ rrow[DB_type][0] = 'E';
+ rrow[DB_type][1] = '\0';
+ cnt++;
+ }
+ }
+ else if ( db_y2k < a_y2k )
+ {
+ rrow[DB_type][0] = 'E';
+ rrow[DB_type][1] = '\0';
+ cnt++;
+ }
+
+ }
+ }
+
+err:
+
+ ASN1_UTCTIME_free( a_tm );
+ Free( a_tm_s );
+ return (cnt);
+}