diff --git a/include/pcp/defines.h b/include/pcp/defines.h index d8cb0b4..5287a4f 100644 --- a/include/pcp/defines.h +++ b/include/pcp/defines.h @@ -49,7 +49,7 @@ typedef unsigned int qbyte; /* Quad byte = 32 bits */ #define PCP_ME "Pretty Curved Privacy" -#define PCP_KEY_VERSION 5 +#define PCP_KEY_VERSION 6 #define PCP_KEY_PRIMITIVE "CURVE25519-ED25519-SALSA20-POLY1305" #define PCP_KEY_TYPE_MAINSECRET 1 @@ -57,7 +57,7 @@ typedef unsigned int qbyte; /* Quad byte = 32 bits */ #define PCP_KEY_TYPE_PUBLIC 3 /* save typing, dammit */ -#define PCP_ENCRYPT_PAD crypto_secretbox_ZEROBYTES + crypto_secretbox_NONCEBYTES +#define PCP_ENCRYPT_MAC crypto_secretbox_ZEROBYTES + crypto_secretbox_NONCEBYTES /* vault id */ #define PCP_VAULT_ID 14 diff --git a/include/pcp/ed.h b/include/pcp/ed.h index 41d2a40..6f3f8c7 100644 --- a/include/pcp/ed.h +++ b/include/pcp/ed.h @@ -43,6 +43,9 @@ returns NULL otherwise */ unsigned char *pcp_ed_sign(unsigned char *message, size_t messagesize, pcp_key_t *s); +/* the same, but use the mastersecret instead, usually for keysigning */ +unsigned char *pcp_ed_sign_key(unsigned char *message, size_t messagesize, pcp_key_t *s); + /* verify a signature of siglen size using p->edpub, if the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES), returns NULL otherwise */ diff --git a/include/pcp/key.h b/include/pcp/key.h index 5d6faa9..402fd9f 100644 --- a/include/pcp/key.h +++ b/include/pcp/key.h @@ -75,12 +75,14 @@ */ struct _pcp_key_t { + byte masterpub[32]; + byte mastersecret[64]; byte pub[32]; byte secret[32]; byte edpub[32]; byte edsecret[64]; byte nonce[24]; - byte encrypted[112]; /* both ed+curve encrypted */ + byte encrypted[176]; /* both sign+ed+curve encrypted */ char owner[255]; char mail[255]; char id[17]; @@ -92,6 +94,7 @@ struct _pcp_key_t { }; struct _pcp_pubkey_t { + byte sigpub[32]; byte pub[32]; byte edpub[32]; char owner[255]; @@ -101,6 +104,8 @@ struct _pcp_pubkey_t { uint64_t ctime; uint32_t version; uint32_t serial; + uint8_t valid; + byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; UT_hash_handle hh; }; @@ -146,8 +151,7 @@ typedef struct _pcp_rec_t pcp_rec_t; void pcp_cleanhashes(); pcp_key_t *pcpkey_new (); -void pcp_keypairs(byte *csk, byte *cpk, byte *esk, byte *epk); -void pcp_ed_keypairs(byte *csk, byte *esk); +void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *epk); char *pcppubkey_get_art(pcp_pubkey_t *k); char *pcpkey_get_art(pcp_key_t *k); diff --git a/libpcp/ed.c b/libpcp/ed.c index 2e4ba21..68dc33d 100644 --- a/libpcp/ed.c +++ b/libpcp/ed.c @@ -37,6 +37,15 @@ unsigned char * pcp_ed_verify(unsigned char *signature, size_t siglen, pcp_pubke return NULL; } +unsigned char *pcp_ed_sign_key(unsigned char *message, size_t messagesize, pcp_key_t *s) { + unsigned long long mlen = messagesize + crypto_sign_BYTES; + unsigned char *signature = ucmalloc(mlen); + + crypto_sign(signature, &mlen, message, messagesize, s->mastersecret); + + return signature; +} + unsigned char *pcp_ed_sign(unsigned char *message, size_t messagesize, pcp_key_t *s) { unsigned long long mlen = messagesize + crypto_sign_BYTES; unsigned char *signature = ucmalloc(mlen); diff --git a/libpcp/key.c b/libpcp/key.c index d63ed7f..cabf847 100644 --- a/libpcp/key.c +++ b/libpcp/key.c @@ -68,39 +68,51 @@ char *pcp_getpubkeyid(pcp_pubkey_t *k) { return id; } -void pcp_keypairs(byte *csk, byte *cpk, byte *esk, byte *epk) { - /* generate ed25519 + curve25519 keypair from random seed */ - byte *seed = urmalloc(32); - byte *tmp = urmalloc(32); +void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *epk) { + /* generate keypairs from random seed */ + byte *ms = urmalloc(32); + byte *ss = urmalloc(32); + byte *cs = urmalloc(32); + + /* ed25519 master key */ + crypto_sign_seed_keypair(mpk, msk, ms); /* ed25519 signing key */ - crypto_sign_seed_keypair(epk, esk, seed); + crypto_sign_seed_keypair(epk, esk, ss); /* curve25519 secret key */ - tmp[0] &= 248; - tmp[31] &= 63; - tmp[31] |= 64; - memcpy(csk, tmp, 32); + memcpy(csk, cs, 32); + csk[0] &= 248; + csk[31] &= 63; + csk[31] |= 64; /* curve25519 public key */ - crypto_scalarmult_curve25519_base(cpk, csk); - memset(tmp, 0, 32); + crypto_scalarmult_curve25519_base(cpk, csk); + + ucfree(ms, 32); + ucfree(ss, 32); + ucfree(cs, 32); } pcp_key_t * pcpkey_new () { - byte pub[32] = { 0 }; - byte secret[32] = { 0 }; - byte edpub[32] = { 0 }; - byte edsec[64] = { 0 }; + byte *mp = ucmalloc(32); + byte *ms = ucmalloc(64); + byte *sp = ucmalloc(32); + byte *ss = ucmalloc(64); + byte *cp = ucmalloc(32); + byte *cs = ucmalloc(32); - pcp_keypairs(secret, pub, edsec, edpub); + /* generate key material */ + pcp_keypairs(ms, mp, cs, cp, ss, sp); /* fill in our struct */ pcp_key_t *key = urmalloc(sizeof(pcp_key_t)); - memcpy (key->pub, pub, 32); - memcpy (key->secret, secret, 32); - memcpy (key->edpub, edpub, 32); - memcpy (key->edsecret, edsec, 64); + memcpy (key->masterpub, mp, 32); + memcpy (key->mastersecret, ms, 64); + memcpy (key->pub, cp, 32); + memcpy (key->secret, cs, 32); + memcpy (key->edpub, ss, 32); + memcpy (key->edsecret, sp, 64); memcpy (key->id, pcp_getkeyid(key), 17); key->ctime = (long)time(0); @@ -108,6 +120,15 @@ pcp_key_t * pcpkey_new () { key->version = PCP_KEY_VERSION; key->serial = arc4random(); key->type = PCP_KEY_TYPE_SECRET; + + /* clean up */ + ucfree(ms, 64); + ucfree(ss, 64); + ucfree(mp, 32); + ucfree(sp, 32); + ucfree(cs, 32); + ucfree(cp, 32); + return key; } @@ -128,24 +149,26 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) { unsigned char *encrypted; size_t es; - unsigned char *both = ucmalloc(96); - memcpy(both, key->edsecret, 64); - memcpy(&both[64], key->secret, 32); + Buffer *both = buffer_new(128, "keypack"); + buffer_add(both, key->mastersecret, 64); + buffer_add(both, key->edsecret, 64); + buffer_add(both, key->secret, 32); - es = pcp_sodium_mac(&encrypted, both, 96, key->nonce, encryptkey); + es = pcp_sodium_mac(&encrypted, buffer_get(both), buffer_size(both), key->nonce, encryptkey); memset(encryptkey, 0, 32); - memset(both, 0, 96); + buffer_free(both); free(encryptkey); - free(both); - if(es == 112) { + if(es == 176) { /* success */ - memcpy(key->encrypted, encrypted, 112); + memcpy(key->encrypted, encrypted, 176); arc4random_buf(key->secret, 32); arc4random_buf(key->edsecret, 64); + arc4random_buf(key->mastersecret, 64); key->secret[0] = 0; key->edsecret[0] = 0; + key->mastersecret[0] = 0; } else { fatal("failed to encrypt the secret key!\n"); @@ -162,15 +185,16 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) { unsigned char *decrypted; size_t es; - es = pcp_sodium_verify_mac(&decrypted, key->encrypted, 112, key->nonce, encryptkey); + es = pcp_sodium_verify_mac(&decrypted, key->encrypted, 176, key->nonce, encryptkey); memset(encryptkey, 0, 32); free(encryptkey); if(es == 0) { /* success */ - memcpy(key->edsecret, decrypted, 64); - memcpy(key->secret, &decrypted[64], 32); + memcpy(key->mastersecret, decrypted, 64); + memcpy(key->edsecret, decrypted + 64, 64); + memcpy(key->secret, decrypted +128, 32); } else { fatal("failed to decrypt the secret key (got %d, expected 32)!\n", es);