Update for new keydata interface.
authormdw <mdw>
Tue, 27 Sep 2005 11:19:36 +0000 (11:19 +0000)
committermdw <mdw>
Tue, 27 Sep 2005 11:19:36 +0000 (11:19 +0000)
13 files changed:
Catacomb/Key.pm
Catacomb/MP.pm
Catacomb::MP::Prime.pod
algs.PL
catacomb-perl.h
catacomb.xs
ec.xs
group.xs
key.xs
keystuff.c
pubkey.xs
t/key.t
typemap

index 6f84492..8f97126 100644 (file)
 
 #----- Key data -------------------------------------------------------------
 
-package Catacomb::Key::StructData;
+package Catacomb::Key::Data::StructTie;
 use Carp;
 use Catacomb::Base;
 
 sub TIEHASH { bless [$_[1], []], $_[0]; }
-sub FETCH { Catacomb::Key::Data::StructItem->new($_[0][0], $_[1]); }
-sub EXISTS { !!$_[0][0]->_get->structfind($_[1]); }
-sub DELETE { $_[0][0]->_get->structdel($_[1]); }
-sub CLEAR { $_[0][0]->_get()->setstruct(); }
-sub STORE {
-  my ($me, $k, $v) = @_;
-  $me->[0]->_get()->structcreate($k)->set($v);
+sub FETCH { $_[0][0]->find($_[1]); }
+sub EXISTS { !!$_[0][0]->find($_[1]); }
+sub DELETE { $_[0][0]->del($_[1]); }
+sub STORE { $_[0][0]->find($_[1], $_[2]); }
+
+sub CLEAR {
+  my ($me) = @_;
+  my $kd = $me->[0];
+  my $i = $kd->iterate();
+  $kd->del($k) while my $k = $i->next();
+  1;
 }
+
 sub FIRSTKEY {
   my ($me) = @_;
-  my $kd = $me->[0]->_get();
-  my $i = $kd->structiter();
+  my $kd = $me->[0];
+  my $i = $kd->iterate();
   my @k = ();
   while (my $k = $i->next()) {
     push(@k, $k);
@@ -53,79 +58,12 @@ sub FIRSTKEY {
 }
 sub NEXTKEY { shift(@{$_[0][1]}); }
 
-package Catacomb::Key::DataRef;
-use Carp;
-use Catacomb::Base;
-use Catacomb::MP;
-use Catacomb::EC;
-sub _adopt {
-  my $kd = shift;
-  defined($kd) or return;
-  $kd = bless [$kd], Catacomb::Key::Data;
-  return wantarray ? ($kd, @_) : $kd;
-}
-sub new { my $me = shift(@_); bless [@_], $me; }
-sub _proxy { my ($op, $kd, @args) = @_; &$op($kd->_get(), @args); }
-
-sub setbinary { _proxy(\&Catacomb::Key::DataImpl::setbinary, @_); }
-sub setencrypted { _proxy(\&Catacomb::Key::DataImpl::setencrypted, @_); }
-sub setmp { _proxy(\&Catacomb::Key::DataImpl::setec, @_); }
-sub setstring { _proxy(\&Catacomb::Key::DataImpl::setstring, @_); }
-sub setec { _proxy(\&Catacomb::Key::DataImpl::setec, @_); }
+package Catacomb::Key::Data::Structured;
+sub open {  my %h; tie %h, Catacomb::Key::Data::StructTie, $_[0]; \%h; }
 
-sub flags { _proxy(\&Catacomb::Key::DataImpl::flags, @_); }
-
-sub getbinary { _proxy(\&Catacomb::Key::DataImpl::getbinary, @_); }
-sub getencrypted { _proxy(\&Catacomb::Key::DataImpl::getencrypted, @_); }
-sub getmp { _proxy(\&Catacomb::Key::DataImpl::getmp, @_); }
-sub getstring { _proxy(\&Catacomb::Key::DataImpl::getstring, @_); }
-sub getec { _proxy(\&Catacomb::Key::DataImpl::getec, @_); }
-
-sub setstruct { _proxy(\&Catacomb::Key::DataImpl::setstruct, @_); }
-sub structfind { Catacomb::Key::Data::StructItem->new($_[0], $_[1]); }
-sub structcreate {
-  _proxy(\&Catacomb::Key::DataImpl::structcreate, @_);
-  Catacomb::Key::Data::StructItem->new($_[0], $_[1]);
-}
-sub structiter { _proxy(\&Catacomb::Key::DataImpl::structiter, @_); }
-sub structdel { _proxy(\&Catacomb::Key::DataImpl::structdel, @_); }
-sub structopen {  my %h; tie %h, Catacomb::Key::StructData, $_[0]; \%h; }
-
-sub copy {
-  croak("Usage: Catacomb::Key::Data::Ref::copy(kd, kkd, [filter])")
-    unless @_ >= 2 && @_ <= 3;
-  my $kd = Catacomb::Key::Data->new();
-  $kd->_get()->set($_[0]->_get(), $_[1]);
-  return $kd;
+foreach $i (qw(Binary Encrypted MP EC String Structured)) {
+  @{"Catacomb::Key::Data::${i}::ISA"} = qw(Catacomb::Key::Data);
 }
-sub lock { _adopt(_proxy(\&Catacomb::Key::DataImpl::lock, @_)); }
-sub unlock { _adopt(_proxy(\&Catacomb::Key::DataImpl::unlock, @_)); }
-sub plock { _adopt(_proxy(\&Catacomb::Key::DataImpl::plock, @_)); }
-sub punlock { _adopt(_proxy(\&Catacomb::Key::DataImpl::punlock, @_)); }
-sub read { _adopt(Catacomb::Key::DataImpl::read(@_)); }
-sub write { _proxy(\&Catacomb::Key::DataImpl::write, @_); }
-sub decode { _adopt(Catacomb::Key::DataImpl::decode(@_)); }
-sub encode { _proxy(\&Catacomb::Key::DataImpl::encode, @_); }
-
-package Catacomb::Key::Data;
-use Carp;
-@ISA = qw(Catacomb::Key::DataRef);
-sub _get { $_[0][0]; }
-## Perl will randomly zap my reference during cleanup.  Just pretend
-## we didn't notice.
-sub DESTROY { $_[0][0]->free() if defined $_[0][0]; }
-sub new {
-  croak("Usage: Catacomb::Key::Data::new(me)") unless @_ == 1;
-  Catacomb::Key::DataRef::_adopt(Catacomb::Key::DataImpl->new());
-}
-
-package Catacomb::Key::Data::StructItem;
-@ISA = qw(Catacomb::Key::DataRef);
-sub _get { $_[0][0]->_get()->structfind($_[0][1]); }
-
-package Catacomb::Key::Data::KeyData;
-@ISA = qw(Catacomb::Key::DataRef);
-sub _get { $_[0][0]->_data(); }
 
 #----- Actual keys ----------------------------------------------------------
 
@@ -157,33 +95,6 @@ sub attrs {
   return \%a;
 }
 
-sub data {
-  croak("Usage: Catacomb::Key::data(k)") unless @_ == 1;
-  return Catacomb::Key::Data::KeyData->new($_[0]);
-}
-
-package Catacomb::Key::File;
-use Carp;
-use Catacomb::Base;
-
-sub qtag {
-  croak("Usage: Catacomb::Key::File::qtag(kf, tag)") unless @_ == 2;
-  my ($kf, $tag) = @_;
-  my @q = ();
-  if ($tag =~ /^([^.]*)\.(.*)$/) {
-    $tag = $1;
-    @q = split(/\./, $2);
-  }
-  my $k = $kf->bytag($tag) or return;
-  my $d = $k->data();
-  my $f = $k->fulltag();
-  foreach my $t (@q) {
-    $d = $d->structfind($t) or return;
-    $f .= "." . $t;
-  }
-  return $k, $d, $f;
-}
-
 #----- That's all, folks ----------------------------------------------------
 
 1;
index 0341626..9a43807 100644 (file)
@@ -33,12 +33,12 @@ use Catacomb::Rand;
 use Catacomb::Field;
 use Carp;
 
-sub mp { new(Catacomb::MP, $_[0]); }
+sub mp { new(Catacomb::MP, @_); }
 sub mp_loadb { loadb(Catacomb::MP, $_[0]); }
 sub mp_loadl { loadl(Catacomb::MP, $_[0]); }
 sub mp_loadb2c { loadb2c(Catacomb::MP, $_[0]); }
 sub mp_loadl2c { loadl2c(Catacomb::MP, $_[0]); }
-sub mp_fromstring { fromstring(Catacomb::MP, $_[0]); }
+sub mp_fromstring { fromstring(Catacomb::MP, @_); }
 
 sub mod { (&div($_[0], $_[1]))[1]; }
 
index 8bd543b..7f856d4 100644 (file)
@@ -512,7 +512,6 @@ long job.
     sub PG_TRY {
       my ($me, $ev) = @_;
       my $r = $ev->rand();
-      my $w = $r->mprange($me->[0]->m());
       return _test($r, $me->[0]) && _test($r, $me->[1]) ? 
         PGEN_PASS : PGEN_FAIL;
     }
diff --git a/algs.PL b/algs.PL
index cab2dc5..e7b7418 100644 (file)
--- a/algs.PL
+++ b/algs.PL
@@ -38,7 +38,8 @@
 @stream = qw(rc4 seal);
 @hash = qw(md5 md4 md2 tiger has160
           sha sha224 sha256 sha384 sha512 
-          rmd128 rmd160 rmd256 rmd320);
+          rmd128 rmd160 rmd256 rmd320
+           whirlpool whirlpool256);
 
 sub enum {
   $x = shift;
index ef36efc..acfff02 100644 (file)
 
 /*----- Header files ------------------------------------------------------*/
 
-#include <assert.h>
-
 #include <EXTERN.h>
 #include <perl.h>
 #include <XSUB.h>
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -186,7 +185,7 @@ typedef struct Key_AttrIter {
 } Key_AttrIter;
 
 typedef int KeyErr;
-typedef key_data Key_DataImpl;
+typedef key_data Key_Data;
 typedef struct Key_FileIter {
   Key_File *kf;
   key_iter i;
@@ -195,6 +194,7 @@ typedef sym_iter Key_StructIter;
 typedef key_filter Key_Filter;
 
 extern void keyreport(const char *file, int line, const char *err, void *p);
+extern const char *keydata_type(Key_Data *kd);
 extern SV *keyerr(int rc);
 
 /*------ Multiprecision maths ---------------------------------------------*/
index 5bcc441..102ee4d 100644 (file)
@@ -38,7 +38,7 @@ const struct consttab ct[] = {
     C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
   C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB),
     C(KCAT_SHARE), C(KF_NONSECRET),
-  C(KF_BURN), C(KF_TEMP), C(KF_OPT),
+  C(KF_BURN), C(KF_OPT),
   C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_MASK), C(KOPEN_NOFILE),
   C(KEXP_FOREVER), C(KEXP_EXPIRE),
   C(KERR_OK), C(KERR_BADTAG), C(KERR_BADTYPE), C(KERR_BADCOMMENT),
diff --git a/ec.xs b/ec.xs
index 83d1f72..7507c8f 100644 (file)
--- a/ec.xs
+++ b/ec.xs
@@ -123,7 +123,7 @@ get(s)
        else {
          XPUSHs(RET(p, "Catacomb::EC::Point"));
          if (GIMME_V == G_ARRAY)
-           XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+           XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b))));
        }
 
 MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_
