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

Conflicts:
	TODO
This commit is contained in:
git@daemon.de
2014-01-27 11:30:30 +01:00
13 changed files with 444 additions and 98 deletions

View File

@@ -12,17 +12,22 @@
Encrypted file format/scheme changed. Previously Encrypted file format/scheme changed. Previously
I included the sender's key-id with the encrypted I included the sender's key-id with the encrypted
cipher as a hash. Now the sender's public key will cipher as a hash. So, encrypted message do no more
be included directly. This way I don't have to reveal contain pk material.
key-ids (which is bad) and people can encrypt for
others without a full key exchange first.
Also I'm no more using the primary secret (or any Changed signature scheme completely. Binary signature
other secret in the vault) for encryption. Instead follow the pbp scheme: calculate blake2 hash of the
every time a user encrypts a file, a new keypair content, sign the hash, write out original content,
will be generated. That way the file can only be add "\nnacl-", add the signature, add the hash.
decrypted by the recipient (which public key have Armored signatures are calculated the same way but
been used) and no one else, not even the sender. output follows the pgp scheme instead.
Detached signatures are still supported as before,
for the user everything with them is as known, but
the commandline option -a (--detach) have to be
applied. Internally, however, inputs will be read in
32k blockwise as well. Detached signatures are now
z85 encoded always.
0.1.5 Fixed a segmentation fault when using pcp1 -t on a 0.1.5 Fixed a segmentation fault when using pcp1 -t on a
public key. I added a double free() there by purpose public key. I added a double free() there by purpose

5
TODO
View File

@@ -13,8 +13,3 @@ allow signing using an alternate secret key, like in pcpdecrypt()
support export/import from/to pbp support export/import from/to pbp
add support for armored signature using -z
add support for buffered_signature (which has to be the default from pcp commandline)
remove z85 mode (-z without -e -d -c -g)

View File

@@ -40,9 +40,10 @@ typedef unsigned int qbyte; // Quad byte = 32 bits
#define PCP_ZFILE_HEADER "----- BEGIN Z85 ENCODED FILE -----" #define PCP_ZFILE_HEADER "----- BEGIN Z85 ENCODED FILE -----"
#define PCP_ZFILE_FOOTER "------ END Z85 ENCODED FILE ------" #define PCP_ZFILE_FOOTER "------ END Z85 ENCODED FILE ------"
#define PCP_SIG_HEADER "----- BEGIN PCP SIGNED MESSAGE -----" #define PCP_SIG_HEADER "----- BEGIN ED25519 SIGNED MESSAGE -----"
#define PCP_SIG_START "----- BEGIN PCP SIGNATURE -----" #define PCP_SIG_START "----- BEGIN ED25519 SIGNATURE -----"
#define PCP_SIG_END "------ END PCP SIGNATURE ------" #define PCP_SIG_END "------ END ED25519 SIGNATURE ------"
#define PCP_SIGPREFIX "\nnacl-"
#define PCP_ME "Pretty Curved Privacy" #define PCP_ME "Pretty Curved Privacy"

View File

@@ -35,6 +35,8 @@
#include "platform.h" #include "platform.h"
#include "mem.h" #include "mem.h"
#include "key.h" #include "key.h"
#include "keyhash.h"
#include "util.h"
/* sign a message of messagesize using s->edsecret, if it works /* sign a message of messagesize using s->edsecret, if it works
return message+signature (size: messagesize + crypto_sign_BYTES), return message+signature (size: messagesize + crypto_sign_BYTES),
@@ -51,4 +53,9 @@ unsigned char * pcp_ed_verify(unsigned char *signature, size_t siglen, pcp_pubke
sig only to the output */ sig only to the output */
size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85); size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85);
pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p);
size_t pcp_ed_detachsign_buffered(FILE *in, FILE *out, pcp_key_t *s);
pcp_pubkey_t *pcp_ed_detachverify_buffered(FILE *in, FILE *sigfd, pcp_pubkey_t *p);
#endif // _HAVE_PCP_ED_H #endif // _HAVE_PCP_ED_H

View File

