I have been thinking about the keys used by mixmaster
and attach a patch for your consideration.

1. Old secret keys are to be deleted automatically after expiry.
   (I was surprised to see that was not already happening.  An adversary
    capturing your old keyfile seems able to decrypt old messages.)
   This patch does not deal with secure deletion of the old file
   which I hope to address later.

2. A new command-line option enables you to set a key lifetime.
   mixmaster -G --lifetime=28
   If you do not specify the lifetime (in days) the default is used.

   If a remailer has a long-term key (such as 1 year) as well
   as generating a 7-day key each day then someone who wanted to could
   choose a key that was close to expiry and less at risk of disclosure.
   (Automation of that would require changes in the client.)

   (Plus a greater volume of 1024-bit keys is more work for anyone
   factoring the remailer keys.)
diff -C3 -r mixmaster-3.0/Src/crypto.c mixmaster-3.0-mymods/Src/crypto.c
*** mixmaster-3.0/Src/crypto.c  2006-06-24 14:40:39.000000000 +0100
--- mixmaster-3.0-mymods/Src/crypto.c   2013-10-10 21:03:14.268793805 +0100
***************
*** 285,291 ****
    return (ret);
  }
  
! int v2createkey(void)
  {
    RSA *k;
    BUFFER *b, *ek, *iv;
--- 285,291 ----
    return (ret);
  }
  
! int v2createkey(long int lifeindays)
  {
    RSA *k;
    BUFFER *b, *ek, *iv;
***************
*** 311,317 ****
        strftime(line, LINELEN, "%Y-%m-%d", gt);
        fprintf(f, "%s\nCreated: %s\n", begin_key, line);
        if (KEYLIFETIME) {
!       now += KEYLIFETIME;
        gt = gmtime(&now);
        strftime(line, LINELEN, "%Y-%m-%d", gt);
        fprintf(f, "Expires: %s\n", line);
--- 311,320 ----
        strftime(line, LINELEN, "%Y-%m-%d", gt);
        fprintf(f, "%s\nCreated: %s\n", begin_key, line);
        if (KEYLIFETIME) {
!         if ((lifeindays>0) && (lifeindays*86400<KEYLIFETIME))
!           now += lifeindays*86400;
!         else
!           now += KEYLIFETIME;
        gt = gmtime(&now);
        strftime(line, LINELEN, "%Y-%m-%d", gt);
        fprintf(f, "Expires: %s\n", line);
diff -C3 -r mixmaster-3.0/Src/keymgt.c mixmaster-3.0-mymods/Src/keymgt.c
*** mixmaster-3.0/Src/keymgt.c  2006-06-24 14:40:39.000000000 +0100
--- mixmaster-3.0-mymods/Src/keymgt.c   2013-10-10 23:06:21.128167914 +0100
***************
*** 194,200 ****
    buf_appends(out, SHORTNAME);
    buf_appends(out, "\n\n");
  
!   keymgt(0);
  
    conf_premail(out);
    buf_nl(out);
--- 194,200 ----
    buf_appends(out, SHORTNAME);
    buf_appends(out, "\n\n");
  
!   keymgt(0,0);
  
    conf_premail(out);
    buf_nl(out);
***************
*** 259,265 ****
        return err;
  }
  
! int v2keymgt(int force)
  /*
   * Mixmaster v2 Key Management
   *
--- 259,265 ----
        return err;
  }
  
! int v2keymgt(int force,long int lifeindays)
  /*
   * Mixmaster v2 Key Management
   *
***************
*** 287,292 ****
--- 287,293 ----
    int err = 0;
    int found, foundnonexpiring;
    time_t created, expires, created_found, expires_found;
+   int need2delete=0;
    char *res;
  
    b = buf_new();
***************
*** 325,333 ****
          } while ( res != NULL && strchr(line, ':') != NULL );
          if (res == NULL)
            break;
!         if (((created != 0) && (created > time(NULL))) ||
!             ((expires != 0) && (expires < time(NULL)))) {
!           /* Key already is expired or has creation date in the future */
            continue;
          }
          id_decode(line, k1);
--- 326,338 ----
          } while ( res != NULL && strchr(line, ':') != NULL );
          if (res == NULL)
            break;