@@ -252,7 +252,7 @@ _getraw(c, s)
        else {
          XPUSHs(RET(p, "Catacomb::EC::Point"));
          if (GIMME_V == G_ARRAY)
-           XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+           XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b))));
        }
 
 ec *
index 51af11c..a329c82 100644 (file)
--- a/group.xs
+++ b/group.xs
@@ -354,7 +354,7 @@ _getbuf(g, s)
        else {
          XPUSHs(RET(x, "Catacomb::Group::Element"));
          if (GIMME_V == G_ARRAY)
-           XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+           XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b))));
        }
 
 SV *
@@ -391,7 +391,7 @@ _getraw(g, s)
        else {
          XPUSHs(RET(x, "Catacomb::Group::Element"));
          if (GIMME_V == G_ARRAY)
-           XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+           XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b))));
        }
 
 SV *
diff --git a/key.xs b/key.xs
index d14ad70..db58921 100644 (file)
--- a/key.xs
+++ b/key.xs
@@ -65,11 +65,21 @@ del(k)
        OUTPUT:
        RETVAL
 
-Key_DataImpl *
-_data(k)
+Key_Data *
+data(k)
        Key *k
        CODE:
-       RETVAL = &k->k->k;
+       RETVAL = k->k->k;
+       key_incref(RETVAL);
+       OUTPUT:
+       RETVAL
+
+KeyErr
+setdata(k, kd)
+       Key *k
+       Key_Data *kd
+       CODE:
+       RETVAL = key_setkeydata(&k->kf->kf, k->k, kd);
        OUTPUT:
        RETVAL
 
