-/*----- Key groups --------------------------------------------------------*/
-
-/* The key-loading functions here must fill in the kdata slot @g@ and
- * either @kpriv@ or @kpub@ as appropriate. The caller will take care of
- * determining @kpub@ given a private key, and of ensuring that @kpriv@ is
- * null for a public key.
- */
-
-typedef struct kgops {
- const char *ty;
- int (*loadpriv)(key_data *, kdata *, dstr *, dstr *);
- int (*loadpub)(key_data *, kdata *, dstr *, dstr *);
-} kgops;
-
-/* --- @KLOAD@ --- *
- *
- * Arguments: @ty@, @TY@ = key type name (lower- and upper-case)
- * @which@, @WHICH@ = `pub' or `priv' (and upper-case)
- * @setgroup@ = code to initialize @kd->g@
- * @setpriv@ = code to initialize @kd->kpriv@
- * @setpub@ = code to initialize @kd->kpub@
- *
- * Use: Generates the body of one of the (rather tedious) key loading
- * functions. See the description of @KEYTYPES@ below for the
- * details.
- */
-
-#define KLOAD(ty, TY, which, WHICH, setgroup, setpriv, setpub) \
-static int kg##ty##_##which(key_data *d, kdata *kd, dstr *t, dstr *e) \
-{ \
- key_packstruct kps[TY##_##WHICH##FETCHSZ]; \
- key_packdef *kp; \
- ty##_##which p; \
- int rc; \
- \
- /* --- Initialize things we've not set up yet --- */ \
- \
- kd->g = 0; kd->kpub = 0; \
- \
- /* --- Unpack the key --- */ \
- \
- kp = key_fetchinit(ty##_##which##fetch, kps, &p); \
- if ((rc = key_unpack(kp, d, t)) != 0) { \
- a_format(e, "unpack-failed", "%s", key_strerror(rc), A_END); \
- goto fail; \
- } \
- \
- /* --- Extract the pieces of the key --- */ \
- \
- setgroup; \
- setpriv; \
- kd->kpub = G_CREATE(kd->g); \
- setpub; \
- \
- /* --- We win --- */ \
- \
- rc = 0; \
- goto done; \
- \
-fail: \
- if (kd->kpub) G_DESTROY(kd->g, kd->kpub); \
- if (kd->g) G_DESTROYGROUP(kd->g); \
- rc = -1; \
- \
-done: \
- key_fetchdone(kp); \
- return (rc); \
-}
-
-/* --- @KEYTYPES@ --- *
- *
- * A list of the various key types, and how to unpack them. Each entry in
- * the list has the form
- *
- * _(ty, TY, setgroup, setpriv, setpub)
- *
- * The @ty@ and @TY@ are lower- and upper-case versions of the key type name,
- * and there should be @key_fetchdef@s called @ty_{priv,pub}fetch@.
- *
- * The @setgroup@, @setpriv@ and @setpub@ items are code fragments which are
- * passed to @KLOAD@ to build appropriate key-loading methods. By the time
- * these code fragments are run, the key has been unpacked from the incoming
- * key data using @ty_whichfetch@ into a @ty_which@ structure named @p@.
- * They can report errors by writing an appropriate token sequence to @e@ and
- * jumping to @fail@.
- */
-
-#define KEYTYPES(_) \
- \
- /* --- Diffie-Hellman --- */ \
- \
- _(dh, DH, \
- { kd->g = group_prime(&p.dp); }, \
- { kd->kpriv = MP_COPY(p.x); }, \
- { if (G_FROMINT(kd->g, kd->kpub, p.y)) { \
- a_format(e, "bad-public-vector", A_END); \
- goto fail; \
- } \
- }) \
- \
- /* --- Elliptic curves --- */ \
- \
- _(ec, EC, \
- { ec_info ei; const char *err; \
- if ((err = ec_getinfo(&ei, p.cstr)) != 0) { \
- a_format(e, "decode-failed", "%s", err, A_END); \
- goto fail; \
- } \
- kd->g = group_ec(&ei); \
- }, \
- { kd->kpriv = MP_COPY(p.x); }, \
- { if (G_FROMEC(kd->g, kd->kpub, &p.p)) { \
- a_format(e, "bad-public-vector", A_END); \
- goto fail; \
- } \
- })
-
-#define KEYTYPE_DEF(ty, TY, setgroup, setpriv, setpub) \
- KLOAD(ty, TY, priv, PRIV, setgroup, setpriv, \
- { G_EXP(kd->g, kd->kpub, kd->g->g, kd->kpriv); }) \
- KLOAD(ty, TY, pub, PUB, setgroup, { }, setpub) \
- static const kgops kg##ty##_ops = { #ty, kg##ty##_priv, kg##ty##_pub };
-KEYTYPES(KEYTYPE_DEF)
-
-/* --- Table of supported key types --- */
-
-static const kgops *kgtab[] = {
-#define KEYTYPE_ENTRY(ty, TY, setgroup, setpriv, setpub) &kg##ty##_ops,
- KEYTYPES(KEYTYPE_ENTRY)
-#undef KEYTYPE_ENTRY
- 0
-};
-