Add consistency checking for public keys.
authormdw <mdw>
Sat, 3 Feb 2001 16:08:24 +0000 (16:08 +0000)
committermdw <mdw>
Sat, 3 Feb 2001 16:08:24 +0000 (16:08 +0000)
dh-check.c [new file with mode: 0644]
dh.h
dsa-check.c [new file with mode: 0644]
dsa.h
keycheck-mp.c [new file with mode: 0644]
keycheck-report.c [new file with mode: 0644]
keycheck.c [new file with mode: 0644]
keycheck.h [new file with mode: 0644]

diff --git a/dh-check.c b/dh-check.c
new file mode 100644 (file)
index 0000000..8956bd1
--- /dev/null
@@ -0,0 +1,177 @@
+/* -*-c-*-
+ *
+ * $Id: dh-check.c,v 1.1 2001/02/03 16:08:24 mdw Exp $
+ *
+ * Checks Diffie-Hellman group parameters
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: dh-check.c,v $
+ * Revision 1.1  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <mLib/dstr.h>
+
+#include "dh.h"
+#include "keycheck.h"
+#include "mp.h"
+#include "mpmont.h"
+#include "mpmul.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @dh_checkparam@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @const dh_param *dp@ = pointer to the parameter set
+ *             @mp **v@ = optional vector of factors
+ *             @size_t n@ = size of vector
+ *
+ * Returns:    Zero if all OK, or return status from function.
+ *
+ * Use:                Checks a set of Diffie-Hellman parameters for consistency and
+ *             security.
+ */
+
+int dh_checkparam(keycheck *kc, const dh_param *dp, mp **v, size_t n)
+{
+  int rc = 0;
+  mpmont mm;
+  mp *pm1 = MP_NEW;
+  mp *q = MP_NEW;
+  mpmul mu;
+  size_t i;
+
+  /* --- Check that the numbers which are supposed to be prime are --- */
+
+  if ((!v && keycheck_prime(kc, KCSEV_WARN, dp->q, "q")) ||
+      keycheck_prime(kc, KCSEV_ERR, dp->p, "p"))
+    goto fail;
+
+  /* --- Ensure that %$q$% is a sensible choice of number --- */
+
+  pm1 = mp_sub(pm1, dp->p, MP_ONE);
+  mp_div(0, &q, pm1, dp->q);
+  if (!mp_eq(q, MP_ZERO) &&
+      keycheck_report(kc, KCSEV_ERR, "q not a factor of p - 1"))
+    goto fail;
+
+  /* --- Check that %$g$% is actually right --- *
+   *
+   * This isn't perfect.  If %$q$% is composite and we don't have the factors
+   * of %$p - 1$% then the order of %$g$% may be some factor of %$q$% which
+   * we can't find.  (If we do have the factors, we check them all lower
+   * down.)  We do strip out powers of two from %$q$% before testing, though.
+   */
+
+  if ((mp_eq(dp->g, MP_ONE) || mp_eq(dp->g, pm1)) &&
+      keycheck_report(kc, KCSEV_ERR, "g is degenerate (+/-1 mod p)"))
+    goto fail;
+  q = mp_odd(q, dp->q, &i);
+  mpmont_create(&mm, dp->p);
+  q = mpmont_expr(&mm, q, dp->g, q);
+  do {
+    if (mp_eq(q, mm.r) != !i) {
+      if (keycheck_report(kc, KCSEV_ERR, "order of g != q")) {
+       mpmont_destroy(&mm);
+       goto fail;
+      }
+      break;
+    }
+    if (i) {
+      q = mp_sqr(q, q);
+      q = mpmont_reduce(&mm, q, q);
+    }
+  } while (i--);
+
+  /* --- Check Lim-Lee primes more carefully --- *
+   *
+   * In this case, we really can be sure whether the order of %$g$% is
+   * actually %$q$% as advertised.  Also ensure that the individual primes
+   * are really prime, and that their product is correct.
+   */
+
+  if (!v)
+    mpmont_destroy(&mm);
+  else {
+    dstr d = DSTR_INIT;
+    mp *r = MP_NEW;
+
+    mpmul_init(&mu);
+    for (i = 0; i < n; i++) {
+      DRESET(&d);
+      dstr_putf(&d, "factor f_%lu of p", (unsigned long)i);
+      if ((rc = keycheck_prime(kc, KCSEV_ERR, v[i], d.buf)) != 0)
+       break;
+      mp_div(&q, &r, dp->q, v[i]);
+      if (mp_eq(r, MP_ZERO) && !mp_eq(q, MP_ONE)) {
+       q = mpmont_exp(&mm, q, dp->g, q);
+       if (mp_eq(q, MP_ONE) &&
+           (rc = keycheck_report(kc, KCSEV_ERR,
+                                 "order of g is proper divisor of q")) != 0)
+         break;
+      }
+      mpmul_add(&mu, v[i]);
+    }
+    mp_drop(q);
+    mp_drop(r);
+    q = mpmul_done(&mu);
+    mpmont_destroy(&mm);
+    dstr_destroy(&d);
+    if (rc)
+      goto fail;
+    q = mp_lsl(q, q, 1);
+    if (!mp_eq(q, pm1) &&
+       keycheck_report(kc, KCSEV_ERR, "product of f_i != (p - 1)/2"))
+      goto fail;
+  }
+
+  /* --- Finally, check the key sizes --- */
+
+  if ((mp_bits(dp->p) < 1024 &&
+       keycheck_report(kc, KCSEV_WARN,
+                      "p too small to resist index calculus attacks")) ||
+      (mp_bits(dp->q) < 160 &&
+       keycheck_report(kc, KCSEV_WARN,
+                      "q too small to resist collision-finding attacks")))
+    goto fail;
+
+  /* --- Done --- */
+
+tidy:
+  mp_drop(q);
+  mp_drop(pm1);
+  return (rc);
+fail:
+  rc = -1;
+  goto tidy;
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/dh.h b/dh.h
index c2f2311..90fdaa3 100644 (file)
--- a/dh.h
+++ b/dh.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: dh.h,v 1.6 2000/07/29 10:01:16 mdw Exp $
+ * $Id: dh.h,v 1.7 2001/02/03 16:08:24 mdw Exp $
  *
  * Diffie-Hellman and related public-key systems
  *
  *
  * Diffie-Hellman and related public-key systems
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: dh.h,v $
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: dh.h,v $
+ * Revision 1.7  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
  * Revision 1.6  2000/07/29 10:01:16  mdw
  * Supply commentry for the Diffie-Hellman parameters.  Add Lim-Lee
  * parameter generation.
  * Revision 1.6  2000/07/29 10:01:16  mdw
  * Supply commentry for the Diffie-Hellman parameters.  Add Lim-Lee
  * parameter generation.
 #  include "key.h"
 #endif
 
 #  include "key.h"
 #endif
 
+#ifndef CATACOMB_KEYCHECK_H
+#  include "keycheck.h"
+#endif
+
 #ifndef CATACOMB_PGEN_H
 #  include "pgen.h"
 #endif
 
 /*----- Data structures ---------------------------------------------------*/
 
 #ifndef CATACOMB_PGEN_H
 #  include "pgen.h"
 #endif
 
 /*----- Data structures ---------------------------------------------------*/
 
-typedef struct dh_param {              /* Prime numbers %$p$% and %$q$% */
-  mp *p, *q;                           /* Generates order-%$q$% subgroup */
-  mp *g;
+typedef struct dh_param {
+  mp *p, *q;                           /* Prime numbers %$p$% and %$q$% */
+  mp *g;                               /* Generates order-%$q$% subgroup */
 } dh_param;
 
 } dh_param;
 
-typedef struct dh_pub {                        /* Shared parameters */
-  dh_param dp;                         /* Public key */
-  mp *y;
+typedef struct dh_pub {
+  dh_param dp;                         /* Shared parameters */         
+  mp *y;                               /* Public key */
 } dh_pub;
 
 } dh_pub;
 
-typedef struct dh_priv {               /* Shared parameters */
-  dh_param dp;                         /* Private key */
-  mp *x;                               /* %$y \equiv g^x \pmod{p}$% */
-  mp *y;
+typedef struct dh_priv {
+  dh_param dp;                         /* Shared parameters */
+  mp *x;                               /* Private key */
+  mp *y;                               /* %$y \equiv g^x \pmod{p}$% */
 } dh_priv;
 
 /*----- Key fetching ------------------------------------------------------*/
 } dh_priv;
 
 /*----- Key fetching ------------------------------------------------------*/
@@ -175,6 +182,22 @@ extern int dh_limlee(dh_param */*dp*/, unsigned /*ql*/, unsigned /*pl*/,
                     pgen_proc */*oev*/, void */*oec*/, pgen_proc */*iev*/,
                     void */*iec*/, size_t */*nf*/, mp ***/*f*/);
 
                     pgen_proc */*oev*/, void */*oec*/, pgen_proc */*iev*/,
                     void */*iec*/, size_t */*nf*/, mp ***/*f*/);
 
