key-binary.c
[u/mdw/catacomb] / keyutil.c
index 1619707..2df4368 100644 (file)
--- a/keyutil.c
+++ b/keyutil.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: keyutil.c,v 1.18 2004/04/01 12:50:09 mdw Exp $
+ * $Id: keyutil.c,v 1.23 2004/04/08 01:02:49 mdw Exp $
  *
  * Simple key manager program
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: keyutil.c,v $
+ * Revision 1.23  2004/04/08 01:02:49  mdw
+ * key-binary.c
+ *
+ * Revision 1.22  2004/04/03 15:45:06  mdw
+ * Oops.  Fix formatting. :-S
+ *
+ * Revision 1.21  2004/04/03 15:15:19  mdw
+ * Fix stupid error in previous rashly-committed version.
+ *
+ * Revision 1.20  2004/04/03 15:14:28  mdw
+ * Handle points at infinity properly in listings.
+ *
+ * Revision 1.19  2004/04/03 03:31:01  mdw
+ * Allow explicit group parameters for DH groups.
+ *
  * Revision 1.18  2004/04/01 12:50:09  mdw
  * Add cyclic group abstraction, with test code.  Separate off exponentation
  * functions for better static linking.  Fix a buttload of bugs on the way.
 #include "mprand.h"
 #include "mptext.h"
 #include "pgen.h"
+#include "ptab.h"
 #include "rsa.h"
 
 #include "sha-mgf.h"
@@ -625,6 +641,22 @@ static void alg_dhparam(keyopts *k)
     dh_param dp;
     int rc;
 
+    if (k->curve) {
+      qd_parse qd;
+      
+      if (strcmp(k->curve, "list") == 0) {
+       const pentry *pe;
+       printf("Built-in prime groups:\n");
+       for (pe = ptab; pe->name; pe++)
+         printf("  %s\n", pe->name);
+       exit(0);
+      }
+      qd.p = k->curve;
+      if (dh_parse(&qd, &dp))
+       die(EXIT_FAILURE, "error in group spec: %s", qd.e);
+      goto done;
+    }
+
     if (!k->bits)
       k->bits = 1024;
 
@@ -658,6 +690,7 @@ static void alg_dhparam(keyopts *k)
     if (rc)
       die(EXIT_FAILURE, "Diffie-Hellman parameter generation failed");
 
+  done:
     key_structure(kd);
     mpkey(kd, "p", dp.p, KCAT_SHARE);
     mpkey(kd, "q", dp.q, KCAT_SHARE);
@@ -751,6 +784,13 @@ static void alg_ecparam(keyopts *k)
     /* --- Decide on a curve --- */
 
     if (!k->bits) k->bits = 256;
+    if (k->curve && strcmp(k->curve, "list") == 0) {
+      const ecentry *ee;
+      printf("Built-in elliptic curves:\n");
+      for (ee = ectab; ee->name; ee++)
+       printf("  %s\n", ee->name);
+      exit(0);
+    }
     if (!k->curve) {
       if (k->bits <= 56) k->curve = "secp112r1";
       else if (k->bits <= 64) k->curve = "secp128r1";
@@ -880,7 +920,8 @@ static int cmd_add(int argc, char *argv[])
       { "subgroup",    0,              0,      'S' },
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:C:A:s:n:lqrLS", opt, 0, 0, 0);
+    int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:C:A:s:n:lqrLS",
+                  opt, 0, 0, 0);
     if (i < 0)
       break;
 
@@ -961,13 +1002,6 @@ static int cmd_add(int argc, char *argv[])
       /* --- Elliptic curve parameters --- */
 
       case 'C':
-       if (strcmp(optarg, "list") == 0) {
-         const ecentry *ee;
-         printf("Built-in elliptic curves:\n");
-         for (ee = ectab; ee->name; ee++)
-           printf("  %s\n", ee->name);
-         exit(0);
-       }
        k.curve = optarg;
        break;
 
@@ -1250,9 +1284,13 @@ static void showkeydata(key_data *k, int ind, listopts *o, dstr *d)
     /* --- Elliptic curve points --- */
 
     case KENC_EC:
