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);
+ }

Reply via email to