X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/cc-sig.c diff --git a/cc-sig.c b/cc-sig.c deleted file mode 100644 index 54b58f3b..00000000 --- a/cc-sig.c +++ /dev/null @@ -1,806 +0,0 @@ -/* -*-c-*- - * - * $Id$ - * - * Catcrypt signatures - * - * (c) 2004 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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#define _FILE_OFFSET_BITS 64 - -#include - -#include - -#include "rand.h" -#include "sha.h" -#include "has160.h" - -#include "ec.h" -#include "ec-keys.h" -#include "dh.h" -#include "gdsa.h" -#include "gkcdsa.h" -#include "rsa.h" - -#include "cc.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- RSA PKCS1 --- */ - -typedef struct rsap1_sigctx { - sig s; - rsa_privctx rp; - pkcs1 p1; -} rsap1_sigctx; - -static sig *rsap1_siginit(key *k, void *kd, const gchash *hc) -{ - rsap1_sigctx *rs = CREATE(rsap1_sigctx); - rsa_privcreate(&rs->rp, kd, &rand_global); - rs->p1.r = &rand_global; - rs->p1.ep = hc->name; - rs->p1.epsz = strlen(hc->name) + 1; - rs->s.h = 0; - return (&rs->s); -} - -static int rsap1_sigdoit(sig *s, dstr *d) -{ - rsap1_sigctx *rs = (rsap1_sigctx *)s; - size_t n; - mp *m = rsa_sign(&rs->rp, MP_NEW, - GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz, - pkcs1_sigencode, &rs->p1); - if (!m) return (-1); - n = mp_octets(rs->rp.rp->n); dstr_ensure(d, n); mp_storeb(m, d->buf, n); - d->len += n; mp_drop(m); - return (0); -} - -static const char *rsa_lengthcheck(mp *n) -{ - if (mp_bits(n) < 1024) return ("key too short"); - return (0); -} - -static const char *rsap1_sigcheck(sig *s) -{ - rsap1_sigctx *rs = (rsap1_sigctx *)s; - const char *e; - if ((e = rsa_lengthcheck(rs->rp.rp->n)) != 0) return (e); - return (0); -} - -static void rsap1_sigdestroy(sig *s) -{ - rsap1_sigctx *rs = (rsap1_sigctx *)s; - rsa_privdestroy(&rs->rp); - DESTROY(rs); -} - -static const sigops rsap1_sig = { - rsa_privfetch, sizeof(rsa_priv), - rsap1_siginit, rsap1_sigdoit, rsap1_sigcheck, rsap1_sigdestroy -}; - -typedef struct rsap1_vrfctx { - sig s; - rsa_pubctx rp; - pkcs1 p1; -} rsap1_vrfctx; - -static sig *rsap1_vrfinit(key *k, void *kd, const gchash *hc) -{ - rsap1_vrfctx *rv = CREATE(rsap1_vrfctx); - rsa_pubcreate(&rv->rp, kd); - rv->p1.r = &rand_global; - rv->p1.ep = hc->name; - rv->p1.epsz = strlen(hc->name) + 1; - rv->s.h = 0; - return (&rv->s); -} - -static int rsap1_vrfdoit(sig *s, dstr *d) -{ - rsap1_vrfctx *rv = (rsap1_vrfctx *)s; - mp *m = mp_loadb(MP_NEW, d->buf, d->len); - int rc = rsa_verify(&rv->rp, m, - GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz, - 0, pkcs1_sigdecode, &rv->p1); - mp_drop(m); - return (rc); -} - -static const char *rsap1_vrfcheck(sig *s) -{ - rsap1_vrfctx *rv = (rsap1_vrfctx *)s; - const char *e; - if ((e = rsa_lengthcheck(rv->rp.rp->n)) != 0) return (e); - return (0); -} - -static void rsap1_vrfdestroy(sig *s) -{ - rsap1_vrfctx *rv = (rsap1_vrfctx *)s; - rsa_pubdestroy(&rv->rp); - DESTROY(rv); -} - -static const sigops rsap1_vrf = { - rsa_pubfetch, sizeof(rsa_pub), - rsap1_vrfinit, rsap1_vrfdoit, rsap1_vrfcheck, rsap1_vrfdestroy -}; - -/* --- RSA PSS --- */ - -static const gccipher *getmgf(key *k, const gchash *hc) -{ - dstr d = DSTR_INIT; - const gccipher *gc; - const char *mm; - - if ((mm = key_getattr(0, k, "mgf")) == 0) { - dstr_putf(&d, "%s-mgf", hc->name); - mm = d.buf; - } - if ((gc = gcipher_byname(mm)) == 0) - die(EXIT_FAILURE, "unknown encryption scheme `%s'", mm); - dstr_destroy(&d); - return (gc); -} - -typedef struct rsapss_sigctx { - sig s; - rsa_privctx rp; - pss p; -} rsapss_sigctx; - -static sig *rsapss_siginit(key *k, void *kd, const gchash *hc) -{ - rsapss_sigctx *rs = CREATE(rsapss_sigctx); - rsa_privcreate(&rs->rp, kd, &rand_global); - rs->p.r = &rand_global; - rs->p.cc = getmgf(k, hc); - rs->p.ch = hc; - rs->p.ssz = hc->hashsz; - rsa_privdestroy(&rs->rp); - return (&rs->s); -} - -static int rsapss_sigdoit(sig *s, dstr *d) -{ - rsapss_sigctx *rs = (rsapss_sigctx *)s; - size_t n; - mp *m = rsa_sign(&rs->rp, MP_NEW, - GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz, - pss_encode, &rs->p); - if (!m) return (-1); - n = mp_octets(rs->rp.rp->n); dstr_ensure(d, n); mp_storeb(m, d->buf, n); - d->len += n; mp_drop(m); - return (0); -} - -static const char *rsapss_sigcheck(sig *s) -{ - rsapss_sigctx *rs = (rsapss_sigctx *)s; - const char *e; - if ((e = rsa_lengthcheck(rs->rp.rp->n)) != 0) return (e); - return (0); -} - -static void rsapss_sigdestroy(sig *s) -{ - rsapss_sigctx *rs = (rsapss_sigctx *)s; - rsa_privdestroy(&rs->rp); - DESTROY(rs); -} - -static const sigops rsapss_sig = { - rsa_privfetch, sizeof(rsa_priv), - rsapss_siginit, rsapss_sigdoit, rsapss_sigcheck, rsapss_sigdestroy -}; - -typedef struct rsapss_vrfctx { - sig s; - rsa_pubctx rp; - pss p; -} rsapss_vrfctx; - -static sig *rsapss_vrfinit(key *k, void *kd, const gchash *hc) -{ - rsapss_vrfctx *rv = CREATE(rsapss_vrfctx); - rsa_pubcreate(&rv->rp, kd); - rv->p.r = &rand_global; - rv->p.cc = getmgf(k, hc); - rv->p.ch = hc; - rv->p.ssz = hc->hashsz; - return (&rv->s); -} - -static int rsapss_vrfdoit(sig *s, dstr *d) -{ - rsapss_vrfctx *rv = (rsapss_vrfctx *)s; - mp *m = mp_loadb(MP_NEW, d->buf, d->len); - int rc = rsa_verify(&rv->rp, m, - GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz, - 0, pss_decode, &rv->p); - mp_drop(m); - return (rc); -} - -static const char *rsapss_vrfcheck(sig *s) -{ - rsapss_vrfctx *rv = (rsapss_vrfctx *)s; - const char *e; - if ((e = rsa_lengthcheck(rv->rp.rp->n)) != 0) return (e); - return (0); -} - -static void rsapss_vrfdestroy(sig *s) -{ - rsapss_vrfctx *rv = (rsapss_vrfctx *)s; - rsa_pubdestroy(&rv->rp); - DESTROY(rv); -} - -static const sigops rsapss_vrf = { - rsa_pubfetch, sizeof(rsa_pub), - rsapss_vrfinit, rsapss_vrfdoit, rsapss_vrfcheck, rsapss_vrfdestroy -}; - -/* --- DSA and ECDSA --- */ - -typedef struct dsa_sigctx { - sig s; - gdsa g; -} dsa_sigctx; - -static void dsa_initcommon(dsa_sigctx *ds, const gchash *hc, - const char *ktag) -{ - ds->g.r = &rand_global; - ds->g.h = hc; - ds->g.u = MP_NEW; - ds->s.h = 0; -} - -static dsa_sigctx *dsa_doinit(key *k, const gprime_param *gp, - mp *y, const gchash *hc, - group *(*makegroup)(const gprime_param *), - const char *what) -{ - dsa_sigctx *ds = CREATE(dsa_sigctx); - dstr t = DSTR_INIT; - - key_fulltag(k, &t); - if ((ds->g.g = makegroup(gp)) == 0) - die(EXIT_FAILURE, "bad %s group in key `%s'", what, t.buf); - ds->g.p = G_CREATE(ds->g.g); - if (G_FROMINT(ds->g.g, ds->g.p, y)) - die(EXIT_FAILURE, "bad public key in key `%s'", t.buf); - dsa_initcommon(ds, hc, t.buf); - dstr_destroy(&t); - return (ds); -} - -static dsa_sigctx *ecdsa_doinit(key *k, const char *cstr, - ec *y, const gchash *hc) -{ - dsa_sigctx *ds = CREATE(dsa_sigctx); - ec_info ei; - const char *e; - dstr t = DSTR_INIT; - - key_fulltag(k, &t); - if ((e = ec_getinfo(&ei, cstr)) != 0) - die(EXIT_FAILURE, "bad curve in key `%s': %s", t.buf, e); - ds->g.g = group_ec(&ei); - ds->g.p = G_CREATE(ds->g.g); - if (G_FROMEC(ds->g.g, ds->g.p, y)) - die(EXIT_FAILURE, "bad public key in key `%s'", t.buf); - dsa_initcommon(ds, hc, t.buf); - dstr_destroy(&t); - return (ds); -} - -static sig *dsa_siginit(key *k, void *kd, const gchash *hc) -{ - dh_priv *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_prime, "prime"); - ds->g.u = MP_COPY(dp->x); - return (&ds->s); -} - -static sig *bindsa_siginit(key *k, void *kd, const gchash *hc) -{ - dh_priv *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_binary, "binary"); - ds->g.u = MP_COPY(dp->x); - return (&ds->s); -} - -static sig *ecdsa_siginit(key *k, void *kd, const gchash *hc) -{ - ec_priv *ep = kd; - dsa_sigctx *ds = ecdsa_doinit(k, ep->cstr, &ep->p, hc); - ds->g.u = MP_COPY(ep->x); - return (&ds->s); -} - -static int dsa_sigdoit(sig *s, dstr *d) -{ - dsa_sigctx *ds = (dsa_sigctx *)s; - gdsa_sig ss = GDSA_SIG_INIT; - size_t n = mp_octets(ds->g.g->r); - - gdsa_sign(&ds->g, &ss, GH_DONE(ds->s.h, 0), 0); - dstr_ensure(d, 2 * n); - mp_storeb(ss.r, d->buf, n); - mp_storeb(ss.s, d->buf + n, n); - d->len += 2 * n; - mp_drop(ss.r); mp_drop(ss.s); - return (0); -} - -static const char *dsa_sigcheck(sig *s) -{ - dsa_sigctx *ds = (dsa_sigctx *)s; - const char *e; - if ((e = G_CHECK(ds->g.g, &rand_global)) != 0) - return (0); - if (group_check(ds->g.g, ds->g.p)) - return ("public key not in subgroup"); - return (0); -} - -static void dsa_sigdestroy(sig *s) -{ - dsa_sigctx *ds = (dsa_sigctx *)s; - G_DESTROY(ds->g.g, ds->g.p); - mp_drop(ds->g.u); - G_DESTROYGROUP(ds->g.g); - DESTROY(ds); -} - -static const sigops dsa_sig = { - dh_privfetch, sizeof(dh_priv), - dsa_siginit, dsa_sigdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops bindsa_sig = { - dh_privfetch, sizeof(dh_priv), - bindsa_siginit, dsa_sigdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops ecdsa_sig = { - ec_privfetch, sizeof(ec_priv), - ecdsa_siginit, dsa_sigdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static sig *dsa_vrfinit(key *k, void *kd, const gchash *hc) -{ - dh_pub *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_prime, "prime"); - return (&ds->s); -} - -static sig *bindsa_vrfinit(key *k, void *kd, const gchash *hc) -{ - dh_pub *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_binary, "binary"); - return (&ds->s); -} - -static sig *ecdsa_vrfinit(key *k, void *kd, const gchash *hc) -{ - ec_pub *ep = kd; - dsa_sigctx *ds = ecdsa_doinit(k, ep->cstr, &ep->p, hc); - return (&ds->s); -} - -static int dsa_vrfdoit(sig *s, dstr *d) -{ - dsa_sigctx *ds = (dsa_sigctx *)s; - gdsa_sig ss; - size_t n = d->len/2; - int rc; - - ss.r = mp_loadb(MP_NEW, d->buf, n); - ss.s = mp_loadb(MP_NEW, d->buf + n, d->len - n); - rc = gdsa_verify(&ds->g, &ss, GH_DONE(ds->s.h, 0)); - mp_drop(ss.r); mp_drop(ss.s); - return (rc); -} - -static const sigops dsa_vrf = { - dh_pubfetch, sizeof(dh_pub), - dsa_vrfinit, dsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops bindsa_vrf = { - dh_pubfetch, sizeof(dh_pub), - bindsa_vrfinit, dsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops ecdsa_vrf = { - ec_pubfetch, sizeof(ec_pub), - ecdsa_vrfinit, dsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy -}; - -/* --- KCDSA and ECKCDSA --- */ - -static void kcdsa_privkey(dsa_sigctx *ds, mp *x) - { ds->g.u = mp_modinv(MP_NEW, x, ds->g.g->r); } - -static void kcdsa_sethash(dsa_sigctx *ds, const gchash *hc) - { ds->s.h = gkcdsa_beginhash(&ds->g); } - -static sig *kcdsa_siginit(key *k, void *kd, const gchash *hc) -{ - dh_priv *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_prime, "prime"); - kcdsa_privkey(ds, dp->x); - kcdsa_sethash(ds, hc); - return (&ds->s); -} - -static sig *binkcdsa_siginit(key *k, void *kd, const gchash *hc) -{ - dh_priv *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_binary, "binary"); - kcdsa_privkey(ds, dp->x); - kcdsa_sethash(ds, hc); - return (&ds->s); -} - -static sig *eckcdsa_siginit(key *k, void *kd, const gchash *hc) -{ - ec_priv *ep = kd; - dsa_sigctx *ds = ecdsa_doinit(k, ep->cstr, &ep->p, hc); - kcdsa_privkey(ds, ep->x); - kcdsa_sethash(ds, hc); - return (&ds->s); -} - -static int kcdsa_sigdoit(sig *s, dstr *d) -{ - dsa_sigctx *ds = (dsa_sigctx *)s; - gkcdsa_sig ss = GKCDSA_SIG_INIT; - size_t hsz = ds->g.h->hashsz, n = mp_octets(ds->g.g->r); - - gkcdsa_sign(&ds->g, &ss, GH_DONE(ds->s.h, 0), 0); - dstr_ensure(d, hsz + n); - memcpy(d->buf, ss.r, hsz); - mp_storeb(ss.s, d->buf + hsz, n); - d->len += hsz + n; - xfree(ss.r); mp_drop(ss.s); - return (0); -} - -static const sigops kcdsa_sig = { - dh_privfetch, sizeof(dh_priv), - kcdsa_siginit, kcdsa_sigdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops binkcdsa_sig = { - dh_privfetch, sizeof(dh_priv), - binkcdsa_siginit, kcdsa_sigdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops eckcdsa_sig = { - ec_privfetch, sizeof(ec_priv), - eckcdsa_siginit, kcdsa_sigdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static sig *kcdsa_vrfinit(key *k, void *kd, const gchash *hc) -{ - dh_pub *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_prime, "prime"); - kcdsa_sethash(ds, hc); - return (&ds->s); -} - -static sig *binkcdsa_vrfinit(key *k, void *kd, const gchash *hc) -{ - dh_pub *dp = kd; - dsa_sigctx *ds = dsa_doinit(k, &dp->dp, dp->y, hc, group_binary, "binary"); - kcdsa_sethash(ds, hc); - return (&ds->s); -} - -static sig *eckcdsa_vrfinit(key *k, void *kd, const gchash *hc) -{ - ec_pub *ep = kd; - dsa_sigctx *ds = ecdsa_doinit(k, ep->cstr, &ep->p, hc); - kcdsa_sethash(ds, hc); - return (&ds->s); -} - -static int kcdsa_vrfdoit(sig *s, dstr *d) -{ - dsa_sigctx *ds = (dsa_sigctx *)s; - gkcdsa_sig ss; - size_t hsz = ds->g.h->hashsz, n = d->len - hsz; - int rc; - - if (d->len < hsz) - return (-1); - ss.r = (octet *)d->buf; - ss.s = mp_loadb(MP_NEW, d->buf + hsz, n); - rc = gkcdsa_verify(&ds->g, &ss, GH_DONE(ds->s.h, 0)); - mp_drop(ss.s); - return (rc); -} - -static const sigops kcdsa_vrf = { - dh_pubfetch, sizeof(dh_pub), - kcdsa_vrfinit, kcdsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops binkcdsa_vrf = { - dh_pubfetch, sizeof(dh_pub), - binkcdsa_vrfinit, kcdsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy -}; - -static const sigops eckcdsa_vrf = { - ec_pubfetch, sizeof(ec_pub), - eckcdsa_vrfinit, kcdsa_vrfdoit, dsa_sigcheck, dsa_sigdestroy -}; - -/* --- Symmetric message authentication --- */ - -typedef struct mac_ctx { - sig s; - const gcmac *mc; - gmac *m; - key_packdef kp; - key_bin kb; -} mac_ctx; - -static sig *mac_init(key *k, void *kd, const gchash *hc) -{ - mac_ctx *m; - dstr d = DSTR_INIT; - int err; - const char *mm; - - m = CREATE(mac_ctx); - - key_fulltag(k, &d); - m->kp.e = KENC_BINARY; - m->kp.p = &m->kb; - m->kp.kd = 0; - - if ((mm = key_getattr(0 /*yik*/, k, "mac")) == 0) { - dstr_putf(&d, "%s-hmac", hc->name); - mm = d.buf; - } - if ((m->mc = gmac_byname(mm)) == 0) - die(EXIT_FAILURE, "unknown message authentication scheme `%s'", mm); - dstr_reset(&d); - - if ((err = key_unpack(&m->kp, kd, &d)) != 0) { - die(EXIT_FAILURE, "failed to unpack symmetric key `%s': %s", - d.buf, key_strerror(err)); - } - dstr_destroy(&d); - - if (keysz(m->kb.sz, m->mc->keysz) != m->kb.sz) { - die(EXIT_FAILURE, "bad key size %lu for `%s'", - (unsigned long)m->kb.sz, m->mc->name); - } - m->m = GM_KEY(m->mc, m->kb.k, m->kb.sz); - m->s.h = GM_INIT(m->m); - return (&m->s); -} - -static int mac_sigdoit(sig *s, dstr *d) -{ - mac_ctx *m = (mac_ctx *)s; - - dstr_ensure(d, m->mc->hashsz); - GH_DONE(m->s.h, d->buf); - d->len += m->mc->hashsz; - return (0); -} - -static int mac_vrfdoit(sig *s, dstr *d) -{ - mac_ctx *m = (mac_ctx *)s; - const octet *t; - - t = GH_DONE(m->s.h, 0); - if (d->len != m->mc->hashsz || memcmp(d->buf, t, d->len) != 0) - return (-1); - return (0); -} - -static const char *mac_check(sig *s) { return (0); } - -static void mac_destroy(sig *s) -{ - mac_ctx *m = (mac_ctx *)s; - GM_DESTROY(m->m); - key_unpackdone(&m->kp); -} - -static const sigops mac_sig = { - 0, 0, - mac_init, mac_sigdoit, mac_check, mac_destroy -}; - -static const sigops mac_vrf = { - 0, 0, - mac_init, mac_vrfdoit, mac_check, mac_destroy -}; - -/* --- The switch table --- */ - -const struct sigtab sigtab[] = { - { "rsapkcs1", &rsap1_sig, &rsap1_vrf, &sha }, - { "rsapss", &rsapss_sig, &rsapss_vrf, &sha }, - { "dsa", &dsa_sig, &dsa_vrf, &sha }, - { "bindsa", &bindsa_sig, &bindsa_vrf, &sha }, - { "ecdsa", &ecdsa_sig, &ecdsa_vrf, &sha }, - { "kcdsa", &kcdsa_sig, &kcdsa_vrf, &has160 }, - { "binkcdsa", &binkcdsa_sig, &binkcdsa_vrf, &has160 }, - { "eckcdsa", &eckcdsa_sig, &eckcdsa_vrf, &has160 }, - { "mac", &mac_sig, &mac_vrf, &rmd160 }, - { 0, 0, 0 } -}; - -/* --- @getsig@ --- * - * - * Arguments: @key *k@ = the key to load - * @const char *app@ = application name - * @int wantpriv@ = nonzero if we want to sign - * - * Returns: A signature-making thing. - * - * Use: Loads a key and starts hashing. - */ - -sig *getsig(key *k, const char *app, int wantpriv) -{ - const char *salg, *halg = 0; - dstr d = DSTR_INIT; - dstr t = DSTR_INIT; - char *p = 0; - const char *q; - sig *s; - size_t n; - const struct sigtab *st; - const sigops *so; - const gchash *ch; - void *kd; - int e; - key_packdef *kp; - - /* --- Setup stuff --- */ - - key_fulltag(k, &t); - - /* --- Get the signature algorithm --- * - * - * Take the attribute if it's there; otherwise use the key type. - */ - - n = strlen(app); - if ((q = key_getattr(0, k, "sig")) != 0) { - dstr_puts(&d, q); - p = d.buf; - } else if (strncmp(k->type, app, n) == 0 && k->type[n] == '-') { - dstr_puts(&d, k->type); - p = d.buf + n + 1; - } else - die(EXIT_FAILURE, "no signature algorithm for key `%s'", t.buf); - - /* --- Grab the hash algorithm --- * - * - * Grab it from the signature algorithm if it's there. But override that - * from the attribute. - */ - - salg = p; - if ((p = strchr(p, '/')) != 0) { - *p++ = 0; - halg = p; - } - if ((q = key_getattr(0, k, "hash")) != 0) - halg = q; - - /* --- Look up the algorithms in the table --- */ - - for (st = sigtab; st->name; st++) { - if (strcmp(st->name, salg) == 0) - goto s_found; - } - die(EXIT_FAILURE, "signature algorithm `%s' not found in key `%s'", - salg, t.buf); -s_found:; - if (!halg) - ch = st->ch; - else { - if ((ch = ghash_byname(halg)) == 0) { - die(EXIT_FAILURE, "hash algorithm `%s' not found in key `%s'", - halg, t.buf); - } - } - so = wantpriv ? st->signops : st->verifyops; - - /* --- Load the key --- */ - - if (!so->kf) { - kd = k->k; - key_incref(kd); - kp = 0; - } else { - kd = xmalloc(so->kdsz); - kp = key_fetchinit(so->kf, 0, kd); - if ((e = key_fetch(kp, k)) != 0) { - die(EXIT_FAILURE, "error fetching key `%s': %s", - t.buf, key_strerror(e)); - } - } - s = so->init(k, kd, ch); - if (!s->h) - s->h = GH_INIT(ch); - s->kp = kp; - s->ops = so; - s->kd = kd; - s->ch = ch; - - /* --- Free stuff up --- */ - - dstr_destroy(&d); - dstr_destroy(&t); - return (s); -} - -/* --- @freesig@ --- * - * - * Arguments: @sig *s@ = signature-making thing - * - * Returns: --- - * - * Use: Frees up a signature-making thing - */ - -void freesig(sig *s) -{ - GH_DESTROY(s->h); - if (!s->ops->kf) - key_drop(s->kd); - else { - key_fetchdone(s->kp); - xfree(s->kd); - } - s->ops->destroy(s); -} - -/*----- That's all, folks -------------------------------------------------*/