mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-18 04:10:57 +01:00
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:
44
libpcp/key.c
44
libpcp/key.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
143
libpcp/mgmt.c
143
libpcp/mgmt.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user