From c05775a3202695ae6dd92965ba0877038e8baa2a Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Mon, 14 Nov 2016 16:25:51 +1030 Subject: [PATCH] Generalise deterministic key generation --- crypto.c | 25 +++++++++++++++++++++++++ crypto.h | 1 + meshms.c | 5 ++++- rhizome.h | 2 +- rhizome_crypto.c | 34 +++++----------------------------- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/crypto.c b/crypto.c index 6a1819b3..2cece144 100644 --- a/crypto.c +++ b/crypto.c @@ -68,4 +68,29 @@ int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, return 0; } +int crypto_seed_keypair(sign_keypair_t *keypair, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int n = vsnprintf(NULL, 0, fmt, ap); + if (n<0) + return WHYF_perror("vsnprintf(%s, ...)", fmt); + va_end(ap); + + char str_seed[n+1]; + va_start(ap, fmt); + if (vsnprintf(str_seed, sizeof str_seed, fmt, ap)<0) + return WHYF_perror("vsnprintf(%s, ...)", fmt); + va_end(ap); + + union { + unsigned char hash[crypto_hash_sha512_BYTES]; + sign_private_t seed; + } u; + + // The first 256 bits (32 bytes) of the hash will be used as the seed bytes + crypto_hash_sha512(u.hash, (uint8_t *)str_seed, n); + crypto_sign_seed_keypair(keypair->public_key.binary, keypair->binary, u.seed.binary); + return 0; +} diff --git a/crypto.h b/crypto.h index a94f8ea8..8b9be940 100644 --- a/crypto.h +++ b/crypto.h @@ -27,5 +27,6 @@ int crypto_isvalid_keypair(const sign_private_t *private_key, const sign_public_ int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, size_t *message_len); int crypto_sign_to_sid(const sign_public_t *public_key, sid_t *sid); int crypto_ismatching_sign_sid(const sign_public_t *public_key, const sid_t *sid); +int crypto_seed_keypair(sign_keypair_t *key, const char *fmt, ...); #endif diff --git a/meshms.c b/meshms.c index 6f84bf1b..5e65cd08 100644 --- a/meshms.c +++ b/meshms.c @@ -46,10 +46,13 @@ void meshms_free_conversations(struct meshms_conversations *conv) static enum meshms_status get_my_conversation_bundle(const keyring_identity *id, rhizome_manifest *m) { /* Find our private key */ - struct rhizome_bundle_result result = rhizome_private_bundle(m, + sign_keypair_t key; + crypto_seed_keypair(&key, "incorrection%sconcentrativeness", alloca_tohex(id->box_sk, crypto_box_SECRETKEYBYTES)); + struct rhizome_bundle_result result = rhizome_private_bundle(m, &key); + switch (result.status) { case RHIZOME_BUNDLE_STATUS_NEW: case RHIZOME_BUNDLE_STATUS_SAME: diff --git a/rhizome.h b/rhizome.h index 10760bc4..7abf63fd 100644 --- a/rhizome.h +++ b/rhizome.h @@ -371,7 +371,7 @@ int rhizome_cleanup(struct rhizome_cleanup_report *report); int rhizome_store_cleanup(struct rhizome_cleanup_report *report); void rhizome_vacuum_db(sqlite_retry_state *retry); int rhizome_manifest_createid(rhizome_manifest *m); -struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const char *fmt, ...); +struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const sign_keypair_t *keypair); void rhizome_new_bundle_from_secret(rhizome_manifest *m, const rhizome_bk_t *bsk); struct rhizome_manifest_summary { diff --git a/rhizome_crypto.c b/rhizome_crypto.c index 0cabd15e..6f99ac36 100644 --- a/rhizome_crypto.c +++ b/rhizome_crypto.c @@ -41,37 +41,13 @@ int rhizome_manifest_createid(rhizome_manifest *m) /* Generate a bundle id deterministically from the given seed. * Then either fetch it from the database or initialise a new empty manifest */ -struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const char *fmt, ...) +struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const sign_keypair_t *keypair) { - va_list ap; - - va_start(ap, fmt); - int n = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - - char seed[n+1]; - va_start(ap, fmt); - vsnprintf(seed, sizeof seed, fmt, ap); - va_end(ap); - - union { - unsigned char hash[crypto_hash_sha512_BYTES]; - sign_private_t bsk; - } u; - - crypto_hash_sha512(u.hash, (uint8_t *)seed, n); - - // The first 256 bits (32 bytes) of the hash will be used as the private key of the BID. - - sign_keypair_t sk; - rhizome_bid_t bid; - crypto_sign_seed_keypair(bid.binary, sk.binary, u.bsk.binary); - - enum rhizome_bundle_status ret = rhizome_retrieve_manifest(&bid, m); + enum rhizome_bundle_status ret = rhizome_retrieve_manifest(&keypair->public_key, m); switch(ret){ case RHIZOME_BUNDLE_STATUS_NEW: - rhizome_manifest_set_id(m, &bid); // zerofills m->keypair.binary - m->keypair = sk; + rhizome_manifest_set_id(m, &keypair->public_key); // zerofills m->keypair.binary + m->keypair = *keypair; m->haveSecret = NEW_BUNDLE_ID; rhizome_manifest_set_service(m, RHIZOME_SERVICE_FILE); rhizome_manifest_set_name(m, ""); @@ -81,7 +57,7 @@ struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const c return rhizome_fill_manifest(m, NULL); case RHIZOME_BUNDLE_STATUS_SAME: m->haveSecret = EXISTING_BUNDLE_ID; - m->keypair = sk; + m->keypair = *keypair; // always consider the content encrypted, we don't need to rely on the manifest itself. rhizome_manifest_set_crypt(m, PAYLOAD_ENCRYPTED); if (strcmp(m->service, RHIZOME_SERVICE_FILE) != 0)