@@ -296,366 +306,345 @@ m(kf)
        OUTPUT:
        RETVAL
 
-MODULE = Catacomb PACKAGE = Catacomb::Key::DataImpl PREFIX = key_
-
-Key_DataImpl *
-new(me)
-       SV *me
-       CODE:
-       RETVAL = CREATE(key_data);
-       RETVAL->e = 0;
-       RETVAL->u.k.k = 0;
-       RETVAL->u.k.sz = 0;
-       OUTPUT:
-       RETVAL
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data PREFIX = key_
 
 SV *
-free(kd)
-       Key_DataImpl *kd
+DESTROY(kd)
+       Key_Data *kd
        CODE:
-       key_destroy(kd);
-       DESTROY(kd);
+       key_drop(kd);
        XSRETURN_YES;
 
-SV *
-clear(kd)
-       Key_DataImpl *kd
+U32
+flags(kd)
+       Key_Data *kd
        CODE:
-       key_destroy(kd);
-       kd->e = 0;
-       kd->u.k.k = 0;
-       kd->u.k.sz = 0;
-       XSRETURN_YES;
+       RETVAL = kd->e;
+       OUTPUT: 
+       RETVAL
 
-SV *
-setbinary(kd, sv)
-       Key_DataImpl *kd
-       SV *sv
+void
+readflags(me, p)
+       SV *me
+       char *p
        PREINIT:
