Refactor keyring identity iteration

This commit is contained in:
Jeremy Lakeman 2014-10-31 13:43:23 +10:30
parent 7e403af715
commit 851144ea0a
14 changed files with 580 additions and 541 deletions

View File

@ -78,13 +78,13 @@ static void directory_send(struct subscriber *directory_service, struct subscrib
// send a registration packet for each unlocked identity
static void directory_send_keyring(struct subscriber *directory_service){
unsigned cn=0, in=0, kp=0;
for (; keyring_next_keytype(keyring, &cn, &in, &kp, KEYTYPE_DID); ++kp){
keyring_identity *i = keyring->contexts[cn]->identities[in];
if (i->subscriber && i->subscriber->reachable == REACHABLE_SELF){
const char *unpackedDid = (const char *) i->keypairs[kp]->private_key;
const char *name = (const char *) i->keypairs[kp]->public_key;
directory_send(directory_service, i->subscriber, unpackedDid, name);
keyring_iterator it;
keyring_iterator_start(keyring, &it);
while(keyring_next_keytype(&it, KEYTYPE_DID)){
if (it.identity->subscriber && it.identity->subscriber->reachable == REACHABLE_SELF){
const char *unpackedDid = (const char *) it.keypair->private_key;
const char *name = (const char *) it.keypair->public_key;
directory_send(directory_service, it.identity->subscriber, unpackedDid, name);
}
}
}

View File

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define __SERVAL_DNA__HTTPD_H
#include "rhizome.h"
#include "keyring.h"
#include "meshms.h"
#include "http_server.h"
@ -32,7 +33,7 @@ int is_httpd_server_running();
extern uint16_t httpd_server_port;
extern unsigned int httpd_request_count;
enum list_phase { LIST_HEADER = 0, LIST_ROWS, LIST_END, LIST_DONE };
enum list_phase { LIST_HEADER = 0, LIST_FIRST, LIST_ROWS, LIST_END, LIST_DONE };
struct form_buf_malloc {
char *buffer;
@ -138,8 +139,7 @@ typedef struct httpd_request
*/
struct {
enum list_phase phase;
unsigned cn;
unsigned in;
keyring_iterator it;
}
sidlist;

759
keyring.c

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __SERVAL_DNA__KEYRING_H
#define __SERVAL_DNA__KEYRING_H
struct cli_parsed;
#include "xprintf.h"
typedef struct keypair {
unsigned type;
unsigned char *private_key;
@ -28,12 +31,12 @@ typedef struct keypair {
unsigned char *public_key;
size_t public_key_len;
uint8_t verified;
struct keypair *next;
} keypair;
/* Contains just the list of private:public key pairs and types,
the pin used to extract them, and the slot in the keyring file
(so that it can be replaced/rewritten as required). */
#define PKR_MAX_KEYPAIRS 64
#define PKR_SALT_BYTES 32
#define PKR_MAC_BYTES 64
typedef struct keyring_identity {
@ -42,21 +45,16 @@ typedef struct keyring_identity {
time_ms_t challenge_expires;
unsigned char challenge[24];
unsigned int slot;
unsigned int keypair_count;
keypair *keypairs[PKR_MAX_KEYPAIRS];
struct keyring_identity *next;
keypair *keypairs;
} keyring_identity;
/* 64K identities, can easily be increased should the need arise,
but keep it low-ish for now so that the 64K pointers don't eat too
much ram on a small device. Should probably think about having
small and large device settings for some of these things */
#define KEYRING_MAX_IDENTITIES 65536
typedef struct keyring_context {
char *KeyRingPin;
unsigned char *KeyRingSalt;
int KeyRingSaltLen;
unsigned int identity_count;
keyring_identity *identities[KEYRING_MAX_IDENTITIES];
struct keyring_context *next;
keyring_identity *identities;
} keyring_context;
#define KEYRING_PAGE_SIZE 4096LL
@ -69,17 +67,32 @@ typedef struct keyring_bam {
struct keyring_bam *next;
} keyring_bam;
#define KEYRING_MAX_CONTEXTS 256
typedef struct keyring_file {
unsigned context_count;
keyring_bam *bam;
keyring_context *contexts[KEYRING_MAX_CONTEXTS];
keyring_context *contexts;
FILE *file;
off_t file_size;
} keyring_file;
typedef struct keyring_iterator{
keyring_file *file;
keyring_context *context;
keyring_identity *identity;
keypair *keypair;
} keyring_iterator;
void keyring_iterator_start(keyring_file *k, keyring_iterator *it);
keyring_context * keyring_next_context(keyring_iterator *it);
keyring_identity * keyring_next_identity(keyring_iterator *it);
keypair * keyring_next_key(keyring_iterator *it);
keypair * keyring_next_keytype(keyring_iterator *it, unsigned keytype);
keypair *keyring_identity_keytype(keyring_identity *id, unsigned keytype);
keypair *keyring_find_did(keyring_iterator *it, const char *did);
keypair *keyring_find_sid(keyring_iterator *it, const sid_t *sidp);
void keyring_free(keyring_file *k);
void keyring_release_identity(keyring_file *k, unsigned cn, unsigned id);
int keyring_release_identity(keyring_iterator *it);
#define KEYTYPE_CRYPTOBOX 0x01 // must be lowest
#define KEYTYPE_CRYPTOSIGN 0x02
#define KEYTYPE_RHIZOME 0x03
@ -99,12 +112,6 @@ keyring_file *keyring_open_instance();
keyring_file *keyring_open_instance_cli(const struct cli_parsed *parsed);
int keyring_enter_pin(keyring_file *k, const char *pin);
int keyring_set_did(keyring_identity *id, const char *did, const char *name);
int keyring_sanitise_position(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp);
int keyring_next_keytype(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp, unsigned keytype);
int keyring_next_identity(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp);
int keyring_identity_find_keytype(const keyring_file *k, unsigned cn, unsigned in, unsigned keytype);
int keyring_find_did(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp, const char *did);
int keyring_find_sid(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp, const sid_t *sidp);
struct keypair *keyring_find_sas_private(keyring_file *k, keyring_identity *identity);
int keyring_send_sas_request(struct subscriber *subscriber);
@ -119,11 +126,11 @@ unsigned char *keyring_get_nm_bytes(const sid_t *known_sidp, const sid_t *unknow
int keyring_mapping_request(struct internal_mdp_header *header, struct overlay_buffer *payload);
int keyring_send_unlock(struct subscriber *subscriber);
void keyring_release_subscriber(keyring_file *k, const sid_t *sid);
int keyring_release_subscriber(keyring_file *k, const sid_t *sid);
int keyring_set_public_tag(keyring_identity *id, const char *name, const unsigned char *value, size_t length);
int keyring_find_public_tag(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp, const char *name, const unsigned char **value, size_t *length);
int keyring_find_public_tag_value(const keyring_file *k, unsigned *cn, unsigned *in, unsigned *kp, const char *name, const unsigned char *value, size_t length);
keypair * keyring_find_public_tag(keyring_iterator *it, const char *name, const unsigned char **value, size_t *length);
keypair * keyring_find_public_tag_value(keyring_iterator *it, const char *name, const unsigned char *value, size_t length);
int keyring_unpack_tag(const unsigned char *packed, size_t packed_len, const char **name, const unsigned char **value, size_t *length);
int keyring_pack_tag(unsigned char *packed, size_t *packed_len, const char *name, const unsigned char *value, size_t length);

View File

@ -136,20 +136,21 @@ static int app_keyring_list(const struct cli_parsed *parsed, struct cli_context
cli_columns(context, 3, names);
size_t rowcount = 0;
unsigned cn, in;
for (cn = 0; cn < k->context_count; ++cn)
for (in = 0; in < k->contexts[cn]->identity_count; ++in) {
const sid_t *sidp = NULL;
const char *did = NULL;
const char *name = NULL;
keyring_identity_extract(k->contexts[cn]->identities[in], &sidp, &did, &name);
if (sidp || did) {
cli_put_string(context, alloca_tohex_sid_t(*sidp), ":");
cli_put_string(context, did, ":");
cli_put_string(context, name, "\n");
rowcount++;
}
keyring_iterator it;
keyring_iterator_start(k, &it);
const keyring_identity *id;
while((id = keyring_next_identity(&it))){
const sid_t *sidp = NULL;
const char *did = NULL;
const char *name = NULL;
keyring_identity_extract(id, &sidp, &did, &name);
if (sidp || did) {
cli_put_string(context, alloca_tohex_sid_t(*sidp), ":");
cli_put_string(context, did, ":");
cli_put_string(context, name, "\n");
rowcount++;
}
}
keyring_free(k);
cli_row_count(context, rowcount);
return 0;
@ -157,9 +158,8 @@ static int app_keyring_list(const struct cli_parsed *parsed, struct cli_context
static void cli_output_identity(struct cli_context *context, const keyring_identity *id)
{
unsigned i;
for (i=0;i<id->keypair_count;i++){
keypair *kp=id->keypairs[i];
keypair *kp=id->keypairs;
while(kp){
switch(kp->type){
case KEYTYPE_CRYPTOBOX:
cli_field_name(context, "sid", ":");
@ -193,6 +193,7 @@ static void cli_output_identity(struct cli_context *context, const keyring_ident
}
break;
}
kp=kp->next;
}
}
@ -203,28 +204,29 @@ static int app_keyring_list2(const struct cli_parsed *parsed, struct cli_context
keyring_file *k = keyring_open_instance_cli(parsed);
if (!k)
return -1;
unsigned cn, in;
for (cn = 0; cn < k->context_count; ++cn)
for (in = 0; in < k->contexts[cn]->identity_count; ++in){
const keyring_identity *id=k->contexts[cn]->identities[in];
unsigned i;
unsigned fields=0;
// count the number of fields that we will output
for (i=0;i<id->keypair_count;i++){
keypair *kp=id->keypairs[i];
if (kp->type==KEYTYPE_CRYPTOBOX || kp->type==KEYTYPE_PUBLIC_TAG)
keyring_iterator it;
keyring_iterator_start(k, &it);
const keyring_identity *id;
while((id = keyring_next_identity(&it))){
unsigned fields=0;
// count the number of fields that we will output
keypair *kp=it.identity->keypairs;
while(kp){
if (kp->type==KEYTYPE_CRYPTOBOX || kp->type==KEYTYPE_PUBLIC_TAG)
fields++;
if (kp->type==KEYTYPE_DID){
if (strlen((char*)kp->private_key))
fields++;
if (strlen((char*)kp->public_key))
fields++;
if (kp->type==KEYTYPE_DID){
if (strlen((char*)kp->private_key))
fields++;
if (strlen((char*)kp->public_key))
fields++;
}
}
cli_field_name(context, "fields", ":");
cli_put_long(context, fields, "\n");
cli_output_identity(context, id);
kp=kp->next;
}
cli_field_name(context, "fields", ":");
cli_put_long(context, fields, "\n");
cli_output_identity(context, id);
}
keyring_free(k);
return 0;
}
@ -242,8 +244,9 @@ static int app_keyring_add(const struct cli_parsed *parsed, struct cli_context *
if (!k)
return -1;
keyring_enter_pin(k, pin);
assert(k->context_count > 0);
const keyring_identity *id = keyring_create_identity(k, k->contexts[k->context_count - 1], pin);
assert(k->contexts);
const keyring_identity *id = keyring_create_identity(k, k->contexts, pin);
if (id == NULL) {
keyring_free(k);
return WHY("Could not create new identity");
@ -292,18 +295,20 @@ static int app_keyring_set_did(const struct cli_parsed *parsed, struct cli_conte
if (!(keyring = keyring_open_instance_cli(parsed)))
return -1;
unsigned cn=0, in=0, kp=0;
keyring_iterator it;
keyring_iterator_start(keyring, &it);
int r=0;
if (!keyring_find_sid(keyring, &cn, &in, &kp, &sid))
if (!keyring_find_sid(&it, &sid))
r=WHY("No matching SID");
else{
if (keyring_set_did(keyring->contexts[cn]->identities[in], did, name))
if (keyring_set_did(it.identity, did, name))
r=WHY("Could not set DID");
else{
if (keyring_commit(keyring))
r=WHY("Could not write updated keyring record");
else{
cli_output_identity(context, keyring->contexts[cn]->identities[in]);
cli_output_identity(context, it.identity);
}
}
}
@ -331,19 +336,20 @@ static int app_keyring_set_tag(const struct cli_parsed *parsed, struct cli_conte
if (str_to_sid_t(&sid, sidhex) == -1)
return WHY("str_to_sid_t() failed");
unsigned cn=0, in=0, kp=0;
keyring_iterator it;
keyring_iterator_start(keyring, &it);
int r=0;
if (!keyring_find_sid(keyring, &cn, &in, &kp, &sid))
if (!keyring_find_sid(&it, &sid))
r=WHY("No matching SID");
else{
int length = strlen(value);
if (keyring_set_public_tag(keyring->contexts[cn]->identities[in], tag, (const unsigned char*)value, length))
if (keyring_set_public_tag(it.identity, tag, (const unsigned char*)value, length))
r=WHY("Could not set tag value");
else{
if (keyring_commit(keyring))
r=WHY("Could not write updated keyring record");
else{
cli_output_identity(context, keyring->contexts[cn]->identities[in]);
cli_output_identity(context, it.identity);
}
}
}

View File

@ -70,8 +70,7 @@ static int restful_keyring_identitylist_json(httpd_request *r, const char *remai
return 404;
r->u.sidlist.phase = LIST_HEADER;
r->u.sidlist.cn = 0;
r->u.sidlist.in = 0;
keyring_iterator_start(keyring, &r->u.sidlist.it);
http_request_response_generated(&r->http, 200, CONTENT_TYPE_JSON, restful_keyring_identitylist_json_content);
return 1;
@ -105,23 +104,21 @@ static int restful_keyring_identitylist_json_content_chunk(struct http_request *
strbuf_json_string(b, headers[i]);
}
strbuf_puts(b, "],\n\"rows\":[");
if (!strbuf_overrun(b))
r->u.sidlist.phase = LIST_ROWS;
if (!strbuf_overrun(b)){
r->u.sidlist.phase = LIST_FIRST;
if (!keyring_next_identity(&r->u.sidlist.it))
r->u.sidlist.phase = LIST_END;
}
return 1;
case LIST_ROWS:
if (r->u.sidlist.cn != 0 || r->u.sidlist.in != 0)
strbuf_putc(b, ',');
if (keyring->context_count == 0 || keyring->contexts[r->u.sidlist.cn]->identity_count == 0) {
r->u.sidlist.phase = LIST_END;
return 1;
}
strbuf_putc(b, ',');
case LIST_FIRST:
r->u.sidlist.phase = LIST_ROWS;
const sid_t *sidp = NULL;
const char *did = NULL;
const char *name = NULL;
keyring_identity_extract(keyring->contexts[r->u.sidlist.cn]->identities[r->u.sidlist.in], &sidp, &did, &name);
keyring_identity_extract(r->u.sidlist.it.identity, &sidp, &did, &name);
if (sidp || did) {
strbuf_puts(b, "\n[");
strbuf_json_string(b, alloca_tohex_sid_t(*sidp));
@ -133,15 +130,8 @@ static int restful_keyring_identitylist_json_content_chunk(struct http_request *
}
if (!strbuf_overrun(b)) {
++r->u.sidlist.in;
if (r->u.sidlist.in >= keyring->contexts[r->u.sidlist.cn]->identity_count) {
r->u.sidlist.in = 0;
++r->u.sidlist.cn;
if (r->u.sidlist.cn >= keyring->context_count) {
r->u.sidlist.phase = LIST_END;
}
}
if (!keyring_next_identity(&r->u.sidlist.it))
r->u.sidlist.phase = LIST_END;
}
return 1;

View File

@ -48,15 +48,16 @@ void meshms_free_conversations(struct meshms_conversations *conv)
static enum meshms_status get_my_conversation_bundle(const sid_t *my_sidp, rhizome_manifest *m)
{
/* Find our private key */
unsigned cn=0, in=0, kp=0;
if (!keyring_find_sid(keyring,&cn,&in,&kp,my_sidp))
keyring_iterator it;
keyring_iterator_start(keyring, &it);
if (!keyring_find_sid(&it, my_sidp))
return MESHMS_STATUS_SID_LOCKED;
char seed[1024];
snprintf(seed, sizeof(seed),
"incorrection%sconcentrativeness",
alloca_tohex(keyring->contexts[cn]->identities[in]
->keypairs[kp]->private_key, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES));
alloca_tohex(it.keypair->private_key, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES));
if (rhizome_get_bundle_from_seed(m, seed) == -1)
return MESHMS_STATUS_ERROR;

View File

@ -239,15 +239,19 @@ static int restful_meshms_conversationlist_json_content_chunk(struct http_reques
}
strbuf_puts(b, "],\n\"rows\":[");
if (!strbuf_overrun(b))
r->u.mclist.phase = LIST_ROWS;
r->u.mclist.phase = LIST_FIRST;
return 1;
case LIST_ROWS:
case LIST_FIRST:
if (r->u.mclist.conv == NULL || r->u.mclist.iter.current == NULL) {
r->u.mclist.phase = LIST_END;
// fall through...
} else {
if (r->u.mclist.rowcount != 0)
if (r->u.mclist.phase==LIST_ROWS)
strbuf_putc(b, ',');
else
r->u.mclist.phase=LIST_ROWS;
strbuf_puts(b, "\n[");
strbuf_sprintf(b, "%zu", r->u.mclist.rowcount);
strbuf_putc(b, ',');
@ -388,6 +392,7 @@ static int restful_meshms_messagelist_json_content_chunk(struct http_request *hr
if (!strbuf_overrun(b))
r->u.msglist.phase = LIST_ROWS;
return 1;
case LIST_FIRST:
case LIST_ROWS:
{
if ( r->u.msglist.finished

View File

@ -1241,15 +1241,14 @@ static int mdp_process_identity_request(struct socket_address *client, struct md
const char *pin = ob_get_str_ptr(payload);
if (!pin)
break;
unsigned cn;
for (cn = keyring->context_count; cn > 0;) {
keyring_context *cx = keyring->contexts[--cn];
unsigned in;
for (in = cx->identity_count; in > 0;) {
keyring_identity *id = cx->identities[--in];
if (id->subscriber != my_subscriber && strcmp(id->PKRPin, pin) == 0)
keyring_release_identity(keyring, cn, in);
}
keyring_iterator it;
keyring_iterator_start(keyring, &it);
keyring_next_identity(&it);
while(it.identity){
if (it.identity->subscriber != my_subscriber && strcmp(it.identity->PKRPin, pin) == 0)
keyring_release_identity(&it);
else
keyring_next_identity(&it);
}
}
}
@ -1296,7 +1295,9 @@ static int mdp_process_identity_request(struct socket_address *client, struct md
static int mdp_search_identities(struct socket_address *client, struct mdp_header *header,
struct overlay_buffer *payload)
{
unsigned cn=0, in=0, kp=0;
keyring_iterator it;
keyring_iterator_start(keyring, &it);
const char *tag=NULL;
const unsigned char *value=NULL;
size_t value_len=0;
@ -1313,30 +1314,28 @@ static int mdp_search_identities(struct socket_address *client, struct mdp_heade
if (value_len){
if (config.debug.mdprequests)
DEBUGF("Looking for next %s tag & value", tag);
if (!keyring_find_public_tag_value(keyring, &cn, &in, &kp, tag, value, value_len))
if (!keyring_find_public_tag_value(&it, tag, value, value_len))
break;
}else if(tag){
if (config.debug.mdprequests)
DEBUGF("Looking for next %s tag", tag);
if (!keyring_find_public_tag(keyring, &cn, &in, &kp, tag, NULL, NULL))
if (!keyring_find_public_tag(&it, tag, NULL, NULL))
break;
}else{
if (config.debug.mdprequests)
DEBUGF("Looking for next identity");
if (!keyring_next_identity(keyring, &cn, &in, &kp))
if (!keyring_next_identity(&it))
break;
}
keyring_identity *id = keyring->contexts[cn]->identities[in];
unsigned char reply_payload[1200];
size_t ofs=0;
bcopy(id->subscriber->sid.binary, &reply_payload[ofs], sizeof(id->subscriber->sid));
ofs+=sizeof(id->subscriber->sid);
bcopy(it.identity->subscriber->sid.binary, &reply_payload[ofs], sizeof(it.identity->subscriber->sid));
ofs+=sizeof(it.identity->subscriber->sid);
// TODO return other details of this identity
mdp_reply2(client, header, 0, reply_payload, ofs);
kp++;
}
mdp_reply_ok(client, header);
return 0;

View File

@ -174,7 +174,8 @@ int overlay_mdp_service_rhizomeresponse(struct internal_mdp_header *UNUSED(heade
int overlay_mdp_service_dnalookup(struct internal_mdp_header *header, struct overlay_buffer *payload)
{
IN();
unsigned cn=0, in=0, kp=0;
keyring_iterator it;
keyring_iterator_start(keyring, &it);
char did[64+1];
int pll=ob_remaining(payload);
@ -191,19 +192,18 @@ int overlay_mdp_service_dnalookup(struct internal_mdp_header *header, struct ove
DEBUG("MDP_PORT_DNALOOKUP");
int results=0;
while(keyring_find_did(keyring,&cn,&in,&kp,did))
while(keyring_find_did(&it, did))
{
struct keypair *keypair = keyring->contexts[cn]->identities[in]->keypairs[kp];
/* package DID and Name into reply (we include the DID because
it could be a wild-card DID search, but the SID is implied
in the source address of our reply). */
if (keypair->private_key_len > DID_MAXSIZE)
if (it.keypair->private_key_len > DID_MAXSIZE)
/* skip excessively long DID records */
continue;
struct subscriber *subscriber = keyring->contexts[cn]->identities[in]->subscriber;
const char *unpackedDid = (const char *) keypair->private_key;
const char *name = (const char *)keypair->public_key;
struct subscriber *subscriber = it.identity->subscriber;
const char *unpackedDid = (const char *) it.keypair->private_key;
const char *name = (const char *)it.keypair->public_key;
// URI is sid://SIDHEX/DID
strbuf b = strbuf_alloca(SID_STRLEN + DID_MAXSIZE + 10);
strbuf_puts(b, "sid://");
@ -211,7 +211,6 @@ int overlay_mdp_service_dnalookup(struct internal_mdp_header *header, struct ove
strbuf_puts(b, "/local/");
strbuf_puts(b, unpackedDid);
overlay_mdp_dnalookup_reply(header->source, header->source_port, subscriber, strbuf_str(b), unpackedDid, name);
kp++;
results++;
}
if (!results) {

View File

@ -1226,13 +1226,14 @@ int rhizome_fill_manifest(rhizome_manifest *m, const char *filepath, const sid_t
int rhizome_lookup_author(rhizome_manifest *m)
{
IN();
unsigned cn, in, kp;
keyring_iterator it;
switch (m->authorship) {
case AUTHOR_NOT_CHECKED:
if (config.debug.rhizome)
DEBUGF("manifest[%d] lookup author=%s", m->manifest_record_number, alloca_tohex_sid_t(m->author));
cn = 0, in = 0, kp = 0;
if (keyring_find_sid(keyring, &cn, &in, &kp, &m->author)) {
keyring_iterator_start(keyring, &it);
if (keyring_find_sid(&it, &m->author)) {
if (config.debug.rhizome)
DEBUGF("found author");
m->authorship = AUTHOR_LOCAL;
@ -1243,8 +1244,8 @@ int rhizome_lookup_author(rhizome_manifest *m)
if (m->has_sender) {
if (config.debug.rhizome)
DEBUGF("manifest[%d] lookup sender=%s", m->manifest_record_number, alloca_tohex_sid_t(m->sender));
cn = 0, in = 0, kp = 0;
if (keyring_find_sid(keyring, &cn, &in, &kp, &m->sender)) {
keyring_iterator_start(keyring, &it);
if (keyring_find_sid(&it, &m->sender)) {
if (config.debug.rhizome)
DEBUGF("found sender");
rhizome_manifest_set_author(m, &m->sender);

View File

@ -192,25 +192,26 @@ int rhizome_secret2bk(
enum rhizome_secret_disposition find_rhizome_secret(const sid_t *authorSidp, size_t *rs_len, const unsigned char **rs)
{
IN();
unsigned cn=0, in=0, kp=0;
if (!keyring_find_sid(keyring,&cn,&in,&kp, authorSidp)) {
keyring_iterator it;
keyring_iterator_start(keyring, &it);
if (!keyring_find_sid(&it, authorSidp)) {
if (config.debug.rhizome)
DEBUGF("identity sid=%s is not in keyring", alloca_tohex_sid_t(*authorSidp));
RETURN(IDENTITY_NOT_FOUND);
}
int kpi = keyring_identity_find_keytype(keyring, cn, in, KEYTYPE_RHIZOME);
if (kpi == -1) {
keypair *kp=keyring_identity_keytype(it.identity, KEYTYPE_RHIZOME);
if (!kp) {
WARNF("Identity sid=%s has no Rhizome Secret", alloca_tohex_sid_t(*authorSidp));
RETURN(IDENTITY_HAS_NO_RHIZOME_SECRET);
}
kp = (unsigned)kpi;
int rslen = keyring->contexts[cn]->identities[in]->keypairs[kp]->private_key_len;
int rslen = kp->private_key_len;
assert(rslen >= 16);
assert(rslen <= 1024);
if (rs_len)
*rs_len = rslen;
if (rs)
*rs = keyring->contexts[cn]->identities[in]->keypairs[kp]->private_key;
*rs = kp->private_key;
RETURN(FOUND_RHIZOME_SECRET);
}
@ -354,28 +355,31 @@ void rhizome_find_bundle_author_and_secret(rhizome_manifest *m)
assert(is_sid_t_any(m->author));
if (!m->has_bundle_key)
RETURNVOID;
unsigned cn = 0, in = 0, kp = 0;
for (; keyring_next_identity(keyring, &cn, &in, &kp); ++kp) {
const sid_t *authorSidp = (const sid_t *) keyring->contexts[cn]->identities[in]->keypairs[kp]->public_key;
//if (config.debug.rhizome) DEBUGF("try author identity sid=%s", alloca_tohex_sid_t(*authorSidp));
int rkp = keyring_identity_find_keytype(keyring, cn, in, KEYTYPE_RHIZOME);
if (rkp != -1) {
size_t rs_len = keyring->contexts[cn]->identities[in]->keypairs[rkp]->private_key_len;
if (rs_len < 16 || rs_len > 1024) {
WHYF("invalid Rhizome Secret: length=%zu", rs_len);
m->authorship = AUTHENTICATION_ERROR;
RETURNVOID;
}
const unsigned char *rs = keyring->contexts[cn]->identities[in]->keypairs[rkp]->private_key;
unsigned char *secretp = m->cryptoSignSecret;
if (m->haveSecret)
secretp = alloca(sizeof m->cryptoSignSecret);
if (rhizome_bk2secret(&m->cryptoSignPublic, rs, rs_len, m->bundle_key.binary, secretp) == 0) {
if (m->haveSecret) {
if (memcmp(secretp, m->cryptoSignSecret, sizeof m->cryptoSignSecret) != 0)
FATALF("Bundle secret does not match derived secret");
} else
m->haveSecret = EXISTING_BUNDLE_ID;
keyring_iterator it;
keyring_iterator_start(keyring, &it);
keypair *kp;
while((kp=keyring_next_keytype(&it, KEYTYPE_RHIZOME))){
size_t rs_len = kp->private_key_len;
if (rs_len < 16 || rs_len > 1024) {
// should a bad key be fatal??
WARNF("invalid Rhizome Secret: length=%zu", rs_len);
continue;
}
const unsigned char *rs = kp->private_key;
unsigned char *secretp = m->cryptoSignSecret;
if (m->haveSecret)
secretp = alloca(sizeof m->cryptoSignSecret);
if (rhizome_bk2secret(&m->cryptoSignPublic, rs, rs_len, m->bundle_key.binary, secretp) == 0) {
if (m->haveSecret) {
if (memcmp(secretp, m->cryptoSignSecret, sizeof m->cryptoSignSecret) != 0)
FATALF("Bundle secret does not match derived secret");
} else
m->haveSecret = EXISTING_BUNDLE_ID;
keypair *kp_sid = keyring_identity_keytype(it.identity, KEYTYPE_CRYPTOBOX);
if (kp_sid){
const sid_t *authorSidp = (const sid_t *) kp_sid->public_key;
if (config.debug.rhizome)
DEBUGF("found bundle author sid=%s", alloca_tohex_sid_t(*authorSidp));
rhizome_manifest_set_author(m, authorSidp);
@ -387,8 +391,9 @@ void rhizome_find_bundle_author_and_secret(rhizome_manifest *m)
SID_T, &m->author,
INT64, m->rowid,
END);
RETURNVOID; // bingo
}
RETURNVOID; // bingo
}
}
assert(m->authorship == ANONYMOUS);
@ -608,10 +613,12 @@ int rhizome_derive_payload_key(rhizome_manifest *m)
unsigned char hash[crypto_hash_sha512_BYTES];
if (m->has_sender && m->has_recipient) {
unsigned char *nm_bytes=NULL;
unsigned cn=0, in=0, kp=0;
if (!keyring_find_sid(keyring, &cn, &in, &kp, &m->sender)){
cn=in=kp=0;
if (!keyring_find_sid(keyring, &cn, &in, &kp, &m->recipient)){
keyring_iterator it;
keyring_iterator_start(keyring, &it);
if (!keyring_find_sid(&it, &m->sender)){
keyring_iterator_start(keyring, &it);
if (!keyring_find_sid(&it, &m->recipient)){
WARNF("Neither sender=%s nor recipient=%s is in keyring",
alloca_tohex_sid_t(m->sender),
alloca_tohex_sid_t(m->recipient));

View File

@ -235,6 +235,8 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct http_request *hr
if (!strbuf_overrun(b))
r->u.rhlist.phase = LIST_ROWS;
return 1;
case LIST_FIRST:
case LIST_ROWS:
{
int ret = rhizome_list_next(&r->u.rhlist.cursor);

View File

@ -32,11 +32,12 @@ includeTests dnahelper
includeTests dnaprotocol
includeTests rhizomeops
includeTests rhizomeprotocol
includeTests rhizomerestful
includeTests meshms
includeTests meshmsrestful
includeTests directory_service
includeTests vomp
includeTests rhizomerestful
includeTests keyringrestful
includeTests meshmsrestful
if type -p "$JAVAC" >/dev/null; then
includeTests jni
includeTests rhizomejava