changed secret key export format, now we encrypt the whole thing, and we use an extra passphrase to do so. import wrapper in src/ not implemented yet.

This commit is contained in:
git@daemon.de
2014-02-12 16:47:24 +01:00
parent a78dd9c6eb
commit 621cece568
12 changed files with 294 additions and 148 deletions

View File

@@ -296,28 +296,6 @@ pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
#endif
}
pcp_keysig_t * keysig2be(pcp_keysig_t *s) {
#ifdef __CPU_IS_BIG_ENDIAN
return s;
#else
uint32_t size = s->size;
unsigned char* p = (unsigned char*)&size;
if(p[0] != 0) {
s->size = htobe32(s->size);
}
return s;
#endif
}
pcp_keysig_t *keysig2native(pcp_keysig_t *s) {
#ifdef __CPU_IS_BIG_ENDIAN
return s;
#else
s->size = be32toh(s->size);
return s;
#endif
}
void pcp_seckeyblob(void *blob, pcp_key_t *k) {
memcpy(blob, k, PCP_RAW_KEYSIZE);
}
@@ -441,25 +419,3 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
return 0;
}
pcp_keysig_t *pcp_keysig_new(Buffer *blob) {
/* FIXME: sanity check before actually loading it */
pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t));
uint8_t type = buffer_get8(blob);
uint32_t size = buffer_get32na(blob);
byte *checksum = ucmalloc(32);
buffer_get_chunk(blob, checksum, 32);
sk->blob = ucmalloc(size);
buffer_get_chunk(blob, sk->blob, size);
sk->size = size;
sk->type = type;
memcpy(sk->checksum, checksum, 32);
ucfree(checksum, 32);
return sk;
}

View File

