bugfix in encryption key computing, added new feature: derived public keys

This commit is contained in:
TLINDEN
2013-11-02 11:02:36 +01:00
parent c93f9c6cdd
commit bf5556e1ec
29 changed files with 514 additions and 242 deletions

View File

@@ -1,4 +1,20 @@
0.1.1 changed output format of encrypted keys. now we 0.1.2 Fixed bug in pcp_derivekey() which derives encryption
keys. it generated collisions due coding error, e.g.
passphase 'a' resulted in the same encryptionkey as
passphase 'r'. Now uses SHA256 witout the xor stuff,
which was the cause for the bug. This also fixes a
segmentation fault which occured invariably by entering
an invalid passphrase.
Added support for derived public keys using the -R
option, which allows two peers to encrypt messages
without the need to reveal their primary public keys.
That way each peer will have another public key of
the same source.
Added more unit tests to reflect the above changes.
0.1.1 Changed output format of encrypted keys. now we
encode it properly with the Z85 encoding and add encode it properly with the Z85 encoding and add
a header and footer to it: a header and footer to it:
@@ -8,4 +24,4 @@
EU]wBzf{UrCgBNSHcGBT EU]wBzf{UrCgBNSHcGBT
-----END CURVE25519 SECRET KEY----- -----END CURVE25519 SECRET KEY-----
0.0.1 initial version 0.0.1 Initial version

View File

@@ -2,7 +2,7 @@ SUBDIRS = libpcp src man tests
ACLOCAL_AMFLAGS = -I config ACLOCAL_AMFLAGS = -I config
test: test:
cd tests && make test cd tests && make test $(CHECK)
stresstest: stresstest:
cd tests && make stresstest cd tests && make stresstest

View File

@@ -745,7 +745,7 @@ uninstall-am:
test: test:
cd tests && make test cd tests && make test $(CHECK)
stresstest: stresstest:
cd tests && make stresstest cd tests && make stresstest

2
TODO
View File

@@ -1 +1,3 @@
- always save vault to tmp, then validate it and copy if ok - always save vault to tmp, then validate it and copy if ok

View File

@@ -170,6 +170,23 @@ unsigned char * pcp_gennonce();
void pcpedit_key(char *keyid); void pcpedit_key(char *keyid);
// proprietary key derivation function. derives an
// secure encryption key from the given passphrase by
// calculating a SALSA20 hash from it HCYCLES times.
//
// turns the result into a proper CURVE25519 secret
// key. allocates memory for key and it is up to the
// user to free it after use.
//
// deprecation warning: maybe removed once the libsodium
// developers incorporated some key derivation function
// into libsodium. so far, there's none but word goes
// that perhaps something like scrypt() from the star
// distribution may be added in the future.
unsigned char *pcp_derivekey(char *passphrase);
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -218,25 +235,8 @@ int pcp_sodium_verify_mac(unsigned char **cleartext,
unsigned char *nonce, unsigned char *nonce,
unsigned char *key); unsigned char *key);
// generate a nonce from random source arc4random().
// allocates memory for the returned nonce and
// it is up to the user to free it after use.
void pcp_makenonce(unsigned char **nonce);
// proprietary key derivation function. derives an
// secure encryption key from the given passphrase by
// calculating a SALSA20 hash from it HCYCLES times.
//
// turns the result into a proper CURVE25519 secret
// key. allocates memory for key and it is up to the
// user to free it after use.
//
// deprecation warning: maybe removed once the libsodium
// developers incorporated some key derivation function
// into libsodium. so far, there's none but word goes
// that perhaps something like scrypt() from the star
// distribution may be added in the future.
unsigned char *pcp_derivekey(char *passphrase);
// +++ from libpcp/mem.h: +++ // +++ from libpcp/mem.h: +++

View File

@@ -47,4 +47,7 @@ void fatal(const char * fmt, ...);
// fetch error // fetch error
void fatals_ifany(); void fatals_ifany();
// reset
void fatals_reset();
#endif // _DEFINES_H #endif // _DEFINES_H

View File