!         if ((created != 0) && (created > time(NULL))) {
!           /* Key has creation date in the future */
!           continue;
!           }
!         if  ((expires != 0) && (expires < time(NULL))) {
!           /* Key already is expired.*/
!             need2delete=1;
            continue;
          }
          id_decode(line, k1);
***************
*** 368,374 ****
      }
  
      if (!foundnonexpiring || (force == 2)) {
!       v2createkey();
        foundnonexpiring = 1;
        force = 1;
      } else
--- 373,379 ----
      }
  
      if (!foundnonexpiring || (force == 2)) {
!       v2createkey(lifeindays);
        foundnonexpiring = 1;
        force = 1;
      } else
***************
*** 412,421 ****
    buf_free(pk);
    buf_free(pk_found);
  
    return (err);
  }
  
! int keymgt(int force)
  {
    /* force = 0: write key file if there is none
       force = 1: update key file
--- 417,429 ----
    buf_free(pk);
    buf_free(pk_found);
  
+   if (need2delete)
+       fprintf(stderr, "key deletion returns %d\n", deleteoldkeys());
+ 
    return (err);
  }
  
! int keymgt(int force,long int lifeindays)
  {
    /* force = 0: write key file if there is none
       force = 1: update key file
***************
*** 423,429 ****
    int err = 0;
  
    if (REMAIL || force == 2) {
!     if (MIX && (err = v2keymgt(force)) == -1)
        err = -1;
  #ifdef USE_PGP
      if (PGP && (err = pgp_keymgt(force)) == -1)
--- 431,437 ----
    int err = 0;
  
    if (REMAIL || force == 2) {
!     if (MIX && (err = v2keymgt(force,lifeindays)) == -1)
        err = -1;
  #ifdef USE_PGP
      if (PGP && (err = pgp_keymgt(force)) == -1)
***************
*** 432,434 ****
--- 440,494 ----
    }
    return (err);
  }
+ 
+ int deleteoldkeys(void)
+ {
+   FILE *keyring, *newsecring, *newpubring;
+   int show=1;
+   int expires;
+   char line[LINELEN];
+   char *res;
+ 
+     keyring = mix_openfile(SECRING, "r");
+     if (!keyring)
+         return -1;
+     newsecring = mix_openfile("secring.mix.new", "w");
+     if (!newsecring)
+         return -1;
+     newpubring = mix_openfile("key.txt.new", "w");
+     if (!newpubring)
+         return -1;
+ 
+     for (;;) {
+         if (fgets(line, sizeof(line), keyring) == NULL)
+             break;
+         fprintf(newsecring, "%s", line);
+         if (strleft(line, begin_key)) {
+             expires = 0;
+             do {
+                 res = fgets(line, sizeof(line), keyring);
+                 if (show)
+                     fprintf(newsecring, "%s", line);
+                 if (strileft(line, "expires:")) {
+                     expires = parse_yearmonthday(strchr(line, ':')+1);
+                     if (expires == -1)
+                         expires = 0;
+                   if  (expires < time(NULL))
+                         show=0;
+                 }
+             /* Fetch lines until end key */
+             } while ( res != NULL && !strileft(line,end_key) );
+             if (res == NULL)
+                 break;
+             if (!show)
+                 fprintf(newsecring, "%s", line);
+             show=1;
+         }
+     }
+ 
+     if (fclose(keyring)) return -11;
+     if (fclose(newsecring)) return -12;
+     if (fclose(newpubring)) return -13;
+     rename("secring.mix.new", SECRING);
+ return 0;
+ }
diff -C3 -r mixmaster-3.0/Src/main.c mixmaster-3.0-mymods/Src/main.c
*** mixmaster-3.0/Src/main.c    2006-06-24 16:52:20.000000000 +0100
--- mixmaster-3.0-mymods/Src/main.c     2013-10-10 21:05:05.064073899 +0100
***************
*** 45,50 ****
--- 45,51 ----
    int daemon = 0, type_list = 0, nodetach = 0;
    int update_stats = 0, update_pingerlist = 0;
    int never_ask_for_passphrase = 0;
