finally fixed all stream related problems, z85 transparent en/decoding works, unittests all ok.

This commit is contained in:
git@daemon.de
2014-02-27 13:55:43 +01:00
parent c11ce76d21
commit 97f4d14d3b
17 changed files with 209 additions and 68 deletions

View File

@@ -50,6 +50,9 @@
on the caller if it works on files or on buffers. on the caller if it works on files or on buffers.
Pcpstreams also automatically encode/decode Z85. Pcpstreams also automatically encode/decode Z85.
Due to the new pcpstream class pcp now supports
armored encrypted files, which it didn't previously.
Lots of refactoring have been done to clear things Lots of refactoring have been done to clear things
out and make the system work with the changes out and make the system work with the changes
above. above.
@@ -73,6 +76,11 @@
in man/html/. Latest API docs can be found on in man/html/. Latest API docs can be found on
http://www.daemon.de/libpcp/. http://www.daemon.de/libpcp/.
At this point I'd like to thank Liquid Soul. Only
thanks to their music I was able to do those heavy
changes. It's like a drug boosting the brain. Love
U, man!
0.2.0 ED25519 and Curve25519 keys are now generated 0.2.0 ED25519 and Curve25519 keys are now generated
separately (previously they were generated from separately (previously they were generated from
one random seed, the curve had been derived from one random seed, the curve had been derived from

1
TODO
View File

@@ -46,6 +46,7 @@ Check is_utf8 license.
Vault checksum with global vault Vault checksum with global vault
Symmetric crypt mode tries to open vault
Python binding, e.g.: Python binding, e.g.:
py % cdll.LoadLibrary("libsodium.so.8") py % cdll.LoadLibrary("libsodium.so.8")

View File

@@ -8,7 +8,6 @@ extern "C" {
#include "pcp/config.h" #include "pcp/config.h"
#include "pcp/base85.h" #include "pcp/base85.h"
#include "pcp/buffer.h" #include "pcp/buffer.h"
#include "pcp/config.h"
#include "pcp/crypto.h" #include "pcp/crypto.h"
#include "pcp/defines.h" #include "pcp/defines.h"
#include "pcp/digital_crc32.h" #include "pcp/digital_crc32.h"

View File

@@ -1,7 +1,7 @@
/* /*
This file is part of Pretty Curved Privacy (pcp1). This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden. Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>. You can contact me by mail: <tom AT vondein DOT org>.
*/ */
@@ -58,8 +58,8 @@ typedef unsigned short dbyte; /* Double byte = 16 bits */
typedef unsigned int qbyte; /* Quad byte = 32 bits */ typedef unsigned int qbyte; /* Quad byte = 32 bits */
/* key stuff, deprecated. */ /* key stuff, deprecated. */
#define PCP_ENFILE_HEADER "~~~~~ BEGIN PCP ENCRYPTED FILE ~~~~~" #define PCP_ENFILE_HEADER "~~~~~ BEGIN PCP ENCRYPTED FILE ~~~~~\r\n"
#define PCP_ENFILE_FOOTER "~~~~~ END PCP ENCRYPTED FILE ~~~~~" #define PCP_ENFILE_FOOTER "\r\n~~~~~ END PCP ENCRYPTED FILE ~~~~~\r\n"
#define PCP_ZFILE_HEADER "~~~~~ BEGIN Z85 ENCODED FILE ~~~~~" #define PCP_ZFILE_HEADER "~~~~~ BEGIN Z85 ENCODED FILE ~~~~~"
#define PCP_ZFILE_FOOTER "~~~~~ END Z85 ENCODED FILE ~~~~~" #define PCP_ZFILE_FOOTER "~~~~~ END Z85 ENCODED FILE ~~~~~"

View File

@@ -70,6 +70,8 @@ struct _pcp_stream_t {
uint8_t firstread; /**< Internal flag, will be set after first read() */ uint8_t firstread; /**< Internal flag, will be set after first read() */
size_t linewr; /**< Used for Z85 writing, number of chars written on last line */ size_t linewr; /**< Used for Z85 writing, number of chars written on last line */
size_t blocksize; /**< Blocksize used for z85, if requested */ size_t blocksize; /**< Blocksize used for z85, if requested */
uint8_t is_output; /**< marks the stream as output stream */
size_t pos; /**< remember i/o position */
}; };
/** The name used everywhere */ /** The name used everywhere */
@@ -254,6 +256,15 @@ void ps_setdetermine(Pcpstream *stream, size_t blocksize);
*/ */
void ps_armor(Pcpstream *stream, size_t blocksize); void ps_armor(Pcpstream *stream, size_t blocksize);
/** Disable Z85 encoding for an output stream.
\param[in] stream The stream object.
*/
void ps_unarmor(Pcpstream *stream);
/* read from primary source, decode z85 and out into cache. /* read from primary source, decode z85 and out into cache.
if buf != NULL, consider it as the start of encoded data if buf != NULL, consider it as the start of encoded data
and remove headers and comments, then continue as normal. */ and remove headers and comments, then continue as normal. */
@@ -280,6 +291,9 @@ void ps_write_encode(Pcpstream *stream, Buffer *dst);
/* really write the buffer z into the output stream */ /* really write the buffer z into the output stream */
size_t ps_write_buf(Pcpstream *stream, Buffer *z); size_t ps_write_buf(Pcpstream *stream, Buffer *z);
/* tell if we really reached eof, caching or not. 1=eof, 0=ok */
int ps_left(Pcpstream *stream);
#endif // HAVE_PCP_PCPSTEAM_H #endif // HAVE_PCP_PCPSTEAM_H

View File

@@ -1,7 +1,7 @@
/* /*
This file is part of Pretty Curved Privacy (pcp1). This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden. Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>. You can contact me by mail: <tom AT vondein DOT org>.
*/ */
@@ -25,7 +25,7 @@
#define PCP_VERSION_MAJOR 0 #define PCP_VERSION_MAJOR 0
#define PCP_VERSION_MINOR 2 #define PCP_VERSION_MINOR 2
#define PCP_VERSION_PATCH 1 #define PCP_VERSION_PATCH 2
#define PCP_MAKE_VERSION(major, minor, patch) \ #define PCP_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch)) ((major) * 10000 + (minor) * 100 + (patch))

View File

@@ -125,11 +125,16 @@ byte *buffer_get(Buffer *b) {
} }
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) { size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
if(len > b->end - b->offset || len == 0) { if(len > b->end - b->offset) {
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n", fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
b->name, len, b->end - b->offset, b->offset); b->name, len, b->end - b->offset, b->offset);
return 0; return 0;
} }
else if(len == 0) {
/* FIXME: check how this happens */
return 0;
}
memcpy(buf, b->buf + b->offset, len); memcpy(buf, b->buf + b->offset, len);
b->offset += len; b->offset += len;
@@ -137,11 +142,15 @@ size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
} }
size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) { size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) {
if(len > b->end - b->offset || len == 0) { if(len > b->end - b->offset) {
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n", fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
b->name, len, b->end - b->offset, b->offset); b->name, len, b->end - b->offset, b->offset);
return 0; return 0;
} }
else if(len == 0) {
/* FIXME: check how this happens */
return 0;
}
buffer_resize(dst, len); buffer_resize(dst, len);
memcpy(dst->buf+buffer_size(dst), b->buf + b->offset, len); memcpy(dst->buf+buffer_size(dst), b->buf + b->offset, len);