@@ -26,13 +26,36 @@
#define _HAVE_PCP_UTIL_H #define _HAVE_PCP_UTIL_H
#include <ctype.h> #include <ctype.h>
#include <wctype.h>
// lowercase a string
static inline char *_lc(char *in) { static inline char *_lc(char *in) {
size_t len = strlen(in); size_t len = strlen(in);
int i; size_t i;
for(i=0; i<len; ++i) for(i=0; i<len; ++i)
in[i] = towlower(in[i]); in[i] = towlower(in[i]);
return in; return in;
} }
// find the offset of the beginning of a certain string within binary data
static inline size_t _findoffset(unsigned char *bin, size_t binlen, char *sigstart, size_t hlen) {
size_t i;
size_t offset = 0;
int m = 0;
for(i=0; i<binlen-hlen; ++i) {
if(memcmp(&bin[i], sigstart, hlen) == 0) {
offset = i;
m = 1;
break;
}
}
if(m == 0)
offset = -1;
return offset;
}
#endif // _HAVE_PCP_UTIL_H #endif // _HAVE_PCP_UTIL_H

View File

@@ -456,6 +456,4 @@ size_t pcp_decrypt_file_sym(FILE *in, FILE* out, unsigned char *symkey) {
fclose(out); fclose(out);
return out_size; return out_size;
} }

View File