+   long int lifeindays=0;
  
  #ifdef USE_SOCK
    int pop3 = 0;
***************
*** 153,158 ****
--- 154,163 ----
            deflt = 0;
            fprintf(stderr, "%s: No current stats source --%s\n", argv[0], p);
          }
+       } else if (strleft(p, "lifetime") && p[strlen("lifetime")] == '=') {
+             lifeindays=strtol(p + strlen("lifetime") + 1,NULL,10);
+             if (lifeindays<0)
+                 lifeindays=0;
        } else if (strleft(p, "update-stats") && p[strlen("update-stats")] == 
'=') {
          buf_clear(statssrc);
          buf_appendf(statssrc, "%s", (p + strlen("update-stats") + 1));
***************
*** 682,688 ****
  
    if (keygen) {
      check_get_pass(0, never_ask_for_passphrase);
!     keymgt(keygen);
    }
    if (sendpool)
      mix_send();
--- 687,693 ----
  
    if (keygen) {
      check_get_pass(0, never_ask_for_passphrase);
!     keymgt(keygen,lifeindays);
    }
    if (sendpool)
      mix_send();
diff -C3 -r mixmaster-3.0/Src/mix3.h mixmaster-3.0-mymods/Src/mix3.h
*** mixmaster-3.0/Src/mix3.h    2006-06-24 14:40:39.000000000 +0100
--- mixmaster-3.0-mymods/Src/mix3.h     2013-10-10 20:22:55.574669270 +0100
***************
*** 210,216 ****
  int digest_rmd160(BUFFER *b, BUFFER *md);
  
  #define KEY_ID_LEN 32
! int keymgt(int force);
  int key(BUFFER *b);
  int adminkey(BUFFER *b);
  
--- 210,216 ----
  int digest_rmd160(BUFFER *b, BUFFER *md);
  
  #define KEY_ID_LEN 32
! int keymgt(int force,long int lifeindays);
  int key(BUFFER *b);
  int adminkey(BUFFER *b);
  
***************
*** 234,240 ****
  int pk_encrypt(BUFFER *plaintext, BUFFER *privkey);
  int check_seckey(BUFFER *buf, const byte id[]);
  int check_pubkey(BUFFER *buf, const byte id[]);
! int v2createkey(void);
  int getv2seckey(byte keyid[], BUFFER *key);
  int seckeytopub(BUFFER *pub, BUFFER *sec, byte keyid[]);
  
--- 234,240 ----
  int pk_encrypt(BUFFER *plaintext, BUFFER *privkey);
  int check_seckey(BUFFER *buf, const byte id[]);
  int check_pubkey(BUFFER *buf, const byte id[]);
! int v2createkey(long int lifeindays);
  int getv2seckey(byte keyid[], BUFFER *key);
  int seckeytopub(BUFFER *pub, BUFFER *sec, byte keyid[]);
  
diff -C3 -r mixmaster-3.0/Src/mix.c mixmaster-3.0-mymods/Src/mix.c
*** mixmaster-3.0/Src/mix.c     2007-11-19 13:42:41.000000000 +0000
--- mixmaster-3.0-mymods/Src/mix.c      2013-10-10 20:07:28.510328589 +0100
***************
*** 1022,1028 ****
    pgpmaxexp();
    pool_packetexp();
    stats(NULL);
!   keymgt(0);
    return (0);
  }
  
--- 1022,1028 ----
    pgpmaxexp();
    pool_packetexp();
    stats(NULL);
!   keymgt(0,0);
    return (0);
  }
  
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134071&iu=/4140/ostg.clktrk
_______________________________________________
Mixmaster-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixmaster-devel

Reply via email to