+/* --- @dh_checkparam@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @const dh_param *dp@ = pointer to the parameter set
+ *             @mp **v@ = optional vector of factors
+ *             @size_t n@ = size of vector
+ *
+ * Returns:    Zero if all OK, or return status from function.
+ *
+ * Use:                Checks a set of Diffie-Hellman parameters for consistency and
+ *             security.
+ */
+
+extern int dh_checkparam(keycheck */*kc*/, const dh_param */*dp*/,
+                        mp **/*v*/, size_t /*n*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus
diff --git a/dsa-check.c b/dsa-check.c
new file mode 100644 (file)
index 0000000..88a5686
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*-c-*-
+ *
+ * $Id: dsa-check.c,v 1.1 2001/02/03 16:08:24 mdw Exp $
+ *
+ * Consistency checking for DSA keys
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: dsa-check.c,v $
+ * Revision 1.1  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include "dh.h"
+#include "dsa.h"
+#include "dsarand.h"
+#include "grand.h"
+#include "keycheck.h"
+#include "mp.h"
+#include "mprand.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @dsa_checkparam@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @const dsa_param *dp@ = pointer to the parameter set
+ *             @const dsa_seed *ds@ = pointer to seed information
+ *
+ * Returns:    Zero if all OK, or return status from function.
+ *
+ * Use:                Checks a set of DSA parameters for consistency and security.
+ */
+
+int dsa_checkparam(keycheck *kc, const dsa_param *dp, const dsa_seed *ds)
+{
+  if (ds) {
+    grand *r = dsarand_create(ds->p, ds->sz);
+    mp *p = MP_NEW, *q = MP_NEW;
+    int rc = 0;
+    unsigned i;
+    unsigned long n;
+
+    r->ops->misc(r, DSARAND_PASSES, 2);
+    q = mprand(q, mp_bits(dp->q), r, 1);
+    if (!mp_eq(q, dp->q) &&
+       keycheck_report(kc, KCSEV_ERR, "q doesn't match seed provided"))
+      rc = -1;
+    else {
+      n = mp_bits(dp->p);
+      r->ops->misc(r, DSARAND_PASSES, 1);
+      for (i = 0; i <= ds->count; i++)
+       p = mprand(p, n, r, 0);
+      q = mp_lsl(q, q, 1);
+      mp_div(0, &q, p, q);
+      p = mp_sub(p, p, q);
+      p->v[0] |= 1;
+      if (!mp_eq(p, dp->p) &&
+         keycheck_report(kc, KCSEV_ERR, "p doesn't match seed provided"))
+       rc = -1;
+    }
+    mp_drop(p);
+    mp_drop(q);
+    r->ops->destroy(r);
+    if (rc)
+      return (rc);
+  }
+  return (dh_checkparam(kc, dp, 0, 0));
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/dsa.h b/dsa.h
index dfd04db..ce7e762 100644 (file)
--- a/dsa.h
+++ b/dsa.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: dsa.h,v 1.7 2000/07/29 09:59:44 mdw Exp $
+ * $Id: dsa.h,v 1.8 2001/02/03 16:08:24 mdw Exp $
  *
  * Digital Signature Algorithm
  *
  *
  * Digital Signature Algorithm
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: dsa.h,v $
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: dsa.h,v $
+ * Revision 1.8  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
  * Revision 1.7  2000/07/29 09:59:44  mdw
  * Share data structures with Diffie-Hellman stuff.
  *
  * Revision 1.7  2000/07/29 09:59:44  mdw
  * Share data structures with Diffie-Hellman stuff.
  *
 #  include "key.h"
 #endif
 
 #  include "key.h"
 #endif
 
+#ifndef CATACOMB_KEYCHECK_H
+#  include "keycheck.h"
+#endif
+
 #ifndef CATACOMB_MP_H
 #  include "mp.h"
 #endif
 #ifndef CATACOMB_MP_H
 #  include "mp.h"
 #endif
@@ -95,6 +102,14 @@ typedef dh_param dsa_param;
 typedef dh_pub dsa_pub;
 typedef dh_priv dsa_priv;
 
 typedef dh_pub dsa_pub;
 typedef dh_priv dsa_priv;
 
+/* --- DSA key seed structure --- */
+
+typedef struct dsa_seed {
+  void *p;                             /* Pointer to seed material */
+  size_t sz;                           /* Size of seed material */
+  unsigned count;                      /* Iterations to find @p@ */
+} dsa_seed;
+
 /* --- DSA signature structure --- *
  *
  * This is the recommended structure for a DSA signature.  The actual signing
 /* --- DSA signature structure --- *
  *
  * This is the recommended structure for a DSA signature.  The actual signing
@@ -133,6 +148,8 @@ typedef struct dsa_stepctx {
   mp *q;                               /* Force @p@ to be a multiple */
   size_t bits;                         /* Number of bits in the result */
   unsigned or;                         /* OR mask for low order bits */
   mp *q;                               /* Force @p@ to be a multiple */
   size_t bits;                         /* Number of bits in the result */
   unsigned or;                         /* OR mask for low order bits */
+  unsigned count;                      /* Counts the number of steps made */
+  void *seedbuf;                       /* Pointer to seed buffer */
 } dsa_stepctx;
 
 /* --- @dsa_step@ --- *
 } dsa_stepctx;
 
 /* --- @dsa_step@ --- *
@@ -154,6 +171,7 @@ extern int dsa_step(int /*rq*/, pgen_event */*ev*/, void */*p*/);
  *             @unsigned steps@ = number of steps to find @q@
  *             @const void *k@ = pointer to key material
  *             @size_t sz@ = size of key material
  *             @unsigned steps@ = number of steps to find @q@
  *             @const void *k@ = pointer to key material
  *             @size_t sz@ = size of key material
