diff --git a/Makefile.am b/Makefile.am index c47891b..019296a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # # This file is part of Pretty Curved Privacy (pcp1). # -# Copyright (C) 2013 T.Linden. +# Copyright (C) 2013-2015 T.Linden. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,7 +19,15 @@ # You can contact me by mail: . # -SUBDIRS = include libpcp src man tests bindings/cpp +if BUILDPY + MAYPY=bindings/py +endif + +if BUILDCPP + MAYCPP=bindings/cpp +endif + +SUBDIRS = include libpcp src man tests $(MAYCPP) $(MAYPY) ACLOCAL_AMFLAGS = -I config test: diff --git a/autogen.sh b/autogen.sh index fab63b9..d896e3a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -63,7 +63,7 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography. bindings/py/gencffi.pl include/pcp/defines.h include/pcp/structs.h include/pcp/key.h \ include/pcp/buffer.h include/pcp/context.h include/pcp/mac.h \ include/pcp/ed.h include/pcp/crypto.h include/pcp/vault.h \ - include/pcp/mgmt.h \ + include/pcp/mgmt.h include/pcp/keyhash.h include/pcp/scrypt.h \ include/pcp/pcpstream.h include/pcp/z85.h > bindings/py/pypcp/raw.py exit @@ -103,6 +103,7 @@ find . -name .deps -exec rm -rf {} \; > /dev/null 2>&1 find . -name .libs -exec rm -rf {} \; > /dev/null 2>&1 find . -name .o -exec rm -rf {} \; > /dev/null 2>&1 find . -name .lo -exec rm -rf {} \; > /dev/null 2>&1 +find . -name .pyc -exec rm -rf {} \; > /dev/null 2>&1 rm -rf aclocal.m4 libtool configure config.* config autom4te.cache tests/test* tests/v* tests/stresstest/* libpcp/libpcp1.pc rm clean.sh @@ -114,4 +115,4 @@ chmod 700 clean.sh rm -rf README include/pcp/config.h.in~ libpcp/stamp-h1 autom4te.cache sleep 1 -touch Makefile.in configure */Makefile.in \ No newline at end of file +touch Makefile.in configure */Makefile.in diff --git a/bindings/py/gencffi.pl b/bindings/py/gencffi.pl index 7d3b896..8d5d022 100755 --- a/bindings/py/gencffi.pl +++ b/bindings/py/gencffi.pl @@ -26,6 +26,7 @@ my %sobytes = ( ); my @code; +my %defs; foreach my $head (@ARGV) { open HEAD, "<$head" or die "Could not open $head: $!\n"; @@ -62,6 +63,16 @@ foreach my $head (@ARGV) { push @code, $c; } + # a definition + while ($raw =~ /^\s*#define ((EXP|PCP|PBP).*)$/gm) { + my ($name, $def) = split /\s\s*/, $1, 2; + $def =~ s/\/\*.*//; + if (!exists $defs{$name} && $def !~ /(sizeof| \+ )/) { + print STDERR "name: $name\ndef: $def\n\n"; + $defs{$name} = "\n# $0: from $head:$.\n$name = $def\n"; + } + } + close $head; } @@ -71,3 +82,5 @@ print "PCP_RAW_CODE = '''\n"; print join "\n", @code; print "'''\n"; + +print join "\n", values %defs; diff --git a/bindings/py/pypcp/__init__.py b/bindings/py/pypcp/__init__.py index ea9d076..bc64e87 100644 --- a/bindings/py/pypcp/__init__.py +++ b/bindings/py/pypcp/__init__.py @@ -1,90 +1,16 @@ from cffi import FFI + +# loads generated structs and typedefs and imports them into cffi from pypcp.dll import * + +# load oop wrapper classes +from pypcp.publickey import * +from pypcp.key import * +from pypcp.stream import * from pprint import pprint -__all__ = ('raw Key PublicKey'.split() ) +__all__ = ('raw Context Key PublicKey Stream Buffer'.split() ) -# https://gist.github.com/inactivist/4ef7058c2132fa16759d -class Context(object): - def __init__(self): - self._ctx = libpcp.ptx_new() - def __del__(self): - libpcp.ptx_clean(self._ctx) - def throw(self, E=None, msg=None): - # forward libpcp generated exceptions - pcpmsg = ffi.string(self._ctx.pcp_err) - if msg: - pcpmsg = "%s: %s" % (msg, pcpmsg) - if E: - raise E(pcpmsg) - else: - raise RuntimeError(pcpmsg) - -class PublicKey(object): - def __init__(self, pk=None, encoded=None): - self._pk = None - - if pk: - self._pk = pk - elif encoded: - self.importkey(Context(), encoded) - else: - self._pk = ffi.new("struct _pcp_pubkey_t*") - - for key, value in convert_to_python(self._pk).iteritems(): - self.__setattr__(key, value) - - def importkey(self, context, encoded=None): - ks = libpcp.pcp_import_pub(context._ctx, encoded, len(encoded)) - if not ks: - context.throw(IOError, "failed to import key") - self._pk = ks.p - - def dump(self): - if self._pk: - libpcp.pcp_dumppubkey(self._pk) - - def __dict__(self): - return convert_to_python(self._pk) - -class Key(object): - def __init__(self, owner=None, mail=None, sk=None, encoded=None, passphrase=None): - self._sk = None - - if owner or mail: - # generate new one - if not owner: - owner='' - if not mail: - mail='' - self.generate(owner, mail) - elif sk: - # use the raw sk - self._sk = sk - elif encoded: - # import an encoded key - self.importkey(Context(), encoded, passphrase) - else: - self._sk = ffi.new("struct pcp_key_t*") - - for key, value in convert_to_python(self._sk).iteritems(): - self.__setattr__(key, value) - - def importkey(self, context, encoded=None, passphrase=None): - sk = libpcp.pcp_import_secret(context._ctx, encoded, len(encoded), passphrase) - if not sk: - context.throw(IOError, "failed to import key") - self._sk = sk - - def generate(self, owner=None, mail=None): - self._sk = libpcp.pcpkey_new() - if owner: - libpcp.pcpkey_setowner(self._sk, owner, mail) - - def dump(self): - if self._sk: - libpcp.pcp_dumpkey(self._sk) - diff --git a/bindings/py/pypcp/context.py b/bindings/py/pypcp/context.py new file mode 100644 index 0000000..c413854 --- /dev/null +++ b/bindings/py/pypcp/context.py @@ -0,0 +1,69 @@ +from pypcp.dll import * +from pypcp.stream import * + +class Context(object): + def __init__(self): + self._ctx = libpcp.ptx_new() + self._sk = None + + def __del__(self): + libpcp.ptx_clean(self._ctx) + + def throw(self, E=None, msg=None): + # forward libpcp generated exceptions + pcpmsg = ffi.string(self._ctx.pcp_err) + if msg: + pcpmsg = "%s: %s" % (msg, pcpmsg) + if E: + raise E(pcpmsg) + else: + raise RuntimeError(pcpmsg) + + def addkey(self, Key): + self._sk = Key._sk + + def pubkeycount(self): + return libpcp.pcphash_countpub(self._ctx) + + def recipients(self, *recipients): + for key in recipients: + libpcp.pcphash_add(self._ctx, key._pk, key._pk.type) + + def encrypt(self, string=None, file=None, sign=False, passphrase=None): + anon = 0 + instream = None + outstream = None + + if string: + instream = Stream(string=string) + else: + instream = Stream(file) + + outstream = Stream() + + if self.pubkeycount() > 0: + if not self._sk: + anon = 1 + + dosign = 0 + if sign: + dosign = 1 + + size = libpcp.pcp_encrypt_stream(self._ctx, instream._stream, outstream._stream, + self._sk, self._ctx.pcppubkey_hash, dosign, anon) + + if size <= 0: + self.throw(IOError, "failed to encrypt") + + return ffi.buffer(libpcp.buffer_get_remainder(outstream._stream.b), libpcp.buffer_size(outstream._stream.b))[:] + + else: + # symmetric + salt = ffi.new("byte[]", PBP_COMPAT_SALT) + symkey = libpcp.pcp_scrypt(self._ctx, passphrase, len(passphrase), salt, 90); + size = libpcp.pcp_encrypt_stream_sym(self._ctx, instream._stream, outstream._stream, symkey, 0, ffi.NULL) + + if size <= 0: + self.throw(IOError, "failed to encrypt") + + return ffi.buffer(libpcp.buffer_get_remainder(outstream._stream.b), libpcp.buffer_size(outstream._stream.b))[:] diff --git a/bindings/py/pypcp/key.py b/bindings/py/pypcp/key.py new file mode 100644 index 0000000..fce0cc5 --- /dev/null +++ b/bindings/py/pypcp/key.py @@ -0,0 +1,41 @@ +from pypcp.dll import * +from pypcp.context import * + +class Key(object): + def __init__(self, owner=None, mail=None, sk=None, encoded=None, passphrase=None): + self._sk = None + + if owner or mail: + # generate new one + if not owner: + owner='' + if not mail: + mail='' + self.generate(owner, mail) + elif sk: + # use the raw sk + self._sk = sk + elif encoded: + # import an encoded key + self.importkey(Context(), encoded, passphrase) + else: + self._sk = ffi.new("struct _pcp_key_t*") + + # just for convenience + for key, value in convert_to_python(self._sk).iteritems(): + self.__setattr__(key, value) + + def importkey(self, context, encoded=None, passphrase=None): + sk = libpcp.pcp_import_secret(context._ctx, encoded, len(encoded), passphrase) + if not sk: + context.throw(IOError, "failed to import key") + self._sk = sk + + def generate(self, owner=None, mail=None): + self._sk = libpcp.pcpkey_new() + if owner: + libpcp.pcpkey_setowner(self._sk, owner, mail) + + def dump(self): + if self._sk: + libpcp.pcp_dumpkey(self._sk) diff --git a/bindings/py/pypcp/publickey.py b/bindings/py/pypcp/publickey.py new file mode 100644 index 0000000..cc7c50f --- /dev/null +++ b/bindings/py/pypcp/publickey.py @@ -0,0 +1,29 @@ +from pypcp.dll import * +from pypcp.context import * + +class PublicKey(object): + def __init__(self, pk=None, encoded=None): + self._pk = None + + if pk: + self._pk = pk + elif encoded: + self.importkey(Context(), encoded) + else: + self._pk = ffi.new("struct _pcp_pubkey_t*") + + for key, value in convert_to_python(self._pk).iteritems(): + self.__setattr__(key, value) + + def importkey(self, context, encoded=None): + ks = libpcp.pcp_import_pub(context._ctx, encoded, len(encoded)) + if not ks: + context.throw(IOError, "failed to import key") + self._pk = ks.p + + def dump(self): + if self._pk: + libpcp.pcp_dumppubkey(self._pk) + + def __dict__(self): + return convert_to_python(self._pk) diff --git a/bindings/py/pypcp/raw.py b/bindings/py/pypcp/raw.py index 0347c32..2c00faa 100644 --- a/bindings/py/pypcp/raw.py +++ b/bindings/py/pypcp/raw.py @@ -593,125 +593,338 @@ int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t /*** bindings/py/gencffi.pl: from include/pcp/mgmt.h:2712 */ int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +void pcphash_del(PCPCTX *ptx, void *key, int type); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +void pcphash_clean(PCPCTX *ptx); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +void pcphash_cleanpub(pcp_pubkey_t *pub); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +pcp_key_t *pcphash_keyexists(PCPCTX *ptx, char *id); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +void pcphash_add(PCPCTX *ptx, void *key, int type); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +int pcphash_count(PCPCTX *ptx); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +int pcphash_countpub(PCPCTX *ptx); + +/*** bindings/py/gencffi.pl: from include/pcp/keyhash.h:2865 */ +pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id); + +/*** bindings/py/gencffi.pl: from include/pcp/scrypt.h:2908 */ +byte * pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen); + +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ Pcpstream *ps_init(void); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ Pcpstream *ps_new_file(FILE *backendfd); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ Pcpstream *ps_new_inbuffer(Buffer *b); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ Pcpstream *ps_new_outbuffer(); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_read(Pcpstream *stream, void *buf, size_t readbytes); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_finish(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_print(Pcpstream *stream, const char * fmt, ...); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_tell(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ Buffer *ps_buffer(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ void ps_close(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ int ps_end(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ int ps_err(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ void ps_setdetermine(Pcpstream *stream, size_t blocksize); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ void ps_armor(Pcpstream *stream, size_t blocksize); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ void ps_unarmor(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_read_decode(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ void ps_determine(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_read_next(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ void ps_write_encode(Pcpstream *stream, Buffer *dst); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ size_t ps_write_buf(Pcpstream *stream, Buffer *z); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ int ps_left(Pcpstream *stream); -/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3003 */ +/*** bindings/py/gencffi.pl: from include/pcp/pcpstream.h:3199 */ int ps_readline(Pcpstream *stream, Buffer *line); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ byte *pcp_padfour(byte *src, size_t srclen, size_t *dstlen); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ size_t pcp_unpadfour(byte *src, size_t srclen); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen, int doblock); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ char *pcp_readz85file(PCPCTX *ptx, FILE *infile); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ char *pcp_readz85string(PCPCTX *ptx, byte *input, size_t bufsize); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ uint8_t is_utf8(const byte * bytes); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ size_t _buffer_is_binary(byte *buf, size_t len); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ uint8_t _parse_zchar(Buffer *z, uint8_t c, uint8_t is_comment); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ long int z85_header_startswith(Buffer *buf, char *what); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ int z85_isheader(Buffer *buf); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ int z85_isend(Buffer *buf); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ int z85_isbegin(Buffer *buf); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ int z85_iscomment(Buffer *buf); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ int z85_isempty(Buffer *line); -/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3181 */ +/*** bindings/py/gencffi.pl: from include/pcp/z85.h:3377 */ int z85_isencoded(Buffer *line);''' + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ASYM_CIPHER = 5 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_FORMAT_C = 4 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_BLOCK_SIZE = 32 * 1024 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_PK_HEADER = "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SK_FOOTER = "----- END ED25519-CURVE29915 PRIVATE KEY -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ENFILE_HEADER = "----- BEGIN PCP ENCRYPTED FILE -----\r\n" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_FORMAT_NATIVE = 1 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PBP_COMPAT_SALT = "qa~t](84z<1t<1oz:ik.@IRNyhG=8q(on9}4#!/_h#a7wqK{Nt$T?W>,mt8NqYq&6U,rSYI2GRDd:Bcm" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_HASH_CIPHER = 0x22 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_HASH_NAME = "BLAKE2" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_SUB_NOTATION = 20 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_CIPHER_NAME = "ED25519" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_CIPHER = 0x23 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ZFILE_HEADER = "----- BEGIN Z85 ENCODED FILE -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_SIG_END = "----- END ED25519 SIGNATURE -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_KEY_VERSION = 6 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_PK_CIPHER = 0x21 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_KEY_PRIMITIVE = "CURVE25519-ED25519-SALSA20-POLY1305" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_RFC_CIPHER = 0x21 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ASYM_CIPHER_ANON = 6 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_FORMAT_PERL = 6 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ENFILE_FOOTER = "\r\n----- END PCP ENCRYPTED FILE -----\r\n" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_FORMAT_YAML = 3 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_SYM_CIPHER = 23 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_TYPE = 0x1F + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_FORMAT_PY = 5 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_SUB_KEYFLAGS = 27 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SK_HEADER = "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_SIGPREFIX = "\nnacl-" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ME = "Pretty Curved Privacy" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ZFILE_FOOTER = "----- END Z85 ENCODED FILE -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_SUB_SIGEXPIRE = 3 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ENCRYPT_MAC = 56 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_PK_FOOTER = "----- END ED25519-CURVE29915 PUBLIC KEY -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_SUB_CTIME = 2 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_VAULT_ID = 14 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_SIG_HEADER = "----- BEGIN ED25519 SIGNED MESSAGE -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_ASYM_CIPHER_SIG = 24 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_PK_CIPHER_NAME = "CURVE25519-ED25519-POLY1305-SALSA20" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_FORMAT_PBP = 2 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_VAULT_VERSION = 2 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_CRYPTO_ADD = (32 - 16) + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_SUB_KEYEXPIRE = 9 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_SIG_VERSION = 2 + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +PCP_SIG_START = "----- BEGIN ED25519 SIGNATURE -----" + + +# bindings/py/gencffi.pl: from include/pcp/defines.h:187 +EXP_SIG_VERSION = 0x01 diff --git a/bindings/py/pypcp/stream.py b/bindings/py/pypcp/stream.py new file mode 100644 index 0000000..85d4151 --- /dev/null +++ b/bindings/py/pypcp/stream.py @@ -0,0 +1,27 @@ +from pypcp.dll import * + + +class Stream(object): + def __init__(self, string=None, file=None): + if file: + fd = open(file, 'r') + self._stream = libpcp.ps_new_file(fd) + elif string: + buf = libpcp.buffer_new_buf('inbuf', string, len(string)) + self._stream = libpcp.ps_new_inbuffer(buf) + else: + self._stream = libpcp.ps_new_outbuffer() + + def __del__(self): + libpcp.ps_close(self._stream) + + +class Buffer(object): + def __init__(self, string=None): + if string: + self._buffer = libpcp.buffer_new_buf('pybuf', string, len(string)) + else: + self._buffer = libpcp.buffer_new(32, 'pybuf') + + def __del__(self): + libpcp.buffer_free(self._buffer) diff --git a/bindings/py/test.py b/bindings/py/test.py index cf763b5..e88927e 100755 --- a/bindings/py/test.py +++ b/bindings/py/test.py @@ -3,16 +3,20 @@ from pypcp import * from pprint import pprint -sk = Key("tom", "me@there") -sk.dump() +zbobsec = open("../../tests/key-bobby-sec", "r").read() -encoded = open("../../tests/key-bobby-sec", "r").read() +bobsec = Key(encoded=zbobsec, passphrase="b") +#bobsec.dump() -sk = Key(encoded=encoded, passphrase="b") -sk.dump() +zalipub = open("../../tests/key-alicia-pub", "r").read() +alipub = PublicKey(encoded=zalipub) +#alipub.dump() -p = open("../../tests/key-bobby-pub", "r").read() -pk = PublicKey(encoded=p) -pk.dump() +ctx = Context() + +encrypted = ctx.encrypt(string="hello world", passphrase="x") + +ctx.addkey(bobsec) +ctx.recipients(alipub) +encrypted = ctx.encrypt(string="hello world") -pprint(pk.masterpub) diff --git a/configure.ac b/configure.ac index ae26128..a564319 100755 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # # This file is part of Pretty Curved Privacy (pcp1). # -# Copyright (C) 2013 T.Linden. +# Copyright (C) 2013-2015 T.Linden. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -294,27 +294,42 @@ fi CFLAGS="$CFLAGS -Werror -Wextra -O2" CXXFLAGS="$CFLAGS" -AC_ARG_WITH([python-binding], - [AS_HELP_STRING([--with-python-binding], - [Enable python binding])], - [python="yes"], - []) +# conditionals for bindings and stuff + +# c++ +AC_ARG_ENABLE([cpp-binding], + [AS_HELP_STRING([--disable-cpp-binding], + [Disable C++ binding])], + ) + +AM_CONDITIONAL([BUILDCPP], [test "x$enable_cpp_binding" != "xno"]) + +# py +AC_ARG_ENABLE([python-binding], + [AS_HELP_STRING([--enable-python-binding], + [Enable python binding])], + [python="yes"], + []) + +if test "x$python" = "xyes"; then + if ! python -c "import cffi" > /dev/null 2>&1; then + python="no" + AC_MSG_ERROR([python or cffi is not installed]) + fi +fi + +AM_CONDITIONAL([BUILDPY], [test "x$python" = "xyes"]) AC_SUBST(PACKAGE_VERSION) # Specify output files -AC_CONFIG_FILES([Makefile include/Makefile libpcp/Makefile src/Makefile man/Makefile tests/Makefile libpcp/libpcp1.pc bindings/cpp/Makefile]) +AC_CONFIG_FILES([Makefile include/Makefile libpcp/Makefile src/Makefile man/Makefile \ + tests/Makefile libpcp/libpcp1.pc bindings/cpp/Makefile bindings/py/Makefile]) + -if test "x$python" = "xyes"; then - if python -c "import cffi" > /dev/null 2>&1; then - AC_CONFIG_FILES([bindings/py/Makefile]) - else - AC_MSG_ERROR([python or cffi is not installed]) - fi -fi AC_OUTPUT