Merge branch 'master' of github.com:TLINDEN/pcp

This commit is contained in:
TLINDEN
2014-03-14 15:52:55 +01:00
17 changed files with 142 additions and 56 deletions

4
TODO
View File

@@ -25,6 +25,10 @@ Symmetric decrypt mode tries to open vault
pcp_find_primary_secret() makes a copy ??? pcp_find_primary_secret() makes a copy ???
sym encrypt mac => mac, mac => freebsd and freebsd => mac doesnt work
c++ destructor double free mess
Python binding, e.g.: Python binding, e.g.:
py % cdll.LoadLibrary("libsodium.so.8") py % cdll.LoadLibrary("libsodium.so.8")
<CDLL 'libsodium.so.8', handle 800776c00 at 80192a3d0> <CDLL 'libsodium.so.8', handle 800776c00 at 80192a3d0>

View File

@@ -62,6 +62,7 @@ AC_TYPE_SIZE_T
# Checks for library functions. # Checks for library functions.
AC_CHECK_FUNCS( \ AC_CHECK_FUNCS( \
arc4random_buf \ arc4random_buf \
arc4random \
fread \ fread \
fopen \ fopen \
free \ free \
@@ -75,6 +76,7 @@ AC_CHECK_FUNCS( \
memcpy \ memcpy \
perror \ perror \
strnlen \ strnlen \
strnstr \
strlen \ strlen \
strtol \ strtol \
sizeof \ sizeof \

View File

@@ -1,5 +1,8 @@
/* include/pcp/config.h.in. Generated from configure.ac by autoheader. */ /* include/pcp/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `arc4random' function. */
#undef HAVE_ARC4RANDOM
/* Define to 1 if you have the `arc4random_buf' function. */ /* Define to 1 if you have the `arc4random_buf' function. */
#undef HAVE_ARC4RANDOM_BUF #undef HAVE_ARC4RANDOM_BUF
@@ -115,6 +118,9 @@
/* Define to 1 if you have the `strnlen' function. */ /* Define to 1 if you have the `strnlen' function. */
#undef HAVE_STRNLEN #undef HAVE_STRNLEN
/* Define to 1 if you have the `strnstr' function. */
#undef HAVE_STRNSTR
/* Define to 1 if you have the `strtol' function. */ /* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL #undef HAVE_STRTOL

View File

@@ -33,11 +33,14 @@
# include <sys/endian.h> # include <sys/endian.h>
# ifndef HAVE_BE32TOH # ifndef HAVE_BE32TOH
# /* openbsd, use aliases */ # /* openbsd, use aliases */
# define be16toh betoh16
# define be32toh betoh32 # define be32toh betoh32
# define be64toh betoh64 # define be64toh betoh64
# endif # endif
# else /* no sys/endian.h */ # else /* no sys/endian.h */
# ifdef __CPU_IS_BIG_ENDIAN # ifdef __CPU_IS_BIG_ENDIAN
# define be16toh(x) (x)
# define htobe16(x) (x)
# define be32toh(x) (x) # define be32toh(x) (x)
# define htobe32(x) (x) # define htobe32(x) (x)
# define be64toh(x) (x) # define be64toh(x) (x)
@@ -52,6 +55,8 @@
# error Need either netinet/in.h or arpa/inet.h for ntohl() and htonl() # error Need either netinet/in.h or arpa/inet.h for ntohl() and htonl()
# endif # endif
# endif # endif
# define be16toh(x) ((u_int16_t)ntohl((u_int16_t)(x)))
# define htobe16(x) ((u_int16_t)htonl((u_int16_t)(x)))
# define be32toh(x) ((u_int32_t)ntohl((u_int32_t)(x))) # define be32toh(x) ((u_int32_t)ntohl((u_int32_t)(x)))
# define htobe32(x) ((u_int32_t)htonl((u_int32_t)(x))) # define htobe32(x) ((u_int32_t)htonl((u_int32_t)(x)))
# define be64toh(x) ((u_int64_t)ntohl((u_int64_t)(x))) # define be64toh(x) ((u_int64_t)ntohl((u_int64_t)(x)))
@@ -61,20 +66,18 @@
#endif /* HAVE_ENDIAN_H */ #endif /* HAVE_ENDIAN_H */
#ifndef HAVE_ARC4RANDOM_BUF #ifndef HAVE_ARC4RANDOM
/* shitty OS. we're using libsodium's implementation */
#include <sodium.h> #include <sodium.h>
static inline u_int32_t arc4random() { static inline u_int32_t arc4random() {
return randombytes_random(); return randombytes_random();
} }
#endif
#ifndef HAVE_ARC4RANDOM_BUF
#include <sodium.h>
static inline void arc4random_buf(void *buf, size_t nbytes) { static inline void arc4random_buf(void *buf, size_t nbytes) {
randombytes((unsigned char*)buf, nbytes); randombytes((unsigned char*)buf, nbytes);
} }
#endif #endif
@@ -140,6 +143,47 @@ int vasprintf(char **ret, const char *format, va_list args) {
#endif #endif
#ifndef HAVE_STRNLEN
static inline size_t
strnlen(const char *msg, size_t maxlen)
{
size_t i;
for (i=0; i<maxlen; i++)
if (msg[i] == '\0')
break;
return i;
}
#endif
#ifndef HAVE_STRNSTR
/* via FreeBSD libc */
#include <string.h>
static inline char *
strnstr(const char *s, const char *find, size_t slen)
{
char c, sc;
size_t len;
if ((c = *find++) != '\0') {
len = strlen(find);
do {
do {
if (slen-- < 1 || (sc = *s++) == '\0')
return (NULL);
} while (sc != c);
if (len > slen)
return (NULL);
} while (strncmp(s, find, len) != 0);
s--;
}
return ((char *)s);
}
#endif
#endif /* !_HAVE_PCP_PLATFORM_H */ #endif /* !_HAVE_PCP_PLATFORM_H */

View File

@@ -19,6 +19,8 @@
You can contact me by mail: <tom AT vondein DOT org>. You can contact me by mail: <tom AT vondein DOT org>.
*/ */
#define _GNU_SOURCE /* vasprintf() linux */
#include "buffer.h" #include "buffer.h"
void buffer_init(Buffer *b, size_t blocksize, char *name) { void buffer_init(Buffer *b, size_t blocksize, char *name) {
@@ -88,11 +90,12 @@ void buffer_add_str(Buffer *b, const char * fmt, ...) {
va_list ap; va_list ap;
char *dst; char *dst;
va_start(ap, fmt); va_start(ap, fmt);
vasprintf(&dst, fmt, ap); if(vasprintf(&dst, fmt, ap) >= 0) {
if(b->end > 0)
b->end--;
buffer_add(b, dst, strlen(dst)+1);
}
va_end(ap); va_end(ap);
if(b->end > 0)
b->end--;
buffer_add(b, dst, strlen(dst)+1);
free(dst); free(dst);
} }

View File

@@ -600,7 +600,6 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
#endif #endif
} }
free(buf_nonce);
free(buf_cipher); free(buf_cipher);
if(recverify != NULL) { if(recverify != NULL) {
@@ -637,6 +636,8 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
free(signature_cr); free(signature_cr);
} }
free(buf_nonce);
return out_size; return out_size;
} }
@@ -655,8 +656,8 @@ pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_
r->secret = NULL; r->secret = NULL;
if(pub != NULL) { if(pub != NULL) {
r->pub = ucmalloc(sizeof(pcp_key_t)); r->pub = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(r->pub, pub, sizeof(pcp_key_t)); memcpy(r->pub, pub, sizeof(pcp_pubkey_t));
} }
else else
r->pub = NULL; r->pub = NULL;

View File

@@ -22,7 +22,7 @@
#include "ed.h" #include "ed.h"
byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) { byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) {
byte *message = ucmalloc(siglen - crypto_sign_BYTES); byte *message = ucmalloc(siglen);
unsigned long long mlen; unsigned long long mlen;
if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) { if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) {
@@ -142,7 +142,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
byte sighash[mlen]; byte sighash[mlen];
char z85sigstart[] = "\n" PCP_SIG_START; /* FIXME: verifies, but it misses the \r! */ char z85sigstart[] = "\n" PCP_SIG_START; /* FIXME: verifies, but it misses the \r! */
char binsigstart[] = PCP_SIGPREFIX; char binsigstart[] = PCP_SIGPREFIX;
char sigstart[] = PCP_SIG_START; char sigstart[] = "\n" PCP_SIG_START;
size_t siglen, startlen; size_t siglen, startlen;
size_t offset = -1; size_t offset = -1;
@@ -172,8 +172,8 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
} }
if(z85 == 1) { if(z85 == 1) {
/* keep sigstart as is, it's per default set to z85 sigstart */
siglen = zlen; siglen = zlen;
strcpy(sigstart, z85sigstart);
startlen = strlen(z85sigstart); startlen = strlen(z85sigstart);
} }
else { else {

View File

@@ -19,10 +19,12 @@
You can contact me by mail: <tlinden AT cpan DOT org>. You can contact me by mail: <tlinden AT cpan DOT org>.
*/ */
#define _GNU_SOURCE /* vasprintf() linux */
#include "defines.h" #include "defines.h"
#include "platform.h" #include "platform.h"
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@@ -38,11 +40,14 @@ void fatal(const char * fmt, ...) {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
vasprintf(&PCP_ERR, fmt, ap); if(vasprintf(&PCP_ERR, fmt, ap) >= 0) {
va_end(ap);
va_end(ap); PCP_ERRSET = 1;
}
PCP_ERRSET = 1; else {
fprintf(stderr, "Could not store fatal error message %s!\n", fmt);
PCP_ERRSET = 1;
}
} }
void fatals_reset() { void fatals_reset() {
@@ -51,7 +56,7 @@ void fatals_reset() {
void fatals_ifany() { void fatals_ifany() {
if(PCP_ERRSET == 1) { if(PCP_ERRSET == 1) {
fprintf(stderr, PCP_ERR); fprintf(stderr, "%s", PCP_ERR);
if(errno) { if(errno) {
fprintf(stderr, "Error: %s\n", strerror(errno)); fprintf(stderr, "Error: %s\n", strerror(errno));
} }

View File

@@ -19,6 +19,8 @@
You can contact me by mail: <tom AT vondein DOT org>. You can contact me by mail: <tom AT vondein DOT org>.
*/ */
#define _XOPEN_SOURCE /* strptime, linux glibc*/
#define _BSD_SOURCE
#include "mgmt.h" #include "mgmt.h"
@@ -76,7 +78,7 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
uint16_t nsize = buffer_get16na(blob); uint16_t nsize = buffer_get16na(blob);
uint16_t vsize = buffer_get16na(blob); uint16_t vsize = buffer_get16na(blob);
char *notation = ucmalloc(nsize); char *notation = ucmalloc(nsize+1);
if(buffer_get_chunk(blob, notation, nsize) == 0) if(buffer_get_chunk(blob, notation, nsize) == 0)
return 1; return 1;

View File

@@ -19,6 +19,7 @@
You can contact me by mail: <tom AT vondein DOT org>. You can contact me by mail: <tom AT vondein DOT org>.
*/ */
#define _GNU_SOURCE /* vasprintf() linux */
#include "pcpstream.h" #include "pcpstream.h"
Pcpstream *ps_init(void) { Pcpstream *ps_init(void) {
@@ -618,17 +619,22 @@ size_t ps_print(Pcpstream *stream, const char * fmt, ...) {
va_list ap; va_list ap;
char *dst; char *dst;
va_start(ap, fmt); va_start(ap, fmt);
vasprintf(&dst, fmt, ap); if(vasprintf(&dst, fmt, ap) >= 0) {
va_end(ap); va_end(ap);
size_t len = strlen(dst); size_t len = strlen(dst);
if(stream->is_buffer) { if(stream->is_buffer) {
buffer_add(stream->b, dst, len); buffer_add(stream->b, dst, len);
}
else {
len = ps_write(stream, dst, len);
}
free(dst);
return len; return len;
} }
else { va_end(ap);
return ps_write(stream, dst, len); return 0;
}
} }
void ps_close(Pcpstream *stream) { void ps_close(Pcpstream *stream) {

View File

@@ -79,7 +79,7 @@ blkxor(void * dest, void * src, size_t len)
static void static void
salsa20_8(uint32_t B[16]) salsa20_8(uint32_t B[16])
{ {
uint32_t x[16]; uint32_t x[16] = {0};
size_t i; size_t i;
blkcpy(x, B, 64); blkcpy(x, B, 64);

View File

@@ -318,7 +318,7 @@ int pcpvault_copy(vault_t *tmp, vault_t *vault) {
int tmpsize = ftell(tmp->fd); int tmpsize = ftell(tmp->fd);
fseek(tmp->fd, 0, SEEK_SET); fseek(tmp->fd, 0, SEEK_SET);
byte *in = ucmalloc(tmpsize); byte *in = ucmalloc(tmpsize);
fread(in, tmpsize, 1, tmp->fd); tmpsize = fread(in, 1, tmpsize, tmp->fd);
/* and put it into the new file */ /* and put it into the new file */
vault->fd = freopen(vault->filename, "wb+", vault->fd); vault->fd = freopen(vault->filename, "wb+", vault->fd);
@@ -407,16 +407,21 @@ vault_item_header_t * ih2native(vault_item_header_t *h) {
int pcpvault_fetchall(vault_t *vault) { int pcpvault_fetchall(vault_t *vault) {
size_t got = 0;
fseek(vault->fd, 0, SEEK_SET); fseek(vault->fd, 0, SEEK_SET);
vault_header_t *header = ucmalloc(sizeof(vault_header_t)); vault_header_t *header = ucmalloc(sizeof(vault_header_t));
vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t)); vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t));
fread(header, sizeof(vault_header_t), 1, vault->fd); got = fread(header, 1, sizeof(vault_header_t), vault->fd);
if(got < sizeof(vault_header_t)) {
fatal("empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t));
goto err;
}
vh2native(header); vh2native(header);
if(header->fileid == PCP_VAULT_ID && header->version == PCP_VAULT_VERSION) { if(header->fileid == PCP_VAULT_ID && header->version == PCP_VAULT_VERSION) {
/* loop over the file and slurp everything in */ /* loop over the file and slurp everything in */
int readpos = 0; size_t readpos = 0;
pcp_key_t *key; pcp_key_t *key;
pcp_pubkey_t *pubkey; pcp_pubkey_t *pubkey;
int bytesleft = 0; int bytesleft = 0;
@@ -431,7 +436,7 @@ int pcpvault_fetchall(vault_t *vault) {
readpos = ftell(vault->fd); readpos = ftell(vault->fd);
if(vault->size - readpos >= sizeof(vault_item_header_t)) { if(vault->size - readpos >= sizeof(vault_item_header_t)) {
/* an item header follows */ /* an item header follows */
fread(item, sizeof(vault_item_header_t), 1, vault->fd); got = fread(item, sizeof(vault_item_header_t), 1, vault->fd);
ih2native(item); ih2native(item);
if(item->size > 0) { if(item->size > 0) {
@@ -444,14 +449,14 @@ int pcpvault_fetchall(vault_t *vault) {
item->type == PCP_KEY_TYPE_SECRET) { item->type == PCP_KEY_TYPE_SECRET) {
/* read a secret key */ /* read a secret key */
key = ucmalloc(sizeof(pcp_key_t)); key = ucmalloc(sizeof(pcp_key_t));
fread(key, PCP_RAW_KEYSIZE, 1, vault->fd); got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
key2native(key); key2native(key);
pcphash_add((void *)key, item->type); pcphash_add((void *)key, item->type);
} }
else if(item->type == PCP_KEY_TYPE_PUBLIC) { else if(item->type == PCP_KEY_TYPE_PUBLIC) {
/* read a public key */ /* read a public key */
pubkey = ucmalloc(sizeof(pcp_pubkey_t)); pubkey = ucmalloc(sizeof(pcp_pubkey_t));
fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd); got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
pubkey2native(pubkey); pubkey2native(pubkey);
pcphash_add((void *)pubkey, item->type); pcphash_add((void *)pubkey, item->type);
} }

View File

@@ -70,10 +70,10 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
} }
else { else {
passphrase = ucmalloc(strlen(passwd)+1); passphrase = ucmalloc(strlen(passwd)+1);
strncpy(passphrase, passwd, strlen(passwd)+1); strncpy(passphrase, passwd, strlen(passwd));
} }
symkey = pcp_scrypt(passphrase, crypto_secretbox_KEYBYTES, salt, 90); symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90);
free(salt); free(salt);
} }
else { else {
@@ -159,12 +159,12 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
} }
else { else {
passphrase = ucmalloc(strlen(passwd)+1); passphrase = ucmalloc(strlen(passwd)+1);
strncpy(passphrase, passwd, strlen(passwd)+1); strncpy(passphrase, passwd, strlen(passwd));
} }
byte *salt = ucmalloc(90); /* FIXME: use random salt, concat it with result afterwards */ byte *salt = ucmalloc(90); /* FIXME: use random salt, concat it with result afterwards */
char stsalt[] = PBP_COMPAT_SALT; char stsalt[] = PBP_COMPAT_SALT;
memcpy(salt, stsalt, 90); memcpy(salt, stsalt, 90);
symkey = pcp_scrypt(passphrase, crypto_secretbox_KEYBYTES, salt, 90); symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90);
free(salt); free(salt);
} }
else if(id != NULL && recipient == NULL) { else if(id != NULL && recipient == NULL) {

View File

@@ -555,7 +555,7 @@ char *pcp_find_id_byrec(char *recipient) {
int pcp_import (vault_t *vault, FILE *in, char *passwd) { int pcp_import (vault_t *vault, FILE *in, char *passwd) {
byte *buf = ucmalloc(2048); byte *buf = ucmalloc(PCP_BLOCK_SIZE);
size_t bufsize; size_t bufsize;
pcp_pubkey_t *pub = NULL; pcp_pubkey_t *pub = NULL;
pcp_key_t *sk = NULL; pcp_key_t *sk = NULL;

View File

@@ -60,7 +60,8 @@ void test0() {
DECRYPTED = _openrd("testcppdecrypted"); DECRYPTED = _openrd("testcppdecrypted");
char *got = (char *)ucmalloc(10); char *got = (char *)ucmalloc(10);
fread(got, 1, 6, DECRYPTED); size_t h;
h = fread(got, 1, 6, DECRYPTED);
if(strncmp(got, "HALLO", 5) != 0) { if(strncmp(got, "HALLO", 5) != 0) {
throw pcp::exception(); throw pcp::exception();
} }

7
tests/md5 Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
file=$1
if type md5 > /dev/null 2>&1; then
md5 -q $*
else
md5sum $* | awk '{print $1}'
fi

View File

@@ -38,33 +38,33 @@ include keys.cfg
<test check-streams> <test check-streams>
<test check-streams-8-8> <test check-streams-8-8>
md5 = `md5 -q ../COPYING` md5 = `./md5 ../COPYING`
cmd = ./pipetest 8 8 e < ../COPYING | ./pipetest 8 8 d | md5 -q cmd = ./pipetest 8 8 e < ../COPYING | ./pipetest 8 8 d | ./md5
expect = /$md5/ expect = /$md5/
</test> </test>
<test check-streams-8-16> <test check-streams-8-16>
md5 = `md5 -q ../COPYING` md5 = `./md5 ../COPYING`
cmd = ./pipetest 8 16 e < ../COPYING | ./pipetest 8 16 d | md5 -q cmd = ./pipetest 8 16 e < ../COPYING | ./pipetest 8 16 d | ./md5
expect = /$md5/ expect = /$md5/
</test> </test>
<test check-streams-16-8> <test check-streams-16-8>
md5 = `md5 -q ../COPYING` md5 = `./md5 ../COPYING`
cmd = ./pipetest 16 8 e < ../COPYING | ./pipetest 16 8 d | md5 -q cmd = ./pipetest 16 8 e < ../COPYING | ./pipetest 16 8 d | ./md5
expect = /$md5/ expect = /$md5/
</test> </test>
<test check-streams-64-32> <test check-streams-64-32>
md5 = `md5 -q ../COPYING` md5 = `./md5 ../COPYING`
cmd = ./pipetest 64 32 e < ../COPYING | ./pipetest 64 32 d | md5 -q cmd = ./pipetest 64 32 e < ../COPYING | ./pipetest 64 32 d | ./md5
expect = /$md5/ expect = /$md5/
</test> </test>
<test check-streams-32-64> <test check-streams-32-64>
md5 = `md5 -q ../COPYING` md5 = `./md5 ../COPYING`
cmd = ./pipetest 32 64 e < ../COPYING | ./pipetest 32 64 d | md5 -q cmd = ./pipetest 32 64 e < ../COPYING | ./pipetest 32 64 d | ./md5
expect = /$md5/ expect = /$md5/
</test> </test>
<test check-streams-64-64> <test check-streams-64-64>
md5 = `md5 -q ../COPYING` md5 = `./md5 ../COPYING`
cmd = ./pipetest 64 64 e < ../COPYING | ./pipetest 64 64 d | md5 -q cmd = ./pipetest 64 64 e < ../COPYING | ./pipetest 64 64 d | ./md5
expect = /$md5/ expect = /$md5/
</test> </test>
</test> </test>