diff --git a/include/pcp/crypto.h b/include/pcp/crypto.h index da8d190..50afe5b 100644 --- a/include/pcp/crypto.h +++ b/include/pcp/crypto.h @@ -32,6 +32,7 @@ #include "defines.h" #include "mem.h" #include "key.h" +#include "keyhash.h" size_t pcp_sodium_box(unsigned char **cipher, unsigned char *cleartext, diff --git a/include/pcp/defines.h b/include/pcp/defines.h index 36fb647..24856c9 100644 --- a/include/pcp/defines.h +++ b/include/pcp/defines.h @@ -65,6 +65,15 @@ typedef unsigned int qbyte; // Quad byte = 32 bits // sigs #define PCP_SIG_VERSION 2 +// crypto file format stuff +#define PCP_ASYM_CIPHER 5 +#define PCP_BLOCK_CIPHER 23 +#define PCP_BLOCK_SIZE 32 * 1024 +#define PCP_BLOCK_SIZE_IN (PCP_BLOCK_SIZE) + 16 + crypto_secretbox_NONCEBYTES +#define PCP_ASYM_RECIPIENT_SIZE ((crypto_secretbox_KEYBYTES + crypto_box_ZEROBYTES) - crypto_box_BOXZEROBYTES) + crypto_secretbox_NONCEBYTES +//#define PCP_ASYM_ADD_SENDER_PUB + +// error handling extern char *PCP_ERR; extern byte PCP_ERRSET; extern int PCP_EXIT; diff --git a/libpcp/crypto.c b/libpcp/crypto.c index 2095d83..8f32acf 100644 --- a/libpcp/crypto.c +++ b/libpcp/crypto.c @@ -149,7 +149,7 @@ unsigned char *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub, // resulting size: // ciphersize - crypto_secretbox_ZEROBYTES - *dsize = ciphersize - crypto_secretbox_ZEROBYTES; + *dsize = ciphersize - crypto_secretbox_NONCEBYTES - 16; return message; errbed: @@ -161,67 +161,119 @@ unsigned char *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub, return NULL; } + size_t pcp_decrypt_file(FILE *in, FILE* out, pcp_key_t *s) { - pcp_pubkey_t *p; - size_t clen; - size_t dlen = 0; + unsigned char *symkey = NULL; + pcp_pubkey_t *cur, *sender; + size_t es; + int nrec, recmatch; + uint32_t lenrec; + uint8_t head; + size_t cur_bufsize, rec_size, out_size; + size_t ciphersize = (PCP_BLOCK_SIZE_IN) - crypto_secretbox_NONCEBYTES; + unsigned char in_buf[PCP_BLOCK_SIZE_IN]; + unsigned char rec_buf[PCP_ASYM_RECIPIENT_SIZE]; + unsigned char *buf_nonce; + unsigned char *buf_cipher; + unsigned char *buf_clear; +#ifdef PCP_ASYM_ADD_SENDER_PUB + unsigned char *senderpub; +#endif - char *encoded = pcp_readz85file(in); - if(encoded == NULL) - return 0; + // step 1, check header + cur_bufsize = fread(&head, 1, 1, in); + if(cur_bufsize != 1 && !feof(in) && !ferror(in)) + if(head != PCP_ASYM_CIPHER) { + fatal("Error: input file is not asymetrically encrypted\n"); // FIXME: check for sym + goto errdef1; + } - unsigned char *combined = pcp_z85_decode((char *)encoded, &clen); - clen = clen - crypto_secretbox_KEYBYTES; - - if(combined == NULL) - goto errdf1; - - // extract the sender's public key from the cipher - p = ucmalloc(sizeof(pcp_pubkey_t)); - memcpy(p->pub, combined, crypto_secretbox_KEYBYTES); - - unsigned char *encrypted = ucmalloc(clen); - memcpy(encrypted, &combined[crypto_secretbox_KEYBYTES], clen); - - unsigned char *decrypted = pcp_box_decrypt(s, p, - encrypted, - clen, &dlen); - - if(decrypted == NULL) { - // maybe self encryption? - pcp_pubkey_t *mypub = pcpkey_pub_from_secret(s); - decrypted = pcp_box_decrypt(s, mypub, - encrypted, - clen, &dlen); - free(mypub); +#ifdef PCP_ASYM_ADD_SENDER_PUB + // step 2, sender's pubkey + cur_bufsize = fread(&in_buf, 1, crypto_box_PUBLICKEYBYTES, in); + if(cur_bufsize != crypto_box_PUBLICKEYBYTES && !feof(in) && !ferror(in)) { + fatal("Error: input file doesn't contain senders public key\n"); + goto errdef1; } +#endif - if(decrypted != NULL) { - fatals_reset(); - fwrite(decrypted, dlen, 1, out); - fclose(out); - - if(ferror(out) != 0) { - fatal("Failed to write decrypted output!\n"); - dlen = 0; - goto errdf2; + // step 3, check len recipients + cur_bufsize = fread(&lenrec, 1, 4, in); + if(cur_bufsize != 4 && !feof(in) && !ferror(in)) { + fatal("Error: input file doesn't contain recipient count\n"); + goto errdef1; + } + lenrec = be32toh(lenrec); + + // step 4, fetch recipient list and try to decrypt it for us + for(nrec=0; nrecpub, crypto_box_PUBLICKEYBYTES, 1, out); - fprintf(stderr, "D: sender pub - %d\n", crypto_box_PUBLICKEYBYTES); + //fprintf(stderr, "D: sender pub - %d\n", crypto_box_PUBLICKEYBYTES); if(ferror(out) != 0) goto errec1; +#endif // step 3, len recipients, big endian lenrec = recipient_count; lenrec = htobe32(lenrec); fwrite(&lenrec, 4, 1, out); - fprintf(stderr, "D: %d recipients - 4\n", recipient_count); + //fprintf(stderr, "D: %d recipients - 4\n", recipient_count); if(ferror(out) != 0) goto errec1; // step 4, recipient list fwrite(recipients_cipher, rec_size * recipient_count, 1, out); - fprintf(stderr, "D: recipients - %d * %d\n", rec_size, recipient_count); + //fprintf(stderr, "D: recipients - %ld * %d\n", rec_size, recipient_count); if(ferror(out) != 0) goto errec1; @@ -300,15 +353,15 @@ size_t pcp_encrypt_file(FILE *in, FILE* out, pcp_key_t *s, pcp_pubkey_t *p, int cur_bufsize = 0; while(!feof(in)) { - cur_bufsize = fread(&in_buf, 1, blocksize, in); + cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in); if(cur_bufsize <= 0) break; buf_nonce = pcp_gennonce(); es = pcp_sodium_mac(&buf_cipher, in_buf, cur_bufsize, buf_nonce, symkey); fwrite(buf_nonce, crypto_secretbox_NONCEBYTES, 1, out); - fprintf(stderr, "D: 32k buf nonce - %d\n", crypto_secretbox_NONCEBYTES); + //fprintf(stderr, "D: 32k buf nonce - %d\n", crypto_secretbox_NONCEBYTES); fwrite(buf_cipher, es, 1, out); - fprintf(stderr, "D: 32k buf cipher - %d\n", es); + //fprintf(stderr, "D: 32k buf cipher - %ld\n", es); free(buf_nonce); free(buf_cipher); out_size += crypto_secretbox_NONCEBYTES + es; @@ -338,78 +391,3 @@ size_t pcp_encrypt_file(FILE *in, FILE* out, pcp_key_t *s, pcp_pubkey_t *p, int return 0; } - -size_t OLD_pcp_encrypt_file(FILE *in, FILE* out, pcp_key_t *s, pcp_pubkey_t *p, int self) { - unsigned char *input = NULL; - size_t inputBufSize = 0; - unsigned char byte[1]; - size_t ciphersize; - size_t clen = 0; - size_t zlen = 0; - unsigned char *cipher; - unsigned char *combined; - - while(!feof(in)) { - if(!fread(&byte, 1, 1, in)) - break; - unsigned char *tmp = realloc(input, inputBufSize + 1); - input = tmp; - memmove(&input[inputBufSize], byte, 1); - inputBufSize ++; - } - fclose(in); - - if(inputBufSize == 0) { - fatal("Input file is empty!\n"); - goto erref1; - } - - cipher = pcp_box_encrypt(s, p, input, inputBufSize, &ciphersize); - if(cipher == NULL) - goto erref2; - - clen = ciphersize + crypto_secretbox_KEYBYTES; - combined = ucmalloc(clen); - - if(self == 1) { - unsigned char *fakepub = urmalloc(crypto_secretbox_KEYBYTES); - memcpy(combined, fakepub, crypto_secretbox_KEYBYTES); - free(fakepub); - } - else { - memcpy(combined, s->pub, crypto_secretbox_KEYBYTES); - } - - memcpy(&combined[crypto_secretbox_KEYBYTES], cipher, ciphersize); - - // combined consists of: - // our-public-key|nonce|cipher - char *encoded = pcp_z85_encode(combined, clen, &zlen); - - if(encoded == NULL) - goto erref3; - - fprintf(out, "%s\n%s\n%s\n", PCP_ENFILE_HEADER, encoded, PCP_ENFILE_FOOTER); - if(ferror(out) != 0) { - fatal("Failed to write encrypted output!\n"); - inputBufSize = 0; - } - - fclose(out); - free(encoded); - free(combined); - free(cipher); - - return inputBufSize; - - erref3: - free(combined); - free(cipher); - - erref2: - free(input); - - erref1: - - return 0; -} diff --git a/src/encryption.c b/src/encryption.c index be1113c..3a3a852 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -159,7 +159,31 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec // we're using a random secret keypair on our side +#ifdef PCP_ASYM_ADD_SENDER_PUB secret = pcpkey_new(); +#else + secret = pcp_find_primary_secret(); + if(secret == NULL) { + fatal("Could not find a secret key in vault %s!\n", id, vault->filename); + goto erren2; + } + + if(secret->secret[0] == 0) { + // encrypted, decrypt it + char *passphrase; + if(passwd == NULL) { + pcp_readpass(&passphrase, + "Enter passphrase to decrypt your secret key", NULL, 1); + } + else { + passphrase = ucmalloc(strlen(passwd)+1); + strncpy(passphrase, passwd, strlen(passwd)+1); + } + secret = pcpkey_decrypt(secret, passphrase); + if(secret == NULL) + goto erren2; + } +#endif if(infile == NULL) in = stdin; diff --git a/tests/unittests.cfg b/tests/unittests.cfg index c0b060c..cd18b84 100644 --- a/tests/unittests.cfg +++ b/tests/unittests.cfg @@ -153,11 +153,6 @@ dxmorg@florida.cops.gov cmd = $pcp -V va -e -i ${idbobby} -I testmessage -O testencrypted -x a expect = /for ${idbobby} successfully/ - - - cmd = cat testencrypted - expect = /END PCP ENCRYPTED FILE/ -