-       char *p;
-       STRLEN len;
-       CODE:
-       p = SvPV(sv, len);
-       key_destroy(kd);
-       key_binary(kd, p, len);
-       XSRETURN_YES;
+       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 *
-setencrypted(kd, sv)
-       Key_DataImpl *kd
-       SV *sv
+getflags(me, f)
+       SV *me
+       U32 f
        PREINIT:
-       char *p;
-       STRLEN len;
+       dstr d = DSTR_INIT;
        CODE:
-       p = SvPV(sv, len);
-       key_destroy(kd);
-       key_encrypted(kd, p, len);
-       XSRETURN_YES;
+       key_writeflags(f, &d);
+       RETVAL = newSVpvn(d.buf, d.len);
+       dstr_destroy(&d);
+       OUTPUT:
+       RETVAL
 
 SV *
-setmp(kd, x)
-       Key_DataImpl *kd
-       mp *x
+setflags(kd, f)
+       Key_Data *kd
+       U32 f
        CODE:
-       key_destroy(kd);
-       key_mp(kd, x);
+       kd->e = (kd->e & KF_ENCMASK) | (f & ~KF_ENCMASK);
        XSRETURN_YES;
 
-SV *
-setstring(kd, p)
-       Key_DataImpl *kd
+void
+read(me, p)
+       SV *me
        char *p
-       CODE:
-       key_destroy(kd);
-       key_string(kd, p);
-       XSRETURN_YES;
+       PREINIT:
+       key_data *kd;
+       char *pp;
+       PPCODE:
+       if ((kd = key_read(p, &pp)) != 0) {
+         XPUSHs(RET(kd, keydata_type(kd)));
+         if (GIMME_V == G_ARRAY)
+           XPUSHs(sv_2mortal(newSVpvn(pp, strlen(pp))));
+       }
 
 SV *
-setec(kd, p)
-       Key_DataImpl *kd
-       ec *p
-       CODE:
-       key_destroy(kd);
-       key_ec(kd, p);
-       XSRETURN_YES;
-
-U32
-flags(kd)
-       Key_DataImpl *kd
+write(kd, kf = 0)
+       Key_Data *kd
+       Key_Filter *kf
+       PREINIT:
+       dstr d = DSTR_INIT;
        CODE:
-       RETVAL = kd->e;
-       OUTPUT: 
+       if (key_write(kd, &d, kf))
+         RETVAL = newSVpvn(d.buf, d.len);
+       else
+         RETVAL = &PL_sv_undef;
+       dstr_destroy(&d);
+       OUTPUT:
        RETVAL
 
-SV *
-setflags(kd, f)
-       Key_DataImpl *kd
-       U32 f
-       CODE:
-       if (f & KF_ENCMASK)
-         croak("can't change encoding flags");
-       kd->e = (kd->e & KF_ENCMASK) | (f & ~KF_ENCMASK);
-       XSRETURN_YES;
-
-SV *
-getbinary(kd)
-       Key_DataImpl *kd
+Key_Data *
+decode(me, sv)
+       SV *me
+       SV *sv
+       PREINIT:
+       char *p;
+       STRLEN len;
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_BINARY)
-         croak("key is not binary");
-       RETVAL = newSVpvn(kd->u.k.k, kd->u.k.sz);
+       p = SvPV(sv, len);
+       RETVAL = key_decode(p, len);
        OUTPUT:
        RETVAL
 
 SV *
-getencrypted(kd)
-       Key_DataImpl *kd
+encode(kd, kf = 0)
+       Key_Data *kd
+       Key_Filter *kf
+       PREINIT:
+       dstr d = DSTR_INIT;
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
-         croak("key is not encrypted");
-       RETVAL = newSVpvn(kd->u.k.k, kd->u.k.sz);
+       if (key_encode(kd, &d, kf))
+         RETVAL = newSVpvn(d.buf, d.len);
+       else
+         RETVAL = &PL_sv_undef;
+       dstr_destroy(&d);
        OUTPUT:
        RETVAL
 
-mp *
-getmp(kd)
-       Key_DataImpl *kd
+Key_Data *
+lock(kd, key)
+       Key_Data *kd
+       SV *key
+       PREINIT:
+       STRLEN len;
+       char *p;
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_MP)
-         croak("key is not bignum");
-       RETVAL = MP_COPY(kd->u.m);
+       p = SvPV(key, len);
+       key_lock(&RETVAL, kd, p, len);
        OUTPUT:
        RETVAL
 
