From b8008d1207af7da1f6379292ce5c5a5b87b48202 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Thu, 20 Oct 2016 23:14:14 +0200 Subject: [PATCH] removed endian conversion code, now we just write in big-endian on output with shifts, not swaps etc --- configure.ac | 106 +++++++++------------------------- include/pcp.h | 1 + include/pcp/config.h.in | 12 ---- include/pcp/key.h | 4 ++ include/pcp/platform.h | 53 ----------------- include/pcp/util.h | 13 +++++ include/pcp/version.h | 6 +- libpcp/buffer.c | 39 ++++++------- libpcp/crypto.c | 36 +++++------- libpcp/key.c | 123 +++++++++++++++++----------------------- libpcp/keysig.c | 16 +----- libpcp/mgmt.c | 14 ++--- libpcp/util.c | 68 ++++++++++++++++++++++ libpcp/vault.c | 69 ++++++++-------------- 14 files changed, 231 insertions(+), 329 deletions(-) diff --git a/configure.ac b/configure.ac index 9c7f81b..47e6c75 100755 --- a/configure.ac +++ b/configure.ac @@ -58,8 +58,8 @@ AC_CANONICAL_HOST # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(errno.h err.h stdlib.h string.h unistd.h stdio.h getopt.h\ - limits.h stddef.h stdint.h sys/types.h sys/stat.h endian.h \ - sys/endian.h termios.h arpa/inet.h netinet/in.h wctype.h) + limits.h stddef.h stdint.h sys/types.h sys/stat.h \ + termios.h arpa/inet.h netinet/in.h wctype.h) AC_TYPE_SIZE_T @@ -94,39 +94,6 @@ AC_CHECK_FUNCS( \ vasprintf ) -AC_MSG_CHECKING([for be32toh]) -AC_TRY_LINK([ -#include "libpcp/pcp/config.h" -#ifdef HAVE_ENDIAN_H -#include -#endif -#ifdef HAVE_SYS_ENDIAN_H -#include -#endif -], [ - (void)be32toh(0); -], [AC_MSG_RESULT([no])], [ - AC_DEFINE(HAVE_BE32TOH,, Define if be32toh() is available) - AC_MSG_RESULT([yes]) -]) - -AC_MSG_CHECKING([for htobe32]) -AC_TRY_LINK([ -#include "libpcp/pcp/config.h" -#ifdef HAVE_ENDIAN_H -#include -#endif -#ifdef HAVE_SYS_ENDIAN_H -#include -#endif -], [ - (void)htobe32(0); -], [AC_MSG_RESULT([no])], [ - AC_DEFINE(HAVE_HTOBE32,, Define if htobe32() is available) - AC_MSG_RESULT([yes]) -]) - - cross_compile="no" AC_MSG_CHECKING([compiler and flags for sanity]) AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], @@ -309,27 +276,6 @@ AC_LANG_PROGRAM([[ ) fi -if test "$cross_compile" = "no"; then -# check endianess -# program returns 0 on little and 1 on big endian systems -AC_MSG_CHECKING([are we on a big endian system]) -AC_RUN_IFELSE([ -AC_LANG_PROGRAM([[]],[[long one= 1; exit(!(*((char *)(&one)))); ]])], - [ - AC_MSG_RESULT([no]) - bigendian="no" - ], - [ - AC_MSG_RESULT([yes]) - bigendian="yes" - ] -) -fi - -if test "x$bigendian" = "xyes"; then - CFLAGS="$CFLAGS -D__CPU_IS_BIG_ENDIAN=1" -fi - # prepare FLAGS CFLAGS="$CFLAGS -Werror -Wextra -Wall" @@ -410,28 +356,28 @@ AC_CONFIG_FILES([Makefile include/Makefile libpcp/Makefile src/Makefile man/Make AC_OUTPUT AC_MSG_RESULT([ - Build configured for $PACKAGE $VERSION: - CC: ${CC} - CFLAGS: ${CFLAGS} - CXX: ${CXX} - CXXFLAGS: ${CXXFLAGS} - LDFLAGS: ${LDFLAGS} - LIBS: ${LIBS} - debug: ${enable_debug} - optimize: ${enable_optimize} - - prefix: ${prefix} - libdir: ${libdir} - includedir: ${includedir} - - target platform: ${host} - big endian cpu: ${bigendian} - cross compile: ${cross_compile} - - build python binding: ${python} - build c++ binding: ${enable_cpp_binding} - - json support ${_have_json} - Type 'make' to build, 'make install' to install. - To execute unit tests, type 'make test'. + Build configured for $PACKAGE $VERSION: + CC: ${CC} + CFLAGS: ${CFLAGS} + CXX: ${CXX} + CXXFLAGS: ${CXXFLAGS} + LDFLAGS: ${LDFLAGS} + LIBS: ${LIBS} + DEBUG: ${enable_debug} + optimize: ${enable_optimize} + + prefix: ${prefix} + libdir: ${libdir} + includedir: ${includedir} + + target platform: ${host} + cross compile: ${cross_compile} + + build python binding: ${python} + build c++ binding: ${enable_cpp_binding} + + json support: ${_have_json} + + Type 'make' to build, 'make install' to install. + To execute unit tests, type 'make test'. ]) diff --git a/include/pcp.h b/include/pcp.h index bf2f993..9c1213d 100644 --- a/include/pcp.h +++ b/include/pcp.h @@ -7,6 +7,7 @@ extern "C" { #include "pcp/config.h" #include "pcp/buffer.h" +#include "pcp/config.h" #include "pcp/context.h" #include "pcp/crypto.h" #include "pcp/defines.h" diff --git a/include/pcp/config.h.in b/include/pcp/config.h.in index b53de92..88f26bc 100644 --- a/include/pcp/config.h.in +++ b/include/pcp/config.h.in @@ -9,15 +9,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H -/* Define if be32toh() is available */ -#undef HAVE_BE32TOH - /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H -/* Define to 1 if you have the header file. */ -#undef HAVE_ENDIAN_H - /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H @@ -51,9 +45,6 @@ /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG -/* Define if htobe32() is available */ -#undef HAVE_HTOBE32 - /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -126,9 +117,6 @@ /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_ENDIAN_H - /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H diff --git a/include/pcp/key.h b/include/pcp/key.h index 6f9e84d..2d4c69b 100644 --- a/include/pcp/key.h +++ b/include/pcp/key.h @@ -271,6 +271,10 @@ void pcp_seckeyblob(Buffer *b, pcp_key_t *k); void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k); Buffer *pcp_keyblob(void *k, int type); /* allocates blob */ +/* reads key from blob */ +pcp_key_t *pcp_blob2key(Buffer *b); /* allocates key */ +pcp_pubkey_t *pcp_blob2pubkey(Buffer *b); + /** Make a sanity check of the given public key structure. \param[in] ptx pcp context. diff --git a/include/pcp/platform.h b/include/pcp/platform.h index bba945e..abf0356 100644 --- a/include/pcp/platform.h +++ b/include/pcp/platform.h @@ -25,59 +25,6 @@ #include "config.h" -#ifdef HAVE_ENDIAN_H -# include -#else /* no endian.h */ -# ifdef HAVE_SYS_ENDIAN_H -# include -# include -# ifndef HAVE_BE32TOH -# /* openbsd, use aliases */ -# define be16toh betoh16 -# define be32toh betoh32 -# define be64toh betoh64 -# endif -# else /* no sys/endian.h */ -# ifdef __CPU_IS_BIG_ENDIAN -# define be16toh(x) (x) -# define htobe16(x) (x) -# define be32toh(x) (x) -# define htobe32(x) (x) -# define be64toh(x) (x) -# define htobe64(x) (x) -# elif defined(__APPLE__) /* from https://gist.github.com/panzi/6856583 */ -# include -# define htobe16(x) OSSwapHostToBigInt16(x) -# define be16toh(x) OSSwapBigToHostInt16(x) -# define htobe32(x) OSSwapHostToBigInt32(x) -# define be32toh(x) OSSwapBigToHostInt32(x) -# define htobe64(x) OSSwapHostToBigInt64(x) -# define be64toh(x) OSSwapBigToHostInt64(x) -# define __BYTE_ORDER BYTE_ORDER -# define __BIG_ENDIAN BIG_ENDIAN -# define __LITTLE_ENDIAN LITTLE_ENDIAN -# define __PDP_ENDIAN PDP_ENDIAN -# else -# ifdef HAVE_ARPA_INET_H -# include -# else -# ifdef HAVE_NETINET_IN_H -# include -# else -# error Need either netinet/in.h or arpa/inet.h for ntohl() and htonl() -# endif -# endif -# define be16toh(x) ((uint16_t)ntohl((uint16_t)(x))) -# define htobe16(x) ((uint16_t)htonl((uint16_t)(x))) -# define be32toh(x) ((uint32_t)ntohl((uint32_t)(x))) -# define htobe32(x) ((uint32_t)htonl((uint32_t)(x))) -# define be64toh(x) ((uint64_t)ntohl((uint64_t)(x))) -# define htobe64(x) ((uint64_t)htonl((uint64_t)(x))) -# endif -# endif /* HAVE_SYS_ENDIAN_H */ -#endif /* HAVE_ENDIAN_H */ - - #ifndef HAVE_ARC4RANDOM #include #define arc4random() randombytes_random() diff --git a/include/pcp/util.h b/include/pcp/util.h index 10e98e2..f1637ac 100644 --- a/include/pcp/util.h +++ b/include/pcp/util.h @@ -123,6 +123,19 @@ size_t _hex2bin(const char *hex_str, unsigned char *byte_array, size_t byte_arra */ int cst_time_memcmp(const void *m1, const void *m2, size_t n); + + +// be32toh +uint64_t _wireto64(byte *data); +uint32_t _wireto32(byte *data); +uint16_t _wireto16(byte *data); + +// htobe32 +void _64towire(uint64_t i, byte *data); +void _32towire(uint32_t i, byte *data); +void _16towire(uint16_t i, byte *data); + + #endif /* _HAVE_PCP_UTIL_H */ /**@}*/ diff --git a/include/pcp/version.h b/include/pcp/version.h index f34b509..80b1194 100644 --- a/include/pcp/version.h +++ b/include/pcp/version.h @@ -1,7 +1,7 @@ /* This file is part of Pretty Curved Privacy (pcp1). - Copyright (C) 2013-2014 T.v.Dein. + Copyright (C) 2013-2016 T.v.Dein. 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 @@ -24,8 +24,8 @@ #define _HAVE_PCP_VERSION #define PCP_VERSION_MAJOR 0 -#define PCP_VERSION_MINOR 3 -#define PCP_VERSION_PATCH 1 +#define PCP_VERSION_MINOR 4 +#define PCP_VERSION_PATCH 0 #define PCP_VERSION PCP_MAKE_VERSION(PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH) #define PCP_MAKE_VERSION(major, minor, patch) ((major * 10000) + (minor * 100) + (patch)) diff --git a/libpcp/buffer.c b/libpcp/buffer.c index 933bba6..c1623fc 100644 --- a/libpcp/buffer.c +++ b/libpcp/buffer.c @@ -221,30 +221,27 @@ uint64_t buffer_get64(Buffer *b) { } uint16_t buffer_get16na(Buffer *b) { - uint16_t i; - if(buffer_get_chunk(b, &i, 2) > 0) { - i = be16toh(i); - return i; + uint8_t bin[2]; + if(buffer_get_chunk(b, bin, 2) > 0) { + return _wireto16(bin); } else return 0; } uint32_t buffer_get32na(Buffer *b) { - uint32_t i; - if(buffer_get_chunk(b, &i, 4) > 0) { - i = be32toh(i); - return i; + uint8_t bin[4]; + if(buffer_get_chunk(b, bin, 4) > 0) { + return _wireto32(bin); } else return 0; } uint64_t buffer_get64na(Buffer *b) { - uint64_t i; - if(buffer_get_chunk(b, &i, 8) > 0) { - i = be64toh(i); - return i; + uint8_t bin[8]; + if(buffer_get_chunk(b, bin, 8) > 0) { + return _wireto64(bin); } else return 0; @@ -362,19 +359,19 @@ void buffer_add64(Buffer *b, uint64_t v) { } void buffer_add16be(Buffer *b, uint16_t v) { - uint16_t e = v; - e = htobe16(e); - buffer_add(b, &e, 2); + uint8_t bin[2]; + _16towire(v, bin); + buffer_add(b, bin, 2); } void buffer_add32be(Buffer *b, uint32_t v) { - uint32_t e = v; - e = htobe32(e); - buffer_add(b, &e, 4); + uint8_t bin[4]; + _32towire(v, bin); + buffer_add(b, bin, 4); } void buffer_add64be(Buffer *b, uint64_t v) { - uint64_t e = v; - e = htobe64(e); - buffer_add(b, &e, 8); + uint8_t bin[8]; + _64towire(v, bin); + buffer_add(b, bin, 8); } diff --git a/libpcp/crypto.c b/libpcp/crypto.c index 3f360e1..40fc29a 100644 --- a/libpcp/crypto.c +++ b/libpcp/crypto.c @@ -202,12 +202,13 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t } /* step 3, check len recipients */ - cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */ + byte li[4]; + cur_bufsize = ps_read(in, li, 4); /* fread(&lenrec, 1, 4, in); */ if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) { fatal(ptx, "Error: input file doesn't contain recipient count\n"); goto errdef1; } - lenrec = be32toh(lenrec); + lenrec = _wireto32(li); if (ptx->verbose) { fprintf(stderr, "crypto.c: input is encrypted for %ld recipients\n", (long int)lenrec); @@ -353,10 +354,10 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t pcp_pubkey_t *cur, *t; size_t es; int nrec; - uint32_t lenrec; size_t rec_size, out_size; byte head[1]; - + byte bo[4]; + /* 6[1]|temp_keypair.pubkey|len(recipients)[4]|(recipients...)|(secretboxes...) where recipients is a concatenated list of @@ -437,9 +438,9 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t } /* step 3, len recipients, big endian */ - lenrec = recipient_count; - lenrec = htobe32(lenrec); - ps_write(out, &lenrec, 4); + + _32towire(recipient_count, bo); + ps_write(out, bo, 4); if(ps_err(out) != 0) goto errec1; @@ -789,8 +790,6 @@ void pcp_rec_free(pcp_rec_t *r) { uint64_t _get_nonce_ctr(byte *nonce) { uint64_t ctr = 0; uint8_t i = nonce[0]; - uint16_t m16 = 0; - uint32_t m32 = 0; if(i > 16) { /* counter bigger than max allowed by protocol, could lead to overflow, therefore die hard here */ @@ -803,16 +802,13 @@ uint64_t _get_nonce_ctr(byte *nonce) { ctr = nonce[1]; break; case 2: - memcpy(&m16, &nonce[1], 2); - ctr = be16toh(m16); + ctr = _wireto16(&nonce[1]); break; case 4: - memcpy(&m32, &nonce[1], 4); - ctr = be32toh(m32); + ctr = _wireto32(&nonce[1]); break; case 8: - memcpy(&ctr, &nonce[1], 8); - ctr = be64toh(ctr); + ctr = _wireto64(&nonce[1]); break; } @@ -876,25 +872,21 @@ byte *_gen_ctr_nonce(uint64_t ctr) { uint8_t m8 = -1; uint16_t m16 = -1; uint32_t m32 = -1; - uint64_t m64 = -1; uint8_t i = 1; byte *nonce = pcp_gennonce(); if(ctr > m32) { i = 8; - m64 = htobe64(ctr); - memcpy(&nonce[1], &m64, 8); + _64towire(ctr, &nonce[1]); } else if(ctr <= m32 && ctr > m16) { i = 4; - m32 = htobe32(ctr); - memcpy(&nonce[1], &m32, 4); + _32towire(ctr, &nonce[1]); } else if(ctr <= m16 && ctr > m8) { i = 2; - m16 = htobe16(ctr); - memcpy(&nonce[1], &m16, 2); + _16towire(ctr, &nonce[1]); } else { i = 1; diff --git a/libpcp/key.c b/libpcp/key.c index 4df8a1b..4e46dcc 100644 --- a/libpcp/key.c +++ b/libpcp/key.c @@ -253,96 +253,77 @@ byte *pcpkey_getchecksum(pcp_key_t *k) { } -pcp_key_t * key2be(pcp_key_t *k) { -#ifdef __CPU_IS_BIG_ENDIAN - return k; -#else - uint32_t version = k->version; - byte* p = (byte*)&version; - if(p[0] != 0) { - k->version = htobe32(k->version); - k->serial = htobe32(k->serial); - k->ctime = htobe64(k->ctime); - } - return k; -#endif -} - -pcp_key_t *key2native(pcp_key_t *k) { -#ifdef __CPU_IS_BIG_ENDIAN - return k; -#else - k->version = be32toh(k->version); - k->serial = be32toh(k->serial); - k->ctime = be64toh(k->ctime); - return k; -#endif -} - -pcp_pubkey_t * pubkey2be(pcp_pubkey_t *k) { -#ifdef __CPU_IS_BIG_ENDIAN - return k; -#else - uint32_t version = k->version; - byte* p = (byte*)&version; - if(p[0] != 0) { - k->version = htobe32(k->version); - k->serial = htobe32(k->serial); - k->ctime = htobe64(k->ctime); - } - return k; -#endif -} - -pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) { -#ifdef __CPU_IS_BIG_ENDIAN - return k; -#else - k->version = be32toh(k->version); - k->serial = be32toh(k->serial); - k->ctime = be64toh(k->ctime); - return k; -#endif +void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) { + buffer_add(b, k->masterpub, LEDPUB); + buffer_add(b, k->pub, LBOXPUB); + buffer_add(b, k->edpub, LEDPUB); + buffer_add(b, k->owner, 255); + buffer_add(b, k->mail, 255); + buffer_add(b, k->id, 17); + buffer_add8(b, k->type); + buffer_add64be(b, k->ctime); + buffer_add32be(b, k->version); + buffer_add32be(b, k->serial); + buffer_add8(b, k->valid); } void pcp_seckeyblob(Buffer *b, pcp_key_t *k) { buffer_add(b, k->masterpub, LEDPUB); buffer_add(b, k->mastersecret, LEDSEC); - buffer_add(b, k->pub, LBOXPUB); buffer_add(b, k->secret, LBOXPUB); - buffer_add(b, k->edpub, LEDPUB); buffer_add(b, k->edsecret, LEDSEC); - buffer_add(b, k->nonce, LNONCE); - buffer_add(b, k->encrypted, LSEC); - buffer_add(b, k->owner, 255); buffer_add(b, k->mail, 255); buffer_add(b, k->id, 17); - buffer_add8(b, k->type); - buffer_add64(b, k->ctime); - buffer_add32(b, k->version); - buffer_add32(b, k->serial); + buffer_add64be(b, k->ctime); + buffer_add32be(b, k->version); + buffer_add32be(b, k->serial); } -void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) { - buffer_add(b, k->masterpub, LEDPUB); - buffer_add(b, k->pub, LBOXPUB); - buffer_add(b, k->edpub, LEDPUB); +pcp_key_t *pcp_blob2key(Buffer *b) { + pcp_key_t *k = ucmalloc(sizeof(pcp_key_t)); + + buffer_get_chunk(b, k->masterpub, LEDPUB); + buffer_get_chunk(b, k->mastersecret, LEDSEC); + buffer_get_chunk(b, k->pub, LBOXPUB); + buffer_get_chunk(b, k->secret, LBOXPUB); + buffer_get_chunk(b, k->edpub, LEDPUB); + buffer_get_chunk(b, k->edsecret, LEDSEC); + buffer_get_chunk(b, k->nonce, LNONCE); + buffer_get_chunk(b, k->encrypted, LSEC); + buffer_get_chunk(b, k->owner, 255); + buffer_get_chunk(b, k->mail, 255); + buffer_get_chunk(b, k->id, 17); - buffer_add(b, k->owner, 255); - buffer_add(b, k->mail, 255); - buffer_add(b, k->id, 17); + k->type = buffer_get8(b); + k->ctime = buffer_get64na(b); + k->version = buffer_get32na(b); + k->serial = buffer_get32na(b); - buffer_add8(b, k->type); - buffer_add64(b, k->ctime); - buffer_add32(b, k->version); - buffer_add32(b, k->serial); - buffer_add8(b, k->valid); + return k; +} + +pcp_pubkey_t *pcp_blob2pubkey(Buffer *b) { + pcp_pubkey_t *k = ucmalloc(sizeof(pcp_key_t)); + + buffer_get_chunk(b, k->masterpub, LEDPUB); + buffer_get_chunk(b, k->pub, LBOXPUB); + buffer_get_chunk(b, k->edpub, LEDPUB); + buffer_get_chunk(b, k->owner, 255); + buffer_get_chunk(b, k->mail, 255); + buffer_get_chunk(b, k->id, 17); + + k->type = buffer_get8(b); + k->ctime = buffer_get64na(b); + k->version = buffer_get32na(b); + k->serial = buffer_get32na(b); + k->valid = buffer_get8(b); + return k; } Buffer *pcp_keyblob(void *k, int type) { diff --git a/libpcp/keysig.c b/libpcp/keysig.c index 738d148..a3da830 100644 --- a/libpcp/keysig.c +++ b/libpcp/keysig.c @@ -23,25 +23,13 @@ #include "keysig.h" pcp_keysig_t * keysig2be(pcp_keysig_t *s) { -#ifdef __CPU_IS_BIG_ENDIAN + _32towire(s->size, (byte *)&s->size); return s; -#else - uint32_t size = s->size; - byte* p = (byte*)&size; - if(p[0] != 0) { - s->size = htobe32(s->size); - } - return s; -#endif } pcp_keysig_t *keysig2native(pcp_keysig_t *s) { -#ifdef __CPU_IS_BIG_ENDIAN + s->size = _wireto32((byte *)&s->size); return s; -#else - s->size = be32toh(s->size); - return s; -#endif } Buffer *pcp_keysig2blob(pcp_keysig_t *s) { diff --git a/libpcp/mgmt.c b/libpcp/mgmt.c index c7a3d6f..e787f2e 100644 --- a/libpcp/mgmt.c +++ b/libpcp/mgmt.c @@ -36,9 +36,9 @@ int _get_pk(Buffer *blob, pcp_pubkey_t *p) { int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) { if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) { - buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h)); + buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h)); /* FIXME: blog 2 struct? thafck */ - h->numsubs = be16toh(h->numsubs); + h->numsubs = _wireto16((byte *)&h->numsubs); if(h->version != EXP_SIG_VERSION) { fatal(ptx, "Unsupported pubkey signature version %d, expected %d\n", @@ -800,7 +800,7 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras cipherlen, nonce, symkey) != 0) { fatal(ptx, "failed to decrypt the secret key file\n"); - goto impserr1; + goto impserr2; } /* prepare the extraction buffer */ @@ -817,7 +817,8 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras notationlen = buffer_get16na(blob); if(notationlen > 255) { - fatal(ptx, "Invalid notation value size for owner\n"); + fatal(ptx, "Invalid notation value size for owner (got: %ld, expected: 255)\n", + notationlen); goto impserr2; } else if(notationlen > 0) @@ -825,7 +826,8 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras notationlen = buffer_get16na(blob); if(notationlen > 255) { - fatal(ptx, "Invalid notation value size for mail\n"); + fatal(ptx, "Invalid notation value size for mail (got: %ld, expected: 255)\n", + notationlen); goto impserr2; } else if(notationlen > 0) @@ -862,8 +864,6 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras buffer_free(blob); if(symkey != NULL) sfree(symkey); - if(clear != NULL) - free(clear); return NULL; } diff --git a/libpcp/util.c b/libpcp/util.c index 2f798c7..7835565 100644 --- a/libpcp/util.c +++ b/libpcp/util.c @@ -120,6 +120,74 @@ size_t _hex2bin(const char *hex_str, unsigned char *byte_array, size_t byte_arra return byte_array_size; } + + +/* + * Convert byte arrays from big endian to numbers and vice versa. Do + * not take care about host endianess. In Rob Pikes' words: + * https://commandcenter.blogspot.de/2012/04/byte-order-fallacy.html + * + * With this, we remove all calls to byte swap functions like b64toh + * and the likes. They are problematic and I really hated the ifdef + * mess in platform.h anyway. + */ + +uint64_t _wireto64(byte *data) { + uint64_t i = + ((uint64_t)data[7]<<0) | + ((uint64_t)data[6]<<8) | + ((uint64_t)data[5]<<16) | + ((uint64_t)data[4]<<24) | + ((uint64_t)data[3]<<32) | + ((uint64_t)data[2]<<40) | + ((uint64_t)data[1]<<48) | + ((uint64_t)data[0]<<56); + return i; +} + +uint32_t _wireto32(byte *data) { + uint32_t i = + ((uint32_t)data[3]<<0) | + ((uint32_t)data[2]<<8) | + ((uint32_t)data[1]<<16) | + ((uint32_t)data[0]<<24); + return i; +} + +uint16_t _wireto16(byte *data) { + uint16_t i = + ((uint16_t)data[1]<<0) | + ((uint16_t)data[0]<<8); + return i; +} + +void _64towire(uint64_t i, byte *data) { + data[0] = (i >> 56) & 0xFF; + data[1] = (i >> 48) & 0xFF; + data[2] = (i >> 40) & 0xFF; + data[3] = (i >> 32) & 0xFF; + data[4] = (i >> 24) & 0xFF; + data[5] = (i >> 16) & 0xFF; + data[6] = (i >> 8) & 0xFF; + data[7] = i & 0xFF; +} + +void _32towire(uint32_t i, byte *data) { + data[0] = (i >> 24) & 0xFF; + data[1] = (i >> 16) & 0xFF; + data[2] = (i >> 8) & 0xFF; + data[3] = i & 0xFF; +} + +void _16towire(uint16_t i, byte *data) { + data[0] = (i >> 8) & 0xFF; + data[1] = i & 0xFF; +} + + + + + /* via https://github.com/chmike/cst_time_memcmp Licensed as: diff --git a/libpcp/vault.c b/libpcp/vault.c index 9831e9d..8949c0b 100644 --- a/libpcp/vault.c +++ b/libpcp/vault.c @@ -164,11 +164,10 @@ int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) { itemsize = PCP_RAW_PUBKEYSIZE; saveitem = ucmalloc(sizeof(pcp_pubkey_t)); memcpy(saveitem, item, sizeof(pcp_pubkey_t)); - pubkey2be((pcp_pubkey_t *)item); - blob = buffer_new(PCP_RAW_KEYSIZE, "bs"); - pcp_pubkeyblob(blob, (pcp_pubkey_t *)item); + blob = pcp_keyblob(item, type); } else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) { + /* FIXME: handle the same way as keys */ saveitem = ucmalloc(sizeof(pcp_keysig_t)); pcp_keysig_t *ksin = (pcp_keysig_t *)item; pcp_keysig_t *ksout = (pcp_keysig_t *)saveitem; @@ -183,9 +182,7 @@ int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) { itemsize = PCP_RAW_KEYSIZE; saveitem = ucmalloc(sizeof(pcp_key_t)); memcpy(saveitem, item, sizeof(pcp_key_t)); - key2be((pcp_key_t *)item); blob = pcp_keyblob(item, type); - pcp_seckeyblob(blob, (pcp_key_t *)item); } if(tmp != NULL) { @@ -295,23 +292,19 @@ byte *pcpvault_create_checksum(PCPCTX *ptx) { byte *checksum = ucmalloc(LSHA); pcphash_iterate(ptx, k) { - key2be(k); pcp_seckeyblob(blob, (pcp_key_t *)k); - memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE); + memcpy(&data[datapos], buffer_get(blob), buffer_size(blob)); buffer_clear(blob); - key2native(k); - datapos += PCP_RAW_KEYSIZE; + datapos += buffer_size(blob); } pcp_pubkey_t *p = NULL; pcphash_iteratepub(ptx, p) { /* pcp_dumppubkey(p); */ - pubkey2be(p); pcp_pubkeyblob(blob, (pcp_pubkey_t *)p); - memcpy(&data[datapos], buffer_get(blob), PCP_RAW_PUBKEYSIZE); + memcpy(&data[datapos], buffer_get(blob), buffer_size(blob)); buffer_clear(blob); - pubkey2native(p); - datapos += PCP_RAW_PUBKEYSIZE; + datapos += PCP_RAW_KEYSIZE; } buffer_free(blob); @@ -390,41 +383,25 @@ void pcpvault_free(vault_t *vault) { } vault_header_t * vh2be(vault_header_t *h) { -#ifdef __CPU_IS_BIG_ENDIAN + _32towire(h->version, (byte *)&h->version); return h; -#else - h->version = htobe32(h->version); - return h; -#endif } vault_header_t * vh2native(vault_header_t *h) { -#ifdef __CPU_IS_BIG_ENDIAN + h->version = _wireto32((byte *)&h->version); return h; -#else - h->version = be32toh(h->version); - return h; -#endif } vault_item_header_t * ih2be(vault_item_header_t *h) { -#ifdef __CPU_IS_BIG_ENDIAN + _32towire(h->version, (byte *)&h->version); + _32towire(h->size, (byte *)&h->size); return h; -#else - h->version = htobe32(h->version); - h->size = htobe32(h->size); - return h; -#endif } vault_item_header_t * ih2native(vault_item_header_t *h) { -#ifdef __CPU_IS_BIG_ENDIAN + h->version = _wireto32((byte *)&h->version); + h->size = _wireto32((byte *)&h->size); return h; -#else - h->version = be32toh(h->version); - h->size = be32toh(h->size); - return h; -#endif } @@ -449,7 +426,8 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) { pcp_pubkey_t *pubkey; int bytesleft = 0; int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */ - + Buffer *raw = buffer_new(256, "rawin"); + vault->version = header->version; memcpy(vault->checksum, header->checksum, LSHA); @@ -469,24 +447,23 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) { if(item->type == PCP_KEY_TYPE_MAINSECRET || item->type == PCP_KEY_TYPE_SECRET) { /* read a secret key */ - key = ucmalloc(sizeof(pcp_key_t)); - got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd); - key2native(key); + buffer_fd_read(raw, vault->fd, item->size); + key = pcp_blob2key(raw); pcphash_add(ptx, (void *)key, item->type); + buffer_clear(raw); } else if(item->type == PCP_KEY_TYPE_PUBLIC) { /* read a public key */ - pubkey = ucmalloc(sizeof(pcp_pubkey_t)); - got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd); - pubkey2native(pubkey); + buffer_fd_read(raw, vault->fd, item->size); + pubkey = pcp_blob2pubkey(raw); pcphash_add(ptx, (void *)pubkey, item->type); + buffer_clear(raw); } else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) { - Buffer *rawks = buffer_new(256, "keysig"); - buffer_fd_read(rawks, vault->fd, item->size); - pcp_keysig_t *s = pcp_keysig_new(rawks); + buffer_fd_read(raw, vault->fd, item->size); + pcp_keysig_t *s = pcp_keysig_new(raw); pcphash_add(ptx, (void *)s, item->type); - buffer_free(rawks); + buffer_clear(raw); } else { fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n",