X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-perl/blobdiff_plain/f9952aec1cf6c64a5681308eea817b6113a37433..fcd15e0b7a3d0f0ca2f30953573f8d1f6b8e8bd2:/pubkey.xs diff --git a/pubkey.xs b/pubkey.xs new file mode 100644 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 ----------------------------------------------------