From e847e7057d1f08c5dfa4d6c5b36bcf84daa94776 Mon Sep 17 00:00:00 2001 From: TLINDEN Date: Mon, 7 Dec 2015 14:13:27 +0100 Subject: [PATCH] fix #14: use longterm secret key for signing in -Ac mode (anonymous encrypt+sign) --- ChangeLog | 4 + bindings/cpp/crypto.cpp | 2 +- bindings/py/pypcp/raw.py | 263 ++++++++++++++++++++------------------- include/pcp/crypto.h | 7 +- include/pcp/defines.h | 1 + libpcp/crypto.c | 61 ++++++--- man/pcp1.1 | 2 +- src/encryption.c | 24 ++-- tests/sample.c | 2 +- 9 files changed, 203 insertions(+), 163 deletions(-) diff --git a/ChangeLog b/ChangeLog index d028860..40827bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,10 @@ NEXT of libc's memcpy: constant time memcpy is much more secure than the default, especially in our context. + Anonymous encrypted files are now signed with primary + secret key, so that the recipient will be able to + verify the signature. + 0.3.0 Changed publuc key signature storage, previously I didn't add the actual signature, therefore a diff --git a/bindings/cpp/crypto.cpp b/bindings/cpp/crypto.cpp index 0d8cbb5..2790edd 100644 --- a/bindings/cpp/crypto.cpp +++ b/bindings/cpp/crypto.cpp @@ -54,7 +54,7 @@ bool Crypto::encrypt(FILE *in, FILE *out, bool sign) { Pcpstream *pin = ps_new_file(in); Pcpstream *pout = ps_new_file(out); - size_t clen = pcp_encrypt_stream(PTX->ptx, pin, pout, S.K, pubhash, sign, 0); // FIXME: add anon support + size_t clen = pcp_encrypt_stream(PTX->ptx, pin, pout, S.K, S.K, pubhash, sign, 0); // FIXME: add anon support if(clen <= 0) throw exception(PTX); ps_close(pin); diff --git a/bindings/py/pypcp/raw.py b/bindings/py/pypcp/raw.py index 3fd5f5c..3e135ba 100644 --- a/bindings/py/pypcp/raw.py +++ b/bindings/py/pypcp/raw.py @@ -16,13 +16,13 @@ typedef struct json_t { size_t refcount; } json_t; -/*** ./gencffi.pl: from ../../include/pcp/defines.h:182 */ +/*** ./gencffi.pl: from ../../include/pcp/defines.h:183 */ typedef unsigned char byte; -/*** ./gencffi.pl: from ../../include/pcp/defines.h:182 */ +/*** ./gencffi.pl: from ../../include/pcp/defines.h:183 */ typedef unsigned short dbyte; -/*** ./gencffi.pl: from ../../include/pcp/defines.h:182 */ +/*** ./gencffi.pl: from ../../include/pcp/defines.h:183 */ typedef unsigned int qbyte; /*** ./gencffi.pl: from ../../include/pcp/plist.h:83 */ @@ -403,31 +403,28 @@ void final(const char * fmt, ...); /*** ./gencffi.pl: from ../../include/pcp/context.h:96 */ void ptx_dump(PCPCTX *ptx); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ -size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt, int anon); - -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, int havehead, pcp_rec_t *recsign); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify, int anon); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ int pcp_checksum(PCPCTX *ptx, Pcpstream *in, byte *checksum, byte *key, size_t keylen); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ void pcp_rec_free(pcp_rec_t *r); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ byte *_gen_ctr_nonce(uint64_t ctr); -/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */ +/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */ uint64_t _get_nonce_ctr(byte *nonce); /*** ./gencffi.pl: from ../../include/pcp/ed.h:202 */ @@ -874,141 +871,145 @@ uint8_t *zmq_z85_decode (uint8_t *dest, char *string); /*** ./gencffi.pl: from ../../include/pcp/zmq_z85.h:31 */ char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);''' -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_FORMAT_NATIVE = 1 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_SIG_HEADER = "----- BEGIN ED25519 SIGNED MESSAGE -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_ASYM_CIPHER_ANON = 6 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_SIG_END = "----- END ED25519 SIGNATURE -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_SUB_CTIME = 2 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_SYM_CIPHER = 23 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 PCP_ENFILE_HEADER = "----- BEGIN PCP ENCRYPTED FILE -----\r\n" -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PBP_COMPAT_SALT = "qa~t](84z<1t<1oz:ik.@IRNyhG=8q(on9}4#!/_h#a7wqK{Nt$T?W>,mt8NqYq&6U,rSYI2GRDd:Bcm" +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_SYM_CIPHER = 23 -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_FORMAT_PBP = 2 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_HASH_NAME = "BLAKE2" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SK_HEADER = "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_RFC_CIPHER = 0x21 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_ASYM_CIPHER_SIG = 24 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_CIPHER_NAME = "ED25519" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SK_FOOTER = "----- END ED25519-CURVE29915 PRIVATE KEY -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_ME = "Pretty Curved Privacy" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_ZFILE_HEADER = "----- BEGIN Z85 ENCODED FILE -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_SUB_SIGEXPIRE = 3 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_VAULT_ID = 14 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_ZFILE_FOOTER = "----- END Z85 ENCODED FILE -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_SUB_KEYFLAGS = 27 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_PK_FOOTER = "----- END ED25519-CURVE29915 PUBLIC KEY -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_SIGPREFIX = "\nnacl-" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -PCP_SIG_START = "----- BEGIN ED25519 SIGNATURE -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_PK_HEADER = "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----" - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_SUB_KEYEXPIRE = 9 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_HASH_CIPHER = 0x22 - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 PCP_ENFILE_FOOTER = "\r\n----- END PCP ENCRYPTED FILE -----\r\n" -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_SUB_NOTATION = 20 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_SIG_START = "----- BEGIN ED25519 SIGNATURE -----" -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_CIPHER = 0x23 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_PK_HEADER = "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----" -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_SIG_TYPE = 0x1F - - -# ./gencffi.pl: from ../../include/pcp/defines.h:182 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 PCP_ASYM_CIPHER = 5 -# ./gencffi.pl: from ../../include/pcp/defines.h:182 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_ASYM_CIPHER_SIG = 24 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_SIGPREFIX = "\nnacl-" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 EXP_PK_CIPHER_NAME = "CURVE25519-ED25519-POLY1305-SALSA20" -# ./gencffi.pl: from ../../include/pcp/defines.h:182 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PBP_COMPAT_SALT = "qa~t](84z<1t<1oz:ik.@IRNyhG=8q(on9}4#!/_h#a7wqK{Nt$T?W>,mt8NqYq&6U,rSYI2GRDd:Bcm" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_SUB_KEYEXPIRE = 9 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_VAULT_ID = 14 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_PK_CIPHER = 0x21 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_ASYM_CIPHER_ANON = 6 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_HASH_CIPHER = 0x22 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_SUB_CTIME = 2 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SK_FOOTER = "----- END ED25519-CURVE29915 PRIVATE KEY -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_TYPE = 0x1F + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_HASH_NAME = "BLAKE2" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_PK_FOOTER = "----- END ED25519-CURVE29915 PUBLIC KEY -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_CIPHER = 0x23 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_ASYM_CIPHER_ANON_SIG = 7 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_SUB_KEYFLAGS = 27 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 PCP_BLOCK_SIZE = 32 * 1024 -# ./gencffi.pl: from ../../include/pcp/defines.h:182 -EXP_PK_CIPHER = 0x21 +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SK_HEADER = "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_ZFILE_FOOTER = "----- END Z85 ENCODED FILE -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_SUB_SIGEXPIRE = 3 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_ZFILE_HEADER = "----- BEGIN Z85 ENCODED FILE -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_ME = "Pretty Curved Privacy" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_SIG_END = "----- END ED25519 SIGNATURE -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_FORMAT_NATIVE = 1 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_SIG_HEADER = "----- BEGIN ED25519 SIGNED MESSAGE -----" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_FORMAT_PBP = 2 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_CIPHER_NAME = "ED25519" + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +EXP_SIG_SUB_NOTATION = 20 + + +# ./gencffi.pl: from ../../include/pcp/defines.h:183 +PCP_RFC_CIPHER = 0x21 diff --git a/include/pcp/crypto.h b/include/pcp/crypto.h index 2b2c551..ba0ec4e 100644 --- a/include/pcp/crypto.h +++ b/include/pcp/crypto.h @@ -183,7 +183,9 @@ byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub, \param[out] out Stream to write encrypted result to. - \param[in] s Secret key structure of the sender. + \param[in] s Secret key structure of the sender for encryption. + + \param[in] s Secret key structure of the sender for signing. \param[in] p Public key hash containing a list of the recipients. @@ -193,7 +195,8 @@ byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub, \return Returns the size of the output written to the output stream or 0 in case of errors. */ -size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt, int anon); +size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, + pcp_key_t *ss, pcp_pubkey_t *p, int signcrypt, int anon); /** Symmetrically encrypt a file or a buffer stream. diff --git a/include/pcp/defines.h b/include/pcp/defines.h index 78936a3..b5e16af 100644 --- a/include/pcp/defines.h +++ b/include/pcp/defines.h @@ -125,6 +125,7 @@ typedef enum _PCP_KEY_TYPES { /* crypto file format stuff */ #define PCP_ASYM_CIPHER 5 #define PCP_ASYM_CIPHER_ANON 6 +#define PCP_ASYM_CIPHER_ANON_SIG 7 #define PCP_SYM_CIPHER 23 #define PCP_ASYM_CIPHER_SIG 24 #define PCP_BLOCK_SIZE 32 * 1024 diff --git a/libpcp/crypto.c b/libpcp/crypto.c index 17353f3..8aacf90 100644 --- a/libpcp/crypto.c +++ b/libpcp/crypto.c @@ -157,6 +157,11 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t self = 0; anon = 1; } + else if(head[0] == PCP_ASYM_CIPHER_ANON_SIG) { + self = 0; + anon = 1; + verify = 1; + } else if(head[0] == PCP_ASYM_CIPHER) { self = 0; } @@ -171,6 +176,7 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t } } + if(self) { /* just decrypt symetrically and go outa here */ return pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL); @@ -193,7 +199,7 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t goto errdef1; } lenrec = be32toh(lenrec); - + if(verify) { reccipher = ucmalloc(lenrec * PCP_ASYM_RECIPIENT_SIZE); } @@ -223,6 +229,10 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t memcpy(symkey, recipient, crypto_secretbox_KEYBYTES); free(recipient); ucfree(senderpub, sizeof(pcp_pubkey_t)); + if(verify) { + memcpy(reccipher, rec_buf, PCP_ASYM_RECIPIENT_SIZE); + } + nrec++; /* otherwise missing */ break; } free(recipient); @@ -237,6 +247,7 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t recmatch = 1; symkey = smalloc(crypto_secretbox_KEYBYTES); memcpy(symkey, recipient, crypto_secretbox_KEYBYTES); + free(recipient); break; } @@ -282,7 +293,7 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t /* step 5, actually decrypt the file, finally */ 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); nrec = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec); pcp_rec_free(rec); ucfree(reccipher, lenrec * PCP_ASYM_RECIPIENT_SIZE); @@ -304,7 +315,8 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t return 0; } -size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign, int anon) { +size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *secret, + pcp_key_t *signsecret, pcp_pubkey_t *p, int sign, int anon) { byte *symkey; int recipient_count; byte *recipients_cipher; @@ -333,7 +345,7 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t HASH_ITER(hh, p, cur, t) { byte *rec_cipher; - rec_cipher = pcp_box_encrypt(ptx, s, cur, symkey, crypto_secretbox_KEYBYTES, &es); + rec_cipher = pcp_box_encrypt(ptx, secret, cur, symkey, crypto_secretbox_KEYBYTES, &es); if(es != rec_size) { fatal(ptx, "invalid rec_size, expected %dl, got %dl\n", rec_size, es); if(rec_cipher != NULL) @@ -348,14 +360,16 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t } /* step 1, file header */ - if(sign) - head[0] = PCP_ASYM_CIPHER_SIG; + if(sign && anon) + head[0] = PCP_ASYM_CIPHER_ANON_SIG; + else if(sign) + head[0] = PCP_ASYM_CIPHER_SIG; else if(anon) head[0] = PCP_ASYM_CIPHER_ANON; - else + else head[0] = PCP_ASYM_CIPHER; ps_write(out, head, 1); - + if(ps_err(out) != 0) { fatal(ptx, "Failed to write encrypted output!\n"); goto errec1; @@ -363,9 +377,7 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t if(anon) { /* step 2, sender's pubkey */ - ps_write(out, s->pub, crypto_box_PUBLICKEYBYTES); - /*fwrite(s->pub, crypto_box_PUBLICKEYBYTES, 1, out); */ - /* fprintf(stderr, "D: sender pub - %d\n", crypto_box_PUBLICKEYBYTES); */ + ps_write(out, secret->pub, crypto_box_PUBLICKEYBYTES); if(ps_err(out) != 0) goto errec1; } @@ -374,14 +386,11 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t lenrec = recipient_count; lenrec = htobe32(lenrec); ps_write(out, &lenrec, 4); - /* fwrite(&lenrec, 4, 1, out); */ - /* fprintf(stderr, "D: %d recipients - 4\n", recipient_count); */ if(ps_err(out) != 0) goto errec1; /* step 4, recipient list */ ps_write(out, recipients_cipher, rec_size * recipient_count); - /* fwrite(recipients_cipher, rec_size * recipient_count, 1, out); */ /* fprintf(stderr, "D: recipients - %ld * %d\n", rec_size, recipient_count); */ if(ps_err(out) != 0) goto errec1; @@ -391,7 +400,7 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t /* step 5, actual encrypted data */ size_t sym_size = 0; if(sign) { - pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL); + pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, signsecret, NULL); sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, rec); pcp_rec_free(rec); } @@ -520,7 +529,8 @@ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte * return 0; } -size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) { +size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, + byte *symkey, pcp_rec_t *recverify) { byte *buf_nonce; byte *buf_cipher; byte *buf_clear; @@ -619,12 +629,26 @@ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte * crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX); byte *verifiedhash = NULL; - verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub); + + if(recverify->pub == NULL) { + /* anonymous encrypted but with known pub signed, + dig through our list of known public keys for a match */ + pcp_pubkey_t *cur; + pcphash_iteratepub(ptx, cur) { + verifiedhash = pcp_ed_verify(ptx, signature, siglen, cur); + if(verifiedhash != NULL) + break; + } + } + else { + verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub); + } + if(verifiedhash == NULL) out_size = 0; else { if(cst_time_memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) { - /* sig verified, but the hash doesn't match */ + /* sig verified, but the hash doesn't match */ fatal(ptx, "signed hash doesn't match actual hash of signed decrypted file content\n"); out_size = 0; } @@ -652,7 +676,6 @@ pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_ r->cipher = ucmalloc(clen); memcpy(r->cipher, cipher, clen); r->ciphersize = clen; - if(secret != NULL) { r->secret = ucmalloc(sizeof(pcp_key_t)); memcpy(r->secret, secret, sizeof(pcp_key_t)); diff --git a/man/pcp1.1 b/man/pcp1.1 index 6771fd7..e659e0c 100644 --- a/man/pcp1.1 +++ b/man/pcp1.1 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "PCP1 1" -.TH PCP1 1 "2015-11-15" "PCP 0.3.1" "USER CONTRIBUTED DOCUMENTATION" +.TH PCP1 1 "2015-12-07" "PCP 0.3.1" "USER CONTRIBUTED DOCUMENTATION" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/src/encryption.c b/src/encryption.c index 58108a3..8bf155f 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -78,7 +78,8 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i sfree(passphrase); free(salt); } - else if(head == PCP_ASYM_CIPHER || head == PCP_ASYM_CIPHER_SIG || head == PCP_ASYM_CIPHER_ANON) { + else if(head == PCP_ASYM_CIPHER || head == PCP_ASYM_CIPHER_SIG + || head == PCP_ASYM_CIPHER_ANON || head == PCP_ASYM_CIPHER_ANON_SIG) { /* asymetric mode */ if(useid) { secret = pcphash_keyexists(ptx, id); @@ -116,6 +117,11 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i if(head == PCP_ASYM_CIPHER_SIG) verify = 1; + + if(head == PCP_ASYM_CIPHER_ANON_SIG) { + anon = 1; + verify = 1; + } } else { fatal(ptx, "Could not determine input file type (got: %02x)\n", head); @@ -157,13 +163,15 @@ 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 armor, int anon) { +int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, + plist_t *recipient, int signcrypt, int armor, int anon) { FILE *in = NULL; FILE *out = NULL; pcp_pubkey_t *pubhash = NULL; /* FIXME: add free() */ pcp_pubkey_t *tmp = NULL; pcp_pubkey_t *pub = NULL; pcp_key_t *secret = NULL; + pcp_key_t *signsecret = NULL; byte *symkey = NULL; int symmode = 0; @@ -252,10 +260,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec if(symmode != 1) { /* we're using a random secret keypair on our side */ - if(anon) { - secret = pcpkey_new(); - } - else { + if(signcrypt || !anon) { secret = pcp_find_primary_secret(); if(secret == NULL) { fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename); @@ -275,8 +280,11 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec sfree(passphrase); if(secret == NULL) goto erren2; - + + signsecret = secret; } + if(anon) + secret = pcpkey_new(); } if(infile == NULL) @@ -312,7 +320,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec sfree(symkey); } else { - clen = pcp_encrypt_stream(ptx, pin, pout, secret, pubhash, signcrypt, anon); + clen = pcp_encrypt_stream(ptx, pin, pout, secret, signsecret, pubhash, signcrypt, anon); } if(armor == 1) { diff --git a/tests/sample.c b/tests/sample.c index ff0fe1c..f0ec0f0 100644 --- a/tests/sample.c +++ b/tests/sample.c @@ -36,7 +36,7 @@ int main() { /* actually encrypt the message, don't sign it Alice is the sender, Bob is the recipient */ - pcp_encrypt_stream(ptx, clear_in, crypt_out, alice, pubhash, 0, 0); + pcp_encrypt_stream(ptx, clear_in, crypt_out, alice, alice, pubhash, 0, 0); /* now, print the encrypted result */ fprintf(stderr, "Alice encrypted %"FMT_SIZE_T" bytes for Bob:\n", (SIZE_T_CAST)strlen(message));