-ec *
-getec(kd)
-       Key_DataImpl *kd
+Key_Data *
+plock(kd, tag)
+       Key_Data *kd
+       char *tag
+       PREINIT:
+       int rc;
        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);
+       if ((rc = key_plock(&RETVAL, kd, tag)) != 0) {
+         keyerr(rc);
+         RETVAL = 0;
+       }
        OUTPUT:
        RETVAL
 
-char *
-getstring(kd)
-       Key_DataImpl *kd
+bool
+key_match(kd, kf)
+       Key_Data *kd
+       Key_Filter *kf
+
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data::Binary PREFIX = key_
+
+Key_Data *
+new(me, sv, f = 0)
+       SV *me
+       SV *sv
+       unsigned f
+       PREINIT:
+       char *p;
+       STRLEN len;
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_STRING)
-         croak("key is not string");
-       RETVAL = kd->u.p;
+       p = SvPV(sv, len);
+       RETVAL = key_newbinary(f, p, len);
        OUTPUT:
        RETVAL
 
 SV *
-setstruct(kd)
-       Key_DataImpl *kd
+bin(kd)
+       Key_Data *kd
        CODE:
-       key_destroy(kd);
-       key_structure(kd);
-       XSRETURN_YES;
-
-Key_DataImpl *
-key_structfind(kd, tag)
-       Key_DataImpl *kd
-       char *tag
-       INIT:
-       if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
-         XSRETURN_UNDEF;
+       RETVAL = newSVpvn((char *)kd->u.k.k, kd->u.k.sz);
+       OUTPUT:
+       RETVAL
 
-Key_DataImpl *
-key_structcreate(kd, tag)
-       Key_DataImpl *kd
-       char *tag
-       INIT:
-       if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
-         croak("key is not structured");
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data::Encrypted PREFIX = key_
 
-Key_StructIter *
-structiter(kd)
-       Key_DataImpl *kd
+Key_Data *
+new(me, sv, f = 0)
+       SV *me
+       SV *sv
+       unsigned f
+       PREINIT:
+       char *p;
+       STRLEN len;
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
-         croak("key is not structured");
-       RETVAL = CREATE(Key_StructIter);
-       sym_mkiter(RETVAL, &kd->u.s);
+       p = SvPV(sv, len);
+       RETVAL = key_newencrypted(f, p, len);
        OUTPUT:
        RETVAL
 
 SV *
-structdel(kd, tag)
-       Key_DataImpl *kd
-       char *tag
-       PREINIT:
-       key_struct *ks;
+ct(kd)
+       Key_Data *kd
        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;
-       key_destroy(&ks->k);
-       sym_remove(&kd->u.s, ks);
-       XSRETURN_YES;
-
-bool
-key_match(kd, kf)
-       Key_DataImpl *kd
-       Key_Filter *kf
-
-bool
-set(kd, kkd, kf = 0)
-       Key_DataImpl *kd
-       Key_DataImpl *kkd
-       Key_Filter *kf
-       CODE:
-       key_destroy(kd);
-       kd->e = 0;
-       kd->u.k.k = 0;
-       kd->u.k.sz = 0;
-       RETVAL = key_copy(kd, kkd, kf);
+       RETVAL = newSVpvn((char *)kd->u.k.k, kd->u.k.sz);
        OUTPUT:
        RETVAL
 
-Key_DataImpl *
+SV *
 lock(kd, key)
-       Key_DataImpl *kd
+       Key_Data *kd
        SV *key
-       PREINIT:
-       STRLEN len;
-       char *p;
        CODE:
-       if ((kd->e & KF_ENCMASK) == KENC_ENCRYPT)
-         croak("already encrypted");
-       RETVAL = CREATE(Key_DataImpl);
-       p = SvPV(key, len);
-       key_lock(RETVAL, kd, p, len);
-       OUTPUT:
-       RETVAL
+       croak("already encrypted");
+
+SV *
+plock(kd, tag)
+       Key_Data *kd
+       char *tag
+       CODE:
+       croak("already encrypted");
 
-Key_DataImpl *
+Key_Data *
 unlock(kd, key)
-       Key_DataImpl *kd
+       Key_Data *kd
        SV *key
        PREINIT:
        STRLEN len;
        char *p;
        int rc;
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
-         croak("not encrypted");
-       RETVAL = CREATE(Key_DataImpl);
        p = SvPV(key, len);