View File

@@ -178,7 +178,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
nrec = recmatch = self = 0; nrec = recmatch = self = 0;
if(ps_tell(in) == 1) { if(ps_tell(in) > 1) {
/* header has already been determined outside the lib */ /* header has already been determined outside the lib */
if(symkey != NULL) if(symkey != NULL)
self = 1; self = 1;
@@ -233,7 +233,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
for(nrec=0; nrec<lenrec; nrec++) { for(nrec=0; nrec<lenrec; nrec++) {
cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */ cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) { if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
fatal("Error: input file corrupted, incomplete or no recipients\n"); fatal("Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
goto errdef1; goto errdef1;
} }
recmatch = 0; recmatch = 0;
@@ -262,17 +262,18 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
fatal("Sorry, there's no matching public key in your vault for decryption\n"); fatal("Sorry, there's no matching public key in your vault for decryption\n");
goto errdef1; goto errdef1;
} }
/* step 5, actually decrypt the file, finally */ /* step 5, actually decrypt the file, finally */
if(verify) { if(verify) {
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur); pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
return pcp_decrypt_stream_sym(in, out, symkey, rec); size_t s = pcp_decrypt_stream_sym(in, out, symkey, rec);
pcp_rec_free(rec); pcp_rec_free(rec);
return s;
}
else {
size_t s = pcp_decrypt_stream_sym(in, out, symkey, NULL);
return s;
} }
else
return pcp_decrypt_stream_sym(in, out, symkey, NULL);
errdef1: errdef1:
return 0; return 0;