-      fputs(" 0x", stdout); mp_writefile(k->u.e.x, stdout, 16);
-      fputs(", 0x", stdout); mp_writefile(k->u.e.y, stdout, 16);
-      putchar('\n');
+      if (EC_ATINF(&k->u.e))
+       fputs(" inf\n", stdout);
+      else {
+       fputs(" 0x", stdout); mp_writefile(k->u.e.x, stdout, 16);
+       fputs(", 0x", stdout); mp_writefile(k->u.e.y, stdout, 16);
+       putchar('\n');
+      }
       break;      
 
     /* --- Structured keys --- *
@@ -1540,42 +1578,42 @@ static int cmd_setattr(int argc, char *argv[])
 
 /* --- @cmd_finger@ --- */
 
-static void fingerprint(key *k, const key_filter *kf)
+static void fingerprint(key *k, const gchash *ch, const key_filter *kf)
 {
-  rmd160_ctx r;
-  octet hash[RMD160_HASHSZ];
+  ghash *h;
   dstr d = DSTR_INIT;
-  int i;
+  const octet *p;
+  size_t i;
 
-  if (!key_encode(&k->k, &d, kf))
-    return;
-  rmd160_init(&r);
-  rmd160_hash(&r, d.buf, d.len);
-  rmd160_done(&r, hash);
-
-  DRESET(&d);
-  key_fulltag(k, &d);
-  for (i = 0; i < sizeof(hash); i++) {
-    if (i && i % 4 == 0)
-      putchar('-');
-    printf("%02x", hash[i]);
+  h = GH_INIT(ch);
+  if (key_fingerprint(k, h, kf)) {
+    p = GH_DONE(h, 0);
+    key_fulltag(k, &d);
+    for (i = 0; i < ch->hashsz; i++) {
+      if (i && i % 4 == 0)
+       putchar('-');
+      printf("%02x", p[i]);
+    }
+    printf(" %s\n", d.buf);
   }
-  printf(" %s\n", d.buf);
   dstr_destroy(&d);
+  GH_DESTROY(h);
 }
 
 static int cmd_finger(int argc, char *argv[])
 {
   key_file f;
   int rc = 0;
+  const gchash *ch = &rmd160;
   key_filter kf = { KF_NONSECRET, KF_NONSECRET };
 
   for (;;) {
     static struct option opt[] = {
       { "filter",      OPTF_ARGREQ,    0,      'f' },
+      { "algorithm",   OPTF_ARGREQ,    0,      'a' },
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "+f:", opt, 0, 0, 0);
+    int i = mdwopt(argc, argv, "+f:a:", opt, 0, 0, 0);
     if (i < 0)
       break;
     switch (i) {
@@ -1585,6 +1623,10 @@ static int cmd_finger(int argc, char *argv[])
        if (err || *p)
          die(EXIT_FAILURE, "bad filter string `%s'", optarg);
       } break;
+      case 'a':
+       if ((ch = ghash_byname(optarg)) == 0)
+         die(EXIT_FAILURE, "unknown hash algorithm `%s'", optarg);
+       break;
       default:
        rc = 1;
        break;
@@ -1602,7 +1644,7 @@ static int cmd_finger(int argc, char *argv[])
     for (i = 0; i < argc; i++) {
       key *k = key_bytag(&f, argv[i]);
       if (k)
-       fingerprint(k, &kf);
+       fingerprint(k, ch, &kf);
       else {
        rc = 1;
        moan("key `%s' not found", argv[i]);
@@ -1612,7 +1654,7 @@ static int cmd_finger(int argc, char *argv[])
     key_iter i;
     key *k;
     for (key_mkiter(&i, &f); (k = key_next(&i)) != 0; )
-      fingerprint(k, &kf);
+      fingerprint(k, ch, &kf);
   }
   return (rc);
 }
@@ -1876,6 +1918,7 @@ Options:\n\
 Options:\n\
 \n\
 -f, --filter=FILT      Only hash key components matching FILT.\n\
+-a, --algorithm=HASH   Use the named HASH algorithm.\n\
 " },
   { "tidy", cmd_tidy, "tidy" },
   { "extract", cmd_extract, "extract [-f filter] file [tag...]", "\