@@ -49,6 +49,7 @@ unsigned char *pcp_ed_sign(unsigned char *message, size_t messagesize, pcp_key_t
size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) { size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) {
unsigned char in_buf[PCP_BLOCK_SIZE]; unsigned char in_buf[PCP_BLOCK_SIZE];
size_t cur_bufsize = 0; size_t cur_bufsize = 0;
size_t outsize = 0;
crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state)); crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state));
unsigned char hash[crypto_generichash_BYTES_MAX]; unsigned char hash[crypto_generichash_BYTES_MAX];
@@ -61,7 +62,7 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) {
cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in); cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in);
if(cur_bufsize <= 0) if(cur_bufsize <= 0)
break; break;
outsize += cur_bufsize;
crypto_generichash_update(st, in_buf, cur_bufsize); crypto_generichash_update(st, in_buf, cur_bufsize);
fwrite(in_buf, cur_bufsize, 1, out); fwrite(in_buf, cur_bufsize, 1, out);
} }
@@ -74,20 +75,18 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) {
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX); crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
unsigned char *signature = pcp_ed_sign(hash, crypto_generichash_BYTES_MAX, s);
size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX; size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
unsigned char *signature = ucmalloc(mlen);
crypto_sign(signature, &mlen, hash, crypto_generichash_BYTES_MAX, s->edsecret);
if(z85) { if(z85) {
if(in_buf[cur_bufsize] != '\n') fprintf(out, "\n%s\n Version: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
fprintf(out, "\n");
fprintf(out, "%s\nVersion: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
size_t zlen; size_t zlen;
char *z85encoded = pcp_z85_encode((unsigned char*)signature, crypto_sign_BYTES, &zlen); char *z85encoded = pcp_z85_encode((unsigned char*)signature, mlen, &zlen);
fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END); fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END);
} }
else { else {
fwrite(signature, crypto_sign_BYTES, 1, out); fprintf(out, "%s", PCP_SIGPREFIX);
fwrite(signature, mlen, 1, out);
} }
if(fileno(in) != 0) if(fileno(in) != 0)
@@ -97,5 +96,321 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) {
free(st); free(st);
return mlen; // ??? return outsize;
}
pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) {
unsigned char in_buf[PCP_BLOCK_SIZE/2];
unsigned char in_next[PCP_BLOCK_SIZE/2];
unsigned char in_full[PCP_BLOCK_SIZE];
size_t cur_bufsize = 0;
size_t next_bufsize = 0;
size_t full_bufsize = 0;
int z85 = 0;
int gotsig = 0;
unsigned char hash[crypto_generichash_BYTES_MAX];
char zhead[] = PCP_SIG_HEADER;
size_t hlen = strlen(PCP_SIG_HEADER);
size_t hlen2 = 15; // hash: blake2\n\n
size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
size_t zlen = 262; // FIXME: calculate
unsigned char z85encoded[zlen];
unsigned char sighash[mlen];
char z85sigstart[] = PCP_SIG_START;
char binsigstart[] = PCP_SIGPREFIX;
char sigstart[] = PCP_SIG_START;
size_t siglen, startlen;
size_t offset = -1;
crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state));
crypto_generichash_init(st, NULL, 0, 0);
/* use two half blocks, to overcome sigs spanning block boundaries */
cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE/2, in);
// look for z85 header and cut it out
if(_findoffset(in_buf, cur_bufsize, zhead, hlen) == 0) {
// it is armored
next_bufsize = cur_bufsize - (hlen+hlen2); // size - the header
memcpy(in_next, &in_buf[hlen+hlen2], next_bufsize); // tmp save
memcpy(in_buf, in_next, next_bufsize); // put into inbuf without header
if(cur_bufsize == PCP_BLOCK_SIZE/2) {
// more to come
cur_bufsize = fread(&in_buf[next_bufsize], 1, ((PCP_BLOCK_SIZE/2) - next_bufsize), in);
cur_bufsize += next_bufsize;
next_bufsize = 0;
// now we've got the 1st half block in in_buf
// unless the file was smaller than blocksize/2,
// in which case it contains all the rest til eof
}
z85 = 1;
}
if(z85 == 1) {
siglen = zlen;
strcpy(sigstart, z85sigstart);
startlen = strlen(z85sigstart);
}
else {
siglen = mlen + strlen(binsigstart);
strcpy(sigstart, binsigstart);
startlen = strlen(binsigstart);
}
while (cur_bufsize > 0) {
if(cur_bufsize == PCP_BLOCK_SIZE/2) {
// probably not eof
next_bufsize = fread(&in_next, 1, PCP_BLOCK_SIZE/2, in);
}
else
next_bufsize = 0; // <= this is eof
// concatenate previous and current buffer
if(next_bufsize == 0)
memcpy(in_full, in_buf, cur_bufsize);
else {
memcpy(in_full, in_buf, cur_bufsize);
memcpy(&in_full[cur_bufsize], in_next, next_bufsize);
}
full_bufsize = cur_bufsize+next_bufsize;
// find signature offset
offset = _findoffset(in_full, full_bufsize, sigstart, startlen);
//printf("offset: %ld, full: %ld, cur: %ld\n", offset, full_bufsize, cur_bufsize);
if(offset >= 0 && offset <= PCP_BLOCK_SIZE/2) {
// sig begins within the first half, adjust in_buf size
//printf("1st half\n");
next_bufsize = 0;
cur_bufsize = offset;
gotsig = 1;
if(z85) {
cur_bufsize -= 1;
memcpy(z85encoded, &in_full[offset], zlen);
}
else
memcpy(sighash, &in_full[offset + strlen(binsigstart)], mlen);
}
else if(full_bufsize - offset == siglen) {
// sig fits within the 2nd half
// offset: 28279, full: 28413, cur: 16384
//printf("2nd half\n");
next_bufsize -= siglen;
gotsig = 1;
if(z85) {
cur_bufsize -= 1;
memcpy(z85encoded, &in_full[full_bufsize - siglen], siglen);
}
else
memcpy(sighash, &in_full[full_bufsize - mlen], mlen);
}
else
offset = 0;
// add previous half block to hash
crypto_generichash_update(st, in_buf, cur_bufsize);
// next => in
if(next_bufsize > 0) {
memcpy(in_buf, in_next, next_bufsize);
cur_bufsize = next_bufsize;
}
else
break;
} // while
if(gotsig == 0) {
fatal("Error, the signature doesn't contain the ed25519 signed hash\n");
goto errvb1;
}
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
if(z85) {
char *z85block = pcp_readz85string(z85encoded, zlen);
if(z85block == NULL)
goto errvb1;
size_t dstlen;
unsigned char *z85decoded = pcp_z85_decode(z85block, &dstlen);
if(dstlen != mlen) {
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen);
goto errvb1;
}
memcpy(sighash, z85decoded, mlen);
}
// else: if unarmored, sighash is already filled
// huh, how did we made it til here?
unsigned char *verifiedhash = NULL;
if(p == NULL) {
pcphash_iteratepub(p) {
verifiedhash = pcp_ed_verify(sighash, mlen, p);
if(verifiedhash != NULL)
break;
}
}
else {
verifiedhash = pcp_ed_verify(sighash, mlen, p);
}
if(verifiedhash == NULL)
goto errvb1;
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
// sig verified, but the hash doesn't
fatal("signed hash doesn't match actual hash of signed file content\n");
free(verifiedhash);
return NULL;
}
return p;
errvb1:
free(st);
return NULL;
}
size_t pcp_ed_detachsign_buffered(FILE *in, FILE *out, pcp_key_t *s) {
unsigned char in_buf[PCP_BLOCK_SIZE];
size_t cur_bufsize = 0;
size_t outsize = 0;
crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state));
unsigned char hash[crypto_generichash_BYTES_MAX];
crypto_generichash_init(st, NULL, 0, 0);
while(!feof(in)) {
cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in);
if(cur_bufsize <= 0)
break;
outsize += cur_bufsize;
crypto_generichash_update(st, in_buf, cur_bufsize);
}
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
unsigned char *signature = pcp_ed_sign(hash, crypto_generichash_BYTES_MAX, s);
size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
fprintf(out, "\n%s\n Version: PCP v%d.%d.%d\n\n",
PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
size_t zlen;
char *z85encoded = pcp_z85_encode((unsigned char*)signature, mlen, &zlen);
fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END);
if(fileno(in) != 0)
fclose(in);
if(fileno(out) != 1)
fclose(out);
free(st);
return outsize;
}
pcp_pubkey_t *pcp_ed_detachverify_buffered(FILE *in, FILE *sigfd, pcp_pubkey_t *p) {
unsigned char in_buf[PCP_BLOCK_SIZE];
size_t cur_bufsize = 0;
size_t outsize = 0;
crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state));
unsigned char hash[crypto_generichash_BYTES_MAX];
size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
crypto_generichash_init(st, NULL, 0, 0);
while(!feof(in)) {
cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in);
if(cur_bufsize <= 0)
break;
outsize += cur_bufsize;
crypto_generichash_update(st, in_buf, cur_bufsize);
}
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
// read the sig
unsigned char *sig = NULL;
size_t inputBufSize = 0;
unsigned char byte[1];
while(!feof(sigfd)) {
if(!fread(&byte, 1, 1, sigfd))
break;
unsigned char *tmp = realloc(sig, inputBufSize + 1);
sig = tmp;
memmove(&sig[inputBufSize], byte, 1);
inputBufSize ++;
}
fclose(sigfd);
if(sig == NULL) {
fatal("Invalid detached signature\n");
goto errdea1;
}
char *z85block = pcp_readz85string(sig, inputBufSize);
if(z85block == NULL)
goto errdea2;
size_t clen;
unsigned char *sighash = pcp_z85_decode(z85block, &clen);
if(sighash == NULL)
goto errdea3;
if(clen != mlen) {
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen);
goto errdea4;
}
unsigned char *verifiedhash = NULL;
if(p == NULL) {
pcphash_iteratepub(p) {
verifiedhash = pcp_ed_verify(sighash, mlen, p);
if(verifiedhash != NULL)
break;
}
}
else {
verifiedhash = pcp_ed_verify(sighash, mlen, p);
}
if(verifiedhash == NULL)
goto errdea4;
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
// sig verified, but the hash doesn't
fatal("signed hash doesn't match actual hash of signed file content\n");
goto errdea5;
}
free(verifiedhash);
free(sighash);
free(z85block);
free(sig);
return p;
errdea5:
free(verifiedhash);
errdea4:
free(sighash);
errdea3:
free(z85block);
errdea2:
free(sig);
errdea1:
return NULL;
} }