View File

@@ -60,8 +60,8 @@ void ps_setdetermine(Pcpstream *stream, size_t blocksize) {
stream->determine = 1; stream->determine = 1;
stream->blocksize = blocksize + (5 - (blocksize % 5)); stream->blocksize = blocksize + (5 - (blocksize % 5));
if(stream->cache == NULL) { if(stream->cache == NULL) {
stream->cache = buffer_new(32, "Pcpstreamcache"); stream->cache = buffer_new(32, "Pcpstreamcachedetermine");
stream->next = buffer_new(32, "Pcpstreamcachenext"); stream->next = buffer_new(32, "Pcpstreamcachenextdetermin");
} }
} }
@@ -75,6 +75,10 @@ void ps_armor(Pcpstream *stream, size_t blocksize) {
} }
} }
void ps_unarmor(Pcpstream *stream) {
stream->armor = 0;
}
size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) { size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) {
size_t gotbytes = 0; size_t gotbytes = 0;
@@ -107,18 +111,28 @@ size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) {
/* return readbytes from cache. if it is more than left in the cache /* return readbytes from cache. if it is more than left in the cache
fetch (and decode) the next chunk, append it to cache and return from fetch (and decode) the next chunk, append it to cache and return from
that */ that */
size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes) { size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes) {
if(buffer_left(stream->cache) <= readbytes && buffer_left(stream->cache) > 0 && readbytes <= stream->blocksize) { /*
fprintf(stderr, "%ld <= %ld && %ld <= %ld\n",
readbytes, buffer_left(stream->cache), readbytes, stream->blocksize) ;
fprintf(stderr, "%d == 1 && %ld >= %ld\n", ps_left(stream), readbytes, buffer_left(stream->cache));
*/
if(readbytes <= buffer_left(stream->cache) && readbytes <= stream->blocksize) {
/* enough left in current cache */ /* enough left in current cache */
return buffer_get_chunk(stream->cache, buf, readbytes); return buffer_get_chunk(stream->cache, buf, readbytes);
} }
else if(ps_left(stream) == 1 && readbytes >= buffer_left(stream->cache)) {
return buffer_get_chunk(stream->cache, buf, buffer_left(stream->cache));
}
else { else {
/* request for chunk larger than what we've got in the cache */ /* request for chunk larger than what we've got in the cache */
Buffer *tmp = buffer_new(stream->blocksize, "Pcpreadover"); Buffer *tmp = buffer_new(stream->blocksize, "Pcpreadchunktmp");
if( buffer_left(stream->cache) > 0) { if( buffer_left(stream->cache) > 0) {
/* put the remaining cache into dest */ /* put the remaining cache into dest */
buffer_get_chunk_tobuf(stream->cache, tmp, buffer_size(stream->cache)); buffer_get_chunk_tobuf(stream->cache, tmp, buffer_left(stream->cache));
} }
/* how much left to fetch */ /* how much left to fetch */
@@ -170,26 +184,31 @@ size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes) {
/* read and decode the next chunk and put it into stream->next */ /* read and decode the next chunk and put it into stream->next */
size_t ps_read_next(Pcpstream *stream) { size_t ps_read_next(Pcpstream *stream) {
if(stream->armor == 1) { if(ps_left(stream) == 0) {
/* fetch next chunk and decode it */ if(stream->armor == 1) {
return ps_read_decode(stream, NULL, 0); /* fetch next chunk and decode it */
} return ps_read_decode(stream, NULL, 0);
else { }
/* unencoded source, fetch as is */ else {
void *buf = ucmalloc(stream->blocksize); /* unencoded source, fetch as is */
size_t got = ps_read_raw(stream, buf, stream->blocksize); void *buf = ucmalloc(stream->blocksize);
buffer_add(stream->next, buf, got); size_t got = ps_read_raw(stream, buf, stream->blocksize);
return got; buffer_add(stream->next, buf, got);
return got;
}
} }
else
return 0;
} }
size_t ps_read(Pcpstream *stream, void *buf, size_t readbytes) { size_t ps_read(Pcpstream *stream, void *buf, size_t readbytes) {
size_t got = 0;
if(stream->cache == NULL) { if(stream->cache == NULL) {
return ps_read_raw(stream, buf, readbytes); got = ps_read_raw(stream, buf, readbytes);
} }
else if(buffer_size(stream->cache) > 0) { else if(buffer_size(stream->cache) > 0) {
/* use cache */ /* use cache */
return ps_read_cached(stream, buf, readbytes); got = ps_read_cached(stream, buf, readbytes);
} }
else { else {
/* no cache yet */ /* no cache yet */
@@ -197,18 +216,22 @@ size_t ps_read(Pcpstream *stream, void *buf, size_t readbytes) {
/* fetch the first chunk into the cache and decode, if required, /* fetch the first chunk into the cache and decode, if required,
recursively call ps_read() again to return the apropriate data */ recursively call ps_read() again to return the apropriate data */
ps_determine(stream); ps_determine(stream);
return ps_read(stream, buf, readbytes); got = ps_read(stream, buf, readbytes);
} }
else if(stream->armor == 1) { else if(stream->armor == 1) {
/* z85 encoding has already been determined, therefore the cache /* z85 encoding has already been determined, therefore the cache
is now filled, use it then */ is now filled, use it then */
return ps_read_cached(stream, buf, readbytes); got = ps_read_cached(stream, buf, readbytes);
} }
else { else {
/* read directly from source */ /* read directly from source */
return ps_read_raw(stream, buf, readbytes); got = ps_read_raw(stream, buf, readbytes);
} }
} }
stream->pos += got;
return got;
} }
void ps_determine(Pcpstream *stream) { void ps_determine(Pcpstream *stream) {
@@ -285,6 +308,8 @@ size_t ps_read_decode(Pcpstream *stream, void *buf, size_t bufsize) {
size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes) { size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes) {
Buffer *z = buffer_new(32, "Pcpwritetemp"); Buffer *z = buffer_new(32, "Pcpwritetemp");
stream->is_output = 1;
if(stream->armor == 1) { if(stream->armor == 1) {
if(buffer_size(stream->cache) + writebytes < stream->blocksize) { if(buffer_size(stream->cache) + writebytes < stream->blocksize) {
/* just put it into the cache and done with it */ /* just put it into the cache and done with it */
@@ -350,13 +375,16 @@ size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes) {
/* actually put it out */ /* actually put it out */
size_t outsize = ps_write_buf(stream, z); size_t outsize = ps_write_buf(stream, z);
buffer_free(z); buffer_free(z);
return outsize; writebytes = outsize;
} }
else { else {
/* buf has been put into the cache only, no writing required */ /* buf has been put into the cache only, no writing required */
buffer_free(z); buffer_free(z);
return writebytes;
} }
stream->pos += writebytes;
return writebytes;
} }
void ps_write_encode(Pcpstream *stream, Buffer *dst) { void ps_write_encode(Pcpstream *stream, Buffer *dst) {
@@ -372,14 +400,14 @@ void ps_write_encode(Pcpstream *stream, Buffer *dst) {
} }
/* z85 encode */ /* z85 encode */
zlen = (buffer_size(stream->cache) * 5 / 4); zlen = (buffer_size(stream->cache) * 5 / 4) + 1;
char *z85 = ucmalloc(zlen); char *z85 = ucmalloc(zlen);
zmq_z85_encode(z85, buffer_get(stream->cache), buffer_size(stream->cache)); zmq_z85_encode(z85, buffer_get(stream->cache), buffer_size(stream->cache));
/* add newlines */ /* add newlines */
pos = stream->linewr; pos = stream->linewr;
for(i=0; i<zlen; ++i) { for(i=0; i<zlen-1; ++i) {
if(pos >= 71) { if(pos >= 71) {
buffer_add8(dst, '\r'); buffer_add8(dst, '\r');
buffer_add8(dst, '\n'); buffer_add8(dst, '\n');
@@ -445,7 +473,11 @@ size_t ps_print(Pcpstream *stream, const char * fmt, ...) {
void ps_close(Pcpstream *stream) { void ps_close(Pcpstream *stream) {
if(stream->cache != NULL) { if(stream->cache != NULL) {
assert(buffer_left(stream->cache) == 0); /* there's something left in the cache, call ps_finish() */ if(stream->is_output == 1) {
if(buffer_left(stream->cache) != 0)
buffer_info(stream->cache);
assert(buffer_left(stream->cache) == 0); /* there's something left in the cache, call ps_finish() */
}
buffer_free(stream->cache); buffer_free(stream->cache);
} }
@@ -467,25 +499,31 @@ void ps_close(Pcpstream *stream) {
int ps_end(Pcpstream *stream) { int ps_end(Pcpstream *stream) {
/* simulate open file if there's still something in the cache */ /* simulate open file if there's still something in the cache */
if(stream->cache != NULL) if(stream->cache != NULL)
if(buffer_left(stream->cache) > 0) if(buffer_left(stream->cache) > 0) {
return 0; return 0;
}
return stream->eof; return stream->eof;
} }
int ps_left(Pcpstream *stream) {
/* used internally to determine if we reached end of source */
if(stream->is_buffer) {
if(buffer_left(stream->b) == 0)
return 1;
else
return 0;
}
else {
return feof(stream->fd);
}
}
int ps_err(Pcpstream *stream) { int ps_err(Pcpstream *stream) {
return stream->err; return stream->err;
} }
size_t ps_tell(Pcpstream *stream) { size_t ps_tell(Pcpstream *stream) {
if(stream->is_buffer) { return stream->pos;
if(stream->b->end > stream->b->offset)
return stream->b->end; /* write buffer */
else
return stream->b->offset; /* read buffer */
}
else {
return ftell(stream->fd);
}
} }
Buffer *ps_buffer(Pcpstream *stream) { Buffer *ps_buffer(Pcpstream *stream) {

View File

@@ -448,6 +448,9 @@ secret key, R is the recipient list, L is the number of recipients,
T is the filetype header, I is a block of input with a size T is the filetype header, I is a block of input with a size
of 32k, N is a nonce (new per block) and S the symmetric key. of 32k, N is a nonce (new per block) and S the symmetric key.
The encrypted output maybe Z85 encoded. In this case the Z85
encoding will be done blockwise with blocks of 16k bytes. The
decoded content inside will be as described above.
=head2 SIGNATURE FORMAT =head2 SIGNATURE FORMAT
@@ -552,6 +555,19 @@ secret signing key and S the symmetric key.
=head2 Z85 ENCODING =head2 Z85 ENCODING
B<pcp1> uses Z85 to encode exported keys and armored signatures. B<pcp1> uses Z85 to encode exported keys and armored signatures.
Comments in encoded files are surrounded by the tilde character.
We're using the tilde because it's not part of the Z85 base
charset. Sample:
~~~ Header ~~~
~ Version: 1 ~
246ge]+yn={<I&&Z%(pm[09lc5[dx4TZALi/6cjVe)Kx5S}7>}]Xi3*N3Xx34Y^0rz:r.5j
v#6Sh/m3XKwy?VlA+h8ks]9:kVj{D[fd7]NA]T-(ne+xo!W5X5-gIUWqM
~~~ Footer ~~~
Multiple tildes can be used as long as their number is uneven.
This is a proprietary PCP extension.
=head3 Z85 BACKGROUND =head3 Z85 BACKGROUND

View File

@@ -75,6 +75,7 @@
If none of -i or -r has been given, encrypt If none of -i or -r has been given, encrypt
the message symetrically. This is the same the message symetrically. This is the same
as -m (self-encryption mode). as -m (self-encryption mode).
Add -z to ascii armor the output using Z85.
-m --encrypt-me Sym-Encrypt a message. Specify -I and/or -m --encrypt-me Sym-Encrypt a message. Specify -I and/or
-O for input/output file. You will be asked -O for input/output file. You will be asked
for a passphrase. No key material will for a passphrase. No key material will
@@ -112,9 +113,9 @@
If used with encryption or singing operation If used with encryption or singing operation
encode its output. Otherwise encode a plain encode its output. Otherwise encode a plain
file. Use -I and -O respectively, otherwise it file. Use -I and -O respectively, otherwise it
stdin/stdout. uses stdin/stdout.
-Z --z85-decode Decode (dearmor) something from Z85 encoding. -Z --z85-decode Decode (dearmor) something from Z85 encoding.
Use -I and -O respectively, otherwise it Use -I and -O respectively, otherwise it
stdin/stdout uses stdin/stdout

View File

@@ -1,7 +1,7 @@
/* /*
This file is part of Pretty Curved Privacy (pcp1). This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden. Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>. You can contact me by mail: <tom AT vondein DOT org>.
*/ */
@@ -48,9 +48,15 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
} }
} }
Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out);
ps_setdetermine(pin, PCP_BLOCK_SIZE/2);
/* determine crypt mode */ /* determine crypt mode */
fread(&head, 1, 1, in); ps_read(pin, &head, 1);
if(!feof(in) && !ferror(in)) {
if(!ps_end(pin) && !ps_err(pin)) {
if(head == PCP_SYM_CIPHER) { if(head == PCP_SYM_CIPHER) {
/* symetric mode */ /* symetric mode */
byte *salt = ucmalloc(90); byte *salt = ucmalloc(90);
@@ -110,9 +116,6 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
goto errde3; goto errde3;
} }
Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out);
if(symkey == NULL) if(symkey == NULL)
dlen = pcp_decrypt_stream(pin, pout, secret, NULL, verify); dlen = pcp_decrypt_stream(pin, pout, secret, NULL, verify);
else else
@@ -136,7 +139,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt) { int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor) {
FILE *in = NULL; FILE *in = NULL;
FILE *out = NULL; FILE *out = NULL;
pcp_pubkey_t *pubhash = NULL; /* FIXME: add free() */ pcp_pubkey_t *pubhash = NULL; /* FIXME: add free() */
@@ -266,14 +269,26 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
Pcpstream *pin = ps_new_file(in); Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out); Pcpstream *pout = ps_new_file(out);
if(armor == 1) {
ps_print(pout, PCP_ENFILE_HEADER);
ps_armor(pout, PCP_BLOCK_SIZE/2);
}
if(self == 1) if(self == 1)
clen = pcp_encrypt_stream_sym(pin, pout, symkey, 0, NULL); clen = pcp_encrypt_stream_sym(pin, pout, symkey, 0, NULL);
else else
clen = pcp_encrypt_stream(pin, pout, secret, pubhash, signcrypt); clen = pcp_encrypt_stream(pin, pout, secret, pubhash, signcrypt);
ps_close(pin); if(armor == 1) {
ps_finish(pout);
ps_unarmor(pout);
ps_print(pout, PCP_ENFILE_FOOTER);
}
ps_close(pout); ps_close(pout);
ps_close(pin);
if(clen > 0) { if(clen > 0) {
if(id == NULL && recipient == NULL) if(id == NULL && recipient == NULL)
fprintf(stderr, "Encrypted %ld bytes symetrically\n", clen); fprintf(stderr, "Encrypted %ld bytes symetrically\n", clen);

View File

@@ -38,6 +38,6 @@
#include "pcpstream.h" #include "pcpstream.h"
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify); int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify);
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt); int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor);
#endif /* _HAVE_ENCRYPTION_H */ #endif /* _HAVE_ENCRYPTION_H */

View File

@@ -474,11 +474,11 @@ int main (int argc, char **argv) {
if(useid == 1 && userec == 0) { if(useid == 1 && userec == 0) {
/* one dst, FIXME: make id a list as well */ /* one dst, FIXME: make id a list as well */
id = pcp_normalize_id(keyid); id = pcp_normalize_id(keyid);
pcpencrypt(id, infile, outfile, xpass, NULL, signcrypt); pcpencrypt(id, infile, outfile, xpass, NULL, signcrypt, armor);
} }
else if(useid == 0 && userec == 1) { else if(useid == 0 && userec == 1) {
/* multiple dst */ /* multiple dst */
pcpencrypt(NULL, infile, outfile, xpass, recipient, signcrypt); pcpencrypt(NULL, infile, outfile, xpass, recipient, signcrypt, armor);
} }
else { else {
/* -i and -r specified */ /* -i and -r specified */
@@ -558,7 +558,7 @@ int main (int argc, char **argv) {
break; break;
case PCP_MODE_ENCRYPT_ME: case PCP_MODE_ENCRYPT_ME:
pcpencrypt(NULL, infile, outfile, xpass, NULL, 0); pcpencrypt(NULL, infile, outfile, xpass, NULL, 0, armor);
break; break;
case PCP_MODE_TEXT: case PCP_MODE_TEXT:

View File

@@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <sys/select.h>
#include <pcp.h> #include <pcp.h>

View File

@@ -35,6 +35,40 @@ include keys.cfg
</test> </test>
<test check-streams>
<test check-streams-8-8>
md5 = `md5 -q ../COPYING`
cmd = ./pipetest 8 8 e < ../COPYING | ./pipetest 8 8 d | md5 -q
expect = /$md5/
</test>
<test check-streams-8-16>
md5 = `md5 -q ../COPYING`
cmd = ./pipetest 8 16 e < ../COPYING | ./pipetest 8 16 d | md5 -q
expect = /$md5/
</test>
<test check-streams-16-8>
md5 = `md5 -q ../COPYING`
cmd = ./pipetest 16 8 e < ../COPYING | ./pipetest 16 8 d | md5 -q
expect = /$md5/
</test>
<test check-streams-64-32>
md5 = `md5 -q ../COPYING`
cmd = ./pipetest 64 32 e < ../COPYING | ./pipetest 64 32 d | md5 -q
expect = /$md5/
</test>
<test check-streams-32-64>
md5 = `md5 -q ../COPYING`
cmd = ./pipetest 32 64 e < ../COPYING | ./pipetest 32 64 d | md5 -q
expect = /$md5/
</test>
<test check-streams-64-64>
md5 = `md5 -q ../COPYING`
cmd = ./pipetest 64 64 e < ../COPYING | ./pipetest 64 64 d | md5 -q
expect = /$md5/
</test>
</test>
<test check-show-help> <test check-show-help>
cmd = $pcp -h cmd = $pcp -h
expect = /export/ expect = /export/

View File

@@ -73,6 +73,10 @@ sub runtest {
my($cfg, $name) = @_; my($cfg, $name) = @_;
my($in, $out, $error, $timeout); my($in, $out, $error, $timeout);
foreach my $key (keys %{$cfg}) {
$cfg->{$key} =~ s/\`([^\`]*)\`/my $result = `$1`; chomp $result; $result/ge;
}
if (exists $cfg->{prepare}) { if (exists $cfg->{prepare}) {
print STDERR " executing prepare command: $cfg->{prepare}\n" if ($verbose); print STDERR " executing prepare command: $cfg->{prepare}\n" if ($verbose);
if ($cfg->{prepare} =~ />/) { if ($cfg->{prepare} =~ />/) {