@@ -17,6 +17,10 @@ void fatal(const char * fmt, ...) {
PCP_ERRSET = 1; PCP_ERRSET = 1;
} }
void fatals_reset() {
PCP_ERRSET = 0;
}
void fatals_ifany() { void fatals_ifany() {
if(PCP_ERRSET == 1) { if(PCP_ERRSET == 1) {
fprintf(stderr, PCP_ERR); fprintf(stderr, PCP_ERR);

View File

@@ -1,5 +1,40 @@
#include "key.h" #include "key.h"
unsigned char *pcp_derivekey(char *passphrase) {
unsigned char *hash32 = ucmalloc(crypto_hash_sha256_BYTES);
unsigned char *key = ucmalloc(crypto_secretbox_KEYBYTES);
size_t plen = strnlen(passphrase, 255);
unsigned char *temp = ucmalloc(crypto_hash_sha256_BYTES);
int i;
// make a hash from the passphrase and then HCYCLES times from the result
crypto_hash_sha256(temp, passphrase, plen);
for(i=0; i<HCYCLES; ++i) {
if(crypto_hash_sha256(hash32, temp, crypto_hash_sha256_BYTES) == 0) {
memcpy(temp, hash32, crypto_hash_sha256_BYTES);
}
}
// turn the 32byte hash into a secret key
temp[0] &= 248;
temp[31] &= 127;
temp[31] |= 64;
memcpy(key, temp, crypto_secretbox_KEYBYTES);
memset(passphrase, 0, plen);
memset(temp, 0, crypto_hash_sha256_BYTES);
free(passphrase);
free(temp);
free(hash32);
return key;
}
char *pcp_getkeyid(pcp_key_t *k) { char *pcp_getkeyid(pcp_key_t *k) {
uint32_t s, p; uint32_t s, p;
p = jen_hash(k->public, 32, JEN_PSALT); p = jen_hash(k->public, 32, JEN_PSALT);
@@ -196,4 +231,58 @@ pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
return k; return k;
} }
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs) {
size_t thlen = strnlen(theirs, 255);
size_t inlen = 32 + thlen;
unsigned char *both = ucmalloc(inlen);
unsigned char *hash = ucmalloc(crypto_hash_BYTES);
memcpy(both, ours->secret, 32);
memcpy(&both[32], theirs, thlen);
if(crypto_hash(hash, both, inlen) != 0) {
fatal("Failed to generate a hash of our pub key and recipient id!\n");
goto errdp1;
}
unsigned char *xor = ucmalloc(crypto_secretbox_KEYBYTES);
unsigned char *secret = ucmalloc(crypto_secretbox_KEYBYTES);
int i;
for(i=0; i<crypto_secretbox_KEYBYTES; ++i) {
xor[i] = hash[i] ^ hash[i + crypto_secretbox_KEYBYTES];
}
xor[0] &= 248;
xor[31] &= 127;
xor[31] |= 64;
memcpy(secret, xor, crypto_secretbox_KEYBYTES);
pcp_key_t * tmp = pcpkey_new ();
memcpy(tmp->secret, secret, 32);
// calculate pub from secret
crypto_scalarmult_curve25519_base(tmp->public, tmp->secret);
memcpy(tmp->owner, ours->owner, 255);
memcpy(tmp->mail, ours->mail, 255);
memcpy(tmp->id, pcp_getkeyid(tmp), 17);
memset(both, 0, inlen);
memset(xor, 0, crypto_secretbox_KEYBYTES);
memset(hash, 0, crypto_hash_BYTES);
free(both);
free(xor);
free(hash);
return tmp;
errdp1:
memset(both, 0, inlen);
free(both);
return NULL;
}

View File

@@ -113,6 +113,23 @@ unsigned char * pcp_gennonce();
void pcpedit_key(char *keyid); void pcpedit_key(char *keyid);
// proprietary key derivation function. derives an
// secure encryption key from the given passphrase by
// calculating a SALSA20 hash from it HCYCLES times.
//
// turns the result into a proper CURVE25519 secret
// key. allocates memory for key and it is up to the
// user to free it after use.
//
// deprecation warning: maybe removed once the libsodium
// developers incorporated some key derivation function
// into libsodium. so far, there's none but word goes
// that perhaps something like scrypt() from the star
// distribution may be added in the future.
unsigned char *pcp_derivekey(char *passphrase);
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -2,49 +2,6 @@
unsigned char *pcp_derivekey(char *passphrase) {
unsigned char *hash64 = ucmalloc(crypto_hash_BYTES);
unsigned char *xor = ucmalloc(crypto_secretbox_KEYBYTES);
unsigned char *key = ucmalloc(crypto_secretbox_KEYBYTES);
size_t plen = strnlen(passphrase, 255);
unsigned char *temp = ucmalloc(crypto_hash_BYTES);
int i;
// make a hash from the passphrase and then HCYCLES times from the result
memcpy(temp, passphrase, plen);
for(i=0; i<HCYCLES; ++i) {
if(crypto_hash(hash64, temp, plen) == 0) {
memcpy(temp, hash64, crypto_hash_BYTES);
}
}
// xor the first half of the hash with the latter to get
// a 32 byte array
for(i=0; i<crypto_secretbox_KEYBYTES; ++i) {
xor[i] = hash64[i] ^ hash64[i + crypto_secretbox_KEYBYTES];
}
// turn the 32byte hash into a secret key
xor[0] &= 248;
xor[31] &= 127;
xor[31] |= 64;
memcpy(key, xor, crypto_secretbox_KEYBYTES);
memset(passphrase, 0, plen);
memset(temp, 0, crypto_hash_BYTES);
free(passphrase);
free(temp);
free(xor);
free(hash64);
return key;
}
size_t pcp_sodium_mac(unsigned char **cipher, size_t pcp_sodium_mac(unsigned char **cipher,
unsigned char *cleartext, unsigned char *cleartext,
size_t clearsize, size_t clearsize,

View File

@@ -47,24 +47,7 @@ int pcp_sodium_verify_mac(unsigned char **cleartext,
unsigned char *nonce, unsigned char *nonce,
unsigned char *key); unsigned char *key);
// generate a nonce from random source arc4random().
// allocates memory for the returned nonce and
// it is up to the user to free it after use.
void pcp_makenonce(unsigned char **nonce);
// proprietary key derivation function. derives an
// secure encryption key from the given passphrase by
// calculating a SALSA20 hash from it HCYCLES times.
//
// turns the result into a proper CURVE25519 secret
// key. allocates memory for key and it is up to the
// user to free it after use.
//
// deprecation warning: maybe removed once the libsodium
// developers incorporated some key derivation function
// into libsodium. so far, there's none but word goes
// that perhaps something like scrypt() from the star
// distribution may be added in the future.
unsigned char *pcp_derivekey(char *passphrase);
#endif // _HAVE_PCP_MAC #endif // _HAVE_PCP_MAC

View File

@@ -2,8 +2,8 @@
#define _HAVE_PCP_VERSION #define _HAVE_PCP_VERSION
#define PCP_VERSION_MAJOR 0 #define PCP_VERSION_MAJOR 0
#define PCP_VERSION_MINOR 0 #define PCP_VERSION_MINOR 1
#define PCP_VERSION_PATCH 1 #define PCP_VERSION_PATCH 2
#define PCP_MAKE_VERSION(major, minor, patch) \ #define PCP_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch)) ((major) * 10000 + (minor) * 100 + (patch))

View File

@@ -124,7 +124,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "PCP1 1" .IX Title "PCP1 1"
.TH PCP1 1 "2013-10-29" "PCP 0.0.1" "USER CONTRIBUTED DOCUMENTATION" .TH PCP1 1 "2013-11-01" "PCP 0.0.1" "USER CONTRIBUTED DOCUMENTATION"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .if n .ad l
@@ -144,6 +144,8 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& \-I \-\-infile <file> Input file. If not specified, stdin \& \-I \-\-infile <file> Input file. If not specified, stdin
\& will be used. \& will be used.
\& \-i \-\-keyid <id> Specify a key id to import/export. \& \-i \-\-keyid <id> Specify a key id to import/export.
\& \-R \-\-recipient <string> Specify a recpipient, used for public
\& key export and encryption.
\& \-t \-\-text Print textual representation of some \& \-t \-\-text Print textual representation of some
\& item. Either \-V or \-i must be specified \& item. Either \-V or \-i must be specified
\& as well. \& as well.

View File

@@ -16,6 +16,8 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
-I --infile <file> Input file. If not specified, stdin -I --infile <file> Input file. If not specified, stdin
will be used. will be used.
-i --keyid <id> Specify a key id to import/export. -i --keyid <id> Specify a key id to import/export.
-R --recipient <string> Specify a recpipient, used for public
key export and encryption.
-t --text Print textual representation of some -t --text Print textual representation of some
item. Either -V or -i must be specified item. Either -V or -i must be specified
as well. as well.

View File

@@ -67,14 +67,22 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd) {
if(combined == NULL) if(combined == NULL)
goto errde1; goto errde1;
char *senderid = ucmalloc(17); unsigned char *hash = ucmalloc(crypto_hash_BYTES);
memcpy(senderid, combined, 16); unsigned char *check = ucmalloc(crypto_hash_BYTES);
senderid[16] = '\0'; memcpy(hash, combined, crypto_hash_BYTES);
HASH_FIND_STR(pcppubkey_hash, senderid, public); for(public=pcppubkey_hash;
public != NULL;
public=(pcp_pubkey_t*)(public->hh.next)) {
crypto_hash(check, (unsigned char*)public->id, 16);
if(memcmp(check, hash, crypto_hash_BYTES) == 0) {
// found one
break;
}
}
if(public == NULL) { if(public == NULL) {
fatal("Could not find a public key with id 0x%s in vault %s!\n", fatal("Could not find a usable public key in vault %s!\n",
senderid, vault->filename); vault->filename);
goto errde0; goto errde0;
} }
@@ -85,29 +93,52 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd) {
pcppubkey_printshortinfo(public); pcppubkey_printshortinfo(public);
} }
unsigned char *encrypted = ucmalloc(clen - 16); unsigned char *encrypted = ucmalloc(clen - crypto_hash_BYTES);
memcpy(encrypted, &combined[16], clen - 16); memcpy(encrypted, &combined[crypto_hash_BYTES], clen - crypto_hash_BYTES);
size_t dlen; size_t dlen;
unsigned char *decrypted = pcp_box_decrypt(secret, public, unsigned char *decrypted = pcp_box_decrypt(secret, public,
encrypted, clen - 16, &dlen); encrypted,
clen - crypto_hash_BYTES, &dlen);
if(decrypted == NULL) {
// try it with a derived secret from the sender id
pcp_key_t *s = pcp_derive_pcpkey(secret, public->id);
decrypted = pcp_box_decrypt(s, public,
encrypted,
clen - crypto_hash_BYTES, &dlen);
if(decrypted == NULL) {
// now try the senders key mail address
s = pcp_derive_pcpkey(secret, public->mail);
decrypted = pcp_box_decrypt(s, public,
encrypted,
clen - crypto_hash_BYTES, &dlen);
if(decrypted == NULL) {
// try the name
s = pcp_derive_pcpkey(secret, public->owner);
decrypted = pcp_box_decrypt(s, public,
encrypted,
clen - crypto_hash_BYTES, &dlen);
}
}
}
if(decrypted != NULL) { if(decrypted != NULL) {
fatals_reset();
fwrite(decrypted, dlen, 1, out); fwrite(decrypted, dlen, 1, out);
fclose(out); fclose(out);
if(ferror(out) != 0) { if(ferror(out) != 0) {
fatal("Failed to write decrypted output!\n"); fatal("Failed to write decrypted output!\n");
} }
free(decrypted); free(decrypted);
}
fprintf(stderr, "Decrypted %d bytes from 0x%s successfully\n", fprintf(stderr, "Decrypted %d bytes from 0x%s successfully\n",
(int)dlen, senderid); (int)dlen, public->id);
}
free(encrypted); free(encrypted);
errde0: errde0:
free(senderid);
free(combined); free(combined);
errde1: errde1:
@@ -121,7 +152,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd) {
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd) { int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipient) {
FILE *in = NULL; FILE *in = NULL;
FILE *out = NULL; FILE *out = NULL;
pcp_pubkey_t *public = NULL; pcp_pubkey_t *public = NULL;
@@ -175,6 +206,12 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd) {
goto erren2; goto erren2;
} }
if(recipient != NULL) {
pcp_key_t *derived = pcp_derive_pcpkey(secret, recipient);
memcpy(secret, derived, sizeof(pcp_key_t));
free(derived);
}
if(debug) { if(debug) {
fprintf(stderr, "Using secret key:\n"); fprintf(stderr, "Using secret key:\n");
pcpkey_printshortinfo(secret); pcpkey_printshortinfo(secret);
@@ -208,10 +245,12 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd) {
goto erren1; goto erren1;
size_t zlen; size_t zlen;
size_t clen = ciphersize + 16; size_t clen = ciphersize + crypto_hash_BYTES;
unsigned char *combined = ucmalloc(clen); unsigned char *combined = ucmalloc(clen);
memcpy(combined, secret->id, 16); unsigned char *hash = ucmalloc(crypto_hash_BYTES);
memcpy(&combined[16], cipher, clen - 16); crypto_hash(hash, (unsigned char*)secret->id, 16);
memcpy(combined, hash, crypto_hash_BYTES);
memcpy(&combined[crypto_hash_BYTES], cipher, clen - crypto_hash_BYTES);
// combined consists of: // combined consists of:
// keyid|nonce|cipher // keyid|nonce|cipher

View File

@@ -13,6 +13,6 @@
#include "keyprint.h" #include "keyprint.h"
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd); int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd);
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd); int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipient);
#endif // _HAVE_ENCRYPTION_H #endif // _HAVE_ENCRYPTION_H

