mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +01:00
dropped "derived key feature", pk-encryption now uses a random keypair on the sender side, puts the public part of it into the encrypted output and drops the keypair, no more key-id will be sent over the wire, be it hashed or whatelse.
This commit is contained in:
129
src/encryption.c
129
src/encryption.c
@@ -85,73 +85,40 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd) {
|
|||||||
|
|
||||||
size_t clen;
|
size_t clen;
|
||||||
unsigned char *combined = pcp_z85_decode((char *)encoded, &clen);
|
unsigned char *combined = pcp_z85_decode((char *)encoded, &clen);
|
||||||
|
clen = clen - crypto_secretbox_KEYBYTES;
|
||||||
|
|
||||||
|
|
||||||
if(combined == NULL)
|
if(combined == NULL)
|
||||||
goto errde1;
|
goto errde1;
|
||||||
|
|
||||||
unsigned char *hash = ucmalloc(crypto_hash_BYTES);
|
// extract the sender's public key from the cipher
|
||||||
unsigned char *check = ucmalloc(crypto_hash_BYTES);
|
pub = ucmalloc(sizeof(pcp_pubkey_t));
|
||||||
memcpy(hash, combined, crypto_hash_BYTES);
|
memcpy(pub->pub, combined, crypto_secretbox_KEYBYTES);
|
||||||
|
|
||||||
pcphash_iteratepub(pub) {
|
|
||||||
crypto_hash(check, (unsigned char*)pub->id, 16);
|
|
||||||
if(memcmp(check, hash, crypto_hash_BYTES) == 0) {
|
|
||||||
// found one
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(pub == NULL) {
|
|
||||||
// maybe self encryption, try secrets
|
|
||||||
pcp_key_t *s = NULL;
|
|
||||||
pcphash_iterate(s) {
|
|
||||||
crypto_hash(check, (unsigned char*)s->id, 16);
|
|
||||||
if(memcmp(check, hash, crypto_hash_BYTES) == 0) {
|
|
||||||
// matching secret
|
|
||||||
pub = pcpkey_pub_from_secret(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(pub == NULL) {
|
|
||||||
fatal("Could not find a usable public key in vault %s!\n",
|
|
||||||
vault->filename);
|
|
||||||
goto errde0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
fprintf(stderr, "Using secret key:\n");
|
fprintf(stderr, "Using secret key:\n");
|
||||||
pcpkey_printshortinfo(secret);
|
pcpkey_printshortinfo(secret);
|
||||||
fprintf(stderr, "Using public key:\n");
|
fprintf(stderr, "Using public key:\n");
|
||||||
pcppubkey_printshortinfo(pub);
|
pcpprint_bin(stderr, pub->pub, 32);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *encrypted = ucmalloc(clen - crypto_hash_BYTES);
|
unsigned char *encrypted = ucmalloc(clen);
|
||||||
memcpy(encrypted, &combined[crypto_hash_BYTES], clen - crypto_hash_BYTES);
|
memcpy(encrypted, &combined[crypto_secretbox_KEYBYTES], clen);
|
||||||
|
|
||||||
size_t dlen;
|
size_t dlen;
|
||||||
unsigned char *decrypted = pcp_box_decrypt(secret, pub,
|
unsigned char *decrypted = pcp_box_decrypt(secret, pub,
|
||||||
encrypted,
|
encrypted,
|
||||||
clen - crypto_hash_BYTES, &dlen);
|
clen, &dlen);
|
||||||
|
|
||||||
if(decrypted == NULL) {
|
if(decrypted == NULL) {
|
||||||
// try it with a derived secret from the sender id
|
// maybe self encryption?
|
||||||
pcp_key_t *s = pcp_derive_pcpkey(secret, pub->id);
|
pcp_pubkey_t *mypub = pcpkey_pub_from_secret(secret);
|
||||||
decrypted = pcp_box_decrypt(s, pub,
|
decrypted = pcp_box_decrypt(secret, mypub,
|
||||||
encrypted,
|
encrypted,
|
||||||
clen - crypto_hash_BYTES, &dlen);
|
clen, &dlen);
|
||||||
if(decrypted == NULL) {
|
free(mypub);
|
||||||
// now try the senders key mail address
|
|
||||||
s = pcp_derive_pcpkey(secret, pub->mail);
|
|
||||||
decrypted = pcp_box_decrypt(s, pub,
|
|
||||||
encrypted,
|
|
||||||
clen - crypto_hash_BYTES, &dlen);
|
|
||||||
if(decrypted == NULL) {
|
|
||||||
// try the name
|
|
||||||
s = pcp_derive_pcpkey(secret, pub->owner);
|
|
||||||
decrypted = pcp_box_decrypt(s, pub,
|
|
||||||
encrypted,
|
|
||||||
clen - crypto_hash_BYTES, &dlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decrypted != NULL) {
|
if(decrypted != NULL) {
|
||||||
@@ -163,13 +130,13 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd) {
|
|||||||
}
|
}
|
||||||
free(decrypted);
|
free(decrypted);
|
||||||
|
|
||||||
fprintf(stderr, "Decrypted %d bytes from 0x%s successfully\n",
|
fprintf(stderr, "Decrypted %d bytes successfully\n",
|
||||||
(int)dlen, pub->id);
|
(int)dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(encrypted);
|
|
||||||
|
|
||||||
errde0:
|
free(encrypted);
|
||||||
|
free(pub);
|
||||||
free(combined);
|
free(combined);
|
||||||
|
|
||||||
errde1:
|
errde1:
|
||||||
@@ -188,15 +155,18 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipi
|
|||||||
FILE *out = NULL;
|
FILE *out = NULL;
|
||||||
pcp_pubkey_t *pub = NULL;
|
pcp_pubkey_t *pub = NULL;
|
||||||
pcp_key_t *secret = NULL;
|
pcp_key_t *secret = NULL;
|
||||||
|
int selfcipher = 0;
|
||||||
|
|
||||||
// look if we've got that key
|
// look if we've got that key
|
||||||
HASH_FIND_STR(pcppubkey_hash, id, pub);
|
HASH_FIND_STR(pcppubkey_hash, id, pub);
|
||||||
if(pub == NULL) {
|
if(pub == NULL) {
|
||||||
|
// FIXME: use recipient to lookup by name or email
|
||||||
// self-encryption: look if its a secret one
|
// self-encryption: look if its a secret one
|
||||||
pcp_key_t *s = NULL;
|
pcp_key_t *s = NULL;
|
||||||
HASH_FIND_STR(pcpkey_hash, id, s);
|
HASH_FIND_STR(pcpkey_hash, id, s);
|
||||||
if(s != NULL) {
|
if(s != NULL) {
|
||||||
pub = pcpkey_pub_from_secret(s);
|
pub = pcpkey_pub_from_secret(s);
|
||||||
|
selfcipher = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Could not find a public key with id 0x%s in vault %s!\n",
|
fatal("Could not find a public key with id 0x%s in vault %s!\n",
|
||||||
@@ -205,11 +175,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
secret = pcp_find_primary_secret();
|
secret = pcpkey_new(); // DEPRECATED: pcp_find_primary_secret();
|
||||||
if(secret == NULL) {
|
|
||||||
fatal("Could not find a secret key in vault %s!\n", id, vault->filename);
|
|
||||||
goto erren2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(infile == NULL)
|
if(infile == NULL)
|
||||||
in = stdin;
|
in = stdin;
|
||||||
@@ -229,28 +195,6 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
||||||
pcp_dumpkey(secret);
|
pcp_dumpkey(secret);
|
||||||
@@ -284,15 +228,28 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipi
|
|||||||
goto erren1;
|
goto erren1;
|
||||||
|
|
||||||
size_t zlen;
|
size_t zlen;
|
||||||
size_t clen = ciphersize + crypto_hash_BYTES;
|
size_t clen = ciphersize + crypto_secretbox_KEYBYTES;
|
||||||
unsigned char *combined = ucmalloc(clen);
|
unsigned char *combined = ucmalloc(clen);
|
||||||
unsigned char *hash = ucmalloc(crypto_hash_BYTES);
|
|
||||||
crypto_hash(hash, (unsigned char*)secret->id, 16);
|
if(selfcipher == 1) {
|
||||||
memcpy(combined, hash, crypto_hash_BYTES);
|
unsigned char *fakepub = urmalloc(crypto_secretbox_KEYBYTES);
|
||||||
memcpy(&combined[crypto_hash_BYTES], cipher, clen - crypto_hash_BYTES);
|
memcpy(combined, fakepub, crypto_secretbox_KEYBYTES);
|
||||||
|
free(fakepub);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(combined, secret->pub, crypto_secretbox_KEYBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(debug) {
|
||||||
|
fprintf(stderr, "Using public key:\n");
|
||||||
|
pcpprint_bin(stderr, combined, 32);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&combined[crypto_secretbox_KEYBYTES], cipher, ciphersize);
|
||||||
|
|
||||||
// combined consists of:
|
// combined consists of:
|
||||||
// keyid|nonce|cipher
|
// our-public-key|nonce|cipher
|
||||||
char *encoded = pcp_z85_encode(combined, clen, &zlen);
|
char *encoded = pcp_z85_encode(combined, clen, &zlen);
|
||||||
|
|
||||||
if(encoded == NULL)
|
if(encoded == NULL)
|
||||||
@@ -317,8 +274,6 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, char *recipi
|
|||||||
|
|
||||||
erren1:
|
erren1:
|
||||||
|
|
||||||
erren2:
|
|
||||||
|
|
||||||
erren3:
|
erren3:
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -252,41 +252,12 @@ void pcp_exportsecretkey(pcp_key_t *key, 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,
|
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
|
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
|
keyid we use the primary key. if no keyid has been given but
|
||||||
and a recipient have been given, we use a derived secret key
|
a recipient instead, we try to look up the vault for a match.
|
||||||
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) {
|
void pcp_exportpublic(char *keyid, char *recipient, char *passwd, char *outfile) {
|
||||||
pcp_pubkey_t *key = NULL;
|
pcp_pubkey_t *key = NULL;
|
||||||
@@ -303,8 +274,6 @@ void pcp_exportpublic(char *keyid, char *recipient, char *passwd, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,10 +287,7 @@ void pcp_exportpublic(char *keyid, char *recipient, char *passwd, char *outfile)
|
|||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcp_key_t *t = NULL;
|
key = pcpkey_pub_from_secret(s);
|
||||||
t = pcp_getrsk(s, recipient, passwd);
|
|
||||||
if(t != NULL)
|
|
||||||
key = pcpkey_pub_from_secret(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ int main (int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PCP_MODE_SIGN:
|
case PCP_MODE_SIGN:
|
||||||
pcpsign(infile, outfile, recipient, xpass);
|
pcpsign(infile, outfile, xpass);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCP_MODE_VERIFY:
|
case PCP_MODE_VERIFY:
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "signature.h"
|
#include "signature.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
int pcpsign(char *infile, char *outfile, char *recipient, char *passwd) {
|
int pcpsign(char *infile, char *outfile, char *passwd) {
|
||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
FILE *out = NULL;
|
FILE *out = NULL;
|
||||||
pcp_key_t *secret = NULL;
|
pcp_key_t *secret = NULL;
|
||||||
@@ -71,10 +71,6 @@ int pcpsign(char *infile, char *outfile, char *recipient, char *passwd) {
|
|||||||
goto errs3;
|
goto errs3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(recipient != NULL) {
|
|
||||||
secret = pcp_derive_pcpkey(secret, recipient);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *input = NULL;
|
unsigned char *input = NULL;
|
||||||
size_t inputBufSize = 0;
|
size_t inputBufSize = 0;
|
||||||
unsigned char byte[1];
|
unsigned char byte[1];
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "z85.h"
|
#include "z85.h"
|
||||||
|
|
||||||
int pcpsign(char *infile, char *outfile, char *recipient, char *passwd);
|
int pcpsign(char *infile, char *outfile, char *passwd);
|
||||||
int pcpverify(char *infile, char *sigfile);
|
int pcpverify(char *infile, char *sigfile);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user