-       if ((rc = key_unlock(RETVAL, kd, p, len)) != 0) {
-         DESTROY(RETVAL);
+       if ((rc = key_unlock(&RETVAL, kd, p, len)) != 0) {
          keyerr(rc);
          RETVAL = 0;
        }
        OUTPUT:
        RETVAL
 
-Key_DataImpl *
-plock(kd, tag)
-       Key_DataImpl *kd
+Key_Data *
+punlock(kd, tag)
+       Key_Data *kd
        char *tag
        PREINIT:
        int rc;
        CODE:
-       if ((kd->e & KF_ENCMASK) == KENC_ENCRYPT)
-         croak("already encrypted");
-       RETVAL = CREATE(Key_DataImpl);
-       if ((rc = key_plock(tag, kd, RETVAL)) != 0) {
-         DESTROY(RETVAL);
+       if ((rc = key_punlock(&RETVAL, kd, tag)) != 0) {
          keyerr(rc);
          RETVAL = 0;
        }
        OUTPUT:
        RETVAL
 
-Key_DataImpl *
-punlock(kd, tag)
-       Key_DataImpl *kd
-       char *tag
-       PREINIT:
-       int rc;
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data::MP PREFIX = key_
+
+Key_Data *
+new(me, x, f = 0)
+       SV *me
+       mp *x
+       unsigned f
        CODE:
-       if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
-         croak("not encrypted");
-       RETVAL = CREATE(Key_DataImpl);
-       if ((rc = key_punlock(tag, kd, RETVAL)) != 0) {
-         DESTROY(RETVAL);
-         keyerr(rc);
-         RETVAL = 0;
-       }
+       RETVAL = key_newmp(f, x);
        OUTPUT:
        RETVAL
 
-void
-read(me, p)
+mp *
+mp(kd)
+       Key_Data *kd
+       CODE:
+       RETVAL = MP_COPY(kd->u.m);
+       OUTPUT:
+       RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data::EC PREFIX = key_
+
+Key_Data *
+new(me, p, f = 0)
        SV *me
-       char *p
-       PREINIT:
-       key_data *kd;
-       char *pp;
-       PPCODE:
-       kd = CREATE(key_data);
-       if (key_read(p, kd, &pp))
-         DESTROY(kd);
-       else {
-         XPUSHs(RET(kd, "Catacomb::Key::DataImpl"));
-         if (GIMME_V == G_ARRAY)
-           XPUSHs(sv_2mortal(newSVpvn(pp, strlen(pp))));
-       }
+       ec *p
+       unsigned f
+       CODE:
+       RETVAL = key_newec(f, p);
+       OUTPUT:
+       RETVAL
 
-SV *
-write(kd, kf = 0)
-       Key_DataImpl *kd
-       Key_Filter *kf
-       PREINIT:
-       dstr d = DSTR_INIT;
+ec *
+ec(kd)
+       Key_Data *kd
        CODE:
-       if (key_write(kd, &d, kf))
-         RETVAL = newSVpvn(d.buf, d.len);
-       else
-         RETVAL = &PL_sv_undef;
-       dstr_destroy(&d);
+       RETVAL = CREATE(ec);
+       EC_CREATE(RETVAL);
+       EC_COPY(RETVAL, &kd->u.e);
        OUTPUT:
        RETVAL
 
-Key_DataImpl *
-decode(me, sv)
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data::String PREFIX = key_
+
+Key_Data *
+new(me, p, f = 0)
        SV *me
-       SV *sv
-       PREINIT:
-       char *p;
-       STRLEN len;
+       char *p
+       unsigned f
        CODE:
-       p = SvPV(sv, len);
-       RETVAL = CREATE(key_data);
-       if (key_decode(p, len, RETVAL)) {
-         DESTROY(RETVAL);
-         RETVAL = 0;
-       }
+       RETVAL = key_newstring(f, p);
        OUTPUT:
        RETVAL
 
-SV *
-encode(kd, kf = 0)
-       Key_DataImpl *kd
-       Key_Filter *kf
-       PREINIT:
-       dstr d = DSTR_INIT;
+char *
+str(kd)
+       Key_Data *kd
        CODE:
-       if (key_encode(kd, &d, kf))
-         RETVAL = newSVpvn(d.buf, d.len);
-       else
-         RETVAL = &PL_sv_undef;
-       dstr_destroy(&d);
+       RETVAL = kd->u.p;
+       OUTPUT:
+       RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::Key::Data::Structured PREFIX = key_
+
+Key_Data *
+new()
+       CODE:
+       RETVAL = key_newstruct();
+       OUTPUT:
+       RETVAL
+
+Key_StructIter *
+iterate(kd)
+       Key_Data *kd
+       CODE:
+       RETVAL = CREATE(Key_StructIter);
+       sym_mkiter(RETVAL, &kd->u.s);
+       OUTPUT:
+       RETVAL
+
+Key_Data *
+find(kd, tag)
+       Key_Data *kd
+       char *tag
+       CODE:
+       RETVAL = key_structfind(kd, tag);
+       if (RETVAL) key_incref(RETVAL);
        OUTPUT:
        RETVAL
 
+SV *
+del(kd, tag)
+       Key_Data *kd
+       char *tag
+       CODE:
+       key_structset(kd, tag, 0);
+       XSRETURN_YES;
+
+SV *
+set(kd, tag, kdnew = 0)
+       Key_Data *kd
+       char *tag
+       Key_Data *kdnew
+       CODE:
+       key_structset(kd, tag, kdnew);
+       XSRETURN_YES;
+       
 MODULE = Catacomb PACKAGE = Catacomb::Key::StructIter
 
 SV *
@@ -679,31 +668,6 @@ DESTROY(i)
 
 MODULE = Catacomb PACKAGE = Catacomb::Key::Data
 
-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 = newSVpvn(d.buf, d.len);
-       dstr_destroy(&d);
-       OUTPUT:
-       RETVAL
-
 MODULE = Catacomb PACKAGE = Catacomb::Key::File PREFIX = key_
 
 Key_File *
@@ -748,6 +712,41 @@ key_extract(kf, k, fp, kfilt = 0)
        C_ARGS:
        &kf->kf, k->k, fp, kfilt
 
+void
+qtag(kf, tag, kdnew = 0)
+       Key_File *kf
+       char *tag
+       Key_Data *kdnew
+       PREINIT:
+       dstr d = DSTR_INIT;
+       key_data **kd;
+       key_data *okd;
+       key *k;
+       Key *kk;
+       PPCODE:
+       if (key_qtag(&kf->kf, tag, &d, &k, &kd)) {
+         keyerr(KERR_NOTFOUND);
+         XSRETURN_UNDEF;
+       }
+       okd = *kd;
+       if (kdnew) {
+         if (!(kf->kf.f & KF_WRITE)) {
+           keyerr(KERR_READONLY);
+           XSRETURN_UNDEF;
+         }
+         kf->kf.f |= KF_MODIFIED;
+         *kd = kdnew;
+       }
+       key_incref(*kd);
+       kk = CREATE(Key);
+       kk->k = k;
+       kk->kf = kf;
+       kf->ref++;
+       XPUSHs(sv_2mortal(newSVpvn(d.buf, d.len)));
+       XPUSHs(RET(kk, "Catacomb::Key"));
+       XPUSHs(RET(okd, keydata_type(okd)));
+       dstr_destroy(&d);
+
 int
 key_save(kf)
        Key_File *kf
@@ -803,7 +802,7 @@ bytag(kf, tag)
        RETVAL
 
 Key *
-newkey(kf, id, type, exp)
+newkey(kf, id, type, exp = KEXP_FOREVER)
        Key_File *kf
        U32 id
        const char *type
@@ -812,7 +811,7 @@ newkey(kf, id, type, exp)
        int err;
        CODE:
        RETVAL = CREATE(Key);
-       if ((RETVAL->k = key_new(&kf->kf, id, type, exp, &err)) == 0) {
+       if ((err = key_new(&kf->kf, id, type, exp, &RETVAL->k)) == 0) {
          DESTROY(RETVAL);
          keyerr(err);
          RETVAL = 0;
@@ -822,7 +821,6 @@ newkey(kf, id, type, exp)
        }
        OUTPUT:
        RETVAL
-       
 
 Key_FileIter *
 iterate(kf)
index b22f4eb..73e850f 100644 (file)
@@ -71,6 +71,22 @@ SV *keyerr(int rc)
   return (&PL_sv_undef);
 }
 
+const char *keydata_type(Key_Data *kd)
+{
+  const char *cls;
+  if (!kd) return (0);
+  switch (kd->e & KF_ENCMASK) {
+    case KENC_BINARY: cls = "Catacomb::Key::Data::Binary"; break;
+    case KENC_ENCRYPT: cls = "Catacomb::Key::Data::Encrypted"; break;
+    case KENC_EC: cls = "Catacomb::Key::Data::EC"; break;
+    case KENC_STRING: cls = "Catacomb::Key::Data::String"; break;
+    case KENC_STRUCT: cls = "Catacomb::Key::Data::Structured"; break;
+    case KENC_MP: cls = "Catacomb::Key::Data::MP"; break;
+    default: abort();
+  }
+  return (cls);
+}
+
 void keyfile_dec(Key_File *kf)
 {
   kf->ref--;
index ee98e5c..4db8032 100644 (file)
--- a/pubkey.xs
+++ b/pubkey.xs
@@ -107,7 +107,7 @@ gen_dsa(me, ql, pl, steps = 0, k = &PL_sv_undef, events = &PL_sv_undef)
        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(newSVpvn((char *)ds.p, ds.sz)));
        XPUSHs(sv_2mortal(newSViv(ds.count)));
        xfree(ds.p);
 
@@ -222,7 +222,7 @@ sign(c, m, k = 0)
        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(sv_2mortal(newSVpvn((char *)s.r, g.h->hashsz)));
        XPUSHs(RET_MP(s.s));
        xfree(s.r);
 
@@ -244,7 +244,7 @@ verify(c, m, r, s)
        p = SvPV(m, len);
        if (len != g.h->hashsz)
          croak("bad message length");
-       ss.r = SvPV(r, len);
+       ss.r = (void *)SvPV(r, len);
        if (len != g.h->hashsz)
          croak("bad signature (r) length");
        ss.s = s;
diff --git a/t/key.t b/t/key.t
index 7a8074f..0bf3754 100644 (file)
--- a/t/key.t
+++ b/t/key.t
@@ -37,13 +37,13 @@ $f = Catacomb::Key::File->new("keyring"); ok defined $f;        #t    1
 $k = $f->bytag("tux"); ok defined $k;                              #t    2
 $d = $k->data(); ok defined $d;                                            #t    3
 ok $d->flags() == KENC_STRUCT;                                     #t    4
-$h = $d->structopen();
+$h = $d->open();
 ok exists $h->{"p"};                                               #t    5
 ok !exists $h->{"bogus"};                                          #t    6
 
 ($C, undef, $r) =
-  Catacomb::EC::Curve->getinfo($h->{"curve"}->getstring());
-$p = $C->pt($h->{"p"}->getec());
+  Catacomb::EC::Curve->getinfo($h->{"curve"}->str());
+$p = $C->pt($h->{"p"}->ec());
 ok +($p * $r)->atinfp();                                           #t    7
 
 $h = $k->attrs;
@@ -54,13 +54,13 @@ ok checkhash $h, {                                              #t    8
 };
 
 
-($k, $d, $n) = $f->qtag("rsa.private");
+($n, $k, $d) = $f->qtag("rsa.private");
 ok $k->type, "rsa";                                                #t    9
 ok $d->flags == KENC_ENCRYPT;                                      #t   10
 ok $n, sprintf("%08x:rsa.private", $k->id);                        #t   11
 
-$h = $f->bytag("rsa")->data()->structfind("private")
-  ->unlock("pass")->structopen();
+$h = $f->bytag("rsa")->data()->find("private")
+  ->unlock("pass")->open();
 ok defined $h;                                                     #t   12
 
 
@@ -69,9 +69,9 @@ ok defined $h;                                                            #t   12
   ("struct:[p=integer,public:23,q=integer,public:11],zqzqv");
 ok $rest, ",zqzqv";                                                #t   13
 ok defined $kd;                                                            #t   14
-$h = $kd->structopen(); ok defined $h;                             #t   15
-ok $h->{"p"}->getmp() == 23;                                       #t   16
-ok $h->{"q"}->getmp() == 11;                                       #t   17
+$h = $kd->open(); ok defined $h;                                   #t   15
+ok $h->{"p"}->mp() == 23;                                          #t   16
+ok $h->{"q"}->mp() == 11;                                          #t   17
 $pkd = $kd->lock("passphrase");
 ok !defined $pkd->unlock("wrong");                                 #t   18
 $ukd = $pkd->unlock("passphrase"); ok defined $ukd;                #t   19
diff --git a/typemap b/typemap
index a4f6297..f394c73 100644 (file)
--- a/typemap
+++ b/typemap
@@ -46,7 +46,7 @@ MP_Prime_Gen_JumpStepper *    T_CATSTRUCT
 MP_Prime_Gen_RabinTester *     T_CATSTRUCT
 
 Key_File *                     T_CATSTRUCT
-Key_DataImpl *                 T_CATSTRUCT
+Key_Data *                     T_KEYDATA
 Key_AttrIter *                 T_CATSTRUCT
 Key_StructIter *               T_CATSTRUCT
 Key_FileIter *                 T_CATSTRUCT
@@ -76,6 +76,8 @@ T_GCALG
        $var = ptrfromsv($arg, \"${my $ntt = $ntype; $ntt =~ s/^gc(.*)Ptr$/Catacomb::\u$1Class/; \$ntt}\", \"$var\")
 T_KEYSZ
        $var = ptrfromsv($arg, \"Catacomb::KeySize\", \"$var\")
+T_KEYDATA
+       $var = ptrfromsv($arg, \"${my $ntt = $ntype; $ntt =~ s/^(.*)Ptr$/Catacomb::$1/; $ntt =~ s/_/::/g; \$ntt}\", \"$var\")
 T_PGENPROC
        if (sv_derived_from($arg, \"Catacomb::MP::Prime::Gen::Proc\"))
          $var = $arg;
@@ -111,3 +113,5 @@ T_PGENPROC
        $arg = $var;
 T_KEYERR
        $arg = keyerr($var);
+T_KEYDATA
+       ptrtosv(&$arg, $var, keydata_type($var));