View File

@@ -1,14 +1,13 @@
#include "keymgmt.h" #include "keymgmt.h"
char *pcp_getstdin(const char *prompt) { char *pcp_getstdin(const char *prompt) {
char line[1024]; char line[255];
char *out; char *out;
fprintf(stderr, "%s: ", prompt); fprintf(stderr, "%s: ", prompt);
if (fgets(line, 1024, stdin) == NULL) { if (fgets(line, 255, stdin) == NULL) {
fatal("Cannot read from stdin"); fatal("Cannot read from stdin");
goto errgst; goto errgst;
} }
@@ -26,7 +25,6 @@ char *pcp_getstdin(const char *prompt) {
return NULL; return NULL;
} }
int pcp_storekey (pcp_key_t *key) { int pcp_storekey (pcp_key_t *key) {
if(vault->isnew == 1 || HASH_COUNT(pcpkey_hash) == 0) { if(vault->isnew == 1 || HASH_COUNT(pcpkey_hash) == 0) {
key->type = PCP_KEY_TYPE_MAINSECRET; key->type = PCP_KEY_TYPE_MAINSECRET;
@@ -207,10 +205,46 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile) {
} }
void pcp_exportpublic(char *keyid, int useid, char *outfile) { pcp_key_t *pcp_getrsk(pcp_key_t *s, char *recipient, char *passwd) {
if(recipient != NULL) {
if(s->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);
}
s = pcpkey_decrypt(s, passphrase);
if(s == NULL)
goto errrsk1;
}
pcp_key_t *tmp;
tmp = pcp_derive_pcpkey(s, recipient);
return tmp;
}
return s;
errrsk1:
return NULL;
}
/*
if id given, look if it is already a public and export this,
else we look for a secret key with that id. without a given
keyid we use the primary key. if we start with a secret key
and a recipient have been given, we use a derived secret key
and export the public component from that. without recipient
just export the public component of the found secret key.
*/
void pcp_exportpublic(char *keyid, char *recipient, char *passwd, char *outfile) {
pcp_pubkey_t *key = NULL; pcp_pubkey_t *key = NULL;
if(useid == 1) { if(keyid != NULL) {
// look if we've got that one // look if we've got that one
HASH_FIND_STR(pcppubkey_hash, keyid, key); HASH_FIND_STR(pcppubkey_hash, keyid, key);
if(key == NULL) { if(key == NULL) {
@@ -222,6 +256,8 @@ void pcp_exportpublic(char *keyid, int useid, char *outfile) {
free(s); free(s);
} }
else { else {
s = pcp_getrsk(s, recipient, passwd);
if(s != NULL)
key = pcpkey_pub_from_secret(s); key = pcpkey_pub_from_secret(s);
} }
} }
@@ -235,7 +271,10 @@ void pcp_exportpublic(char *keyid, int useid, char *outfile) {
free(s); free(s);
} }
else { else {
key = pcpkey_pub_from_secret(s); pcp_key_t *t = NULL;
t = pcp_getrsk(s, recipient, passwd);
if(t != NULL)
key = pcpkey_pub_from_secret(t);
} }
} }

View File

@@ -22,7 +22,8 @@ int pcp_storekey (pcp_key_t *key);
void pcp_keygen(); void pcp_keygen();
void pcp_listkeys(); void pcp_listkeys();
void pcp_exportsecret(char *keyid, int useid, char *outfile); void pcp_exportsecret(char *keyid, int useid, char *outfile);
void pcp_exportpublic(char *keyid, int useid, char *outfile); pcp_key_t *pcp_getrsk(pcp_key_t *s, char *recipient, char *passwd);
void pcp_exportpublic(char *keyid, char *recipient, char *passwd, char *outfile);
char *pcp_normalize_id(char *keyid); char *pcp_normalize_id(char *keyid);
pcp_key_t *pcp_find_primary_secret(); pcp_key_t *pcp_find_primary_secret();
int pcp_importpublic (vault_t *vault, FILE *in); int pcp_importpublic (vault_t *vault, FILE *in);

View File

@@ -22,13 +22,14 @@ char *default_vault() {
} }
int main (int argc, char **argv) { int main (int argc, char **argv) {
int opt, mode, usevault, useid; int opt, mode, usevault, useid, userec;
char *vaultfile = default_vault(); char *vaultfile = default_vault();
char *outfile = NULL; char *outfile = NULL;
char *infile = NULL; char *infile = NULL;
char *keyid = NULL; char *keyid = NULL;
char *id = NULL; char *id = NULL;
char *xpass = NULL; char *xpass = NULL;
char *recipient = NULL;
FILE *in; FILE *in;
PCP_EXIT = 0; PCP_EXIT = 0;
@@ -37,6 +38,7 @@ int main (int argc, char **argv) {
mode = 0; mode = 0;
usevault = 0; usevault = 0;
useid = 0; useid = 0;
userec = 0;
static struct option longopts[] = { static struct option longopts[] = {
// generics // generics
@@ -46,6 +48,7 @@ int main (int argc, char **argv) {
{ "keyid", required_argument, NULL, 'i' }, { "keyid", required_argument, NULL, 'i' },
{ "text", required_argument, NULL, 't' }, { "text", required_argument, NULL, 't' },
{ "xpass", required_argument, NULL, 'x' }, { "xpass", required_argument, NULL, 'x' },
{ "recipient", required_argument, NULL, 'R' },
// key management // key management
{ "keygen", no_argument, NULL, 'k' }, { "keygen", no_argument, NULL, 'k' },
@@ -72,7 +75,7 @@ int main (int argc, char **argv) {
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPrtEx:DzZ", while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPrtEx:DzZR:",
longopts, NULL)) != -1) { longopts, NULL)) != -1) {
switch (opt) { switch (opt) {
@@ -150,7 +153,11 @@ int main (int argc, char **argv) {
xpass = ucmalloc(strlen(optarg)+1); xpass = ucmalloc(strlen(optarg)+1);
strncpy(xpass, optarg, strlen(optarg)+1); strncpy(xpass, optarg, strlen(optarg)+1);
break; break;
case 'R':
recipient = ucmalloc(strlen(optarg)+1);
strncpy(recipient, optarg, strlen(optarg)+1);
userec = 1;
break;
case 'D': case 'D':
debug = 1; debug = 1;
@@ -204,14 +211,14 @@ int main (int argc, char **argv) {
case PCP_MODE_EXPORT_PUBLIC: case PCP_MODE_EXPORT_PUBLIC:
if(useid) { if(useid) {
id = pcp_normalize_id(keyid); id = pcp_normalize_id(keyid);
if(id != NULL) { if(id == NULL)
pcp_exportpublic(id, useid, outfile); break;
free(id);
}
}
else {
pcp_exportpublic(NULL, useid, outfile);
} }
pcp_exportpublic(id, recipient, xpass, outfile);
if(xpass != NULL)
free(xpass);
if(recipient != NULL)
free(recipient);
break; break;
case PCP_MODE_IMPORT_PUBLIC: case PCP_MODE_IMPORT_PUBLIC:
@@ -283,10 +290,12 @@ int main (int argc, char **argv) {
if(useid) { if(useid) {
id = pcp_normalize_id(keyid); id = pcp_normalize_id(keyid);
if(id != NULL) { if(id != NULL) {
pcpencrypt(id, infile, outfile, xpass); pcpencrypt(id, infile, outfile, xpass, recipient);
free(id); free(id);
if(xpass != NULL) if(xpass != NULL)
free(xpass); free(xpass);
if(recipient != NULL)
free(recipient);
} }
} }
else { else {

View File

@@ -11,6 +11,8 @@
"-I --infile <file> Input file. If not specified, stdin\n" \ "-I --infile <file> Input file. If not specified, stdin\n" \
" will be used.\n" \ " will be used.\n" \
"-i --keyid <id> Specify a key id to import/export.\n" \ "-i --keyid <id> Specify a key id to import/export.\n" \
"-R --recipient <string> Specify a recpipient, used for public\n" \
" key export and encryption.\n" \
"-t --text Print textual representation of some\n" \ "-t --text Print textual representation of some\n" \
" item. Either -V or -i must be specified\n" \ " item. Either -V or -i must be specified\n" \
" as well.\n" \ " as well.\n" \

View File

@@ -9,6 +9,8 @@ General Options:
-I --infile <file> Input file. If not specified, stdin -I --infile <file> Input file. If not specified, stdin
will be used. will be used.
-i --keyid <id> Specify a key id to import/export. -i --keyid <id> Specify a key id to import/export.
-R --recipient <string> Specify a recpipient, used for public
key export and encryption.
-t --text Print textual representation of some -t --text Print textual representation of some
item. Either -V or -i must be specified item. Either -V or -i must be specified
as well. as well.

View File

@@ -1,17 +1,23 @@
AM_CFLAGS = -I../libpcp -Wall -g AM_CFLAGS = -I../libpcp -Wall -g
check_PROGRAMS = col invalidkeys check_PROGRAMS = col invalidkeys pwhashes
col_LDADD = ../libpcp/.libs/libpcp1.a col_LDADD = ../libpcp/.libs/libpcp1.a
col_SOURCES = collisions.c col_SOURCES = collisions.c
invalidkeys_LDADD = ../libpcp/.libs/libpcp1.a ../src/keyprint.o invalidkeys_LDADD = ../libpcp/.libs/libpcp1.a ../src/keyprint.o
invalidkeys_SOURCES = invalidkeys.c invalidkeys_SOURCES = invalidkeys.c
pwhashes_LDADD = ../libpcp/.libs/libpcp1.a
pwhashes_SOURCES = pwhashes.c
AM_CPPFLAGS = -I$(top_builddir)/src AM_CPPFLAGS = -I$(top_builddir)/src
test: check test: check
./unittests.pl unittests.cfg rm -f test* v* stresstest/*
./unittests.pl unittests.cfg $(CHECK)
@echo "To run a single test only, type: 'make test CHECK=testname'"
stresstest: check stresstest: check
./unittests.pl stresstests.cfg ./unittests.pl stresstests.cfg

View File

@@ -49,7 +49,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
check_PROGRAMS = col$(EXEEXT) invalidkeys$(EXEEXT) check_PROGRAMS = col$(EXEEXT) invalidkeys$(EXEEXT) pwhashes$(EXEEXT)
subdir = tests subdir = tests
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/config/depcomp $(top_srcdir)/config/depcomp
@@ -71,6 +71,9 @@ col_DEPENDENCIES = ../libpcp/.libs/libpcp1.a
am_invalidkeys_OBJECTS = invalidkeys.$(OBJEXT) am_invalidkeys_OBJECTS = invalidkeys.$(OBJEXT)
invalidkeys_OBJECTS = $(am_invalidkeys_OBJECTS) invalidkeys_OBJECTS = $(am_invalidkeys_OBJECTS)
invalidkeys_DEPENDENCIES = ../libpcp/.libs/libpcp1.a ../src/keyprint.o invalidkeys_DEPENDENCIES = ../libpcp/.libs/libpcp1.a ../src/keyprint.o
am_pwhashes_OBJECTS = pwhashes.$(OBJEXT)
pwhashes_OBJECTS = $(am_pwhashes_OBJECTS)
pwhashes_DEPENDENCIES = ../libpcp/.libs/libpcp1.a
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/libpcp DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/libpcp
depcomp = $(SHELL) $(top_srcdir)/config/depcomp depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles am__depfiles_maybe = depfiles
@@ -84,8 +87,9 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@ $(LDFLAGS) -o $@
SOURCES = $(col_SOURCES) $(invalidkeys_SOURCES) SOURCES = $(col_SOURCES) $(invalidkeys_SOURCES) $(pwhashes_SOURCES)
DIST_SOURCES = $(col_SOURCES) $(invalidkeys_SOURCES) DIST_SOURCES = $(col_SOURCES) $(invalidkeys_SOURCES) \
$(pwhashes_SOURCES)
am__can_run_installinfo = \ am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \ case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \ n|no|NO) false;; \
@@ -212,6 +216,8 @@ col_LDADD = ../libpcp/.libs/libpcp1.a
col_SOURCES = collisions.c col_SOURCES = collisions.c
invalidkeys_LDADD = ../libpcp/.libs/libpcp1.a ../src/keyprint.o invalidkeys_LDADD = ../libpcp/.libs/libpcp1.a ../src/keyprint.o
invalidkeys_SOURCES = invalidkeys.c invalidkeys_SOURCES = invalidkeys.c
pwhashes_LDADD = ../libpcp/.libs/libpcp1.a
pwhashes_SOURCES = pwhashes.c
AM_CPPFLAGS = -I$(top_builddir)/src AM_CPPFLAGS = -I$(top_builddir)/src
all: all-am all: all-am
@@ -262,6 +268,9 @@ col$(EXEEXT): $(col_OBJECTS) $(col_DEPENDENCIES) $(EXTRA_col_DEPENDENCIES)
invalidkeys$(EXEEXT): $(invalidkeys_OBJECTS) $(invalidkeys_DEPENDENCIES) $(EXTRA_invalidkeys_DEPENDENCIES) invalidkeys$(EXEEXT): $(invalidkeys_OBJECTS) $(invalidkeys_DEPENDENCIES) $(EXTRA_invalidkeys_DEPENDENCIES)
@rm -f invalidkeys$(EXEEXT) @rm -f invalidkeys$(EXEEXT)
$(LINK) $(invalidkeys_OBJECTS) $(invalidkeys_LDADD) $(LIBS) $(LINK) $(invalidkeys_OBJECTS) $(invalidkeys_LDADD) $(LIBS)
pwhashes$(EXEEXT): $(pwhashes_OBJECTS) $(pwhashes_DEPENDENCIES) $(EXTRA_pwhashes_DEPENDENCIES)
@rm -f pwhashes$(EXEEXT)
$(LINK) $(pwhashes_OBJECTS) $(pwhashes_LDADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@@ -271,6 +280,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collisions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collisions.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invalidkeys.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invalidkeys.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwhashes.Po@am__quote@
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -519,7 +529,9 @@ uninstall-am:
test: check test: check
./unittests.pl unittests.cfg rm -f test* v* stresstest/*
./unittests.pl unittests.cfg $(CHECK)
@echo "To run a single test only, type: 'make test CHECK=testname'"
stresstest: check stresstest: check
./unittests.pl stresstests.cfg ./unittests.pl stresstests.cfg

View File

@@ -3,34 +3,34 @@
Cipher: CURVE25519-ED25519-SALSA20-POLY1305 Cipher: CURVE25519-ED25519-SALSA20-POLY1305
Owner: Alicia Owner: Alicia
Mail: alicia@local Mail: alicia@local
Key-ID: 0xE2942C2B6C96F6CC Key-ID: 0x44713DD4E010C582
Public-Key: 1mZ?-e4^0JA&[}#=t1$/&aI<i:eM^bA/uIJ0O.iRBn#pv Public-Key: 0#17WjFuf7fj](Ij)l%NCBRo:TwopP(6qSXlEzxb0rr91
Creation Time: 2013-10-28T18:43:53 Creation Time: 2013-11-01T15:52:56
Checksum: 1D:33:59:F1:B2:2F:21:73:3A:F6:5E:0D:63:47:76:42 Checksum: A0:AF:A6:F1:07:9F:90:EE:95:AF:D7:EE:44:7E:E8:A7
93:3B:EF:36:D3:20:8E:43:F5:4D:A9:39:9F:09:43:69 ED:C0:71:A4:B3:BF:CD:2B:9C:0E:EC:1D:63:0B:14:A5
Serial Number: 0x90C7B055 Serial Number: 0x2E2A200A
Key Version: 0x00000001 Key Version: 0x00000001
Random Art ID: +----------------+ Random Art ID: +----------------+
| | |+. . .o |
| | |oo o o o |
| o + . . |
| . . . . |
| . o |
| . | | . |
| o | | |
| . . | | |
| .... |
| ..o...= . |
| .+ o.+..|
+----------------+ +----------------+
1mZ?-e4^0JA&[}#=t1$/&aI<i:eM^bA/uIJ0O.iRBu%.Sv}/uK[e:!VVu[(jqvxj3QIzoG< 0#17WjFuf7fj](Ij)l%NCBRo:TwopP(6qSXlEzxb0ypKov}/uK2Q6/xr-Mq6bH=dy8-biEa
/@!Wi0UUCA}6NMwWT$%=Om%gAzYhPvNTZ$mm%*l5YCA>s8fWoUI)[[l?@](l[bY3wzfJg8$ o$IOLG(OLj{dO?B}Vh)-e0X:73@MH9Z=i&FhqqkV{j>wxmJcC0*vL4O<Q+.q)ty:VOAGbyR
+RsBj5+]c/(!ZwWu-lDPCkCGb.GJM$HLPU@np=ZQTh-1[#RaNGdOWb(]ZY=K]fSdMfU4q)Z /3CTX4w{:GavB1[71)Y+O]jo*Fl[k0wyG=rBrVbmSRO3cS/7ZgaC@I8z:iqmr!JQPm3!i#0
T7dmxE:Cmst2o73w4RJ*A%?1idZ2&a^:kXsxnrxCXc5zt>n{QOQY{99oj&^!WH%6b&8@r]o 46m2#Gp9537DU[]VwU2cj0FBbXSnsG(v0R>Mj3sOZNR^3k}OXM!N<]}+!SFY>qoT%H6{tZb
OLEzsx9t]B1/vjj:SUBt3*enaKb?.>2eZdMKvFLQ?7DeedmCz-0FGzc!t#o)&Tg%:jV$8iH WCdrzhvQK7Cc]Prn5yvZvyo*@3:xd-plZ92qy@XnqMuc#N7EdRWP30RnxhloN6ZMTNGKOaR
Iq.#9vqGT/x<<nyz!0i(0i&$kp^ylwen6]g:ytRVULL%s>UF39qu9sT6xka@S9F&fyO%Vgo ETo@7vqGT/x<<nyz!0i(05F-mcd)9K><iy/NSYGQ?-sv*4zeW%*<hX}ErwDIo+=6DyWlED0
AtD^cLtsGtT.DiNQ5&dSeOe2Oa:ETxg&Z[fB+I7uU-Z9OstL?nWLq@O&)a+:vtW1NUrt>4( 5<F%P*cZ0d^3{dA*&DBPG&/(:I3P!t{DA?5jZMIHUs9$+g$yx>]?.C}AEPsc+IVii?J?Tl3
ZaW2D^?xt:CzJ=ARPhD2P6AW5t(E@MD?rpY5MlYFhYv*VU7%6bZ>#hU:<Gv5FX0OCR#PiK} dZ/BB=?og/UGl-AaP(aSG0VxQ9SQMbbnWW1IMzrX<D9YMxa$@J!V)BS#DQU6PgEP!<<baUG
UMFAiwkJ)laaDw53N>kW2r9nA8y5>OCb!u.i3dQ8NK3.<>A62Jy[^p}rzi:f*R-]cll:p!D 7S+q0l2]Zq5t96oB2Gp3/Oli/&<+lBrd4K>{}<bJYekq/as^20FMPcYdrY0BgrvTaThiB$c
hB:kv7pVUjpj*-.5Bg8NBT:HpC:nA*X3)]<eSQP)Qgc4fDlOZ$^lPE4]hBx?i9:bjPqucW% HvxporF*#>>aRm^KrTa#B5oo2uW)@BgRl6kE<bjZgg=EcBl{@>2fFLmGh8)t>BX6q?qucW%
0096109cnzKomKzJcU^k?C=*@OGUI&18tAgfFq^Wi8!R6ac}Deld[lkk0OYPaf}2{5Arw$e 00961016?#e^3NT/77sIVp)H[P%U=36VHc+)7i+Klv>OpXx.Cyv*-/qUB>>TOr/21J^s(4B
Kg$$@/G+8v$i*m)d@U?H5.hN H<GklM1BcPYtTx*%-jvuJp6a
------ END PCP PUBLICKEY ------ ------ END PCP PUBLICKEY ------

View File

@@ -1,23 +1,23 @@
----- BEGIN PCP SECRET KEY ----- ----- BEGIN PCP SECRET KEY -----
Generated by: Pretty Curved Privacy Version 0.0.1 Generated by: Pretty Curved Privacy Version 0.0.1
Cipher: CURVE25519-ED25519-SALSA20-POLY1305 Cipher: CURVE25519-ED25519-SALSA20-POLY1305
Key-ID: 0xE2942C2B6C96F6CC Key-ID: 0x44713DD4E010C582
Creation Time: 2013-10-28T18:43:53 Creation Time: 2013-11-01T15:52:56
Serial Number: 0x3271452A Serial Number: 0xD56BD45A
Key Version: 0x00000001 Key Version: 0x00000001
1mZ?-e4^0JA&[}#=t1$/&aI<i:eM^bA/uIJ0O.iRBo2&m=rz<?V@H>0Z2d1[B(z6I[xE%-a 0#17WjFuf7fj](Ij)l%NCBRo:TwopP(6qSXlEzxb0rrpXZ*@1[iueS8)-7+Yi7*B2x#R0Bl
+sp@mrOlA&rK9gRP1pk=Hnr=sCxjb?Sj51ISMR.YA&:ZT23?J.Nx!{ZHobd9(QUR)FPmjti i[Bb3{IdSVjF+hRw=E7*+R-99mFl}W7zX!]Vy1dY4:E8(Xh/f+^0QRI8jw*cVGk-?W%l8GP
gT//!hkQNum.a9NC[LW>UetZSh%D>rS]#v}/uK[e:!VVu[(jqvxj3QIzoG</@!Wi0UUCA}6 -jBX39B%PNsBu8#$@X]Yw+)Mr=G=L%Gk2v}/uK2Q6/xr-Mq6bH=dy8-biEao$IOLG(OLj{d
NMwWT$%=Om%gAzYhPvNTZ$mm%*l5YCA>s8fWoUI)[[l?@](l[bY3wzfJg8$+RsBj5+]c/(! O?B}Vh)-e0X:73@MH9Z=i&FhqqkV{j>wxmJcC0*vL4O<Q+.q)ty:VOAGbyR/3CTX4w{:Gav
ZwWu-lDPCkCGb.GJM$HLPU@np=ZQTh-1[#RaNGdOWb(]ZY=K]fSdMfU4q)ZT7dmxE:Cmst2 B1[71)Y+O]jo*Fl[k0wyG=rBrVbmSRO3cS/7ZgaC@I8z:iqmr!JQPm3!i#046m2#Gp9537D
o73w4RJ*A%?1idZ2&a^:kXsxnrxCXc5zt>n{QOQY{99oj&^!WH%6b&8@r]oOLEzsx9t]B1/ U[]VwU2cj0FBbXSnsG(v0R>Mj3sOZNR^3k}OXM!N<]}+!SFY>qoT%H6{tZbWCdrzhvQK7Cc
vjj:SUBt3*enaKb?.>2eZdMKvFLQ?7DeedmCz-0FGzc!t#o)&Tg%:jV$8iHIq.#9vqGT/x< ]Prn5yvZvyo*@3:xd-plZ92qy@XnqMuc#N7EdRWP30RnxhloN6ZMTNGKOaRETo@7vqGT/x<
<nyz!0i(0i&$kp^ylwen6]g:ytRVULL%s>UF39qu9sT6xka@S9F&fyO%VgoAtD^cLtsGtT. <nyz!0i(05F-mcd)9K><iy/NSYGQ?-sv*4zeW%*<hX}ErwDIo+=6DyWlED05<F%P*cZ0d^3
DiNQ5&dSeOe2Oa:ETxg&Z[fB+I7uU-Z9OstL?nWLq@O&)a+:vtW1NUrt>4(ZaW2D^?xt:Cz {dA*&DBPG&/(:I3P!t{DA?5jZMIHUs9$+g$yx>]?.C}AEPsc+IVii?J?Tl3dZ/BB=?og/UG
J=ARPhD2P6AW5t(E@MD?rpY5MlYFhYv*VU7%6bZ>#hU:<Gv5FX0OCR#PiK}UMFAiwkJ)laa l-AaP(aSG0VxQ9SQMbbnWW1IMzrX<D9YMxa$@J!V)BS#DQU6PgEP!<<baUG7S+q0l2]Zq5t
Dw53N>kW2r9nA8y5>OCb!u.i3dQ8NK3.<>A62Jy[^p}rzi:f*R-]cll:p!DhB:kv7pVUjpj 96oB2Gp3/Oli/&<+lBrd4K>{}<bJYekq/as^20FMPcYdrY0BgrvTaThiB$cHvxporF*#>>a
*-.5Bg8NBT:HpC:nA*X3)]<eSQP)Qgc4fDlOZ$^lPE4]hBx?i.=-ZKqucW%0096104HASg6 Rm^KrTa#B5oo2uW)@BgRl6kE<bjZgg=EcBl{@>2fFLmGh8)t>/*@]1qucW%0096109W(/!D
4S/xxvy{tr<r40seV900000000000000000000000000000000000000000eu+e0seV901Y 7d$0ht*YE)tbE0seV900000000000000000000000000000000000000000eu+e0seV901Y
bg0kqxS9@(ov bg0f]#U:]zzw
------ END PCP SECRET KEY ------ ------ END PCP SECRET KEY ------

View File

@@ -2,35 +2,35 @@
Generated by: Pretty Curved Privacy Version 0.0.1 Generated by: Pretty Curved Privacy Version 0.0.1
Cipher: CURVE25519-ED25519-SALSA20-POLY1305 Cipher: CURVE25519-ED25519-SALSA20-POLY1305
Owner: Bobby Owner: Bobby
Mail: bobby@<EFBFBD>local Mail: bobby@local
Key-ID: 0x68832D215AFB2440 Key-ID: 0xCE20289DFB268A3D
Public-Key: 1m9SHw3}sw<Ro82?hQ&J[byDA]z(g1.6X$MweEJ95Dz!h Public-Key: 18a+&]*cfaPvpGAs*rp=oWkCXnLGe^aUx%^:BtLfv/MGe
Creation Time: 2013-10-28T18:48:11 Creation Time: 2013-11-01T15:53:45
Checksum: A8:32:16:EF:9D:38:9A:3C:7D:99:F2:81:D4:42:B3:2D Checksum: D6:79:EB:3B:22:CE:77:99:62:58:9A:7D:C5:B7:62:1B
28:13:A9:43:1B:22:C3:71:A8:38:38:10:E3:A3:B9:82 F1:2D:2D:FB:C3:D5:B1:9B:D3:B6:DA:9D:89:5B:14:07
Serial Number: 0x61FDA3CE Serial Number: 0x6F6477D5
Key Version: 0x00000001 Key Version: 0x00000001
Random Art ID: +----------------+ Random Art ID: +----------------+
| | | . |
| | | o |
| |
| |
| o . | | o . |
| o o . | | . = o |
| . Bo.. | | o . B . |
| +o==. | | o + . . |
| . o |
| |
+----------------+ +----------------+
1m9SHw3}sw<Ro82?hQ&J[byDA]z(g1.6X$MweEJ95KHzBvTd%QWcl:NlJtTyRdZ>sTc3J1e 18a+&]*cfaPvpGAs*rp=oWkCXnLGe^aUx%^:BtLfv)U9yvTd$l]THd!tuMEjzY(YpATNQ[=
nQ<!<c@^1<(%aF6ks+&}eE%8}zc<Ny@#5&O%GN6ep49slxWhkSe*jox/(JrkVP[zWJ0.wQ8 +9O9^D(VP+S/a@hLz<>u{Y]esh$8duOcR0iu]e*D%*)/F/JBwGFEOY/Sy.dtBJ:a1C7003$
RqvuRolF*/(wJ&{+Qpd1dyx&=ERL1c$%bg($]4Fe23!410z/HctdobTD=bs#@]sT[[%d7Z& APnZE=KcH[2z+=R]?R?[}M!t@g+p2.UI!HL$?7.5v.w>3}B>dB[l#p7e<7{<I=x8vBCX-+Z
/k:d4>jeJey}hI*S7Pl^8O:i#]wd4}WNR7UYw(=}pBKsHbm^XeFqg^(CtjZG!K4oMPT=bJU +^4{FLkgm=2C2XtC{&RQ$vTD*[GO5edJOJz==3oO+dHiI^tFHJF9th-!zV:rRoe7a]Bf2c4
df/X2F]5iq-bYp:EC82YBJ<[NP*BDW?r-L..!As*CWddicuvsp^AQ20O-$+a@K<}6OPd*Hb 6?KlfIOU$[tib4@ae2gxwErN!nlyFyCjK#fq(nhLdXZnaBZPJH?2<3i.AGbhcn2^REv^wgp
jex#UvSbZ+C%Gt+z!0i(0j#I6?xftr.eqpicnf]DWfiqE:*?/%(slD9QQU[7t4{J>hyLRkC nf^T<vSbZ+C%Dg:v{%fN5jnkID*#%SsF3#*<Gl53B[s3T/u&/u1X+^Xf2H5x@j+Vr!1eAkO
s=uT0HwrFIz6f9C!&=Nf$(jE*(3RFhA>SM5MiFq&8TqUn:^2xzxa70=]T*J[g}vVl8:-Zqq ]*qlLlFNsx+ha/b9Nbn2T.A[{n!PClH%bE{Ou>i)Jl<){nb:RRPgWu/uw8l<tSqoh^L4s-D
N%{=qe7rScb.M4{Ld4j[HDIV(YZZWZ4}At*x.NT5E[/5p/3{SbNK7wjj[1yA2d]ZlE[I4-Z .s+A?7V*0%}2J[XV/XX[L5A8ydsrlSvei+eLs@Eo.#@wENxEYwb+FAAYJ7=ax}ZiXgn(Yy7
11m*e^vcdRz+(xlU=:cXwV2<E1jGb5N/rmsW}O*DM/lG^lEi*+ahIvln>A+463^RQHyN77/ VF7osPjBku4f+P[M^<9V5>a@FBi{i@3y8]O6/l:NF0P7nsx4xKueAjuVY1h5e*K+3RwcZdD
>fdtrPLE^lGYGTc(=FosgPggLZmqU)FTG6g.][KFAi5&YHl]3FOk$jf@g=c(^t3E+tqucW% Gviumba.%%uk*Ve3k39UMAPWa70-7xS7[SeaoyYtQmkuLLi5%w@lnyCUk@g[elv3v/qucW%
009610m4wrvfsIuoY5m{QWy!7fuih0^e@NMCINT@TYUeV/h:L8WNE3YBh]kQ{UG3qf*4Ql9 009610m=p7zV.nxQrk[Mw!!mbV1F[Nd(efiPTr+pd=QNgCQ>-k?#=T)<X%@VePW62>XM7A[
}&1i2de}$URN7GD6yTb/8L^J jSQW]2+-gx<+-p(4+#H8#]%s
------ END PCP PUBLICKEY ------ ------ END PCP PUBLICKEY ------

View File

@@ -1,23 +1,23 @@
----- BEGIN PCP SECRET KEY ----- ----- BEGIN PCP SECRET KEY -----
Generated by: Pretty Curved Privacy Version 0.0.1 Generated by: Pretty Curved Privacy Version 0.0.1
Cipher: CURVE25519-ED25519-SALSA20-POLY1305 Cipher: CURVE25519-ED25519-SALSA20-POLY1305
Key-ID: 0x68832D215AFB2440 Key-ID: 0xCE20289DFB268A3D
Creation Time: 2013-10-28T18:48:11 Creation Time: 2013-11-01T15:53:45
Serial Number: 0xECD29916 Serial Number: 0x2467E86B
Key Version: 0x00000001 Key Version: 0x00000001
1m9SHw3}sw<Ro82?hQ&J[byDA]z(g1.6X$MweEJ95DAzC&hpY67^g3^L>d4K/JF>>JbqkC- 18a+&]*cfaPvpGAs*rp=oWkCXnLGe^aUx%^:BtLfv/OYAu{EkGzV6b}YAR}P{d}y@LR)QXx
ENik9(Oa&k6L^6(cq5O?r}Yx2C5&kgv$qs(-bttGrEtiKwvSQhD6&VdwYg)Fg%dqgVLX#FK Mrlpmmyv5L2*caym<akR-r$9Q$lU2}%>k:0@x*u8U=rjS(uW.b0D5R-Esfd23JQIuCz6)v<
+DcAIb@!A-ql$kqlYXd71ciD-Gs+p^P8fvTd%QWcl:NlJtTyRdZ>sTc3J1enQ<!<c@^1<(% ]f{eDwrpMNMVSH-4zE57W$!jZ(odJy4L)vTd$l]THd!tuMEjzY(YpATNQ[=+9O9^D(VP+S/
aF6ks+&}eE%8}zc<Ny@#5&O%GN6ep49slxWhkSe*jox/(JrkVP[zWJ0.wQ8RqvuRolF*/(w a@hLz<>u{Y]esh$8duOcR0iu]e*D%*)/F/JBwGFEOY/Sy.dtBJ:a1C7003$APnZE=KcH[2z
J&{+Qpd1dyx&=ERL1c$%bg($]4Fe23!410z/HctdobTD=bs#@]sT[[%d7Z&/k:d4>jeJey} +=R]?R?[}M!t@g+p2.UI!HL$?7.5v.w>3}B>dB[l#p7e<7{<I=x8vBCX-+Z+^4{FLkgm=2C
hI*S7Pl^8O:i#]wd4}WNR7UYw(=}pBKsHbm^XeFqg^(CtjZG!K4oMPT=bJUdf/X2F]5iq-b 2XtC{&RQ$vTD*[GO5edJOJz==3oO+dHiI^tFHJF9th-!zV:rRoe7a]Bf2c46?KlfIOU$[ti
Yp:EC82YBJ<[NP*BDW?r-L..!As*CWddicuvsp^AQ20O-$+a@K<}6OPd*Hbjex#UvSbZ+C% b4@ae2gxwErN!nlyFyCjK#fq(nhLdXZnaBZPJH?2<3i.AGbhcn2^REv^wgpnf^T<vSbZ+C%
Gt+z!0i(0j#I6?xftr.eqpicnf]DWfiqE:*?/%(slD9QQU[7t4{J>hyLRkCs=uT0HwrFIz6 Dg:v{%fN5jnkID*#%SsF3#*<Gl53B[s3T/u&/u1X+^Xf2H5x@j+Vr!1eAkO]*qlLlFNsx+h
f9C!&=Nf$(jE*(3RFhA>SM5MiFq&8TqUn:^2xzxa70=]T*J[g}vVl8:-ZqqN%{=qe7rScb. a/b9Nbn2T.A[{n!PClH%bE{Ou>i)Jl<){nb:RRPgWu/uw8l<tSqoh^L4s-D.s+A?7V*0%}2
M4{Ld4j[HDIV(YZZWZ4}At*x.NT5E[/5p/3{SbNK7wjj[1yA2d]ZlE[I4-Z11m*e^vcdRz+ J[XV/XX[L5A8ydsrlSvei+eLs@Eo.#@wENxEYwb+FAAYJ7=ax}ZiXgn(Yy7VF7osPjBku4f
(xlU=:cXwV2<E1jGb5N/rmsW}O*DM/lG^lEi*+ahIvln>A+463^RQHyN77/>fdtrPLE^lGY +P[M^<9V5>a@FBi{i@3y8]O6/l:NF0P7nsx4xKueAjuVY1h5e*K+3RwcZdDGviumba.%%uk
GTc(=FosgPggLZmqU)FTG6g.][KFAi5&YHl]3FOk$jf@g=c(^-9o0OqucW%0096102z0J(& *Ve3k39UMAPWa70-7xS7[SeaoyYtQmkuLLi5%w@lnyCUk@g[e?*91UqucW%009610bH!hbM
Aly(LQ/JMoWb{0seV900000000000000000000000000000000000000000evsu0seV901Y Q0z>Pa*6vN85b0seV900000000000000000000000000000000000000000eu+e0seV901Y
bg08Qd7i@/lX bg0a8w*x-Fbk
------ END PCP SECRET KEY ------ ------ END PCP SECRET KEY ------

View File

@@ -77,10 +77,13 @@ dxmorg@florida.cops.gov
# #
# encryption tests # encryption tests
idbobby = 0x68832D215AFB2440 idbobby = 0xCE20289DFB268A3D
idalicia = 0xE2942C2B6C96F6CC idalicia = 0x44713DD4E010C582
mailbobby = bobby@local
mailalicia = alicia@local
md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50 md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
<test check-crypto-alicia-init> <test check-crypto-alicia-init>
# alicias part
prepare = echo ${md5msg} > testmessage prepare = echo ${md5msg} > testmessage
<test check-crypto-alicia-import-secret> <test check-crypto-alicia-import-secret>
cmd = $pcp -V va -S -I key-alicia-sec -x a cmd = $pcp -V va -S -I key-alicia-sec -x a
@@ -104,6 +107,7 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
</test> </test>
<test check-crypto-bobby-init> <test check-crypto-bobby-init>
# bobbys part
<test check-crypto-bobby-import-secret> <test check-crypto-bobby-import-secret>
cmd = $pcp -V vb -S -I key-bobby-sec -x b cmd = $pcp -V vb -S -I key-bobby-sec -x b
expect = /${idbobby}/ expect = /${idbobby}/
@@ -125,6 +129,52 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
</test> </test>
</test> </test>
#
# same, now with derived keys, keypairs:
# alicia bobby
# secret: derived for bobby secret:primary
# bobby's public: primary alicia's public: derived for him
#
# derived by name
<test check-dcrypto-init>
<test check-dcrypto-alicia-export-derived-byname>
cmd = $pcp -V va -p -R Bobby -x a -O testpub-forbobby-name
expect-file = testpub-forbobby-name
</test>
<test check-dcrypto-bobby-import-byname>
cmd = $pcp -V vb -P -I testpub-forbobby-name
expect = /added/
</test>
<test check-dcrypto-bobby-encrypt-byname>
id = grep Key-ID testpub-forbobby-name | sed 's/^ //g' | cut -d' ' -f2
cmd = $pcp -V vb -e -i %{id} -I testmessage -O testencrypted-name -x b
expect = /success/
</test>
<test check-dcrypto-alicia-decrypt-byname>
cmd = $pcp -V va -d -I testencrypted-name -x a
expect = /success/
</test>
# repeat, but now use derived keys in both directions
<test check-dcrypto-bobby-export-derived-byname>
cmd = $pcp -V vb -p -R Alicia -x b -O testpub-foralicia-name
expect-file = testpub-foralicia-name
</test>
<test check-dcrypto-alicia-import-byname>
cmd = $pcp -V va -P -I testpub-foralicia-name
expect = /added/
</test>
<test check-dcrypto-bobby-encrypt-byname-both>
id = grep Key-ID testpub-forbobby-name | sed 's/^ //g' | cut -d' ' -f2
cmd = $pcp -V vb -e -i %{id} -I testmessage -O testencrypted-name -x b -R Alicia
expect = /success/
</test>
<test check-dcrypto-alicia-decrypt-byname-both>
cmd = $pcp -V va -d -I testencrypted-name -x a
expect = /success/
</test>
</test>
# #
# negative tests, check for error handling # negative tests, check for error handling
@@ -206,7 +256,7 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
</test> </test>
<test check-if-catch-missing-newlines> <test check-if-catch-missing-newlines>
prepare = jot 5000 | while read ignore; do echo -n X; done > testfile-toolong prepare = ./jot 5000 | while read ignore; do echo -n X; done > testfile-toolong
cmd = $pcp -V $vault -P -I testfile-toolong cmd = $pcp -V $vault -P -I testfile-toolong
expect = /line is too long/ expect = /line is too long/
</test> </test>
@@ -216,7 +266,7 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
* catch invalid z85, it only checks the input length and not the actual * catch invalid z85, it only checks the input length and not the actual
* encoding. Re-enable, once that bug is fixed. * encoding. Re-enable, once that bug is fixed.
<test check-if-catch-invalid-z85> <test check-if-catch-invalid-z85>
prepare = jot 30 | while read ignore; do \ prepare = ./jot 30 | while read ignore; do \
echo XXXXXXXXXXXXXXXXXX; done > testfile-noz85 echo XXXXXXXXXXXXXXXXXX; done > testfile-noz85
cmd = $pcp -V $vault -P -I testfile-noz85 cmd = $pcp -V $vault -P -I testfile-noz85
expect = /could not decode input/ expect = /could not decode input/
@@ -224,7 +274,7 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
*/ */
<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/
@@ -306,12 +356,7 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
cmd = $pcp -V testvault-invalidversion -l cmd = $pcp -V testvault-invalidversion -l
expect = /Unexpected vault file format/ expect = /Unexpected vault file format/
</test> </test>
/*
<test check-vault-invalid-itemsize>
cmd = $pcp -V testvault-invaliditemsize -l
expect = /invalid key item header size/
</test>
*/
<test check-vault-invalid-itemtype> <test check-vault-invalid-itemtype>
cmd = $pcp -V testvault-invaliditemtype -l cmd = $pcp -V testvault-invaliditemtype -l
expect = /invalid key type/ expect = /invalid key type/
@@ -321,3 +366,16 @@ md5msg = 66b8c4ca9e5d2a7e3c0559c3cdea3d50
cmd = $pcp -V testvault-invalidkeytype -l cmd = $pcp -V testvault-invalidkeytype -l
expect = /contain any keys so far./ expect = /contain any keys so far./
</test> </test>
<test check-encryptionkeys-dont-collide>
cmd = ./pwhashes
expect = /ok/
</test>
#
# input handling tests
<test check-large-meta>
cmd = (./jot 300 | while read m; do echo -n m; done; echo xxx) \
| $pcp -V $vault -k -x $passwd
expect = /Generated new secret key/
</test>

View File

@@ -10,7 +10,10 @@ use Data::Dumper;
sub run; sub run;
sub execute; sub execute;
my $config = shift @ARGV || die "usage: $0 <config>\n"; my ($config, $check) = @ARGV;
if (! $config) {
die "usage: $0 <config>\n";
}
my %cfg = ParseConfig(-ConfigFile => $config, my %cfg = ParseConfig(-ConfigFile => $config,
-InterPolateVars => 1, -InterPolateVars => 1,
@@ -22,11 +25,22 @@ if (exists $cfg{confirm}) {
my $cont = <STDIN>; my $cont = <STDIN>;
} }
foreach my $test (keys %{$cfg{test}}) { if ($check) {
my $name = "$test ($cfg{test}->{$test}->{cmd})"; if (exists $cfg{test}->{$check}) {
&runtest($cfg{test}->{$test}, $name); &runtest($cfg{test}->{$check}, $check);
}
}
else {
my $continue = 1;
foreach my $test (keys %{$cfg{test}}) {
if ($continue) {
$continue = &runtest($cfg{test}->{$test}, $test);
if (!$continue) {
print "Last failed check: $test\n";
}
}
}
} }
sub runtest { sub runtest {
@@ -46,10 +60,23 @@ sub runtest {
if (exists $cfg->{test}) { if (exists $cfg->{test}) {
foreach my $test (keys %{$cfg->{test}}) { foreach my $test (keys %{$cfg->{test}}) {
my $name = "$test ($cfg->{test}->{$test}->{cmd})"; my $name = "$test ($cfg->{test}->{$test}->{cmd})";
&runtest($cfg->{test}->{$test}, $name); if (&runtest($cfg->{test}->{$test}, $name) == 0) {
return 0;
} }
return;
} }
return 1;
}
$cfg->{cmd} =~ s/%\{([^\}]*)\}/
my $N = $1; my $o;
if (exists $cfg->{$N}) {
$o = `$cfg->{$N}`;
chomp $o;
}
$o;
/gex;
print STDERR "\n$cfg->{cmd}\n ";
my $ret = run($cfg->{cmd}, my $ret = run($cfg->{cmd},
$cfg->{input}, $cfg->{input},
@@ -63,10 +90,10 @@ sub runtest {
if (exists $cfg->{expect}) { if (exists $cfg->{expect}) {
if ($cfg->{expect} =~ /^\//) { if ($cfg->{expect} =~ /^\//) {
like($output, $cfg->{expect}, "$name") or last; like($output, $cfg->{expect}, "$name") or return 0;
} }
else { else {
is($output, $cfg->{expect}, "$name") or last; is($output, $cfg->{expect}, "$name") or return 0;
} }
} }
@@ -75,7 +102,7 @@ sub runtest {
if (-s $cfg->{"expect-file"}) { if (-s $cfg->{"expect-file"}) {
$e = 1; $e = 1;
} }
is($e, 1, "$name") or last; is($e, 1, "$name") or return 0;
} }
elsif (exists $cfg->{"expect-file-contains"}) { elsif (exists $cfg->{"expect-file-contains"}) {
@@ -84,28 +111,30 @@ sub runtest {
if (-s $file) { if (-s $file) {
$e = 1; $e = 1;
} }
is($e, 1, "$name") or last; is($e, 1, "$name") or return 0;
if (open F, "<$file") { if (open F, "<$file") {
my $content = join '', <F>; my $content = join '', <F>;
close F; close F;
like($content, qr/$expect/s, "$name") or last; like($content, qr/$expect/s, "$name") or return 0;
} }
else { else {
fail($test); fail($test);
last; return 0;
} }
} }
elsif (exists $cfg->{exit}) { elsif (exists $cfg->{exit}) {
is($ret, $cfg->{exit}, "$name") or last; is($ret, $cfg->{exit}, "$name") or return 0;
} }
else { else {
diag("invalid test spec for $test") or last; diag("invalid test spec for $test");
fail($test); fail($test);
return 0;
} }
}
return 1;
}
done_testing; done_testing;