Key mangling, and elliptic curves.
[catacomb-perl] / key.xs
diff --git a/key.xs b/key.xs
index 7f0f21d..d4162e9 100644 (file)
--- a/key.xs
+++ b/key.xs
@@ -1,6 +1,6 @@
 # ---?---
 #
-# $Id: key.xs,v 1.2 2004/04/08 01:36:21 mdw Exp $
+# $Id$
 #
 # Key-management interface
 #
 # 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::Key
+MODULE = Catacomb PACKAGE = Catacomb::Key PREFIX = key_
 
-MODULE = Catacomb PACKAGE = Catacomb::Key::Data
+bool
+key_chkident(me, p)
+       SV *me
+       char *p
+       C_ARGS:
+       p
+
+bool
+key_chkcomment(me, p)
+       SV *me
+       char *p
+       C_ARGS:
+       p
+
+time_t
+exp(k)
+       Key *k
+       CODE:
+       RETVAL = k->k->exp;
+       OUTPUT:
+       RETVAL
+
+time_t
+del(k)
+       Key *k
+       CODE:
+       RETVAL = k->k->del;
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+data(k)
+       Key *k
+       CODE:
+       RETVAL = &k->k->k;
+       OUTPUT:
+       RETVAL
+
+char *
+comment(k)
+       Key *k
+       CODE:
+       RETVAL = k->k->c;
+       OUTPUT:
+       RETVAL
+
+U32
+id(k)
+       Key *k
+       CODE:
+       RETVAL = k->k->id;
+       OUTPUT:
+       RETVAL
+
+char *
+tag(k)
+       Key *k
+       CODE:
+       RETVAL = k->k->tag;
+       OUTPUT:
+       RETVAL
+
+char *
+type(k)
+       Key *k
+       CODE:
+       RETVAL = k->k->type;
+       OUTPUT:
+       RETVAL
+
+KeyErr
+key_setcomment(k, p)
+       Key *k
+       char *p
+       C_ARGS:
+       k->kf, k->k, p
+
+KeyErr
+key_settag(k, p)
+       Key *k
+       char *p
+       C_ARGS:
+       k->kf, k->k, p
+
+KeyErr
+key_delete(k)
+       Key *k
+       C_ARGS:
+       k->kf, k->k
+
+SV *
+fulltag(k)
+       Key *k
+       PREINIT:
+       dstr d = DSTR_INIT;
+       CODE:
+       key_fulltag(k->k, &d);
+       RETVAL = newSVpv(d.buf, d.len);
+       dstr_destroy(&d);
+       OUTPUT:
+       RETVAL
+
+const char *
+key_getattr(k, a)
+       Key *k
+       char *a
+       C_ARGS:
+       k->kf, k->k, a
+
+KeyErr
+key_putattr(k, a, v)
+       Key *k
+       char *a
+       char *v
+       C_ARGS:
+       k->kf, k->k, a, v
+
+void
+attrlist(k)
+       Key *k
+       PREINIT:
+       key_attriter i;
+       const char *a, *v;
+       PPCODE:
+       for (key_mkattriter(&i, k->k); key_nextattr(&i, &a, &v); )
+         XPUSHs(sv_2mortal(newSVpv((char *)a, strlen(a))));
+
+bool
+expiredp(k)
+       Key *k
+       CODE:
+       RETVAL = key_expired(k->k);
+       OUTPUT:
+       RETVAL
+
+KeyErr
+key_expire(k)
+       Key *k
+       C_ARGS:
+       k->kf, k->k
+
+KeyErr
+key_used(k, t)
+       Key *k
+       time_t t
+       C_ARGS:
+       k->kf, k->k, t
+
+bool
+fingerprint(k, h, kfiltstr)
+       Key *k
+       ghash *h
+       char *kfiltstr
+       PREINIT:
+       key_filter kfilt;
+       dstr d = DSTR_INIT;
+       CODE:
+       if (!kfiltstr)
+         kfilt.f = kfilt.m = 0;
+       else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m))
+         croak("bad filter string `%s'", kfiltstr);
+       RETVAL = key_fingerprint(k->k, h, &kfilt);
+       OUTPUT:
+       RETVAL
+
+const char *
+key_strerror(me, err)
+       SV *me
+       int err
+       C_ARGS:
+       err
+
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data PREFIX = key_
+
+Key_Data *
+_new(me)
+       SV *me
+       CODE:
+       RETVAL = CREATE(key_data);
+       RETVAL->e = 0;
+       RETVAL->u.k.k = 0;
+       RETVAL->u.k.sz = 0;
+       OUTPUT:
+       RETVAL
+
+SV *
+destroy(kd)
+       Key_Data *kd
+       CODE:
+       key_destroy(kd);
+       XSRETURN_YES;
+
+SV *
+setbinary(kd, sv)
+       Key_Data *kd
+       SV *sv
+       PREINIT:
+       char *p;
+       STRLEN len;
+       CODE:
+       p = SvPV(sv, len);
+       key_binary(kd, p, len);
+       XSRETURN_YES;
+
+SV *
+setencrypted(kd, sv)
+       Key_Data *kd
+       SV *sv
+       PREINIT:
+       char *p;
+       STRLEN len;
+       CODE:
+       p = SvPV(sv, len);
+       key_encrypted(kd, p, len);
+       XSRETURN_YES;
+
+SV *
+setmp(kd, x)
+       Key_Data *kd
+       mp *x
+       CODE:
+       key_mp(kd, x);
+       XSRETURN_YES;
+
+SV *
+setstring(kd, p)
+       Key_Data *kd
+       char *p
+       CODE:
+       key_string(kd, p);
+       XSRETURN_YES;
+
+SV *
+setec(kd, p)
+       Key_Data *kd
+       EC_Point *p
+       CODE:
+       key_ec(kd, p);
+       XSRETURN_YES;
+
+U32
+flags(kd)
+       Key_Data *kd
+       CODE:
+       RETVAL = kd->e;
+       OUTPUT: 
+       RETVAL
+
+SV *
+getbinary(kd)
+       Key_Data *kd
+       CODE:
+       if ((kd->e & KF_ENCMASK) != KENC_BINARY)
+         croak("key is not binary");
+       RETVAL = newSVpv(kd->u.k.k, kd->u.k.sz);
+       OUTPUT:
+       RETVAL
+
+SV *
+getencrypted(kd)
+       Key_Data *kd
+       CODE:
+       if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
+         croak("key is not encrypted");
+       RETVAL = newSVpv(kd->u.k.k, kd->u.k.sz);
+       OUTPUT:
+       RETVAL
+
+mp *
+getmp(kd)
+       Key_Data *kd
+       CODE:
+       if ((kd->e & KF_ENCMASK) != KENC_MP)
+         croak("key is not bignum");
+       RETVAL = kd->u.m;
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+getec(kd)
+       Key_Data *kd
+       CODE:
+       if ((kd->e & KF_ENCMASK) != KENC_EC)
+         croak("key is not a curve point");
+       RETVAL = CREATE(ec);
+       EC_CREATE(RETVAL);
+       EC_COPY(RETVAL, &kd->u.e);
+       OUTPUT:
+       RETVAL
+
+char *
+getstring(kd)
+       Key_Data *kd
+       CODE:
+       if ((kd->e & KF_ENCMASK) != KENC_STRING)
+         croak("key is not string");
+       RETVAL = kd->u.p;
+       OUTPUT:
+       RETVAL
+
+SV *
+setstruct(kd)
+       Key_Data *kd
+       CODE:
+       key_structure(kd);
+       XSRETURN_YES;
+
+Key_Data *
+key_structfind(kd, tag)
+       Key_Data *kd
+       char *tag
+
+Key_Data *
+key_structcreate(kd, tag)
+       Key_Data *kd
+       char *tag
+
+void
+getstruct(kd)
+       Key_Data *kd
+       PREINIT:
+       sym_iter i;
+       key_struct *ks;
+       PPCODE:
+       if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
+         croak("key is not structured");
+       for (sym_mkiter(&i, &kd->u.s); ks = sym_next(&i); )
+         XPUSHs(RET(&ks->k, "Catacomb::Key::Data"));
+
+SV *
+structdel(kd, tag)
+       Key_Data *kd
+       char *tag
+       PREINIT:
+       key_struct *ks;
+       CODE:
+       if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
+         croak("key is not structured");
+       if ((ks = sym_find(&kd->u.s, tag, -1, 0, 0)) == 0)
+         XSRETURN_UNDEF;
+       sym_remove(&kd->u.s, ks);
+       XSRETURN_YES;
+
+void
+readflags(me, p)
+       SV *me
+       char *p
+       PREINIT:
+       unsigned f, m;
+       PPCODE:
+       if (key_readflags(p, &p, &f, &m) || *p)
+         croak("bad flags string");
+       XPUSHs(sv_2mortal(newSVuv(m)));
+       XPUSHs(sv_2mortal(newSVuv(f)));
+
+SV *
+getflags(me, f)
+       SV *me
+       U32 f
+       PREINIT:
+       dstr d = DSTR_INIT;
+       CODE:
+       key_writeflags(f, &d);
+       RETVAL = newSVpv(d.buf, d.len);
+       dstr_destroy(&d);
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+copy(kd, kfiltstr = 0)
+       Key_Data *kd
+       char *kfiltstr
+       PREINIT:
+       key_filter kfilt;
+       CODE:
+       if (!kfiltstr)
+         kfilt.f = kfilt.m = 0;
+       else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m))
+         croak("bad filter string `%s'", kfiltstr);
+       RETVAL = CREATE(key_data);
+       if (!key_copy(RETVAL, kd, &kfilt)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+plock(kd, tag)
+       Key_Data *kd
+       char *tag
+       CODE:
+       RETVAL = CREATE(Key_Data);
+       if (key_plock(tag, kd, RETVAL)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+punlock(kd, tag)
+       Key_Data *kd
+       char *tag
+       CODE:
+       RETVAL = CREATE(Key_Data);
+       if (key_punlock(tag, kd, RETVAL)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+read(me, p)
+       SV *me
+       char *p
+       CODE:
+       RETVAL = CREATE(key_data);
+       if (key_read(p, RETVAL, 0)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+SV *
+write(kd, kfiltstr = 0)
+       Key_Data *kd
+       char *kfiltstr
+       PREINIT:
+       key_filter kfilt;
+       dstr d = DSTR_INIT;
+       CODE:
+       if (!kfiltstr)
+         kfilt.f = kfilt.m = 0;
+       else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m))
+         croak("bad filter string `%s'", kfiltstr);
+       if (key_write(kd, &d, &kfilt))
+         RETVAL = newSVpv(d.buf, d.len);
+       else
+         RETVAL = &PL_sv_undef;
+       dstr_destroy(&d);
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+decode(me, sv)
+       SV *me
+       SV *sv
+       PREINIT:
+       char *p;
+       STRLEN len;
+       CODE:
+       p = SvPV(sv, len);
+       RETVAL = CREATE(key_data);
+       if (key_decode(p, len, RETVAL)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+SV *
+encode(kd, kfiltstr = 0)
+       Key_Data *kd
+       char *kfiltstr
+       PREINIT:
+       key_filter kfilt;
+       dstr d = DSTR_INIT;
+       CODE:
+       if (!kfiltstr)
+         kfilt.f = kfilt.m = 0;
+       else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m))
+         croak("bad filter string `%s'", kfiltstr);
+       if (key_encode(kd, &d, &kfilt))
+         RETVAL = newSVpv(d.buf, d.len);
+       else
+         RETVAL = &PL_sv_undef;
+       dstr_destroy(&d);
+       OUTPUT:
+       RETVAL
 
 MODULE = Catacomb PACKAGE = Catacomb::Key::File PREFIX = key_
 
 Key_File *
-new(file, how)
+new(me, file, how)
+       SV *me
        char *file
        unsigned how
        CODE:
@@ -49,9 +531,10 @@ DESTROY(kf)
        Key_File *kf
        CODE:
        key_close(kf);
+       DESTROY(kf);
        XSRETURN_UNDEF;
 
-KEYERR
+KeyErr
 merge(kf, name, fp)
        Key_File *kf
        char *name
@@ -61,7 +544,110 @@ merge(kf, name, fp)
        OUTPUT:
        RETVAL
 
-SV *
-extract
+bool
+extract(kf, k, fp, kfiltstr = 0)
+       Key_File *kf
+       Key *k
+       FILE *fp
+       char *kfiltstr
+       PREINIT:
+       key_filter kfilt;
+       CODE:
+       if (!kfiltstr)
+         kfilt.f = kfilt.m = 0;
+       else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m))
+         croak("bad filter string `%s'", kfiltstr);
+       RETVAL = key_extract(kf, k->k, fp, &kfilt);
+       OUTPUT:
+       RETVAL
+
+int
+key_save(kf)
+       Key_File *kf
+
+void
+qtag(kf, tag)
+       Key_File *kf
+       char *tag
+       PREINIT:
+       dstr d = DSTR_INIT;
+       Key *k;
+       key_data *kd;
+       PPCODE:
+       k = CREATE(Key);
+       kd = CREATE(key_data);
+       if (key_qtag(kf, tag, &d, &k->k, &kd)) {
+         DESTROY(k);
+         DESTROY(kd);
+         XPUSHs(&PL_sv_undef);
+         XPUSHs(&PL_sv_undef);
+         XPUSHs(&PL_sv_undef);
+       } else {
+         k->kf = kf;
+         XPUSHs(sv_2mortal(newSVpv(d.buf, d.len)));
+         XPUSHs(RET(k, "Catacomb::Key"));
+         XPUSHs(RET(k, "Catacomb::Key::Data"));
+       }
+       dstr_destroy(&d);
+
+Key *
+bytype(kf, type)
+       Key_File *kf
+       char *type
+       CODE:
+       RETVAL = CREATE(Key);
+       if ((RETVAL->k = key_bytype(kf, type)) != 0)
+         RETVAL->kf = kf;
+       else {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+Key *
+byid(kf, id)
+       Key_File *kf
+       U32 id
+       CODE:
+       RETVAL = CREATE(Key);
+       if ((RETVAL->k = key_byid(kf, id)) != 0)
+         RETVAL->kf = kf;
+       else {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+Key *
+bytag(kf, tag)
+       Key_File *kf
+       char *tag
+       CODE:
+       RETVAL = CREATE(Key);
+       if ((RETVAL->k = key_bytag(kf, tag)) != 0)
+         RETVAL->kf = kf;
+       else {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+void
+list(kf)
+       Key_File *kf
+       PREINIT:
+       key_iter i;
+       key *k;
+       Key *kk;
+       PPCODE:
+       for (key_mkiter(&i, kf); k = key_next(&i); ) {
+         kk = CREATE(Key);
+         kk->kf = kf;
+         kk->k = k;
+         XPUSHs(RET(kk, "Catacomb::Key"));
+       }
 
 #----- That's all, folks ----------------------------------------------------