diff --git a/README.pod b/README.pod index 99a3389..22fc870 100644 --- a/README.pod +++ b/README.pod @@ -1,3 +1,10 @@ +=head1 CAUTION + +B + =head1 DESCRIPTION B (pcp1) is a commandline utility which can diff --git a/include/pcp/plist.h b/include/pcp/plist.h index 815b286..1298871 100644 --- a/include/pcp/plist.h +++ b/include/pcp/plist.h @@ -19,37 +19,58 @@ You can contact me by mail: . */ - -// used for recipient- or keyid lists +/* + Simple linked list wrappers, + used for recipient- or keyid lists +*/ #ifndef _HAVE_PCP_PLIST_H #define _HAVE_PCP_PLIST_H #include +#include struct _plist_t { char *value; struct _plist_t *next; + struct _plist_t *first; }; typedef struct _plist_t plist_t; static inline void p_add(plist_t **lst, char *value) { plist_t *newitem; - plist_t *lst_iter = *lst; + plist_t *iter = *lst; newitem = (plist_t *)malloc(sizeof(plist_t)); newitem->value = malloc(strlen(value) + 1); strncpy(newitem->value, value, strlen(value) + 1); newitem->next = NULL; - if ( lst_iter != NULL ) { - while (lst_iter->next != NULL ) - lst_iter = lst_iter->next; - lst_iter->next = newitem; + if ( iter != NULL ) { + while (iter->next != NULL ) { + iter = iter->next; + } + newitem->first = iter->first; + iter->next = newitem; } - else + else { + newitem->first = newitem; *lst = newitem; + } +} + +static inline void p_clean(plist_t *lst) { + plist_t *iter = lst->first; + plist_t *tmp; + + while (iter != NULL) { + tmp = iter; + iter = iter->next; + free(tmp->value); + free(tmp); + } + } #endif // _HAVE_PCP_PLIST_H diff --git a/include/pcp/util.h b/include/pcp/util.h new file mode 100644 index 0000000..82020c0 --- /dev/null +++ b/include/pcp/util.h @@ -0,0 +1,38 @@ +/* + This file is part of Pretty Curved Privacy (pcp1). + + Copyright (C) 2013 T. von 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + You can contact me by mail: . +*/ + + +// various helpers + +#ifndef _HAVE_PCP_UTIL_H +#define _HAVE_PCP_UTIL_H + +#include + +static inline char *_lc(char *in) { + size_t len = strlen(in); + int i; + for(i=0; ipub, crypto_box_PUBLICKEYBYTES, 1, out); + fprintf(stderr, "D: sender pub - %d\n", crypto_box_PUBLICKEYBYTES); + if(ferror(out) != 0) + goto errec1; + + // 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); + 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); + if(ferror(out) != 0) + goto errec1; + + out_size = 5 + (rec_size * recipient_count) + crypto_box_PUBLICKEYBYTES; + + // step 5, actual encrypted data + cur_bufsize = 0; + + while(!feof(in)) { + cur_bufsize = fread(&in_buf, 1, blocksize, 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); + fwrite(buf_cipher, es, 1, out); + fprintf(stderr, "D: 32k buf cipher - %d\n", es); + free(buf_nonce); + free(buf_cipher); + out_size += crypto_secretbox_NONCEBYTES + es; + } + + if(ferror(out) != 0) { + fatal("Failed to write encrypted output!\n"); + goto errec2; + } + + fclose(in); + fclose(out); // FIXME: check for stdin/stdout + + return out_size; + + errec2: + + + errec1: + memset(symkey, 0, crypto_secretbox_KEYBYTES); + free(symkey); + free(recipients_cipher); + + + fclose(in); + fclose(out); + 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]; diff --git a/src/encryption.c b/src/encryption.c index ae53f1a..be1113c 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -124,15 +124,33 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec } else { // found one by id, copy into local hash - pcp_pubkey_t *pub = ucmalloc(sizeof(pcp_pubkey_t)); + pub = ucmalloc(sizeof(pcp_pubkey_t)); memcpy(pub, tmp, sizeof(pcp_pubkey_t)); HASH_ADD_STR( pubhash, id, tmp); } } else if(recipient != NULL) { // lookup by recipient list - // FIXME: implement, iterate through global hashlist - // copy matches into temporary pubhash + // iterate through global hashlist + // copy matches into temporary pubhash + plist_t *rec; + pcphash_iteratepub(tmp) { + rec = recipient->first; + while (rec->next != NULL) { + _lc(rec->value); + if(strnstr(tmp->mail, rec->value, 255) != NULL || strnstr(tmp->owner, rec->value, 255) != NULL) { + pub = ucmalloc(sizeof(pcp_pubkey_t)); + memcpy(pub, tmp, sizeof(pcp_pubkey_t)); + HASH_ADD_STR( pubhash, id, tmp); + //fprintf(stderr, " => found a matching key %s\n", tmp->id); + } + rec = rec->next; + } + } + if(HASH_COUNT(pubhash) == 0) { + fatal("no matching key found for specified recipient(s)!\n"); + goto erren3; + } } else { fatal("id or recipient list required!\n"); @@ -164,12 +182,22 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec size_t clen = pcp_encrypt_file(in, out, secret, pubhash, self); if(clen > 0) { - fprintf(stderr, "Encrypted %d bytes for 0x%s successfully\n", (int)clen, id); + if(id != NULL) + fprintf(stderr, "Encrypted %d bytes for 0x%s successfully\n", (int)clen, id); + else { + fprintf(stderr, "Encrypted %d bytes for:\n", (int)clen); + pcp_pubkey_t *cur, *t; + HASH_ITER(hh, pubhash, cur, t) { + fprintf(stderr, "%s <%s>\n", cur->owner, cur->mail); + } + free(t); + free(cur); + } return 0; } erren2: - free(pubhash); + free(pubhash); // FIXME: it's a uthash, dont use free() but func instead free(tmp); free(pub); diff --git a/src/keymgmt.c b/src/keymgmt.c index 0538971..c72418f 100644 --- a/src/keymgmt.c +++ b/src/keymgmt.c @@ -490,10 +490,3 @@ char *pcp_find_id_byrec(char *recipient) { return id; } -char *_lc(char *in) { - size_t len = strlen(in); - int i; - for(i=0; i