keyutil.c: Remove stray tabs and trailing space from the list format.
[u/mdw/catacomb] / keyutil.c
index 269a85d..74f6409 100644 (file)
--- a/keyutil.c
+++ b/keyutil.c
@@ -7,7 +7,7 @@
  * (c) 1999 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Catacomb.
  *
  * it under the terms of the GNU Library General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
- * 
+ *
  * Catacomb is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Library General Public
  * License along with Catacomb; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -160,17 +160,17 @@ static void setattr(key_file *f, key *k, char *v[])
 
 const struct seedalg { const char *p; grand *(*gen)(const void *, size_t); }
 seedtab[] = {
-  { "dsarand",         dsarand_create },
-  { "rmd128-mgf",  rmd128_mgfrand },
-  { "rmd160-mgf",  rmd160_mgfrand },
-  { "rmd256-mgf",  rmd256_mgfrand },
-  { "rmd320-mgf",  rmd320_mgfrand },
-  { "sha-mgf",  sha_mgfrand },
-  { "sha224-mgf",  sha224_mgfrand },
-  { "sha256-mgf",  sha256_mgfrand },
-  { "sha384-mgf",  sha384_mgfrand },
-  { "sha512-mgf",  sha512_mgfrand },
-  { "tiger-mgf",  tiger_mgfrand },
+  { "dsarand", dsarand_create },
+  { "rmd128-mgf", rmd128_mgfrand },
+  { "rmd160-mgf", rmd160_mgfrand },
+  { "rmd256-mgf", rmd256_mgfrand },
+  { "rmd320-mgf", rmd320_mgfrand },
+  { "sha-mgf", sha_mgfrand },
+  { "sha224-mgf", sha224_mgfrand },
+  { "sha256-mgf", sha256_mgfrand },
+  { "sha384-mgf", sha384_mgfrand },
+  { "sha512-mgf", sha512_mgfrand },
+  { "tiger-mgf", tiger_mgfrand },
   { 0, 0 }
 };
 
@@ -197,6 +197,7 @@ typedef struct keyopts {
 #define f_limlee 8u                    /* Generate Lim-Lee primes */
 #define f_subgroup 16u                 /* Generate a subgroup */
 #define f_retag 32u                    /* Remove any existing tag */
+#define f_kcdsa 64u                    /* Generate KCDSA primes */
 
 /* --- @dolock@ --- *
  *
@@ -234,8 +235,12 @@ static int copyparam(keyopts *k, const char **pp)
 {
   key_filter kf;
   key_attriter i;
+  key_data *kd;
   const char *n, *v;
 
+  kf.f = KCAT_SHARE;
+  kf.m = KF_CATMASK;
+
   /* --- Quick check if no parameters supplied --- */
 
   if (!k->p)
@@ -247,16 +252,17 @@ static int copyparam(keyopts *k, const char **pp)
     key_data *kd = key_structfind(k->p->k, *pp);
     if (!kd)
       die(EXIT_FAILURE, "bad parameter key: parameter `%s' not found", *pp);
-    if ((kd->e & KF_CATMASK) != KCAT_SHARE)
+    if (!KEY_MATCH(kd, &kf))
       die(EXIT_FAILURE, "bad parameter key: subkey `%s' is not shared", *pp);
     pp++;
   }
 
   /* --- Copy over the parameters --- */
 
-  kf.f = KCAT_SHARE;
-  kf.m = KF_CATMASK;
-  key_setkeydata(k->kf, k->k, k->p->k);
+  kd = key_copydata(k->p->k, &kf);
+  assert(kd);
+  key_setkeydata(k->kf, k->k, kd);
+  key_drop(kd);
 
   /* --- Copy over attributes --- */
 
@@ -564,7 +570,7 @@ static void alg_dhparam(keyopts *k)
       qd_parse qd;
       group *g;
       const char *e;
-      
+
       if (strcmp(k->curve, "list") == 0) {
        unsigned i, w;
        LIST("Built-in prime fields", stdout, ptab[i].name, ptab[i].name);
@@ -578,11 +584,11 @@ static void alg_dhparam(keyopts *k)
       if ((g = group_prime(&dp)) == 0)
        die(EXIT_FAILURE, "invalid prime field");
       if (!(k->f & f_quiet) && (e = G_CHECK(g, &rand_global)) != 0)
-       moan("WARNING!  group check failed: %s", e);
+       moan("WARNING!  group check failed: %s", e);
       G_DESTROYGROUP(g);
       goto done;
     }
-    
+
     if (!k->bits)
       k->bits = 1024;
 
@@ -609,6 +615,24 @@ static void alg_dhparam(keyopts *k)
        key_putattr(k->kf, k->k, "factors", d.buf);
        dstr_destroy(&d);
       }
