2013-11-04 17:43:22 +01:00
|
|
|
/*
|
|
|
|
|
This file is part of Pretty Curved Privacy (pcp1).
|
|
|
|
|
|
2014-02-08 20:35:34 +01:00
|
|
|
Copyright (C) 2013-2014 T.v.Dein.
|
2013-11-04 17:43:22 +01:00
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
2014-02-08 20:35:34 +01:00
|
|
|
You can contact me by mail: <tom AT vondein DOT org>.
|
2013-11-04 17:43:22 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2013-10-28 22:50:05 +01:00
|
|
|
#include "key.h"
|
2014-05-04 17:11:03 +02:00
|
|
|
#include "context.h"
|
2013-11-02 11:02:36 +01:00
|
|
|
|
2014-01-16 15:25:09 +01:00
|
|
|
/*
|
|
|
|
|
* AS of 16/01/2014 I'm using scrypt() instead of my crafted key
|
2014-02-03 12:19:17 +01:00
|
|
|
* derivation function. However, I create a hash from the pcp_scrypt()
|
2014-01-16 15:25:09 +01:00
|
|
|
* result anyway because I need a cure25519 secret.
|
|
|
|
|
*/
|
2014-05-04 17:11:03 +02:00
|
|
|
byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
|
2014-02-25 11:09:58 +01:00
|
|
|
byte *key = ucmalloc(crypto_secretbox_KEYBYTES);
|
2014-01-16 15:25:09 +01:00
|
|
|
size_t plen = strnlen(passphrase, 255);
|
|
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* create the scrypt hash */
|
2014-05-04 17:11:03 +02:00
|
|
|
byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
|
2014-01-16 15:25:09 +01:00
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* make a hash from the scrypt() result */
|
2014-02-25 11:09:58 +01:00
|
|
|
crypto_hash_sha256(key, (byte*)scrypted, 64);
|
2014-01-16 15:25:09 +01:00
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* turn the 32byte hash into a secret key */
|
2014-01-16 15:25:09 +01:00
|
|
|
key[0] &= 248;
|
|
|
|
|
key[31] &= 127;
|
|
|
|
|
key[31] |= 64;
|
|
|
|
|
|
2014-02-13 15:32:27 +01:00
|
|
|
/* disabled, must be done outside
|
|
|
|
|
memset(passphrase, 0, plen); */
|
2014-01-16 15:25:09 +01:00
|
|
|
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-02 11:02:36 +01:00
|
|
|
|
2013-10-28 22:50:05 +01:00
|
|
|
char *pcp_getkeyid(pcp_key_t *k) {
|
|
|
|
|
uint32_t s, p;
|
2013-11-29 20:01:42 +01:00
|
|
|
p = jen_hash(k->pub, 32, JEN_PSALT);
|
2014-02-13 15:32:27 +01:00
|
|
|
s = jen_hash(k->edpub, 32, JEN_SSALT);
|
2013-10-28 22:50:05 +01:00
|
|
|
char *id = ucmalloc(17);
|
|
|
|
|
snprintf(id, 17, "%08X%08X", p, s);
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* same as above but for imported pbp keys */
|
2014-01-28 16:53:26 +01:00
|
|
|
char *pcp_getpubkeyid(pcp_pubkey_t *k) {
|
|
|
|
|
uint32_t s, p;
|
|
|
|
|
p = jen_hash(k->pub, 32, JEN_PSALT);
|
|
|
|
|
s = jen_hash(k->edpub, 32, JEN_SSALT);
|
|
|
|
|
char *id = ucmalloc(17);
|
|
|
|
|
snprintf(id, 17, "%08X%08X", p, s);
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
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);
|
2013-11-10 14:25:36 +01:00
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* ed25519 signing key */
|
2014-02-10 11:34:05 +01:00
|
|
|
crypto_sign_seed_keypair(epk, esk, ss);
|
2013-11-10 14:25:36 +01:00
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* curve25519 secret key */
|
2014-02-10 11:34:05 +01:00
|
|
|
memcpy(csk, cs, 32);
|
|
|
|
|
csk[0] &= 248;
|
|
|
|
|
csk[31] &= 63;
|
|
|
|
|
csk[31] |= 64;
|
2014-01-19 23:54:53 +01:00
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* curve25519 public key */
|
2014-02-10 11:34:05 +01:00
|
|
|
crypto_scalarmult_curve25519_base(cpk, csk);
|
|
|
|
|
|
|
|
|
|
ucfree(ms, 32);
|
|
|
|
|
ucfree(ss, 32);
|
|
|
|
|
ucfree(cs, 32);
|
2013-11-10 14:25:36 +01:00
|
|
|
}
|
|
|
|
|
|
2013-10-28 22:50:05 +01:00
|
|
|
pcp_key_t * pcpkey_new () {
|
2014-02-10 11:34:05 +01:00
|
|
|
byte *mp = ucmalloc(32);
|
|
|
|
|
byte *ms = ucmalloc(64);
|
|
|
|
|
byte *sp = ucmalloc(32);
|
|
|
|
|
byte *ss = ucmalloc(64);
|
|
|
|
|
byte *cp = ucmalloc(32);
|
|
|
|
|
byte *cs = ucmalloc(32);
|
2013-10-28 22:50:05 +01:00
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
/* generate key material */
|
|
|
|
|
pcp_keypairs(ms, mp, cs, cp, ss, sp);
|
2013-11-08 12:50:04 +01:00
|
|
|
|
2014-02-05 20:41:16 +01:00
|
|
|
/* fill in our struct */
|
2013-10-28 22:50:05 +01:00
|
|
|
pcp_key_t *key = urmalloc(sizeof(pcp_key_t));
|
2014-02-10 11:34:05 +01:00
|
|
|
memcpy (key->masterpub, mp, 32);
|
|
|
|
|
memcpy (key->mastersecret, ms, 64);
|
|
|
|
|
memcpy (key->pub, cp, 32);
|
|
|
|
|
memcpy (key->secret, cs, 32);
|
2014-02-13 15:32:27 +01:00
|
|
|
memcpy (key->edpub, sp, 32);
|
|
|
|
|
memcpy (key->edsecret, ss, 64);
|
2013-11-10 14:25:36 +01:00
|
|
|
memcpy (key->id, pcp_getkeyid(key), 17);
|
2013-10-28 22:50:05 +01:00
|
|
|
|
|
|
|
|
key->ctime = (long)time(0);
|
|
|
|
|
|
|
|
|
|
key->version = PCP_KEY_VERSION;
|
|
|
|
|
key->serial = arc4random();
|
|
|
|
|
key->type = PCP_KEY_TYPE_SECRET;
|
2014-02-10 11:34:05 +01:00
|
|
|
|
2014-02-19 20:38:21 +01:00
|
|
|
key->owner[0] = '\0';
|
|
|
|
|
key->mail[0] = '\0';
|
|
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
/* clean up */
|
|
|
|
|
ucfree(ms, 64);
|
|
|
|
|
ucfree(ss, 64);
|
|
|
|
|
ucfree(mp, 32);
|
|
|
|
|
ucfree(sp, 32);
|
|
|
|
|
ucfree(cs, 32);
|
|
|
|
|
ucfree(cp, 32);
|
|
|
|
|
|
2013-10-28 22:50:05 +01:00
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-25 11:09:58 +01:00
|
|
|
byte * pcp_gennonce() {
|
|
|
|
|
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
2013-10-28 22:50:05 +01:00
|
|
|
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
|
|
|
|
|
return nonce;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
|
2013-10-28 22:50:05 +01:00
|
|
|
if(key->nonce[0] == 0) {
|
2014-02-25 11:09:58 +01:00
|
|
|
byte *nonce = pcp_gennonce();
|
2013-10-28 22:50:05 +01:00
|
|
|
memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
|
2013-10-28 22:50:05 +01:00
|
|
|
|
2014-02-25 11:09:58 +01:00
|
|
|
byte *encrypted;
|
2013-10-28 22:50:05 +01:00
|
|
|
size_t es;
|
|
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
Buffer *both = buffer_new(128, "keypack");
|
|
|
|
|
buffer_add(both, key->mastersecret, 64);
|
|
|
|
|
buffer_add(both, key->edsecret, 64);
|
|
|
|
|
buffer_add(both, key->secret, 32);
|
2014-01-19 23:54:53 +01:00
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
es = pcp_sodium_mac(&encrypted, buffer_get(both), buffer_size(both), key->nonce, encryptkey);
|
2013-10-28 22:50:05 +01:00
|
|
|
|
2013-10-29 23:08:43 +01:00
|
|
|
memset(encryptkey, 0, 32);
|
2014-02-10 11:34:05 +01:00
|
|
|
buffer_free(both);
|
2013-10-28 22:50:05 +01:00
|
|
|
free(encryptkey);
|
|
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
if(es == 176) {
|
2014-02-05 20:41:16 +01:00
|
|
|
/* success */
|
2014-02-10 11:34:05 +01:00
|
|
|
memcpy(key->encrypted, encrypted, 176);
|
2013-10-28 22:50:05 +01:00
|
|
|
arc4random_buf(key->secret, 32);
|
2013-11-10 14:25:36 +01:00
|
|
|
arc4random_buf(key->edsecret, 64);
|
2014-02-10 11:34:05 +01:00
|
|
|
arc4random_buf(key->mastersecret, 64);
|
2013-10-28 22:50:05 +01:00
|
|
|
key->secret[0] = 0;
|
2013-11-10 14:25:36 +01:00
|
|
|
key->edsecret[0] = 0;
|
2014-02-10 11:34:05 +01:00
|
|
|
key->mastersecret[0] = 0;
|
2013-10-28 22:50:05 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "failed to encrypt the secret key!\n");
|
2013-10-28 22:50:05 +01:00
|
|
|
free(key);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
|
|
|
|
|
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
|
2013-11-16 16:00:53 +01:00
|
|
|
|
2014-02-25 11:09:58 +01:00
|
|
|
byte *decrypted;
|
2013-10-28 22:50:05 +01:00
|
|
|
size_t es;
|
|
|
|
|
|
2014-02-10 11:34:05 +01:00
|
|
|
es = pcp_sodium_verify_mac(&decrypted, key->encrypted, 176, key->nonce, encryptkey);
|
2013-10-28 22:50:05 +01:00
|
|
|
|
2013-10-29 23:08:43 +01:00
|
|
|
memset(encryptkey, 0, 32);
|
2013-10-28 22:50:05 +01:00
|
|
|
free(encryptkey);
|
|
|
|
|
|
|
|
|
|
if(es == 0) {
|
2014-02-05 20:41:16 +01:00
|
|
|
/* success */
|
2014-02-10 11:34:05 +01:00
|
|
|
memcpy(key->mastersecret, decrypted, 64);
|
|
|
|
|
memcpy(key->edsecret, decrypted + 64, 64);
|
|
|
|
|
memcpy(key->secret, decrypted +128, 32);
|
2013-10-28 22:50:05 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "failed to decrypt the secret key (got %d, expected 32)!\n", es);
|
2013-10-28 22:50:05 +01:00
|
|
|
free(key);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key) {
|
2014-02-05 20:41:16 +01:00
|
|
|
/* pcp_dumpkey(key); */
|
2013-10-28 22:50:05 +01:00
|
|
|
pcp_pubkey_t *pub = urmalloc(sizeof (pcp_pubkey_t));
|
2014-02-12 00:37:41 +01:00
|
|
|
memcpy(pub->masterpub, key->masterpub, 32);
|
2013-11-29 20:01:42 +01:00
|
|
|
memcpy(pub->pub, key->pub, 32);
|
2013-11-08 12:50:04 +01:00
|
|
|
memcpy(pub->edpub, key->edpub, 32);
|
2013-10-28 22:50:05 +01:00
|
|
|
memcpy(pub->owner, key->owner, 255);
|
|
|
|
|
memcpy(pub->mail, key->mail, 255);
|
|
|
|
|
memcpy(pub->id, key->id, 17);
|
|
|
|
|
pub->version = key->version;
|
|
|
|
|
pub->type = PCP_KEY_TYPE_PUBLIC;
|
2013-11-19 10:06:24 +01:00
|
|
|
pub->ctime = key->ctime;
|
|
|
|
|
pub->serial = key->serial;
|
2013-10-28 22:50:05 +01:00
|
|
|
return pub;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *pcppubkey_get_art(pcp_pubkey_t *k) {
|
2013-11-29 20:01:42 +01:00
|
|
|
char *r = key_fingerprint_randomart(k->pub, sizeof(k));
|
2013-10-28 22:50:05 +01:00
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *pcpkey_get_art(pcp_key_t *k) {
|
2013-11-29 20:01:42 +01:00
|
|
|
char *r = key_fingerprint_randomart(k->pub, sizeof(k));
|
2013-10-28 22:50:05 +01:00
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-25 11:09:58 +01:00
|
|
|
byte *pcppubkey_getchecksum(pcp_pubkey_t *k) {
|
|
|
|
|
byte *hash = ucmalloc(32);
|
2013-11-29 20:01:42 +01:00
|
|
|
crypto_hash_sha256(hash, k->pub, 32);
|
2013-10-28 22:50:05 +01:00
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-25 11:09:58 +01:00
|
|
|
byte *pcpkey_getchecksum(pcp_key_t *k) {
|
|
|
|
|
byte *hash = ucmalloc(32);
|
2013-11-29 20:01:42 +01:00
|
|
|
crypto_hash_sha256(hash, k->pub, 32);
|
2013-10-28 22:50:05 +01:00
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pcp_key_t * key2be(pcp_key_t *k) {
|
2013-11-19 21:02:59 +01:00
|
|
|
#ifdef __CPU_IS_BIG_ENDIAN
|
2013-11-18 21:48:24 +01:00
|
|
|
return k;
|
|
|
|
|
#else
|
2013-11-18 17:38:03 +01:00
|
|
|
uint32_t version = k->version;
|
2014-02-25 11:09:58 +01:00
|
|
|
byte* p = (byte*)&version;
|
2013-11-18 17:38:03 +01:00
|
|
|
if(p[0] != 0) {
|
|
|
|
|
k->version = htobe32(k->version);
|
|
|
|
|
k->serial = htobe32(k->serial);
|
|
|
|
|
k->ctime = htobe64(k->ctime);
|
|
|
|
|
}
|
2013-10-28 22:50:05 +01:00
|
|
|
return k;
|
2013-11-18 21:48:24 +01:00
|
|
|
#endif
|
2013-10-28 22:50:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pcp_key_t *key2native(pcp_key_t *k) {
|
2013-11-19 21:02:59 +01:00
|
|
|
#ifdef __CPU_IS_BIG_ENDIAN
|
2013-11-18 21:48:24 +01:00
|
|
|
return k;
|
|
|
|
|
#else
|
2013-10-28 22:50:05 +01:00
|
|
|
k->version = be32toh(k->version);
|
|
|
|
|
k->serial = be32toh(k->serial);
|
|
|
|
|
k->ctime = be64toh(k->ctime);
|
|
|
|
|
return k;
|
2013-11-18 21:48:24 +01:00
|
|
|
#endif
|
2013-10-28 22:50:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pcp_pubkey_t * pubkey2be(pcp_pubkey_t *k) {
|
2013-11-19 21:02:59 +01:00
|
|
|
#ifdef __CPU_IS_BIG_ENDIAN
|
2013-11-18 21:48:24 +01:00
|
|
|
return k;
|
|
|
|
|
#else
|
2013-11-18 17:38:03 +01:00
|
|
|
uint32_t version = k->version;
|
2014-02-25 11:09:58 +01:00
|
|
|
byte* p = (byte*)&version;
|
2013-11-18 17:38:03 +01:00
|
|
|
if(p[0] != 0) {
|
|
|
|
|
k->version = htobe32(k->version);
|
|
|
|
|
k->serial = htobe32(k->serial);
|
|
|
|
|
k->ctime = htobe64(k->ctime);
|
|
|
|
|
}
|
2013-10-28 22:50:05 +01:00
|
|
|
return k;
|
2013-11-18 21:48:24 +01:00
|
|
|
#endif
|
2013-10-28 22:50:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
|
2013-11-19 21:02:59 +01:00
|
|
|
#ifdef __CPU_IS_BIG_ENDIAN
|
2013-11-18 21:48:24 +01:00
|
|
|
return k;
|
|
|
|
|
#else
|
2013-10-28 22:50:05 +01:00
|
|
|
k->version = be32toh(k->version);
|
|
|
|
|
k->serial = be32toh(k->serial);
|
|
|
|
|
k->ctime = be64toh(k->ctime);
|
|
|
|
|
return k;
|
2013-11-18 21:48:24 +01:00
|
|
|
#endif
|
2013-10-28 22:50:05 +01:00
|
|
|
}
|
|
|
|
|
|
2014-03-17 18:04:26 +01:00
|
|
|
void pcp_seckeyblob(Buffer *b, pcp_key_t *k) {
|
2014-03-15 17:26:42 +01:00
|
|
|
buffer_add(b, k->masterpub, 32);
|
|
|
|
|
buffer_add(b, k->mastersecret, 64);
|
|
|
|
|
|
|
|
|
|
buffer_add(b, k->pub, 32);
|
|
|
|
|
buffer_add(b, k->secret, 32);
|
|
|
|
|
|
|
|
|
|
buffer_add(b, k->edpub, 32);
|
|
|
|
|
buffer_add(b, k->edsecret, 64);
|
|
|
|
|
|
|
|
|
|
buffer_add(b, k->nonce, 24);
|
|
|
|
|
|
|
|
|
|
buffer_add(b, k->encrypted, 176);
|
|
|
|
|
|
|
|
|
|
buffer_add(b, k->owner, 255);
|
|
|
|
|
buffer_add(b, k->mail, 255);
|
|
|
|
|
buffer_add(b, k->id, 17);
|
|
|
|
|
|
|
|
|
|
buffer_add8(b, k->type);
|
|
|
|
|
buffer_add64(b, k->ctime);
|
|
|
|
|
buffer_add32(b, k->version);
|
|
|
|
|
buffer_add32(b, k->serial);
|
2013-11-18 17:38:03 +01:00
|
|
|
}
|
|
|
|
|
|
2014-03-17 18:04:26 +01:00
|
|
|
void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) {
|
2014-03-15 17:26:42 +01:00
|
|
|
buffer_add(b, k->masterpub, 32);
|
|
|
|
|
buffer_add(b, k->sigpub, 32);
|
|
|
|
|
buffer_add(b, k->pub, 32);
|
|
|
|
|
buffer_add(b, k->edpub, 32);
|
|
|
|
|
|
|
|
|
|
buffer_add(b, k->owner, 255);
|
|
|
|
|
buffer_add(b, k->mail, 255);
|
|
|
|
|
buffer_add(b, k->id, 17);
|
|
|
|
|
|
|
|
|
|
buffer_add8(b, k->type);
|
|
|
|
|
buffer_add64(b, k->ctime);
|
|
|
|
|
buffer_add32(b, k->version);
|
|
|
|
|
buffer_add32(b, k->serial);
|
|
|
|
|
buffer_add8(b, k->valid);
|
2013-11-18 17:38:03 +01:00
|
|
|
}
|
|
|
|
|
|
2014-03-17 18:04:26 +01:00
|
|
|
Buffer *pcp_keyblob(void *k, int type) {
|
2013-11-18 17:38:03 +01:00
|
|
|
if(type == PCP_KEY_TYPE_PUBLIC) {
|
2014-03-17 18:04:26 +01:00
|
|
|
Buffer *b = buffer_new(PCP_RAW_PUBKEYSIZE, "bp");
|
|
|
|
|
pcp_pubkeyblob(b, (pcp_pubkey_t *)k);
|
|
|
|
|
return b;
|
2013-11-18 17:38:03 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2014-03-17 18:04:26 +01:00
|
|
|
Buffer *b = buffer_new(PCP_RAW_KEYSIZE, "bs");
|
|
|
|
|
pcp_seckeyblob(b, (pcp_key_t *)k);
|
|
|
|
|
return b;
|
2013-11-18 17:38:03 +01:00
|
|
|
}
|
|
|
|
|
}
|
2013-11-29 20:01:42 +01:00
|
|
|
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) {
|
2013-11-29 20:01:42 +01:00
|
|
|
if(key->pub[0] == 0) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: public key contained in key seems to be empty!\n");
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->type != PCP_KEY_TYPE_PUBLIC) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
|
2013-11-29 20:01:42 +01:00
|
|
|
PCP_KEY_TYPE_PUBLIC, key->type);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->version != PCP_KEY_VERSION) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
2013-11-29 20:01:42 +01:00
|
|
|
PCP_KEY_VERSION, key->version);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->serial <= 0) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->id[16] != '\0') {
|
|
|
|
|
char *got = ucmalloc(17);
|
|
|
|
|
memcpy(got, key->id, 17);
|
|
|
|
|
got[16] = '\0';
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
2013-11-29 20:01:42 +01:00
|
|
|
free(got);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tm *c;
|
|
|
|
|
time_t t = (time_t)key->ctime;
|
|
|
|
|
c = localtime(&t);
|
|
|
|
|
if(c->tm_year <= 0 || c->tm_year > 1100) {
|
2014-02-05 20:41:16 +01:00
|
|
|
/* well, I'm perhaps overacting here :) */
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id);
|
2013-11-29 20:01:42 +01:00
|
|
|
if(maybe != NULL) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
|
2013-11-29 20:01:42 +01:00
|
|
|
if(key->encrypted[0] == 0) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: secret key contained in key seems to be empty!\n");
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
|
2013-11-29 20:01:42 +01:00
|
|
|
PCP_KEY_TYPE_SECRET, key->type);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->version != PCP_KEY_VERSION) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
2013-11-29 20:01:42 +01:00
|
|
|
PCP_KEY_VERSION, key->version);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->serial <= 0) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key->id[16] != '\0') {
|
|
|
|
|
char *got = ucmalloc(17);
|
|
|
|
|
memcpy(got, key->id, 17);
|
|
|
|
|
got[16] = '\0';
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
2013-11-29 20:01:42 +01:00
|
|
|
free(got);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tm *c;
|
|
|
|
|
time_t t = (time_t)key->ctime;
|
|
|
|
|
c = localtime(&t);
|
2014-02-27 19:53:25 +01:00
|
|
|
if(c->tm_year <= 70 || c->tm_year > 1100) {
|
2014-02-05 20:41:16 +01:00
|
|
|
/* well, I'm perhaps overacting here :) */
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-04 17:11:03 +02:00
|
|
|
pcp_key_t *maybe = pcphash_keyexists(ptx, key->id);
|
2013-11-29 20:01:42 +01:00
|
|
|
if(maybe != NULL) {
|
2014-05-04 17:11:03 +02:00
|
|
|
fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
2013-11-29 20:01:42 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2014-02-12 00:37:41 +01:00
|
|
|
|
2014-02-19 20:38:21 +01:00
|
|
|
void pcp_dumpkey(pcp_key_t *k) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
printf("Dumping pcp_key_t raw values:\n");
|
|
|
|
|
|
|
|
|
|
printf("masterpub: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->masterpub[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" public: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->pub[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" edpub: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->edpub[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf("mastersec: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->mastersecret[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" secret: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->secret[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" edsecret: ");
|
|
|
|
|
for ( i = 0;i < 64;++i) printf("%02x",(unsigned int) k->edsecret[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" nonce: ");
|
|
|
|
|
for ( i = 0;i < 24;++i) printf("%02x",(unsigned int) k->nonce[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf("encrypted: ");
|
|
|
|
|
for ( i = 0;i < 80;++i) printf("%02x",(unsigned int) k->encrypted[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" owner: %s\n", k->owner);
|
|
|
|
|
|
|
|
|
|
printf(" mail: %s\n", k->mail);
|
|
|
|
|
|
|
|
|
|
printf(" id: %s\n", k->id);
|
|
|
|
|
|
|
|
|
|
printf(" ctime: %ld\n", (long int)k->ctime);
|
|
|
|
|
|
|
|
|
|
printf(" version: 0x%08X\n", k->version);
|
|
|
|
|
|
|
|
|
|
printf(" serial: 0x%08X\n", k->serial);
|
|
|
|
|
|
|
|
|
|
printf(" type: 0x%02X\n", k->type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void pcp_dumppubkey(pcp_pubkey_t *k) {
|
|
|
|
|
int i;
|
|
|
|
|
printf("Dumping pcp_pubkey_t raw values:\n");
|
|
|
|
|
|
|
|
|
|
printf("masterpub: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->masterpub[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" public: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->pub[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" edpub: ");
|
|
|
|
|
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->edpub[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
printf(" owner: %s\n", k->owner);
|
|
|
|
|
|
|
|
|
|
printf(" mail: %s\n", k->mail);
|
|
|
|
|
|
|
|
|
|
printf(" id: %s\n", k->id);
|
|
|
|
|
|
|
|
|
|
printf(" ctime: %ld\n", (long int)k->ctime);
|
|
|
|
|
|
|
|
|
|
printf(" version: 0x%08X\n", k->version);
|
|
|
|
|
|
|
|
|
|
printf(" serial: 0x%08X\n", k->serial);
|
|
|
|
|
|
|
|
|
|
printf(" type: 0x%02X\n", k->type);
|
|
|
|
|
}
|