View File

@@ -259,7 +259,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
size_t clen = 0; size_t clen = 0;
if(self == 1) if(self == 1)
pcp_encrypt_file_sym(in, out, symkey, 0); clen = pcp_encrypt_file_sym(in, out, symkey, 0);
else else
clen = pcp_encrypt_file(in, out, secret, pubhash); clen = pcp_encrypt_file(in, out, secret, pubhash);

View File

@@ -44,10 +44,11 @@ char *default_vault() {
} }
int main (int argc, char **argv) { int main (int argc, char **argv) {
int opt, mode, usevault, useid, userec, lo, armor; int opt, mode, usevault, useid, userec, lo, armor, detach;
char *vaultfile = default_vault(); char *vaultfile = default_vault();
char *outfile = NULL; char *outfile = NULL;
char *infile = NULL; char *infile = NULL;
char *sigfile = NULL;
char *keyid = NULL; char *keyid = NULL;
char *id = NULL; char *id = NULL;
char *xpass = NULL; char *xpass = NULL;
@@ -63,6 +64,7 @@ int main (int argc, char **argv) {
userec = 0; userec = 0;
lo = 0; lo = 0;
armor = 0; armor = 0;
detach = 0;
static struct option longopts[] = { static struct option longopts[] = {
// generics // generics
@@ -101,11 +103,12 @@ int main (int argc, char **argv) {
// signing // signing
{ "sign", no_argument, NULL, 'g' }, { "sign", no_argument, NULL, 'g' },
{ "check-signature", no_argument, NULL, 'c' }, { "check-signature", required_argument, NULL, 'c' },
{ "detach", no_argument, NULL, 'a' },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:gcym", while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:gc:yma",
longopts, NULL)) != -1) { longopts, NULL)) != -1) {
switch (opt) { switch (opt) {
@@ -171,12 +174,17 @@ int main (int argc, char **argv) {
case 'Z': case 'Z':
armor = 1; armor = 1;
break; break;
case 'a':
detach = 1;
break;
case 'g': case 'g':
mode += PCP_MODE_SIGN; mode += PCP_MODE_SIGN;
usevault = 1; usevault = 1;
break; break;
case 'c': case 'c':
mode += PCP_MODE_VERIFY; mode += PCP_MODE_VERIFY;
sigfile = ucmalloc(strlen(optarg)+1);
strncpy(sigfile, optarg, strlen(optarg)+1);
usevault = 1; usevault = 1;
break; break;
case 'y': case 'y':
@@ -372,19 +380,19 @@ int main (int argc, char **argv) {
break; break;
case PCP_MODE_SIGN: case PCP_MODE_SIGN:
pcpsign(infile, outfile, xpass, armor); pcpsign(infile, outfile, xpass, armor, detach);
break; break;
case PCP_MODE_VERIFY: case PCP_MODE_VERIFY:
if(useid) { if(useid) {
id = pcp_normalize_id(keyid); id = pcp_normalize_id(keyid);
if(id != NULL) { if(id != NULL) {
pcpverify(infile, id); pcpverify(infile, sigfile, id, detach);
free(id); free(id);
} }
} }
else { else {
pcpverify(infile, NULL); pcpverify(infile, sigfile, NULL, detach);
} }
break; break;

View File

@@ -23,12 +23,14 @@
#include "signature.h" #include "signature.h"
#include "defines.h" #include "defines.h"
int pcpsign(char *infile, char *outfile, char *passwd, int z85) {
int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
FILE *in = NULL; FILE *in = NULL;
FILE *out = NULL; FILE *out = NULL;
pcp_key_t *secret = NULL; pcp_key_t *secret = NULL;
secret = pcp_find_primary_secret(); secret = pcp_find_primary_secret();
if(secret == NULL) { if(secret == NULL) {
fatal("Could not find a secret key in vault %s!\n", vault->filename); fatal("Could not find a secret key in vault %s!\n", vault->filename);
goto errs1; goto errs1;
@@ -69,7 +71,11 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85) {
goto errs1; goto errs1;
} }
size_t sigsize = pcp_ed_sign_buffered(in, out, secret, z85); size_t sigsize;
if(detach == 1)
sigsize = pcp_ed_detachsign_buffered(in, out, secret);
else
sigsize = pcp_ed_sign_buffered(in, out, secret, z85);
if(sigsize == 0) if(sigsize == 0)
goto errs1; goto errs1;
@@ -82,10 +88,10 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85) {
return 1; return 1;
} }
int pcpverify(char *infile, char *id) { int pcpverify(char *infile, char *sigfile, char *id, int detach) {
FILE *in = NULL; FILE *in = NULL;
FILE *sigfd = NULL;
pcp_pubkey_t *pub = NULL; pcp_pubkey_t *pub = NULL;
unsigned char *message = NULL;
if(infile == NULL) if(infile == NULL)
in = stdin; in = stdin;
@@ -96,63 +102,26 @@ int pcpverify(char *infile, char *id) {
} }
} }
if(sigfile != NULL) {
if((sigfd = fopen(sigfile, "rb")) == NULL) {
fatal("Could not open signature file %s\n", sigfile);
goto errv1;
}
}
if(id != NULL) if(id != NULL)
HASH_FIND_STR(pcppubkey_hash, id, pub); HASH_FIND_STR(pcppubkey_hash, id, pub);
/* if(detach)
if(pub == NULL) { pub = pcp_ed_detachverify_buffered(in, sigfd, pub);
fatal("Could not find a usable public key in vault %s!\n",
vault->filename);
goto errv3;
}
*/
unsigned char *input = NULL;
size_t inputBufSize = 0;
unsigned char byte[1];
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 errv4;
}
if(pub != NULL) {
message = pcp_ed_verify(input, inputBufSize, pub);
if(message != NULL) {
fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
}
}
else {
pcphash_iteratepub(pub) {
message = pcp_ed_verify(input, inputBufSize, pub);
if(message != NULL) {
fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
break;
}
}
}
if(message == NULL) {
fprintf(stderr, "Could not verify ignature\n");
}
else else
free(message); pub = pcp_ed_verify_buffered(sigfd, pub);
free(input); if(pub != NULL)
return 0; fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
errv4: errv4:
free(input);
errv1: errv1:
return 1; return 1;

View File

@@ -32,8 +32,8 @@
#include "uthash.h" #include "uthash.h"
#include "z85.h" #include "z85.h"
int pcpsign(char *infile, char *outfile, char *passwd, int z85); int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach);
int pcpverify(char *infile, char *id); int pcpverify(char *infile, char *sigfile, char *id, int detach);

View File

@@ -92,11 +92,15 @@ Signature Options:
-I (or from stdin) using your primary -I (or from stdin) using your primary
secret key. If -r has been given, a derived secret key. If -r has been given, a derived
secret key will be used for signing. secret key will be used for signing.
-c --check-signature <file> Verify a signature in file <file> against -c --check-signature <file> Verify a signature in file <file> against
the file specified with -I (or stdin). the file specified with -I (or stdin).
The public key required for this must The public key required for this must
exist in your vault file. exist in your vault file.
-a --detach Write a detached signature file, which doesn't
contain the original content. Output will be
z85 encoded always. To verify, you need to
specify the original file to be verified
against using -I as well (plus -a).
Encoding Options: Encoding Options:
-z --z85-encode Encode something to Z85 encoding. Use -z --z85-encode Encode something to Z85 encoding. Use

View File

@@ -210,13 +210,31 @@ dxmorg@florida.cops.gov
</test> </test>
# #
# signature test # signature tests
<test check-sign-to-bobby> <test check-sign-detached-to-bobby>
cmd = $pcp -V va -g -I README -O testsig -x a -a
expect-file testsig
</test>
<test check-verify-detached-signature>
cmd = $pcp -V vb -c testsig -I README -i $idalicia -a
expect = /verified/
</test>
<test check-sign-armored-to-bobby>
prepare = rm -f testsig
cmd = $pcp -V va -g -I README -O testsig -x a -z
expect-file testsig
</test>
<test check-verify-armored-signature>
cmd = $pcp -V vb -c testsig -i $idalicia -z
expect = /verified/
</test>
<test check-sign-bin-to-bobby>
prepare = rm -f testsig
cmd = $pcp -V va -g -I README -O testsig -x a cmd = $pcp -V va -g -I README -O testsig -x a
expect-file testsig expect-file testsig
</test> </test>
<test check-verify-signature> <test check-verify-bin-signature>
cmd = $pcp -V vb -c -I testsig -i $idalicia cmd = $pcp -V vb -c testsig -i $idalicia
expect = /verified/ expect = /verified/
</test> </test>
@@ -332,12 +350,15 @@ dxmorg@florida.cops.gov
</test> </test>
*/ */
/*
* Disabled, since z85 standalone mode currently disabled
<test check-if-catch-nokey-behind-z85> <test check-if-catch-nokey-behind-z85>
prepare = ./jot 30 | while read ignore; do echo XXXXX; done \ prepare = ./jot 30 | while read ignore; do echo XXXXX; done \
| $pcp -z > testfile-nokey | $pcp -z > testfile-nokey
cmd = $pcp -V $vault -P -I testfile-nokey cmd = $pcp -V $vault -P -I testfile-nokey
expect = /result to a proper sized key/ expect = /result to a proper sized key/
</test> </test>
*/
<test check-if-sanity-catch-nosecret> <test check-if-sanity-catch-nosecret>
cmd = $pcp -V $vault -S -I bart.pub cmd = $pcp -V $vault -S -I bart.pub