+    } else if (k->f & f_kcdsa) {
+      if (!k->qbits)
+       k->qbits = 256;
+      rc = dh_kcdsagen(&dp, k->qbits, k->bits, 0,
+                      0, k->r, (k->f & f_quiet) ? 0 : pgen_ev, 0);
+      if (!rc) {
+       dstr d = DSTR_INIT;
+       mp *v = MP_NEW;
+
+       mp_writedstr(dp.q, &d, 10);
+       mp_div(&v, 0, dp.p, dp.q);
+       v = mp_lsr(v, v, 1);
+       dstr_puts(&d, ", ");
+       mp_writedstr(v, &d, 10);
+       mp_drop(v);
+       key_putattr(k->kf, k->k, "factors", d.buf);
+       dstr_destroy(&d);
+      }
     } else
       rc = dh_gen(&dp, k->qbits, k->bits, 0, k->r,
                  (k->f & f_quiet) ? 0 : pgen_ev, 0);
@@ -922,6 +946,7 @@ static int cmd_add(int argc, char *argv[])
 {
   key_file f;
   time_t exp = KEXP_EXPIRE;
+  uint32 kid = rand_global.ops->word(&rand_global);
   const char *tag = 0, *ptag = 0;
   const char *c = 0;
   keyalg *alg = algtab;
@@ -943,6 +968,7 @@ static int cmd_add(int argc, char *argv[])
       { "comment",     OPTF_ARGREQ,    0,      'c' },
       { "tag",         OPTF_ARGREQ,    0,      't' },
       { "rand-id",     OPTF_ARGREQ,    0,      'R' },
+      { "key-id",      OPTF_ARGREQ,    0,      'I' },
       { "curve",       OPTF_ARGREQ,    0,      'C' },
       { "seedalg",     OPTF_ARGREQ,    0,      'A' },
       { "seed",                OPTF_ARGREQ,    0,      's' },
@@ -951,9 +977,10 @@ static int cmd_add(int argc, char *argv[])
       { "quiet",       0,              0,      'q' },
       { "lim-lee",     0,              0,      'L' },
       { "subgroup",    0,              0,      'S' },
+      { "kcdsa",       0,              0,      'K' },
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:C:A:s:n:lqrLS",
+    int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:I:C:A:s:n:lqrLKS",
                   opt, 0, 0, 0);
     if (i < 0)
       break;
@@ -1072,7 +1099,7 @@ static int cmd_add(int argc, char *argv[])
       case 's': {
        base64_ctx b;
        dstr d = DSTR_INIT;
-       if (seed) die(EXIT_FAILURE, "seed already set"); 
+       if (seed) die(EXIT_FAILURE, "seed already set");
        base64_init(&b);
        base64_decode(&b, optarg, strlen(optarg), &d);
        base64_decode(&b, 0, 0, &d);
@@ -1080,7 +1107,7 @@ static int cmd_add(int argc, char *argv[])
        seed = optarg;
        dstr_destroy(&d);
       } break;
-       
+
       case 'n': {
        base64_ctx b;
        dstr d = DSTR_INIT;
@@ -1088,7 +1115,7 @@ static int cmd_add(int argc, char *argv[])
        unsigned n = strtoul(optarg, &p, 0);
        if (n == 0 || *p != 0 || n % 8 != 0)
          die(EXIT_FAILURE, "bad seed length `%s'", optarg);
-       if (seed) die(EXIT_FAILURE, "seed already set"); 
+       if (seed) die(EXIT_FAILURE, "seed already set");
        n /= 8;
        p = xmalloc(n);
        rand_get(RAND_GLOBAL, p, n);
@@ -1098,7 +1125,20 @@ static int cmd_add(int argc, char *argv[])
        seed = d.buf;
        k.r = sa->gen(p, n);
       } break;
-       
+
+      /* --- Key id --- */
+
+      case 'I': {
+       char *p;
+       unsigned long id;
+
+       errno = 0;
+       id = strtoul(optarg, &p, 16);
+       if (errno || *p || id > MASK32)
+         die(EXIT_FAILURE, "bad key-id `%s'", optarg);
+       kid = id;
+      } break;
+
       /* --- Other flags --- */
 
       case 'R':
@@ -1113,6 +1153,9 @@ static int cmd_add(int argc, char *argv[])
       case 'L':
        k.f |= f_limlee;
        break;
+      case 'K':
+       k.f |= f_kcdsa;
+       break;
       case 'S':
        k.f |= f_subgroup;
        break;
