mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 02:56:44 +00:00
Refactor keyring identity iteration
This commit is contained in:
parent
7e403af715
commit
851144ea0a
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
6
httpd.h
6
httpd.h
@ -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;
|
||||
|
||||
|
53
keyring.h
53
keyring.h
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
9
meshms.c
9
meshms.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user