From bfdf19cbde6d9f5cdb740d258fcc439a4a412ab0 Mon Sep 17 00:00:00 2001 From: mdw Date: Tue, 27 Sep 2005 11:19:36 +0000 Subject: [PATCH] Update for new keydata interface. --- Catacomb/Key.pm | 127 ++--------- Catacomb/MP.pm | 4 +- Catacomb::MP::Prime.pod | 1 - algs.PL | 3 +- catacomb-perl.h | 6 +- catacomb.xs | 2 +- ec.xs | 4 +- group.xs | 4 +- key.xs | 572 ++++++++++++++++++++++++------------------------ keystuff.c | 16 ++ pubkey.xs | 6 +- t/key.t | 18 +- typemap | 6 +- 13 files changed, 349 insertions(+), 420 deletions(-) diff --git a/Catacomb/Key.pm b/Catacomb/Key.pm index 6f84492..8f97126 100644 --- a/Catacomb/Key.pm +++ b/Catacomb/Key.pm @@ -27,23 +27,28 @@ #----- 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; diff --git a/Catacomb/MP.pm b/Catacomb/MP.pm index 0341626..9a43807 100644 --- a/Catacomb/MP.pm +++ b/Catacomb/MP.pm @@ -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]; } diff --git a/Catacomb::MP::Prime.pod b/Catacomb::MP::Prime.pod index 8bd543b..7f856d4 100644 --- a/Catacomb::MP::Prime.pod +++ b/Catacomb::MP::Prime.pod @@ -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 --- 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; diff --git a/catacomb-perl.h b/catacomb-perl.h index ef36efc..acfff02 100644 --- a/catacomb-perl.h +++ b/catacomb-perl.h @@ -35,12 +35,11 @@ /*----- Header files ------------------------------------------------------*/ -#include - #include #include #include +#include #include #include #include @@ -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 ---------------------------------------------*/ diff --git a/catacomb.xs b/catacomb.xs index 5bcc441..102ee4d 100644 --- a/catacomb.xs +++ b/catacomb.xs @@ -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 --- 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 * diff --git a/group.xs b/group.xs index 51af11c..a329c82 100644 --- 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 --- 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) diff --git a/keystuff.c b/keystuff.c index b22f4eb..73e850f 100644 --- a/keystuff.c +++ b/keystuff.c @@ -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--; diff --git a/pubkey.xs b/pubkey.xs index ee98e5c..4db8032 100644 --- 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 --- 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 --- 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)); -- 2.11.0