@@ -54,7 +54,10 @@ void *urmalloc(size_t s) {
void *ucrealloc(void *d, size_t oldlen, size_t newlen) {
newlen = newlen * sizeof(unsigned char);
void *value = realloc (d, newlen);
/* we're using a 1 byte sized pointer, so that we can
memset(zero) it after resizing */
unsigned char *value = realloc (d, newlen);
if (value == NULL) {
err(errno, "Cannot reallocate %ld bytes of memory", newlen);
@@ -63,7 +66,7 @@ void *ucrealloc(void *d, size_t oldlen, size_t newlen) {
memset (&value[oldlen], 0, newlen-oldlen);
return value;
return (void *)value;
}
void ucfree(void *d, size_t len) {

View File

@@ -93,6 +93,11 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
else if(strncmp(notation, "mail", 4) == 0) {
memcpy(p->mail, value, vsize);
}
else if(strncmp(notation, "serial", 6) == 0) {
uint32_t serial;
memcpy(&serial, value, 4);
p->serial = htobe32(serial);
}
ucfree(notation, nsize);
ucfree(value, vsize);
@@ -194,9 +199,7 @@ pcp_ks_bundle_t *pcp_import_pub(unsigned char *raw, size_t rawsize) {
if(version == PCP_KEY_VERSION) {
/* ah, homerun */
pcp_ks_bundle_t *b = pcp_import_pub_rfc(blob);
pcp_keysig_t *sk = b->s;
return b;
return pcp_import_pub_rfc(blob);
}
else {
/* nope, it's probably pbp */
@@ -332,8 +335,8 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk) {
Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
Buffer *out = buffer_new(320, "bo1");
Buffer *raw = buffer_new(256, "bs1");
Buffer *out = buffer_new(320, "exportbuf");
Buffer *raw = buffer_new(256, "keysigbuf");
/* add the header */
buffer_add8(out, PCP_KEY_VERSION);
@@ -390,6 +393,15 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
buffer_add(raw, sk->mail, strlen(sk->mail));
}
/* add serial number notation sub */
notation_size = 6 + 4 + 4;
buffer_add32be(raw, notation_size);
buffer_add8(raw, EXP_SIG_SUB_NOTATION);
buffer_add16be(raw, 6);
buffer_add16be(raw, 4);
buffer_add(raw, "serial", 6);
buffer_add32be(raw, sk->serial);
/* add key flags */
buffer_add32be(raw, 1);
buffer_add8(raw, 27);
@@ -423,3 +435,124 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
return out;
}
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
unsigned char *nonce = NULL;
unsigned char *symkey = NULL;
unsigned char *cipher = NULL;
size_t es;
Buffer *raw = buffer_new(512, "secretbuf");
Buffer *out = buffer_new(512, "secretciperblob");
buffer_add(raw, sk->mastersecret, 64);
buffer_add(raw, sk->secret, 32);
buffer_add(raw, sk->edsecret, 64);
buffer_add(raw, sk->masterpub, 32);
buffer_add(raw, sk->pub, 32);
buffer_add(raw, sk->edpub, 32);
if(strlen(sk->owner) > 0) {
buffer_add16be(raw, strlen(sk->owner));
buffer_add(raw, sk->owner, strlen(sk->owner));
}
else
buffer_add16be(raw, 0);
if(strlen(sk->mail) > 0) {
buffer_add16be(raw, strlen(sk->mail));
buffer_add(raw, sk->mail, strlen(sk->mail));
}
else
buffer_add16be(raw, 0);
buffer_add64be(raw, sk->ctime);
buffer_add32be(raw, sk->version);
buffer_add32be(raw, sk->serial);
nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey);
buffer_add(out, nonce, crypto_secretbox_NONCEBYTES);
buffer_add(out, cipher, es);
buffer_free(raw);
ucfree(nonce, crypto_secretbox_NONCEBYTES);
ucfree(symkey, 64);
ucfree(cipher, es);
return out;
}
pcp_key_t *pcp_import_secret(Buffer *cipher, char *passphrase) {
pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t));
unsigned char *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
unsigned char *symkey = NULL;
unsigned char *clear = NULL;
size_t cipherlen = 0;
size_t minlen = (64 * 2) * (32 * 4) + 8 + 4 + 4;
uint16_t notationlen = 0;
Buffer *blob = buffer_new(512, "secretdecryptbuf");
if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0)
goto impserr1;
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
cipherlen = buffer_left(cipher);
if(cipherlen < minlen) {
fatal("expected decrypted secret key size %ld is less than minimum len %ld\n", cipherlen, minlen);
goto impserr1;
}
if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher),
cipherlen, nonce, symkey) != 0)
goto impserr1;
buffer_add(blob, clear, cipherlen - PCP_CRYPTO_ADD);
buffer_get_chunk(blob, sk->mastersecret, 64);
buffer_get_chunk(blob, sk->secret, 32);
buffer_get_chunk(blob, sk->edsecret, 64);
buffer_get_chunk(blob, sk->masterpub, 32);
buffer_get_chunk(blob, sk->pub, 32);
buffer_get_chunk(blob, sk->edpub, 32);
notationlen = buffer_get16na(blob);
if(notationlen > 0)
buffer_get_chunk(blob, sk->owner, notationlen);
notationlen = buffer_get16na(blob);
if(notationlen > 0)
buffer_get_chunk(blob, sk->mail, notationlen);
if(buffer_done(blob) == 1)
goto impserr2;
sk->ctime = buffer_get64na(blob);
sk->version = buffer_get32na(blob);
sk->serial = buffer_get32na(blob);
/* ready */
ucfree(clear, cipherlen - PCP_CRYPTO_ADD);
ucfree(nonce, crypto_secretbox_NONCEBYTES);
ucfree(sk, sizeof(pcp_key_t));
buffer_free(blob);
return sk;
impserr2:
ucfree(clear, cipherlen - PCP_CRYPTO_ADD);
impserr1:
ucfree(nonce, crypto_secretbox_NONCEBYTES);
ucfree(sk, sizeof(pcp_key_t));
buffer_free(blob);
return NULL;
}

View File

@@ -168,22 +168,13 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_NATIVE) {
pcp_keysig_t *sk = (pcp_keysig_t *)item;
itemsize = PCP_RAW_KEYSIGSIZE + sk->size;
size_t blobsize = sk->size;
Buffer *b = pcp_keysig2blob(sk);
itemsize = buffer_size(b);
blob = ucmalloc(itemsize);
sk = keysig2be(sk);
memcpy(blob, buffer_get(b), buffer_size(b));
buffer_free(b);
/* FIXME: use Buffer or function */
uint8_t t = sk->type;
uint32_t s = sk->size;
memcpy(blob, &t, 1);
memcpy(blob+1, &s, 4);
memcpy(blob+5, sk->belongs, 17);
memcpy(blob+5+17, sk->checksum, 32);
memcpy(blob+5+17+32, sk->blob, blobsize);
sk = keysig2native(sk);
saveitem = (void *)sk;
}
else {