--- /dev/null
+# ---?---
+#
+# $Id$
+#
+# Key-management interface
+#
+# (c) 2001 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Perl interface to Catacomb.
+#
+# Catacomb/Perl is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Catacomb/Perl 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Catacomb/Perl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+MODULE = Catacomb PACKAGE = Catacomb::PubKey
+
+void
+gen_dh(me, ql, pl, steps = 0, r = &rand_global, events = &PL_sv_undef)
+ SV *me
+ unsigned ql
+ unsigned pl
+ unsigned steps
+ grand *r
+ MP_Prime_Gen_NullProc *events
+ PREINIT:
+ dh_param dp;
+ pgen_proc *evproc;
+ void *evctx;
+ PPCODE:
+ pgproc_get(events, &evproc, &evctx);
+ if (dh_gen(&dp, ql, pl, steps, r, evproc, evctx))
+ XSRETURN_EMPTY;
+ XPUSHs(RET_MP(dp.p));
+ XPUSHs(RET_MP(dp.g));
+ XPUSHs(RET_MP(dp.q));
+
+void
+gen_limlee(me, ql, pl, flags = 0, steps = 0, r = &rand_global, oevents = &PL_sv_undef, ievents = &PL_sv_undef)
+ SV *me
+ unsigned ql
+ unsigned pl
+ unsigned flags
+ unsigned steps
+ grand *r
+ MP_Prime_Gen_NullProc *oevents
+ MP_Prime_Gen_NullProc *ievents
+ PREINIT:
+ dh_param dp;
+ pgen_proc *oev, *iev;
+ void *oec, *iec;
+ size_t nf;
+ mp **f;
+ size_t i;
+ PPCODE:
+ pgproc_get(oevents, &oev, &oec);
+ pgproc_get(ievents, &iev, &iec);
+ if (dh_limlee(&dp, ql, pl, flags, steps, r,
+ oev, oec, iev, iec, &nf, &f))
+ XSRETURN_EMPTY;
+ XPUSHs(RET_MP(dp.p));
+ XPUSHs(RET_MP(dp.g));
+ XPUSHs(RET_MP(dp.q));
+ for (i = 0; i < nf; i++)
+ XPUSHs(RET_MP(f[i]));
+ xfree(f);
+
+void
+gen_dsa(me, ql, pl, steps = 0, k = &PL_sv_undef, events = &PL_sv_undef)
+ SV *me
+ unsigned ql
+ unsigned pl
+ unsigned steps
+ SV *k
+ MP_Prime_Gen_NullProc *events
+ PREINIT:
+ char *kp;
+ STRLEN ksz;
+ dsa_seed ds;
+ dsa_param dp;
+ pgen_proc *evproc;
+ void *evctx;
+ char buf[20];
+ PPCODE:
+ if (SvOK(k))
+ kp = SvPV(k, ksz);
+ else {
+ kp = buf;
+ ksz = 20;
+ rand_get(RAND_GLOBAL, kp, ksz);
+ }
+ pgproc_get(events, &evproc, &evctx);
+ if (dsa_gen(&dp, ql, pl, steps, kp, ksz, &ds, evproc, evctx))
+ XSRETURN_EMPTY;
+ XPUSHs(RET_MP(dp.p));
+ XPUSHs(RET_MP(dp.g));
+ XPUSHs(RET_MP(dp.q));
+ XPUSHs(sv_2mortal(newSVpvn(ds.p, ds.sz)));
+ XPUSHs(sv_2mortal(newSViv(ds.count)));
+ xfree(ds.p);
+
+MODULE = Catacomb PACKAGE = Catacomb::DSA
+
+ghash *
+beginhash(c)
+ SV *c
+ PREINIT:
+ gdsa g;
+ CODE:
+ gdsa_pubfromsv(&g, c);
+ RETVAL = gdsa_beginhash(&g);
+ OUTPUT:
+ RETVAL
+
+SV *
+endhash(c, h)
+ SV *c
+ ghash *h
+ PREINIT:
+ gdsa g;
+ CODE:
+ gdsa_pubfromsv(&g, c);
+ gdsa_endhash(&g, h);
+ XSRETURN_YES;
+
+MODULE = Catacomb PACKAGE = Catacomb::DSA::Private
+
+void
+sign(c, m, k = 0)
+ SV *c
+ SV *m
+ mp *k
+ PREINIT:
+ gdsa g;
+ gdsa_sig s = GDSA_SIG_INIT;
+ char *p;
+ STRLEN len;
+ PPCODE:
+ gdsa_privfromsv(&g, c);
+ p = SvPV(m, len);
+ if (len != g.h->hashsz)
+ croak("bad message length");
+ gdsa_sign(&g, &s, p, k);
+ XPUSHs(MAKE_MP(s.r));
+ XPUSHs(MAKE_MP(s.s));
+
+MODULE = Catacomb PACKAGE = Catacomb::DSA::Public
+
+bool
+verify(c, m, r, s)
+ SV *c
+ mp *r
+ mp *s
+ SV *m
+ PREINIT:
+ gdsa g;
+ gdsa_sig ss = GDSA_SIG_INIT;
+ char *p;
+ STRLEN len;
+ CODE:
+ gdsa_pubfromsv(&g, c);
+ p = SvPV(m, len);
+ if (len != g.h->hashsz)
+ croak("bad message length");
+ ss.r = r;
+ ss.s = s;
+ RETVAL = !gdsa_verify(&g, &ss, p);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::KCDSA
+
+ghash *
+beginhash(c)
+ SV *c
+ PREINIT:
+ gkcdsa g;
+ CODE:
+ gdsa_pubfromsv(&g, c);
+ RETVAL = gkcdsa_beginhash(&g);
+ OUTPUT:
+ RETVAL
+
+SV *
+endhash(c, h)
+ SV *c
+ ghash *h
+ PREINIT:
+ gkcdsa g;
+ CODE:
+ gdsa_pubfromsv(&g, c);
+ gkcdsa_endhash(&g, h);
+ XSRETURN_YES;
+
+MODULE = Catacomb PACKAGE = Catacomb::KCDSA::Private
+
+void
+sign(c, m, k = 0)
+ SV *c
+ SV *m
+ mp *k
+ PREINIT:
+ gkcdsa g;
+ gkcdsa_sig s = GKCDSA_SIG_INIT;
+ char *p;
+ STRLEN len;
+ PPCODE:
+ gdsa_privfromsv(&g, c);
+ p = SvPV(m, len);
+ if (len != g.h->hashsz)
+ croak("bad message length");
+ gkcdsa_sign(&g, &s, p, k);
+ XPUSHs(sv_2mortal(newSVpvn(s.r, g.h->hashsz)));
+ XPUSHs(RET_MP(s.s));
+ xfree(s.r);
+
+MODULE = Catacomb PACKAGE = Catacomb::KCDSA::Public
+
+bool
+verify(c, m, r, s)
+ SV *c
+ SV *r
+ mp *s
+ SV *m
+ PREINIT:
+ gkcdsa g;
+ gkcdsa_sig ss = GKCDSA_SIG_INIT;
+ char *p;
+ STRLEN len;
+ CODE:
+ gdsa_pubfromsv(&g, c);
+ p = SvPV(m, len);
+ if (len != g.h->hashsz)
+ croak("bad message length");
+ ss.r = SvPV(r, len);
+ if (len != g.h->hashsz)
+ croak("bad signature (r) length");
+ ss.s = s;
+ RETVAL = !gkcdsa_verify(&g, &ss, p);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::RSA::Public PREFIX = rsa_
+
+RSA_Public *
+new(me, sv)
+ SV *me
+ SV *sv
+ PREINIT:
+ cursor c;
+ rsa_pub *rp;
+ CODE:
+ rp = CREATE(rsa_pub);
+ c_init(&c, sv);
+ rp->n = C_MP(&c, "n");
+ rp->e = C_MP(&c, "e");
+ RETVAL = CREATE(rsa_pubctx);
+ rsa_pubcreate(RETVAL, rp);
+ OUTPUT:
+ RETVAL
+
+mp *
+n(rp)
+ RSA_Public *rp
+ CODE:
+ RETVAL = MP_COPY(rp->rp->n);
+ OUTPUT:
+ RETVAL
+
+HV *
+extract(rp)
+ RSA_Public *rp
+ CODE:
+ RETVAL = newHV();
+ hvput(RETVAL, "n", MAKE_MP(rp->rp->n));
+ hvput(RETVAL, "e", MAKE_MP(rp->rp->e));
+ OUTPUT:
+ RETVAL
+
+SV *
+DESTROY(rp)
+ RSA_Public *rp
+ PREINIT:
+ rsa_pub *rrp;
+ CODE:
+ rrp = rp->rp;
+ rsa_pubdestroy(rp);
+ DESTROY(rp);
+ rsa_pubfree(rrp);
+ DESTROY(rrp);
+ XSRETURN_YES;
+
+mp *
+op(rp, p)
+ RSA_Public *rp
+ mp *p
+ CODE:
+ RETVAL = rsa_pubop(rp, MP_NEW, p);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::RSA::Private PREFIX = rsa_
+
+RSA_Private *
+new(me, sv)
+ SV *me
+ SV *sv
+ PREINIT:
+ cursor c;
+ rsa_priv *rp;
+ CODE:
+ c_init(&c, sv);
+ rp = CREATE(rsa_priv);
+ rp->n = C_MP(&c, "n");
+ rp->e = C_MP(&c, "e");
+ rp->d = C_MP(&c, "d");
+ rp->p = C_MP(&c, "p");
+ rp->q = C_MP(&c, "q");
+ rp->dp = C_MP(&c, "dp");
+ rp->dq = C_MP(&c, "dq");
+ rp->q_inv = C_MP(&c, "qi");
+ if (rsa_recover(rp))
+ croak("insuffcient values in Catacomb::RSA::Private::new");
+ RETVAL = CREATE(rsa_privctx);
+ rsa_privcreate(RETVAL, rp, &rand_global);
+ OUTPUT:
+ RETVAL
+
+RSA_Private *
+generate(me, nbits, r = &rand_global, n = 0, events = &PL_sv_undef)
+ SV *me
+ unsigned nbits
+ grand *r
+ unsigned n
+ MP_Prime_Gen_NullProc *events
+ PREINIT:
+ pgen_proc *ev;
+ void *ec;
+ rsa_priv *rp;
+ CODE:
+ rp = CREATE(rsa_priv);
+ pgproc_get(events, &ev, &ec);
+ if (rsa_gen(rp, nbits, r, n, ev, ec)) {
+ DESTROY(rp);
+ XSRETURN_UNDEF;
+ }
+ RETVAL = CREATE(rsa_privctx);
+ rsa_privcreate(RETVAL, rp, &rand_global);
+ OUTPUT:
+ RETVAL
+
+HV *
+extract(rp)
+ RSA_Private *rp
+ CODE:
+ RETVAL = newHV();
+ hvput(RETVAL, "n", MAKE_MP(rp->rp->n));
+ hvput(RETVAL, "e", MAKE_MP(rp->rp->e));
+ hvput(RETVAL, "d", MAKE_MP(rp->rp->d));
+ hvput(RETVAL, "p", MAKE_MP(rp->rp->p));
+ hvput(RETVAL, "q", MAKE_MP(rp->rp->q));
+ hvput(RETVAL, "dp", MAKE_MP(rp->rp->dp));
+ hvput(RETVAL, "dq", MAKE_MP(rp->rp->dq));
+ hvput(RETVAL, "qi", MAKE_MP(rp->rp->q_inv));
+ OUTPUT:
+ RETVAL
+
+mp *
+n(rp)
+ RSA_Private *rp
+ CODE:
+ RETVAL = MP_COPY(rp->rp->n);
+ OUTPUT:
+ RETVAL
+
+SV *
+DESTROY(rp)
+ RSA_Private *rp
+ PREINIT:
+ rsa_priv *rrp;
+ CODE:
+ rp->r = &rand_global;
+ rrp = rp->rp;
+ rsa_privdestroy(rp);
+ DESTROY(rp);
+ rsa_privfree(rrp);
+ DESTROY(rrp);
+ XSRETURN_YES;
+
+mp *
+op(rp, p, r = &PL_sv_undef)
+ RSA_Private *rp
+ mp *p
+ SV *r
+ CODE:
+ rp->r = SvOK(r) ? ptrfromsv(r, "Catacomb::Rand", "r") : 0;
+ RETVAL = rsa_privop(rp, MP_NEW, p);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::RSA::PKCS1Crypt
+
+mp *
+pad(c, m, sz, nbits)
+ SV *c
+ SV *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ pkcs1 pc;
+ void *b;
+ void *mm;
+ STRLEN msz;
+ CODE:
+ pkcs1_fromsv(&pc, c);
+ mm = SvPV(m, msz);
+ b = xmalloc(sz);
+ RETVAL = pkcs1_cryptencode(MP_NEW, mm, msz, b, sz, nbits, &pc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+SV *
+unpad(c, m, sz, nbits)
+ SV *c
+ mp *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ pkcs1 pc;
+ void *b;
+ int rc;
+ CODE:
+ pkcs1_fromsv(&pc, c);
+ b = xmalloc(sz);
+ rc = pkcs1_cryptdecode(m, b, sz, nbits, &pc);
+ if (rc < 0)
+ RETVAL = &PL_sv_undef;
+ else
+ RETVAL = newSVpvn(b, rc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::RSA::PKCS1Sign
+
+mp *
+pad(c, m, sz, nbits)
+ SV *c
+ SV *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ pkcs1 pc;
+ void *b;
+ void *mm;
+ STRLEN msz;
+ CODE:
+ pkcs1_fromsv(&pc, c);
+ mm = SvPV(m, msz);
+ b = xmalloc(sz);
+ RETVAL = pkcs1_sigencode(MP_NEW, mm, msz, b, sz, nbits, &pc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+SV *
+unpad(c, s, m, sz, nbits)
+ SV *c
+ mp *s
+ SV *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ pkcs1 pc;
+ void *b;
+ void *mm;
+ STRLEN msz;
+ int rc;
+ CODE:
+ pkcs1_fromsv(&pc, c);
+ mm = SvPV(m, msz);
+ b = xmalloc(sz);
+ rc = pkcs1_sigdecode(s, mm, msz, b, sz, nbits, &pc);
+ if (rc < 0) XSRETURN_UNDEF;
+ RETVAL = newSVpvn(b, rc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::RSA::OAEP
+
+mp *
+pad(c, m, sz, nbits)
+ SV *c
+ SV *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ oaep pc;
+ void *b;
+ void *mm;
+ STRLEN msz;
+ CODE:
+ oaep_fromsv(&pc, c);
+ mm = SvPV(m, msz);
+ b = xmalloc(sz);
+ RETVAL = oaep_encode(MP_NEW, mm, msz, b, sz, nbits, &pc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+SV *
+unpad(c, m, sz, nbits)
+ SV *c
+ mp *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ oaep pc;
+ void *b;
+ int rc;
+ CODE:
+ oaep_fromsv(&pc, c);
+ b = xmalloc(sz);
+ rc = oaep_decode(m, b, sz, nbits, &pc);
+ if (rc < 0)
+ RETVAL = &PL_sv_undef;
+ else
+ RETVAL = newSVpvn(b, rc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::RSA::PSS
+
+mp *
+pad(c, m, sz, nbits)
+ SV *c
+ SV *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ pss pc;
+ void *b;
+ void *mm;
+ STRLEN msz;
+ CODE:
+ pss_fromsv(&pc, c);
+ mm = SvPV(m, msz);
+ b = xmalloc(sz);
+ RETVAL = pss_encode(MP_NEW, mm, msz, b, sz, nbits, &pc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+SV *
+unpad(c, s, m, sz, nbits)
+ SV *c
+ mp *s
+ SV *m
+ size_t sz
+ unsigned long nbits
+ PREINIT:
+ pss pc;
+ void *b;
+ void *mm;
+ STRLEN msz;
+ int rc;
+ CODE:
+ pss_fromsv(&pc, c);
+ mm = SvPV(m, msz);
+ b = xmalloc(sz);
+ rc = pss_decode(s, mm, msz, b, sz, nbits, &pc);
+ if (rc < 0) XSRETURN_UNDEF;
+ RETVAL = newSVpvn(b, rc);
+ xfree(b);
+ OUTPUT:
+ RETVAL
+
+#----- That's all, folks ----------------------------------------------------