Much wider support for Catacomb in all its glory.
[catacomb-perl] / pubkey.xs
diff --git a/pubkey.xs b/pubkey.xs
new file mode 100644 (file)
index 0000000..ee98e5c
--- /dev/null
+++ b/pubkey.xs
@@ -0,0 +1,593 @@
+# ---?---
+#
+# $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 ----------------------------------------------------