@@ -1152,9 +1195,8 @@ static int cmd_add(int argc, char *argv[])
   keyrand(&f, rtag);
 
   for (;;) {
-    uint32 id = rand_global.ops->word(&rand_global);
     int err;
-    if ((err = key_new(&f, id, argv[optind], exp, &k.k)) == 0)
+    if ((err = key_new(&f, kid, argv[optind], exp, &k.k)) == 0)
       break;
     else if (err != KERR_DUPID)
       die(EXIT_FAILURE, "error adding new key: %s", key_strerror(err));
@@ -1326,7 +1368,7 @@ static void showkeydata(key_data *k, int ind, listopts *o, dstr *d)
        fputs(", 0x", stdout); mp_writefile(k->u.e.y, stdout, 16);
        putchar('\n');
       }
-      break;      
+      break;
 
     /* --- Structured keys --- *
      *
@@ -1350,7 +1392,7 @@ static void showkeydata(key_data *k, int ind, listopts *o, dstr *d)
       }
       INDENT(ind);
       fputs("}\n", stdout);
-    } break;      
+    } break;
   }
 
 #undef INDENT
@@ -1400,10 +1442,10 @@ static void showkey(key *k, listopts *o)
 
   if (!o->v) {
     if (!(o->f & f_newline)) {
-      printf("%8s  %-20s  %-20s  %-10s  %-10s\n",
+      printf("%8s  %-20s  %-20s  %-10s  %s\n",
             "Id", "Tag", "Type", "Expire", "Delete");
     }
-    printf("%08lx  %-20s  %-20s  %-10s  %-10s\n",
+    printf("%08lx  %-20s  %-20s  %-10s  %s\n",
           (unsigned long)k->id, k->tag ? k->tag : "<none>",
           k->type, ebuf, dbuf);
     o->f |= f_newline;
@@ -1448,7 +1490,7 @@ static void showkey(key *k, listopts *o)
     showkeydata(k->k, 0, o, &d);
     dstr_destroy(&d);
   }
-    
+
   o->f |= f_newline;
 }
 
@@ -1490,7 +1532,7 @@ static int cmd_list(int argc, char *argv[])
        int e = key_readflags(optarg, &p, &o.kf.f, &o.kf.m);
        if (e || *p)
          die(EXIT_FAILURE, "bad filter string `%s'", optarg);
-      } break; 
+      } break;
       default:
        o.f |= f_bogus;
        break;
@@ -1812,7 +1854,7 @@ static int cmd_verify(int argc, char *argv[])
   doclose(&f);
   return (0);
 }
-  
+
 /* --- @cmd_comment@ --- */
 
 static int cmd_comment(int argc, char *argv[])
@@ -1976,7 +2018,7 @@ static int cmd_extract(int argc, char *argv[])
     key *k;
     for (key_mkiter(&i, &f); (k = key_next(&i)) != 0; )
       key_extract(&f, k, fp, &kf);
-  } else {    
+  } else {
     for (i = 1; i < argc; i++) {
       if ((k = key_bytag(&f, argv[i])) != 0)
        key_extract(&f, k, fp, &kf);
@@ -2102,9 +2144,9 @@ Options:\n\
   { "tidy", cmd_tidy, "tidy" },
   { "add", cmd_add,
     "add [-OPTIONS] TYPE [ATTR...]\n\
-       Options: [-lqrLS] [-a ALG] [-bB BITS] [-p PARAM] [-R TAG]\n\
-                [-A SEEDALG] [-s SEED] [-n BITS]\n\
-                [-e EXPIRE] [-t TAG] [-c COMMENT]", "\
+       Options: [-lqrLKS] [-a ALG] [-bB BITS] [-p PARAM] [-R TAG]\n\
+                [-A SEEDALG] [-s SEED] [-n BITS] [-I KEYID]\n\
+                [-e EXPIRE] [-t TAG] [-c COMMENT]", "\
 Options:\n\
 \n\
 -a, --algorithm=ALG    Generate keys suitable for ALG.\n\
@@ -2123,9 +2165,11 @@ Options:\n\
 -t, --tag=TAG          Tag the key with the name TAG.\n\
 -r, --retag            Untag any key currently with that tag.\n\
 -R, --rand-id=TAG      Use key named TAG for the random number generator.\n\
+-I, --key-id=ID                Force the key-id for the new key.\n\
 -l, --lock             Lock the generated key with a passphrase.\n\
 -q, --quiet            Don't give progress indicators while working.\n\
 -L, --lim-lee          Generate Lim-Lee primes for Diffie-Hellman groups.\n\
+-K, --kcdsa            Generate KCDSA-style Lim-Lee primes for DH groups.\n\
 -S, --subgroup         Use a prime-order subgroup for Diffie-Hellman.\n\
 " },
   { 0, 0, 0 }