mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-14 06:06:44 +00:00
Introduce new typedef for signing keys to expose their internal structure
This commit is contained in:
parent
d572da2529
commit
b927af79a8
28
keyring.c
28
keyring.c
@ -51,7 +51,7 @@ struct combined_pk{
|
||||
};
|
||||
|
||||
struct combined_sk{
|
||||
uint8_t sign_key[crypto_sign_SECRETKEYBYTES];
|
||||
sign_keypair_t sign_key;
|
||||
uint8_t box_key[crypto_box_SECRETKEYBYTES];
|
||||
};
|
||||
|
||||
@ -489,29 +489,29 @@ static void create_cryptocombined(keypair *kp)
|
||||
{
|
||||
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
|
||||
struct combined_sk *sk = (struct combined_sk *)kp->private_key;
|
||||
crypto_sign_ed25519_keypair(pk->sign_key.binary, sk->sign_key);
|
||||
crypto_sign_ed25519_sk_to_curve25519(sk->box_key, sk->sign_key);
|
||||
crypto_sign_ed25519_keypair(pk->sign_key.binary, sk->sign_key.binary);
|
||||
crypto_sign_ed25519_sk_to_curve25519(sk->box_key, sk->sign_key.binary);
|
||||
crypto_scalarmult_base(pk->box_key.binary, sk->box_key);
|
||||
}
|
||||
|
||||
static int pack_cryptocombined(const keypair *kp, struct rotbuf *rb)
|
||||
{
|
||||
uint8_t seed[crypto_sign_SEEDBYTES];
|
||||
sign_private_t seed;
|
||||
struct combined_sk *sk = (struct combined_sk *)kp->private_key;
|
||||
crypto_sign_ed25519_sk_to_seed(seed, sk->sign_key);
|
||||
rotbuf_putbuf(rb, seed, sizeof seed);
|
||||
crypto_sign_ed25519_sk_to_seed(seed.binary, sk->sign_key.binary);
|
||||
rotbuf_putbuf(rb, seed.binary, sizeof seed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpack_cryptocombined(keypair *kp, struct rotbuf *rb, size_t key_length)
|
||||
{
|
||||
uint8_t seed[crypto_sign_SEEDBYTES];
|
||||
sign_private_t seed;
|
||||
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
|
||||
struct combined_sk *sk = (struct combined_sk *)kp->private_key;
|
||||
assert(key_length == sizeof seed);
|
||||
rotbuf_getbuf(rb, seed, sizeof seed);
|
||||
crypto_sign_ed25519_seed_keypair(pk->sign_key.binary, sk->sign_key, seed);
|
||||
crypto_sign_ed25519_sk_to_curve25519(sk->box_key, sk->sign_key);
|
||||
rotbuf_getbuf(rb, seed.binary, sizeof seed);
|
||||
crypto_sign_ed25519_seed_keypair(pk->sign_key.binary, sk->sign_key.binary, seed.binary);
|
||||
crypto_sign_ed25519_sk_to_curve25519(sk->box_key, sk->sign_key.binary);
|
||||
crypto_scalarmult_base(pk->box_key.binary, sk->box_key);
|
||||
return 0;
|
||||
}
|
||||
@ -1199,7 +1199,7 @@ static int keyring_finalise_identity(uint8_t *dirty, keyring_identity *id)
|
||||
*dirty = 1;
|
||||
}
|
||||
id->sign_pk = (const identity_t *)kp->public_key;
|
||||
id->sign_sk = kp->private_key;
|
||||
id->sign_sk = (const sign_keypair_t *)kp->private_key;
|
||||
break;
|
||||
case KEYTYPE_CRYPTOCOMBINED:{
|
||||
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
|
||||
@ -1207,7 +1207,7 @@ static int keyring_finalise_identity(uint8_t *dirty, keyring_identity *id)
|
||||
id->box_pk = &pk->box_key;
|
||||
id->box_sk = sk->box_key;
|
||||
id->sign_pk = &pk->sign_key;
|
||||
id->sign_sk = sk->sign_key;
|
||||
id->sign_sk = &sk->sign_key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1731,7 +1731,7 @@ int keyring_sign_message(struct keyring_identity *identity, unsigned char *conte
|
||||
unsigned char hash[crypto_hash_sha512_BYTES];
|
||||
crypto_hash_sha512(hash, content, *content_len);
|
||||
|
||||
if (crypto_sign_detached(&content[*content_len], NULL, hash, crypto_hash_sha512_BYTES, identity->sign_sk))
|
||||
if (crypto_sign_detached(&content[*content_len], NULL, hash, crypto_hash_sha512_BYTES, identity->sign_sk->binary))
|
||||
return WHY("Signing failed");
|
||||
|
||||
*content_len += SIGNATURE_BYTES;
|
||||
@ -1793,7 +1793,7 @@ static int keyring_respond_id(struct internal_mdp_header *header)
|
||||
ob_append_bytes(response_payload, id->sign_pk->binary, crypto_sign_PUBLICKEYBYTES);
|
||||
uint8_t *sig = ob_append_space(response_payload, crypto_sign_BYTES);
|
||||
|
||||
if (crypto_sign_detached(sig, NULL, header->destination->sid.binary, SID_SIZE, id->sign_sk))
|
||||
if (crypto_sign_detached(sig, NULL, header->destination->sid.binary, SID_SIZE, id->sign_sk->binary))
|
||||
return WHY("crypto_sign() failed");
|
||||
|
||||
DEBUGF(keyring, "Sending SID:SAS mapping, %zd bytes, %s:%"PRImdp_port_t" -> %s:%"PRImdp_port_t,
|
||||
|
@ -50,7 +50,7 @@ typedef struct keyring_identity {
|
||||
struct keyring_challenge *challenge;
|
||||
const uint8_t *box_sk;
|
||||
const sid_t *box_pk;
|
||||
const uint8_t *sign_sk;
|
||||
const sign_keypair_t *sign_sk;
|
||||
const identity_t *sign_pk;
|
||||
struct keyring_identity *next;
|
||||
keypair *keypairs;
|
||||
|
2
meshmb.c
2
meshmb.c
@ -178,7 +178,7 @@ static int app_meshmb_find(const struct cli_parsed *parsed, struct cli_context *
|
||||
rowcount++;
|
||||
rhizome_manifest *m = cursor.manifest;
|
||||
cli_put_long(context, m->rowid, ":");
|
||||
cli_put_hexvalue(context, m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, ":");
|
||||
cli_put_hexvalue(context, m->keypair.public_key.binary, sizeof m->keypair.public_key.binary, ":");
|
||||
cli_put_long(context, m->version, ":");
|
||||
cli_put_long(context, m->has_date ? m->date : 0, ":");
|
||||
cli_put_string(context, m->name, "\n");
|
||||
|
44
meshms.c
44
meshms.c
@ -46,33 +46,19 @@ 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 */
|
||||
strbuf sb = strbuf_alloca(1024);
|
||||
strbuf_puts(sb, "incorrection");
|
||||
strbuf_tohex(sb, crypto_box_SECRETKEYBYTES * 2, id->box_sk);
|
||||
strbuf_puts(sb, "concentrativeness");
|
||||
assert(!strbuf_overrun(sb));
|
||||
if (rhizome_get_bundle_from_seed(m, strbuf_str(sb)) == -1)
|
||||
return MESHMS_STATUS_ERROR;
|
||||
|
||||
// always consider the content encrypted, we don't need to rely on the manifest itself.
|
||||
rhizome_manifest_set_crypt(m, PAYLOAD_ENCRYPTED);
|
||||
assert(m->haveSecret);
|
||||
struct rhizome_bundle_result result = rhizome_private_bundle(m,
|
||||
"incorrection%sconcentrativeness",
|
||||
alloca_tohex(id->box_sk, crypto_box_SECRETKEYBYTES));
|
||||
|
||||
// The 'meshms' automated test depends on this message; do not alter.
|
||||
DEBUGF(meshms, "MESHMS CONVERSATION BUNDLE bid=%s secret=%s",
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
alloca_tohex(m->cryptoSignSecret, RHIZOME_BUNDLE_KEY_BYTES)
|
||||
);
|
||||
|
||||
if (m->haveSecret == NEW_BUNDLE_ID) {
|
||||
rhizome_manifest_set_service(m, RHIZOME_SERVICE_FILE);
|
||||
rhizome_manifest_set_name(m, "");
|
||||
// setting the author would imply needing a BK, which we don't need since the private key is seeded above.
|
||||
struct rhizome_bundle_result result = rhizome_fill_manifest(m, NULL);
|
||||
switch (result.status) {
|
||||
switch (result.status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
// The 'meshms' automated test depends on this message; do not alter.
|
||||
DEBUGF(meshms, "MESHMS CONVERSATION BUNDLE bid=%s secret=%s",
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key),
|
||||
alloca_tohex(m->keypair.private_key.binary, RHIZOME_BUNDLE_KEY_BYTES)
|
||||
);
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
@ -93,14 +79,8 @@ static enum meshms_status get_my_conversation_bundle(const keyring_identity *id,
|
||||
INFOF("Cannot create conversation manifest: %s", alloca_rhizome_bundle_result(result));
|
||||
rhizome_bundle_result_free(&result);
|
||||
return MESHMS_STATUS_SID_LOCKED;
|
||||
}
|
||||
rhizome_bundle_result_free(&result);
|
||||
} else {
|
||||
if (strcmp(m->service, RHIZOME_SERVICE_FILE) != 0) {
|
||||
WARNF("Invalid conversations manifest, service=%s but should be %s", m->service, RHIZOME_SERVICE_FILE);
|
||||
return MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
}
|
||||
}
|
||||
rhizome_bundle_result_free(&result);
|
||||
return MESHMS_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -212,6 +192,7 @@ static enum meshms_status update_their_stats(struct meshms_metadata *metadata, s
|
||||
|
||||
uint8_t found_their_msg=0;
|
||||
uint8_t found_their_ack=0;
|
||||
reader->read.offset = reader->read.length;
|
||||
|
||||
while((!found_their_msg || !found_their_ack) && message_ply_read_prev(reader) == 0){
|
||||
// stop if we've seen these records before
|
||||
@ -258,6 +239,7 @@ static enum meshms_status update_my_stats(struct meshms_metadata *metadata, stru
|
||||
if (meshms_failed(status = open_ply(ply, reader)))
|
||||
return status;
|
||||
|
||||
reader->read.offset = reader->read.length;
|
||||
if (message_ply_find_prev(reader, MESSAGE_BLOCK_TYPE_ACK)==0){
|
||||
uint64_t my_ack = 0;
|
||||
if (unpack_uint(reader->record, reader->record_length, &my_ack) != -1){
|
||||
@ -377,7 +359,7 @@ static enum meshms_status read_known_conversations(rhizome_manifest *m, struct m
|
||||
enum meshms_status status = MESHMS_STATUS_OK;
|
||||
enum rhizome_payload_status pstatus = rhizome_open_decrypt_read(m, &read);
|
||||
if (pstatus == RHIZOME_PAYLOAD_STATUS_NEW) {
|
||||
WARNF("Payload was not found for manifest %s, %"PRIu64, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
|
||||
WARNF("Payload was not found for manifest %s, %"PRIu64, alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version);
|
||||
goto end;
|
||||
}
|
||||
if (pstatus != RHIZOME_PAYLOAD_STATUS_STORED && pstatus != RHIZOME_PAYLOAD_STATUS_EMPTY)
|
||||
|
@ -57,7 +57,7 @@ static int message_ply_fill_manifest(const keyring_identity *id, const sid_t *re
|
||||
if (ret==0){
|
||||
assert(m->haveSecret);
|
||||
assert(!recipient || m->payloadEncryption == PAYLOAD_ENCRYPTED);
|
||||
ply->bundle_id = m->cryptoSignPublic;
|
||||
ply->bundle_id = m->keypair.public_key;
|
||||
ply->found = ply->known_bid = 1;
|
||||
}
|
||||
return ret;
|
||||
|
@ -628,7 +628,7 @@ static void monitor_announce_bundle(rhizome_manifest *m)
|
||||
char msg[1024];
|
||||
int len = snprintf(msg,1024,"\n*%zd:BUNDLE:%s\n",
|
||||
m->manifest_all_bytes,
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
bcopy(m->manifestdata, &msg[len], m->manifest_all_bytes);
|
||||
len+=m->manifest_all_bytes;
|
||||
msg[len++]='\n';
|
||||
|
@ -191,7 +191,7 @@ void overlay_address_append(struct decode_context *context, struct overlay_buffe
|
||||
subscriber->send_full=0;
|
||||
}else{
|
||||
// always send 8-12 extra bits to disambiguate abbreviations
|
||||
int len=(subscriber->tree_depth >> 3) + 1;
|
||||
unsigned len=(subscriber->tree_depth >> 3) + 1;
|
||||
// add another 8 bits for our own packet headers
|
||||
if (context && (context->flags & DECODE_FLAG_ENCODING_HEADER))
|
||||
len++;
|
||||
@ -258,10 +258,10 @@ static int add_explain_response(void **record, void *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int len, struct subscriber **subscriber)
|
||||
static int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, unsigned len, struct subscriber **subscriber)
|
||||
{
|
||||
assert(subscriber);
|
||||
if (len<=0 || len>SID_SIZE)
|
||||
if (len>SID_SIZE)
|
||||
return WHYF("Invalid abbreviation length %d", len);
|
||||
|
||||
uint8_t *id = ob_get_bytes_ptr(b, len);
|
||||
@ -454,6 +454,8 @@ int process_explain(struct overlay_frame *frame)
|
||||
|
||||
while(ob_remaining(b)>0){
|
||||
int len = ob_get(b);
|
||||
if (len<0)
|
||||
return WHY("Badly formatted explain message");
|
||||
switch (len){
|
||||
case OA_CODE_P2P_YOU:
|
||||
{
|
||||
@ -477,7 +479,7 @@ int process_explain(struct overlay_frame *frame)
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (len<=0 || len>SID_SIZE)
|
||||
if ((unsigned)len>SID_SIZE)
|
||||
return WHY("Badly formatted explain message");
|
||||
uint8_t *sid = ob_get_bytes_ptr(b, len);
|
||||
// reply to the sender with all subscribers that match this abbreviation
|
||||
|
@ -374,7 +374,7 @@ static int overlay_mdp_service_manifest_requests(struct internal_mdp_header *hea
|
||||
rhizome_advertise_manifest(header->source, m);
|
||||
// pre-emptively send the payload if it will fit in a single packet
|
||||
if (m->filesize > 0 && m->filesize <= 1024)
|
||||
rhizome_mdp_send_block(header->source, &m->cryptoSignPublic, m->version, 0, 0, m->filesize);
|
||||
rhizome_mdp_send_block(header->source, &m->keypair.public_key, m->version, 0, 0, m->filesize);
|
||||
}
|
||||
rhizome_manifest_free(m);
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ enum rhizome_bundle_status rhizome_manifest_check_stored(rhizome_manifest *m, rh
|
||||
rhizome_manifest *stored_m = rhizome_new_manifest();
|
||||
if (stored_m == NULL)
|
||||
return -1;
|
||||
enum rhizome_bundle_status result = rhizome_retrieve_manifest(&m->cryptoSignPublic, stored_m);
|
||||
enum rhizome_bundle_status result = rhizome_retrieve_manifest(&m->keypair.public_key, stored_m);
|
||||
if (result==RHIZOME_BUNDLE_STATUS_SAME){
|
||||
const char *what = "same as";
|
||||
if (m->version < stored_m->version) {
|
||||
@ -597,14 +597,14 @@ enum rhizome_bundle_status rhizome_manifest_check_stored(rhizome_manifest *m, rh
|
||||
what = "newer than";
|
||||
result = RHIZOME_BUNDLE_STATUS_NEW;
|
||||
}
|
||||
DEBUGF(rhizome, "Bundle %s:%"PRIu64" is %s stored version %"PRIu64, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version, what, stored_m->version);
|
||||
DEBUGF(rhizome, "Bundle %s:%"PRIu64" is %s stored version %"PRIu64, alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version, what, stored_m->version);
|
||||
if (mout)
|
||||
*mout = stored_m;
|
||||
else
|
||||
rhizome_manifest_free(stored_m);
|
||||
}else{
|
||||
rhizome_manifest_free(stored_m);
|
||||
DEBUGF(rhizome, "No stored manifest with id=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
DEBUGF(rhizome, "No stored manifest with id=%s", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
if (mout)
|
||||
*mout = m;
|
||||
}
|
||||
|
10
rhizome.h
10
rhizome.h
@ -59,10 +59,9 @@ typedef struct rhizome_manifest
|
||||
/* CryptoSign key pair for this manifest. The public key is the Bundle ID
|
||||
* (aka Manifest ID).
|
||||
*/
|
||||
rhizome_bid_t cryptoSignPublic;
|
||||
unsigned char cryptoSignSecret[crypto_sign_SECRETKEYBYTES];
|
||||
sign_keypair_t keypair;
|
||||
|
||||
/* Whether cryptoSignSecret is correct (ie, bundle secret is known)
|
||||
/* What do we know about keypair.private_key? (ie, bundle secret is known)
|
||||
*/
|
||||
enum { SECRET_UNKNOWN = 0, EXISTING_BUNDLE_ID, NEW_BUNDLE_ID } haveSecret;
|
||||
|
||||
@ -122,7 +121,7 @@ typedef struct rhizome_manifest
|
||||
*/
|
||||
bool_t selfSigned:1;
|
||||
|
||||
/* Set if the ID field (cryptoSignPublic) contains a bundle ID.
|
||||
/* Set if the ID field (sign_key.public_key) contains a bundle ID.
|
||||
*/
|
||||
bool_t has_id:1;
|
||||
|
||||
@ -371,8 +370,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);
|
||||
int rhizome_get_bundle_from_seed(rhizome_manifest *m, const char *seed);
|
||||
int rhizome_get_bundle_from_secret(rhizome_manifest *m, const rhizome_bk_t *bsk);
|
||||
struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const char *fmt, ...);
|
||||
void rhizome_new_bundle_from_secret(rhizome_manifest *m, const rhizome_bk_t *bsk);
|
||||
|
||||
struct rhizome_manifest_summary {
|
||||
|
@ -106,14 +106,14 @@ static const char *_rhizome_manifest_set_ui64(struct __sourceloc __whence, rhizo
|
||||
void _rhizome_manifest_set_id(struct __sourceloc __whence, rhizome_manifest *m, const rhizome_bid_t *bidp)
|
||||
{
|
||||
if (bidp) {
|
||||
if (m->has_id && (bidp == &m->cryptoSignPublic || cmp_rhizome_bid_t(&m->cryptoSignPublic, bidp) == 0))
|
||||
if (m->has_id && (bidp == &m->keypair.public_key || cmp_rhizome_bid_t(&m->keypair.public_key, bidp) == 0))
|
||||
return; // unchanged
|
||||
const char *v = rhizome_manifest_set(m, "id", alloca_tohex_rhizome_bid_t(*bidp));
|
||||
assert(v); // TODO: remove known manifest fields from vars[]
|
||||
m->cryptoSignPublic = *bidp;
|
||||
m->keypair.public_key = *bidp;
|
||||
m->has_id = 1;
|
||||
} else if (m->has_id) {
|
||||
bzero(&m->cryptoSignPublic, sizeof m->cryptoSignPublic); // not strictly necessary but aids debugging
|
||||
bzero(&m->keypair.public_key, sizeof m->keypair.public_key); // not strictly necessary but aids debugging
|
||||
m->has_id = 0;
|
||||
} else
|
||||
return; // unchanged
|
||||
@ -122,7 +122,7 @@ void _rhizome_manifest_set_id(struct __sourceloc __whence, rhizome_manifest *m,
|
||||
// Any existing secret key and bundle key are no longer valid.
|
||||
if (m->haveSecret) {
|
||||
m->haveSecret = SECRET_UNKNOWN;
|
||||
bzero(m->cryptoSignSecret, sizeof m->cryptoSignSecret); // not strictly necessary but aids debugging
|
||||
bzero(m->keypair.private_key.binary, sizeof m->keypair.private_key.binary); // not strictly necessary but aids debugging
|
||||
}
|
||||
if (m->has_bundle_key) {
|
||||
m->has_bundle_key = 0;
|
||||
@ -440,7 +440,7 @@ int rhizome_manifest_verify(rhizome_manifest *m)
|
||||
m->selfSigned = 0;
|
||||
return 0;
|
||||
}
|
||||
if (memcmp(m->signatories[0], m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary) != 0) {
|
||||
if (memcmp(m->signatories[0], m->keypair.public_key.binary, sizeof m->keypair.public_key.binary) != 0) {
|
||||
DEBUGF(rhizome_manifest, "Manifest id does not match first signature block (signature key is %s)",
|
||||
alloca_tohex(m->signatories[0], crypto_sign_PUBLICKEYBYTES)
|
||||
);
|
||||
@ -685,7 +685,7 @@ static void _rhizome_manifest_unset_id(struct __sourceloc __whence, rhizome_mani
|
||||
}
|
||||
static void _rhizome_manifest_copy_id(struct __sourceloc __whence, rhizome_manifest *m, const rhizome_manifest *srcm)
|
||||
{
|
||||
rhizome_manifest_set_id(m, srcm->has_id ? &srcm->cryptoSignPublic : NULL);
|
||||
rhizome_manifest_set_id(m, srcm->has_id ? &srcm->keypair.public_key : NULL);
|
||||
}
|
||||
static int _rhizome_manifest_parse_id(rhizome_manifest *m, const char *text)
|
||||
{
|
||||
@ -1245,10 +1245,10 @@ static struct rhizome_bundle_result rhizome_manifest_selfsign(rhizome_manifest *
|
||||
crypto_hash_sha512(m->manifesthash.binary, m->manifestdata, m->manifest_body_bytes);
|
||||
uint8_t *p = &m->manifestdata[m->manifest_body_bytes];
|
||||
*p++ = 0x17; // CryptoSign
|
||||
if (crypto_sign_detached(p, NULL, m->manifesthash.binary, sizeof m->manifesthash.binary, m->cryptoSignSecret))
|
||||
if (crypto_sign_detached(p, NULL, m->manifesthash.binary, sizeof m->manifesthash.binary, m->keypair.binary))
|
||||
return rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_ERROR, "crypto_sign_detached() failed");
|
||||
p+=crypto_sign_BYTES;
|
||||
bcopy(m->cryptoSignPublic.binary, p, crypto_sign_BYTES);
|
||||
bcopy(m->keypair.public_key.binary, p, crypto_sign_BYTES);
|
||||
m->manifest_all_bytes = m->manifest_body_bytes + sigLen;
|
||||
m->selfSigned = 1;
|
||||
return rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NEW);
|
||||
@ -1387,7 +1387,7 @@ struct rhizome_bundle_result rhizome_fill_manifest(rhizome_manifest *m, const ch
|
||||
case SECRET_UNKNOWN:
|
||||
// If the Bundle Id is already known, then derive the bundle secret from BK if known.
|
||||
if (m->has_id) {
|
||||
DEBUGF(rhizome, "discover secret for bundle bid=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
DEBUGF(rhizome, "discover secret for bundle bid=%s", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
rhizome_authenticate_author(m);
|
||||
break;
|
||||
}
|
||||
@ -1405,14 +1405,14 @@ struct rhizome_bundle_result rhizome_fill_manifest(rhizome_manifest *m, const ch
|
||||
rhizome_manifest_set_author(m, &m->sender);
|
||||
// If we know the author then set the BK field.
|
||||
if (m->authorship != ANONYMOUS) {
|
||||
DEBUGF(rhizome, "set BK field for bid=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
DEBUGF(rhizome, "set BK field for bid=%s", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
rhizome_manifest_add_bundle_key(m);
|
||||
}
|
||||
break;
|
||||
case EXISTING_BUNDLE_ID:
|
||||
// If modifying an existing bundle, try to discover the bundle secret key and the author.
|
||||
assert(m->has_id);
|
||||
DEBUGF(rhizome, "modifying existing bundle bid=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
DEBUGF(rhizome, "modifying existing bundle bid=%s", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
rhizome_authenticate_author(m);
|
||||
// TODO assert that new version > old version?
|
||||
break;
|
||||
|
@ -29,7 +29,7 @@ static void cli_put_manifest(struct cli_context *context, const rhizome_manifest
|
||||
{
|
||||
assert(m->filesize != RHIZOME_SIZE_UNSET);
|
||||
cli_field_name(context, "manifestid", ":"); // TODO rename to "bundleid" or "bid"
|
||||
cli_put_string(context, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), "\n");
|
||||
cli_put_string(context, alloca_tohex_rhizome_bid_t(m->keypair.public_key), "\n");
|
||||
cli_field_name(context, "version", ":");
|
||||
cli_put_long(context, m->version, "\n");
|
||||
cli_field_name(context, "filesize", ":");
|
||||
@ -70,7 +70,7 @@ static void cli_put_manifest(struct cli_context *context, const rhizome_manifest
|
||||
cli_put_long(context, m->haveSecret ? 0 : 1, "\n");
|
||||
if (m->haveSecret) {
|
||||
char secret[RHIZOME_BUNDLE_KEY_STRLEN + 1];
|
||||
rhizome_bytes_to_hex_upper(m->cryptoSignSecret, secret, RHIZOME_BUNDLE_KEY_BYTES);
|
||||
rhizome_bytes_to_hex_upper(m->keypair.binary, secret, RHIZOME_BUNDLE_KEY_BYTES);
|
||||
cli_field_name(context, ".secret", ":");
|
||||
cli_put_string(context, secret, "\n");
|
||||
}
|
||||
@ -287,7 +287,7 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
|
||||
rhizome_bundle_result_free(&result);
|
||||
result = rhizome_manifest_finalise(m, &mout, !force_new);
|
||||
if (mout && mout != m && !rhizome_manifest_validate(mout)) {
|
||||
WHYF("Stored manifest id=%s is invalid -- overwriting", alloca_tohex_rhizome_bid_t(mout->cryptoSignPublic));
|
||||
WHYF("Stored manifest id=%s is invalid -- overwriting", alloca_tohex_rhizome_bid_t(mout->keypair.public_key));
|
||||
rhizome_bundle_result_free(&result);
|
||||
result = rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NEW);
|
||||
}
|
||||
@ -759,7 +759,7 @@ static int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context
|
||||
rhizome_lookup_author(m);
|
||||
cli_put_long(context, m->rowid, ":");
|
||||
cli_put_string(context, m->service, ":");
|
||||
cli_put_hexvalue(context, m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, ":");
|
||||
cli_put_hexvalue(context, m->keypair.public_key.binary, sizeof m->keypair.public_key.binary, ":");
|
||||
cli_put_long(context, m->version, ":");
|
||||
cli_put_long(context, m->has_date ? m->date : 0, ":");
|
||||
cli_put_long(context, m->inserttime, ":");
|
||||
|
104
rhizome_crypto.c
104
rhizome_crypto.c
@ -32,49 +32,63 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
int rhizome_manifest_createid(rhizome_manifest *m)
|
||||
{
|
||||
if (crypto_sign_keypair(m->cryptoSignPublic.binary, m->cryptoSignSecret))
|
||||
if (crypto_sign_keypair(m->keypair.public_key.binary, m->keypair.binary))
|
||||
return WHY("Failed to create keypair for manifest ID.");
|
||||
rhizome_manifest_set_id(m, &m->cryptoSignPublic); // will remove any existing BK field
|
||||
rhizome_manifest_set_id(m, &m->keypair.public_key); // will remove any existing BK field
|
||||
m->haveSecret = NEW_BUNDLE_ID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate a bundle id deterministically from the given seed.
|
||||
* Then either fetch it from the database or initialise a new empty manifest */
|
||||
int rhizome_get_bundle_from_seed(rhizome_manifest *m, const char *seed)
|
||||
struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const char *fmt, ...)
|
||||
{
|
||||
char seed[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
int n = vsnprintf(seed, sizeof seed, fmt, ap);
|
||||
assert(n < (int)sizeof seed);
|
||||
union {
|
||||
unsigned char hash[crypto_hash_sha512_BYTES];
|
||||
rhizome_bk_t bsk;
|
||||
sign_private_t bsk;
|
||||
} u;
|
||||
crypto_hash_sha512(u.hash, (unsigned char *)seed, strlen(seed));
|
||||
// The first 256 bits (32 bytes) of the hash will be used as the private key of the BID.
|
||||
return rhizome_get_bundle_from_secret(m, &u.bsk);
|
||||
}
|
||||
|
||||
/* Generate a bundle id deterministically from the given bundle secret key.
|
||||
* Then either fetch it from the database or initialise a new empty manifest
|
||||
*/
|
||||
int rhizome_get_bundle_from_secret(rhizome_manifest *m, const rhizome_bk_t *bsk)
|
||||
{
|
||||
uint8_t sk[crypto_sign_SECRETKEYBYTES];
|
||||
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, bsk->binary);
|
||||
switch (rhizome_retrieve_manifest(&bid, m)) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
rhizome_manifest_set_id(m, &bid); // zerofills m->cryptoSignSecret
|
||||
crypto_sign_seed_keypair(bid.binary, sk.binary, u.bsk.binary);
|
||||
|
||||
enum rhizome_bundle_status ret = rhizome_retrieve_manifest(&bid, m);
|
||||
switch(ret){
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
rhizome_manifest_set_id(m, &bid); // zerofills m->keypair.binary
|
||||
m->keypair = sk;
|
||||
m->haveSecret = NEW_BUNDLE_ID;
|
||||
break;
|
||||
rhizome_manifest_set_service(m, RHIZOME_SERVICE_FILE);
|
||||
rhizome_manifest_set_name(m, "");
|
||||
// always consider the content encrypted, we don't need to rely on the manifest itself.
|
||||
rhizome_manifest_set_crypt(m, PAYLOAD_ENCRYPTED);
|
||||
// setting the author would imply needing a BK, which we don't need since the private key is seeded above.
|
||||
return rhizome_fill_manifest(m, NULL);
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
m->haveSecret = EXISTING_BUNDLE_ID;
|
||||
break;
|
||||
m->keypair = sk;
|
||||
// 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)
|
||||
return rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_ERROR);
|
||||
// fallthrough
|
||||
default:
|
||||
return -1;
|
||||
return rhizome_bundle_result(ret);
|
||||
}
|
||||
bcopy(sk, m->cryptoSignSecret, sizeof m->cryptoSignSecret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Generate a bundle id deterministically from the given bundle secret key.
|
||||
* Then initialise a new empty manifest.
|
||||
*/
|
||||
@ -83,9 +97,9 @@ void rhizome_new_bundle_from_secret(rhizome_manifest *m, const rhizome_bk_t *bsk
|
||||
uint8_t sk[crypto_sign_SECRETKEYBYTES];
|
||||
rhizome_bid_t bid;
|
||||
crypto_sign_seed_keypair(bid.binary, sk, bsk->binary);
|
||||
rhizome_manifest_set_id(m, &bid); // zerofills m->cryptoSignSecret
|
||||
rhizome_manifest_set_id(m, &bid); // zerofills m->keypair.binary
|
||||
m->haveSecret = NEW_BUNDLE_ID;
|
||||
bcopy(sk, m->cryptoSignSecret, sizeof m->cryptoSignSecret);
|
||||
bcopy(sk, m->keypair.binary, sizeof m->keypair.binary);
|
||||
}
|
||||
|
||||
/* Given a Rhizome Secret (RS) and bundle ID (BID), XOR a bundle key 'bkin' (private or public) with
|
||||
@ -188,7 +202,7 @@ static keypair *get_secret(const keyring_identity *id)
|
||||
* If this identity has permission to alter the bundle, then set;
|
||||
* - the manifest 'authorship' field to AUTHOR_AUTHENTIC
|
||||
* - the 'author' field to the SID of the identity
|
||||
* - the manifest 'cryptoSignSecret' field to the bundle secret key
|
||||
* - the manifest 'sign_key.binary' field to the bundle secret key
|
||||
* - the 'haveSecret' field to EXISTING_BUNDLE_ID.
|
||||
* and finally update the database with the result.
|
||||
*/
|
||||
@ -207,10 +221,10 @@ static enum rhizome_bundle_authorship try_author(rhizome_manifest *m, const keyr
|
||||
if (!kp)
|
||||
return AUTHENTICATION_ERROR;
|
||||
uint8_t secret[crypto_sign_SECRETKEYBYTES];
|
||||
uint8_t *s = m->haveSecret ? secret : m->cryptoSignSecret;
|
||||
switch (rhizome_bk2secret(&m->cryptoSignPublic, kp->private_key, kp->private_key_len, m->bundle_key.binary, s)) {
|
||||
uint8_t *s = m->haveSecret ? secret : m->keypair.binary;
|
||||
switch (rhizome_bk2secret(&m->keypair.public_key, kp->private_key, kp->private_key_len, m->bundle_key.binary, s)) {
|
||||
case 0:
|
||||
if (m->haveSecret && memcmp(secret, m->cryptoSignSecret, sizeof m->cryptoSignSecret) != 0)
|
||||
if (m->haveSecret && memcmp(secret, m->keypair.binary, sizeof m->keypair.binary) != 0)
|
||||
FATALF("Bundle secret does not match derived secret");
|
||||
break;
|
||||
case -1:
|
||||
@ -219,11 +233,11 @@ static enum rhizome_bundle_authorship try_author(rhizome_manifest *m, const keyr
|
||||
return AUTHOR_IMPOSTOR;
|
||||
}
|
||||
}else{
|
||||
if (memcmp(&m->cryptoSignPublic, id->sign_pk, crypto_sign_PUBLICKEYBYTES)==0){
|
||||
bcopy(id->sign_sk, m->cryptoSignSecret, sizeof m->cryptoSignSecret);
|
||||
if (memcmp(&m->keypair.public_key, id->sign_pk, crypto_sign_PUBLICKEYBYTES)==0){
|
||||
bcopy(id->sign_sk, m->keypair.binary, sizeof m->keypair.binary);
|
||||
}else{
|
||||
DEBUGF(rhizome, " bundle has no BK field");
|
||||
// TODO if cryptoSignPublic == id signing key...
|
||||
// TODO if sign_key.public_key == id signing key...
|
||||
return ANONYMOUS;
|
||||
}
|
||||
}
|
||||
@ -263,7 +277,7 @@ static enum rhizome_bundle_authorship try_author(rhizome_manifest *m, const keyr
|
||||
void rhizome_authenticate_author(rhizome_manifest *m)
|
||||
{
|
||||
IN();
|
||||
DEBUGF(rhizome, "authenticate author for bid=%s", m->has_id ? alloca_tohex_rhizome_bid_t(m->cryptoSignPublic) : "(none)");
|
||||
DEBUGF(rhizome, "authenticate author for bid=%s", m->has_id ? alloca_tohex_rhizome_bid_t(m->keypair.public_key) : "(none)");
|
||||
switch (m->authorship) {
|
||||
case ANONYMOUS:
|
||||
|
||||
@ -321,7 +335,7 @@ int rhizome_manifest_add_bundle_key(rhizome_manifest *m)
|
||||
case AUTHOR_IMPOSTOR: {
|
||||
/* Set the BK using the provided author. Serval Security Framework defines BK as being:
|
||||
* BK = privateKey XOR sha512(RS##BID)
|
||||
* where BID = cryptoSignPublic,
|
||||
* where BID = sign_key.public_key,
|
||||
* RS is the rhizome secret for the specified author.
|
||||
* The nice thing about this specification is that:
|
||||
* privateKey = BK XOR sha512(RS##BID)
|
||||
@ -343,7 +357,7 @@ int rhizome_manifest_add_bundle_key(rhizome_manifest *m)
|
||||
}
|
||||
|
||||
rhizome_bk_t bkey;
|
||||
if (rhizome_secret2bk(&m->cryptoSignPublic, kp->private_key, kp->private_key_len, bkey.binary, m->cryptoSignSecret) != 0) {
|
||||
if (rhizome_secret2bk(&m->keypair.public_key, kp->private_key, kp->private_key_len, bkey.binary, m->keypair.binary) != 0) {
|
||||
m->authorship = AUTHENTICATION_ERROR;
|
||||
break;
|
||||
}
|
||||
@ -384,7 +398,7 @@ int rhizome_apply_bundle_secret(rhizome_manifest *m, const rhizome_bk_t *bsk)
|
||||
IN();
|
||||
DEBUGF(rhizome, "manifest %p bsk=%s", m, bsk ? alloca_tohex_rhizome_bk_t(*bsk) : "NULL");
|
||||
assert(m->haveSecret == SECRET_UNKNOWN);
|
||||
assert(is_all_matching(m->cryptoSignSecret, sizeof m->cryptoSignSecret, 0));
|
||||
assert(is_all_matching(m->keypair.private_key.binary, sizeof m->keypair.private_key.binary, 0));
|
||||
assert(m->has_id);
|
||||
assert(bsk != NULL);
|
||||
assert(!rhizome_is_bk_none(bsk));
|
||||
@ -394,9 +408,9 @@ int rhizome_apply_bundle_secret(rhizome_manifest *m, const rhizome_bk_t *bsk)
|
||||
uint8_t pk[crypto_sign_PUBLICKEYBYTES];
|
||||
crypto_sign_seed_keypair(pk, sk, bsk->binary);
|
||||
|
||||
if (bcmp(pk, m->cryptoSignPublic.binary, crypto_sign_PUBLICKEYBYTES) == 0){
|
||||
if (bcmp(pk, m->keypair.public_key.binary, crypto_sign_PUBLICKEYBYTES) == 0){
|
||||
DEBUG(rhizome, "bundle secret verifies ok");
|
||||
bcopy(sk, m->cryptoSignSecret, crypto_sign_SECRETKEYBYTES);
|
||||
bcopy(sk, m->keypair.binary, crypto_sign_SECRETKEYBYTES);
|
||||
m->haveSecret = EXISTING_BUNDLE_ID;
|
||||
RETURN(1);
|
||||
}
|
||||
@ -581,7 +595,7 @@ int rhizome_derive_payload_key(rhizome_manifest *m)
|
||||
}else{
|
||||
// derive other_pk from BID
|
||||
other_pk = &scratch;
|
||||
if (crypto_sign_ed25519_pk_to_curve25519(scratch.binary, m->cryptoSignPublic.binary))
|
||||
if (crypto_sign_ed25519_pk_to_curve25519(scratch.binary, m->keypair.public_key.binary))
|
||||
other_pk = NULL;
|
||||
}
|
||||
} else if (m->has_sender){
|
||||
@ -615,9 +629,9 @@ int rhizome_derive_payload_key(rhizome_manifest *m)
|
||||
WHY("Cannot derive payload key because bundle secret is unknown");
|
||||
return 0;
|
||||
}
|
||||
DEBUGF(rhizome, "derived payload key from bundle secret bsk=%s", alloca_tohex(m->cryptoSignSecret, sizeof m->cryptoSignSecret));
|
||||
DEBUGF(rhizome, "derived payload key from bundle secret bsk=%s", alloca_tohex(m->keypair.binary, sizeof m->keypair.binary));
|
||||
unsigned char raw_key[9+crypto_sign_SECRETKEYBYTES]="sasquatch";
|
||||
bcopy(m->cryptoSignSecret, &raw_key[9], crypto_sign_SECRETKEYBYTES);
|
||||
bcopy(m->keypair.binary, &raw_key[9], crypto_sign_SECRETKEYBYTES);
|
||||
crypto_hash_sha512(hash, raw_key, sizeof(raw_key));
|
||||
}
|
||||
bcopy(hash, m->payloadKey, RHIZOME_CRYPT_KEY_BYTES);
|
||||
@ -625,12 +639,12 @@ int rhizome_derive_payload_key(rhizome_manifest *m)
|
||||
|
||||
// journal bundles must always have the same nonce, regardless of version.
|
||||
// otherwise, generate nonce from version#bundle id#version;
|
||||
unsigned char raw_nonce[8 + 8 + sizeof m->cryptoSignPublic.binary];
|
||||
unsigned char raw_nonce[8 + 8 + sizeof m->keypair.public_key.binary];
|
||||
uint64_t nonce_version = m->is_journal ? 0 : m->version;
|
||||
write_uint64(&raw_nonce[0], nonce_version);
|
||||
bcopy(m->cryptoSignPublic.binary, &raw_nonce[8], sizeof m->cryptoSignPublic.binary);
|
||||
write_uint64(&raw_nonce[8 + sizeof m->cryptoSignPublic.binary], nonce_version);
|
||||
DEBUGF(rhizome, "derived payload nonce from bid=%s version=%"PRIu64, alloca_tohex_sid_t(m->cryptoSignPublic), nonce_version);
|
||||
bcopy(m->keypair.public_key.binary, &raw_nonce[8], sizeof m->keypair.public_key.binary);
|
||||
write_uint64(&raw_nonce[8 + sizeof m->keypair.public_key.binary], nonce_version);
|
||||
DEBUGF(rhizome, "derived payload nonce from bid=%s version=%"PRIu64, alloca_tohex_sid_t(m->keypair.public_key), nonce_version);
|
||||
crypto_hash_sha512(hash, raw_nonce, sizeof(raw_nonce));
|
||||
bcopy(hash, m->payloadNonce, sizeof(m->payloadNonce));
|
||||
DEBUGF(rhizome_manifest, "SET manifest %p payloadNonce = %s", m, alloca_tohex(m->payloadNonce, sizeof m->payloadNonce));
|
||||
|
@ -1368,7 +1368,7 @@ int rhizome_store_manifest(rhizome_manifest *m)
|
||||
") VALUES("
|
||||
"?,?,?,?,?,?,?,?,?,?,?,?,?,?"
|
||||
");",
|
||||
RHIZOME_BID_T, &m->cryptoSignPublic,
|
||||
RHIZOME_BID_T, &m->keypair.public_key,
|
||||
STATIC_BLOB, m->manifestdata, m->manifest_all_bytes,
|
||||
INT64, m->version,
|
||||
INT64, (int64_t) now,
|
||||
@ -1398,7 +1398,7 @@ int rhizome_store_manifest(rhizome_manifest *m)
|
||||
// This message used in tests; do not modify or remove.
|
||||
INFOF("RHIZOME ADD MANIFEST service=%s bid=%s version=%"PRIu64,
|
||||
m->service ? m->service : "NULL",
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key),
|
||||
m->version
|
||||
);
|
||||
if (serverMode)
|
||||
@ -1408,7 +1408,7 @@ int rhizome_store_manifest(rhizome_manifest *m)
|
||||
rollback:
|
||||
if (stmt)
|
||||
sqlite3_finalize(stmt);
|
||||
WHYF("Failed to store bundle bid=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
WHYF("Failed to store bundle bid=%s", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
sqlite_exec_void_retry(&retry, "ROLLBACK;", END);
|
||||
return -1;
|
||||
}
|
||||
@ -1417,7 +1417,7 @@ static void trigger_rhizome_bundle_added_debug(rhizome_manifest *m)
|
||||
{
|
||||
DEBUGF(rhizome, "TRIGGER rhizome_bundle_added service=%s bid=%s version=%"PRIu64,
|
||||
m->service ? m->service : "NULL",
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key),
|
||||
m->version
|
||||
);
|
||||
}
|
||||
@ -1941,5 +1941,5 @@ int rhizome_is_bar_interesting(const rhizome_bar_t *bar)
|
||||
|
||||
int rhizome_is_manifest_interesting(rhizome_manifest *m)
|
||||
{
|
||||
return is_interesting(alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
|
||||
return is_interesting(alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version);
|
||||
}
|
||||
|
@ -641,7 +641,7 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
|
||||
}
|
||||
|
||||
/* Get filehash and size from manifest if present */
|
||||
DEBUGF(rhizome_tx, "bundle id = %s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
DEBUGF(rhizome_tx, "bundle id = %s", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
DEBUGF(rhizome_tx, "bundle filehash = %s", alloca_tohex_rhizome_filehash_t(m->filehash));
|
||||
DEBUGF(rhizome_tx, "file size = %"PRId64, m->filesize);
|
||||
DEBUGF(rhizome_tx, "version = %"PRIu64, m->version);
|
||||
@ -700,7 +700,7 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
|
||||
/* send file contents */
|
||||
{
|
||||
rhizome_filehash_t filehash;
|
||||
if (rhizome_database_filehash_from_id(&m->cryptoSignPublic, m->version, &filehash) == -1)
|
||||
if (rhizome_database_filehash_from_id(&m->keypair.public_key, m->version, &filehash) == -1)
|
||||
goto closeit;
|
||||
|
||||
struct rhizome_read read;
|
||||
|
@ -262,7 +262,7 @@ static struct rhizome_fetch_slot *fetch_search_slot(const unsigned char *id, int
|
||||
struct rhizome_fetch_queue *q = &rhizome_fetch_queues[i];
|
||||
|
||||
if (q->active.state != RHIZOME_FETCH_FREE &&
|
||||
memcmp(id, q->active.manifest->cryptoSignPublic.binary, prefix_length) == 0)
|
||||
memcmp(id, q->active.manifest->keypair.public_key.binary, prefix_length) == 0)
|
||||
return &q->active;
|
||||
}
|
||||
return NULL;
|
||||
@ -279,7 +279,7 @@ static struct rhizome_fetch_candidate *fetch_search_candidate(const unsigned cha
|
||||
struct rhizome_fetch_candidate *c = &q->candidate_queue[j];
|
||||
if (!c->manifest)
|
||||
continue;
|
||||
if (memcmp(c->manifest->cryptoSignPublic.binary, id, prefix_length))
|
||||
if (memcmp(c->manifest->keypair.public_key.binary, id, prefix_length))
|
||||
continue;
|
||||
return c;
|
||||
}
|
||||
@ -500,7 +500,7 @@ schedule_fetch(struct rhizome_fetch_slot *slot)
|
||||
slot->write_state.blob_rowid = 0;
|
||||
|
||||
if (slot->manifest) {
|
||||
slot->bid = slot->manifest->cryptoSignPublic;
|
||||
slot->bid = slot->manifest->keypair.public_key;
|
||||
slot->prefix_length = sizeof slot->bid.binary;
|
||||
slot->bidVersion = slot->manifest->version;
|
||||
|
||||
@ -511,7 +511,7 @@ schedule_fetch(struct rhizome_fetch_slot *slot)
|
||||
// if we're fetching a journal bundle, work out how many bytes we have of a previous version
|
||||
// and therefore what range of bytes we should ask for
|
||||
slot->previous = rhizome_new_manifest();
|
||||
if (rhizome_retrieve_manifest(&slot->manifest->cryptoSignPublic, slot->previous)!=RHIZOME_BUNDLE_STATUS_SAME){
|
||||
if (rhizome_retrieve_manifest(&slot->manifest->keypair.public_key, slot->previous)!=RHIZOME_BUNDLE_STATUS_SAME){
|
||||
rhizome_manifest_free(slot->previous);
|
||||
slot->previous=NULL;
|
||||
// check that the new journal is valid and has some overlapping bytes
|
||||
@ -682,7 +682,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m,
|
||||
|
||||
DEBUGF(rhizome_rx, "Fetching bundle slot=%d bid=%s version=%"PRIu64" size=%"PRIu64" addr=%s",
|
||||
slotno(slot),
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key),
|
||||
m->version,
|
||||
m->filesize,
|
||||
alloca_socket_address(addr)
|
||||
@ -702,7 +702,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m,
|
||||
* being published faster than we can fetch them.
|
||||
*/
|
||||
{
|
||||
struct rhizome_fetch_slot *as = fetch_search_slot(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary);
|
||||
struct rhizome_fetch_slot *as = fetch_search_slot(m->keypair.public_key.binary, sizeof m->keypair.public_key.binary);
|
||||
if (as){
|
||||
const rhizome_manifest *am = as->manifest;
|
||||
if (am->version < m->version) {
|
||||
@ -875,7 +875,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
|
||||
}
|
||||
|
||||
DEBUGF(rhizome_rx, "Considering import bid=%s version=%"PRIu64" size=%"PRIu64,
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version, m->filesize);
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version, m->filesize);
|
||||
|
||||
if (!rhizome_is_manifest_interesting(m)) {
|
||||
DEBUG(rhizome_rx, " already stored that version or newer");
|
||||
@ -889,7 +889,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
|
||||
if (!m->selfSigned && !rhizome_manifest_verify(m)) {
|
||||
WHY("Error verifying manifest when considering queuing for import");
|
||||
/* Don't waste time looking at this manifest again for a while */
|
||||
rhizome_queue_ignore_manifest(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, 60000);
|
||||
rhizome_queue_ignore_manifest(m->keypair.public_key.binary, sizeof m->keypair.public_key.binary, 60000);
|
||||
rhizome_manifest_free(m);
|
||||
RETURN(-1);
|
||||
}
|
||||
@ -924,7 +924,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmp_rhizome_bid_t(&m->cryptoSignPublic, &c->manifest->cryptoSignPublic) == 0) {
|
||||
if (cmp_rhizome_bid_t(&m->keypair.public_key, &c->manifest->keypair.public_key) == 0) {
|
||||
if (c->manifest->version >= m->version) {
|
||||
rhizome_manifest_free(m);
|
||||
RETURN(0);
|
||||
@ -1266,7 +1266,7 @@ static int rhizome_write_complete(struct rhizome_fetch_slot *slot)
|
||||
rhizome_manifest_free(m);
|
||||
} else {
|
||||
DEBUGF(rhizome_rx, "All looks good for importing manifest id=%s, addr=%s, sid=%s",
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key),
|
||||
alloca_socket_address(&slot->addr),
|
||||
slot->peer?alloca_tohex_sid_t(slot->peer->sid):"unknown"
|
||||
);
|
||||
|
@ -82,7 +82,7 @@ int rhizome_manifest_to_bar(rhizome_manifest *m, rhizome_bar_t *bar)
|
||||
/* Manifest prefix */
|
||||
unsigned i;
|
||||
for(i=0;i<RHIZOME_BAR_PREFIX_BYTES;i++)
|
||||
bar->binary[RHIZOME_BAR_PREFIX_OFFSET+i]=m->cryptoSignPublic.binary[i];
|
||||
bar->binary[RHIZOME_BAR_PREFIX_OFFSET+i]=m->keypair.public_key.binary[i];
|
||||
/* file length */
|
||||
assert(m->filesize != RHIZOME_SIZE_UNSET);
|
||||
bar->binary[RHIZOME_BAR_FILESIZE_OFFSET]=log2ll(m->filesize);
|
||||
@ -164,7 +164,7 @@ int rhizome_advertise_manifest(struct subscriber *dest, rhizome_manifest *m){
|
||||
if (overlay_payload_enqueue(frame) == -1)
|
||||
goto error;
|
||||
DEBUGF(rhizome_ads, "Advertising manifest %s %"PRIu64" to %s",
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version, dest?alloca_tohex_sid_t(dest->sid):"broadcast");
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version, dest?alloca_tohex_sid_t(dest->sid):"broadcast");
|
||||
return 0;
|
||||
error:
|
||||
op_free(frame);
|
||||
@ -255,12 +255,12 @@ int overlay_rhizome_saw_advertisements(struct decode_context *context, struct ov
|
||||
) {
|
||||
WARN("Malformed manifest");
|
||||
// Don't attend to this manifest for at least a minute
|
||||
rhizome_queue_ignore_manifest(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, 60000);
|
||||
rhizome_queue_ignore_manifest(m->keypair.public_key.binary, sizeof m->keypair.public_key.binary, 60000);
|
||||
goto next;
|
||||
}
|
||||
assert(m->has_id);
|
||||
assert(m->version != 0);
|
||||
assert(cmp_rhizome_bid_t(&m->cryptoSignPublic, &summ.bid) == 0);
|
||||
assert(cmp_rhizome_bid_t(&m->keypair.public_key, &summ.bid) == 0);
|
||||
assert(m->version == summ.version);
|
||||
assert(m->manifest_body_bytes == summ.body_len);
|
||||
|
||||
|
@ -300,7 +300,7 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct http_request *hr
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_json_string(b, m->service);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_json_hex(b, m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary);
|
||||
strbuf_json_hex(b, m->keypair.public_key.binary, sizeof m->keypair.public_key.binary);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_sprintf(b, "%"PRIu64, m->version);
|
||||
strbuf_putc(b, ',');
|
||||
@ -1006,7 +1006,7 @@ static void render_manifest_headers(struct http_request *hr, strbuf sb)
|
||||
rhizome_manifest *m = r->manifest;
|
||||
if (m) {
|
||||
if (m->has_id)
|
||||
strbuf_sprintf(sb, "Serval-Rhizome-Bundle-Id: %s\r\n", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
strbuf_sprintf(sb, "Serval-Rhizome-Bundle-Id: %s\r\n", alloca_tohex_rhizome_bid_t(m->keypair.public_key));
|
||||
if (m->version)
|
||||
strbuf_sprintf(sb, "Serval-Rhizome-Bundle-Version: %"PRIu64"\r\n", m->version);
|
||||
if (m->filesize != RHIZOME_SIZE_UNSET)
|
||||
@ -1045,7 +1045,7 @@ static void render_manifest_headers(struct http_request *hr, strbuf sb)
|
||||
strbuf_sprintf(sb, "Serval-Rhizome-Bundle-Author: %s\r\n", alloca_tohex_sid_t(m->author));
|
||||
if (m->haveSecret) {
|
||||
char secret[RHIZOME_BUNDLE_KEY_STRLEN + 1];
|
||||
rhizome_bytes_to_hex_upper(m->cryptoSignSecret, secret, RHIZOME_BUNDLE_KEY_BYTES);
|
||||
rhizome_bytes_to_hex_upper(m->keypair.binary, secret, RHIZOME_BUNDLE_KEY_BYTES);
|
||||
strbuf_sprintf(sb, "Serval-Rhizome-Bundle-Secret: %s\r\n", secret);
|
||||
}
|
||||
if (m->rowid)
|
||||
|
@ -977,7 +977,7 @@ static enum rhizome_payload_status rhizome_write_derive_key(rhizome_manifest *m,
|
||||
return RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL;
|
||||
|
||||
DEBUGF(rhizome_store, "Encrypting payload contents for bid=%s, version=%"PRIu64,
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
|
||||
alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version);
|
||||
|
||||
write->crypt=1;
|
||||
if (m->is_journal && m->tail > 0)
|
||||
@ -1477,7 +1477,7 @@ static enum rhizome_payload_status read_derive_key(rhizome_manifest *m, struct r
|
||||
WHY("Unable to decrypt bundle, valid key not found");
|
||||
return RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
DEBUGF(rhizome_store, "Decrypting payload contents for bid=%s version=%"PRIu64, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
|
||||
DEBUGF(rhizome_store, "Decrypting payload contents for bid=%s version=%"PRIu64, alloca_tohex_rhizome_bid_t(m->keypair.public_key), m->version);
|
||||
if (m->is_journal && m->tail > 0)
|
||||
read_state->tail = m->tail;
|
||||
bcopy(m->payloadKey, read_state->key, sizeof(read_state->key));
|
||||
|
@ -676,7 +676,7 @@ static void process_transfer_message(struct subscriber *peer, struct rhizome_syn
|
||||
// if we're fetching a journal bundle, copy any bytes we have of a previous version
|
||||
// and therefore work out what range of bytes we still need
|
||||
rhizome_manifest *previous = rhizome_new_manifest();
|
||||
if (rhizome_retrieve_manifest(&m->cryptoSignPublic, previous)==RHIZOME_BUNDLE_STATUS_SAME &&
|
||||
if (rhizome_retrieve_manifest(&m->keypair.public_key, previous)==RHIZOME_BUNDLE_STATUS_SAME &&
|
||||
previous->is_journal &&
|
||||
previous->tail <= m->tail &&
|
||||
previous->filesize + previous->tail > m->tail
|
||||
|
@ -60,9 +60,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
|
||||
typedef struct rhizome_bid_binary {
|
||||
unsigned char binary[RHIZOME_MANIFEST_ID_BYTES];
|
||||
} rhizome_bid_t;
|
||||
typedef struct sign_binary rhizome_bid_t;
|
||||
|
||||
#define RHIZOME_BID_ZERO ((rhizome_bid_t){{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}})
|
||||
#define RHIZOME_BID_MAX ((rhizome_bid_t){{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}})
|
||||
|
@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <sodium.h>
|
||||
|
||||
/* Conveniences to assist readability
|
||||
*/
|
||||
@ -32,19 +33,38 @@ typedef char bool_t;
|
||||
/* Serval ID (aka Subscriber ID)
|
||||
*/
|
||||
|
||||
#define SID_SIZE 32 // == crypto_box_PUBLICKEYBYTES
|
||||
#define IDENTITY_SIZE 32 // == crypto_sign_PUBLICKEYBYTES
|
||||
#define SID_SIZE crypto_box_PUBLICKEYBYTES
|
||||
#define IDENTITY_SIZE crypto_sign_PUBLICKEYBYTES
|
||||
|
||||
#define SID_STRLEN (SID_SIZE*2)
|
||||
#define IDENTITY_STRLEN (IDENTITY_SIZE*2)
|
||||
|
||||
typedef struct sid_binary {
|
||||
unsigned char binary[SID_SIZE];
|
||||
uint8_t binary[SID_SIZE];
|
||||
} sid_t;
|
||||
|
||||
typedef struct identity_binary {
|
||||
unsigned char binary[IDENTITY_SIZE];
|
||||
} identity_t;
|
||||
// lib sodium crypto_sign key types;
|
||||
typedef struct sign_binary {
|
||||
uint8_t binary[IDENTITY_SIZE];
|
||||
} sign_public_t;
|
||||
|
||||
typedef struct sign_private_binary{
|
||||
uint8_t binary[crypto_sign_SEEDBYTES];
|
||||
}sign_private_t;
|
||||
|
||||
typedef struct sign_keypair_binary{
|
||||
union{
|
||||
struct{
|
||||
sign_private_t private_key;
|
||||
sign_public_t public_key;
|
||||
};
|
||||
uint8_t binary[crypto_sign_SECRETKEYBYTES];
|
||||
};
|
||||
}sign_keypair_t;
|
||||
|
||||
|
||||
typedef struct sign_binary identity_t;
|
||||
|
||||
|
||||
#define SID_TYPE_ANY (0)
|
||||
#define SID_TYPE_INTERNAL (1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user