+ *             @dsa_seed *sd@ = optional pointer for output seed information
  *             @pgen_proc *event@ = event handler function
  *             @void *ectx@ = argument for event handler
  *
  *             @pgen_proc *event@ = event handler function
  *             @void *ectx@ = argument for event handler
  *
@@ -171,7 +189,21 @@ extern int dsa_step(int /*rq*/, pgen_event */*ev*/, void */*p*/);
 
 extern int dsa_gen(dsa_param */*dp*/, unsigned /*ql*/, unsigned /*pl*/,
                   unsigned /*steps*/, const void */*k*/, size_t /*sz*/,
 
 extern int dsa_gen(dsa_param */*dp*/, unsigned /*ql*/, unsigned /*pl*/,
                   unsigned /*steps*/, const void */*k*/, size_t /*sz*/,
-                  pgen_proc */*event*/, void */*ectx*/);
+                  dsa_seed */*sd*/, pgen_proc */*event*/, void */*ectx*/);
+
+/* --- @dsa_checkparam@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @const dsa_param *dp@ = pointer to the parameter set
+ *             @const dsa_seed *ds@ = pointer to seed information
+ *
+ * Returns:    Zero if all OK, or return status from function.
+ *
+ * Use:                Checks a set of DSA parameters for consistency and security.
+ */
+
+extern int dsa_checkparam(keycheck */*kc*/, const dsa_param */*dp*/,
+                         const dsa_seed */*ds*/);
 
 /* --- @dsa_mksig@ --- *
  *
 
 /* --- @dsa_mksig@ --- *
  *
diff --git a/keycheck-mp.c b/keycheck-mp.c
new file mode 100644 (file)
index 0000000..8b71bf3
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*-c-*-
+ *
+ * $Id: keycheck-mp.c,v 1.1 2001/02/03 16:08:24 mdw Exp $
+ *
+ * Key consistency checking tools for large integers
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: keycheck-mp.c,v $
+ * Revision 1.1  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <mLib/dstr.h>
+
+#include "fibrand.h"
+#include "grand.h"
+#include "keycheck.h"
+#include "mp.h"
+#include "mprand.h"
+#include "pfilt.h"
+#include "pgen.h"
+#include "rabin.h"
+#include "rand.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @keycheck_prime@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @unsigned sev@ = severity if not prime
+ *             @mp *m@ = a number to check for primality
+ *             @const char *name@ = name of this number
+ *
+ * Returns:    Zero if OK, or return status from function.
+ *
+ * Use:                Checks that a number is prime.
+ */
+
+int keycheck_prime(keycheck *kc, unsigned sev, mp *m, const char *name)
+{
+  int rc;
+
+  rc = pfilt_smallfactor(m);
+  if (rc == PGEN_TRY) {
+    rabin rn;
+    grand *r = fibrand_create(0);
+    unsigned n;
+    mp *x = MP_NEW;
+
+    r->ops->misc(r, GRAND_SEEDRAND, &rand_global);
+    n = rabin_iters(mp_bits(m));
+    rabin_create(&rn, m);
+    do {
+      x = mprand_range(x, m, r, 0);
+      rc = rabin_test(&rn, x);
+      n--;
+    } while (n && rc == PGEN_PASS);
+    rabin_destroy(&rn);
+    mp_drop(x);
+    r->ops->destroy(r);
+  }
+  if (rc != PGEN_FAIL)
+    rc = 0;
+  else
+    rc = keycheck_report(kc, sev, "%s not prime", name);
+  return (rc);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/keycheck-report.c b/keycheck-report.c
new file mode 100644 (file)
index 0000000..8a7accd
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*-c-*-
+ *
+ * $Id: keycheck-report.c,v 1.1 2001/02/03 16:08:24 mdw Exp $
+ *
+ * A standard reporter function
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: keycheck-report.c,v $
+ * Revision 1.1  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+
+#include "keycheck.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @keycheck_stdreport@ --- *
+ *
+ * Arguments:  @unsigned sev@ = problem severity
+ *             @const char *msg@ = message to report
+ *             @void *p@ = an uninteresting pointer
+ *
+ * Returns:    Zero.
+ *
+ * Use:                Reports a message to stderr.
+ */
+
+int keycheck_stdreport(unsigned sev, const char *msg, void *p)
+{
+  static const char *const sevtab[] = {
+    "informational", "warning", "error"
+  };
+  keycheck_reportctx *r = p;
+  if (r && sev < r->sev)
+    return (0);
+  fprintf(r ? r->fp : stderr, "keycheck: %s: %s\n", sevtab[sev], msg);
+  return (0);
+}
+
+/*----- that's all, folks -------------------------------------------------*/
diff --git a/keycheck.c b/keycheck.c
new file mode 100644 (file)
index 0000000..2ced761
--- /dev/null
@@ -0,0 +1,118 @@
+/* -*-c-*-
+ *
+ * $Id: keycheck.c,v 1.1 2001/02/03 16:08:24 mdw Exp $
+ *
+ * Framework for checking consistency of keys
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: keycheck.c,v $
+ * Revision 1.1  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdarg.h>
+
+#include <mLib/dstr.h>
+
+#include "keycheck.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @keycheck_report@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @unsigned sev@ = severity of this report
+ *             @const char *msg@ = message to send along
+ *             @...@ = things to fill the message in with
+ *
+ * Returns:    Zero to continue, or nonzero to stop and give up.
+ *
+ * Use:                Reports a message to the user function.
+ */
+
+int keycheck_report(keycheck *kc, unsigned sev, const char *msg, ...)
+{
+  int rc;
+  va_list ap;
+  dstr d = DSTR_INIT;
+
+  kc->sev[sev]++;
+  va_start(ap, msg);
+  dstr_vputf(&d, msg, ap);
+  va_end(ap);
+  rc = kc->func ? kc->func(sev, d.buf, kc->p) : 0;
+  dstr_destroy(&d);
+  return (rc);  
+}
+
+/* --- @keycheck_init@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = pointer to block to initialize
+ *             @int (*func)(unsigned sev, const char *msg, void *p)@ =
+ *                     handler function for problems
+ *             @void *p@ = pointer to give to handler
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes a key checking context.
+ */
+
+void keycheck_init(keycheck *kc,
+                  int (*func)(unsigned /*sev*/,
+                              const char */*msg*/,
+                              void */*p*/),
+                  void *p)
+{
+  unsigned i;
+  kc->func = func;
+  kc->p = p;
+  for (i = 0; i < KCSEV_MAX; i++)
+    kc->sev[i] = 0;
+}
+
+/* --- @keycheck_allclear@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = pointer to keycheck context
+ *             @unsigned sev@ = minimum severity to care about
+ *
+ * Returns:    Nonzero if no problems of @sev@ or above were noticed.
+ */
+
+int keycheck_allclear(keycheck *kc, unsigned sev)
+{
+  while (sev < KCSEV_MAX) {
+    if (kc->sev[sev])
+      return (0);
+    sev++;
+  }
+  return (1);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/keycheck.h b/keycheck.h
new file mode 100644 (file)
index 0000000..7fe159f
--- /dev/null
@@ -0,0 +1,156 @@
+/* -*-c-*-
+ *
+ * $Id: keycheck.h,v 1.1 2001/02/03 16:08:24 mdw Exp $
+ *
+ * Framework for checking consistency of keys
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: keycheck.h,v $
+ * Revision 1.1  2001/02/03 16:08:24  mdw
+ * Add consistency checking for public keys.
+ *
+ */
+
+#ifndef CATACOMB_KEYCHECK_H
+#define CATACOMB_KEYCHECK_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef CATACOMB_MP_H
+#  include "mp.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+enum {
+  KCSEV_ALL,
+  KCSEV_INFO = KCSEV_ALL,
+  KCSEV_WARN,
+  KCSEV_ERR,
+  KCSEV_MAX
+};
+
+typedef struct keycheck {
+  unsigned sev[KCSEV_MAX];
+  int (*func)(unsigned /*sev*/, const char */*msg*/, void */*p*/);
+  void *p;
+} keycheck;
+
+typedef struct keycheck_reportctx {
+  FILE *fp;
+  unsigned sev;
+} keycheck_reportctx;
+
+/*----- Generic functions -------------------------------------------------*/
+
+/* --- @keycheck_report@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @unsigned sev@ = severity of this report
+ *             @const char *msg@ = message to send along
+ *             @...@ = things to fill the message in with
+ *
+ * Returns:    Zero to continue, or nonzero to stop and give up.
+ *
+ * Use:                Reports a message to the user function.
+ */
+
+extern int keycheck_report(keycheck */*kc*/, unsigned /*sev*/,
+                          const char */*msg*/, ...);
+
+/* --- @keycheck_init@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = pointer to block to initialize
+ *             @int (*func)(unsigned sev, const char *msg, void *p)@ =
+ *                     handler function for problems
+ *             @void *p@ = pointer to give to handler
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes a key checking context.
+ */
+
+extern void keycheck_init(keycheck */*kc*/,
+                         int (*/*func*/)(unsigned /*sev*/,
+                                         const char */*msg*/,
+                                         void */*p*/),
+                         void */*p*/);
+
+/* --- @keycheck_allclear@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = pointer to keycheck context
+ *             @unsigned sev@ = minimum severity to care about
+ *
+ * Returns:    Nonzero if no problems of @sev@ or above were noticed.
+ */
+
+extern int keycheck_allclear(keycheck */*kc*/, unsigned /*sev*/);
+
+/*----- A standard report function ----------------------------------------*/
+
+/* --- @keycheck_stdreport@ --- *
+ *
+ * Arguments:  @unsigned sev@ = problem severity
+ *             @const char *msg@ = message to report
+ *             @void *p@ = pointer to a @keycheck_reportctx@ structure
+ *
+ * Returns:    Zero.
+ *
+ * Use:                Reports a message to stderr.
+ */
+
+extern int keycheck_stdreport(unsigned /*sev*/,
+                             const char */*msg*/, void */*p*/);
+
+/*----- Special support functions for large integers ----------------------*/
+
+/* --- @keycheck_prime@ --- *
+ *
+ * Arguments:  @keycheck *kc@ = keycheck state
+ *             @unsigned sev@ = severity if not prime
+ *             @mp *m@ = a number to check for primality
+ *             @const char *name@ = name of this number
+ *
+ * Returns:    Zero if OK, or return status from function.
+ *
+ * Use:                Checks that a number is prime.
+ */
+
+extern int keycheck_prime(keycheck */*kc*/, unsigned /*sev*/,
+                         mp */*m*/, const char */*name*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif