diff --git a/commandline.c b/commandline.c index b63ca4dd..bafce311 100644 --- a/commandline.c +++ b/commandline.c @@ -1322,31 +1322,22 @@ int app_keyring_list(int argc, const char *const *argv, struct command_line_opti keyring_file *k = keyring_open_with_pins(pin); if (!k) return -1; - - int cn=0; - int in=0; - - for(cn=0;cncontext_count;cn++) - for(in=0;incontexts[cn]->identity_count;in++) - { - int kpn; - keypair *kp; - unsigned char *sid=NULL,*did=NULL,*name=NULL; - for(kpn=0;kpncontexts[cn]->identities[in]->keypair_count;kpn++) - { - kp=k->contexts[cn]->identities[in]->keypairs[kpn]; - if (kp->type==KEYTYPE_CRYPTOBOX) sid=kp->public_key; - if (kp->type==KEYTYPE_DID) { did=kp->private_key; name=kp->public_key; } - } - if (sid||did) { - if (sid) cli_printf("%s", alloca_tohex_sid(sid)); - cli_delim(":"); - if (did) cli_puts((char*)did); - cli_delim(":"); - if (name) cli_puts((char*)name); - cli_delim("\n"); - } + int cn, in; + for (cn = 0; cn < k->context_count; ++cn) + for (in = 0; in < k->contexts[cn]->identity_count; ++in) { + const unsigned char *sid = NULL; + const char *did = NULL; + const char *name = NULL; + keyring_identity_extract(k->contexts[cn]->identities[in], &sid, &did, &name); + if (sid || did) { + if (sid) cli_printf("%s", alloca_tohex_sid(sid)); + cli_delim(":"); + if (did) cli_puts(did); + cli_delim(":"); + if (name) cli_puts(name); + cli_delim("\n"); } + } return 0; } @@ -1357,10 +1348,39 @@ int app_keyring_add(int argc, const char *const *argv, struct command_line_optio keyring_file *k = keyring_open_with_pins(""); if (!k) return -1; - if (keyring_create_identity(k,k->contexts[0],(char *)pin)==NULL) - return WHY("Could not create new identity (keyring_create_identity() failed)"); - if (keyring_commit(k)) - return WHY("Could not write new identity (keyring_commit() failed)"); + const keyring_identity *id = keyring_create_identity(k, k->contexts[0], pin); + if (id == NULL) { + keyring_free(k); + return WHY("Could not create new identity"); + } + const unsigned char *sid = NULL; + const char *did = ""; + const char *name = ""; + keyring_identity_extract(id, &sid, &did, &name); + if (!sid) { + keyring_free(k); + return WHY("New identity has no SID"); + } + if (keyring_commit(k) == -1) { + keyring_free(k); + return WHY("Could not write new identity"); + } + cli_puts("sid"); + cli_delim(":"); + cli_printf("%s", alloca_tohex_sid(sid)); + cli_delim("\n"); + if (did) { + cli_puts("did"); + cli_delim(":"); + cli_puts(did); + cli_delim("\n"); + } + if (name) { + cli_puts("name"); + cli_delim(":"); + cli_puts(name); + cli_delim("\n"); + } keyring_free(k); return 0; } diff --git a/keyring.c b/keyring.c index d011ad06..1356f01f 100644 --- a/keyring.c +++ b/keyring.c @@ -787,8 +787,7 @@ int keyring_enter_pin(keyring_file *k, const char *pin) The crypto_box and crypto_sign key pairs are automatically created, and the PKR is packed and written to a hithero unallocated slot which is then marked full. */ -keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c, - char *pin) +keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c, const char *pin) { /* Check obvious abort conditions early */ if (!k) { WHY("keyring is NULL"); return NULL; } @@ -1340,30 +1339,37 @@ unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid) RETURN(NULL); } -int keyring_find_sid(const keyring_file *k,int *cn,int *in,int *kp, const unsigned char *sid) +int keyring_find_sid(const keyring_file *k, int *cn, int *in, int *kp, const unsigned char *sid) { - if (keyring_sanitise_position(k,cn,in,kp)) return 0; - - while (1) { - /* we know we have a sane position, so see if it is interesting */ - - if (k->contexts[*cn]->identities[*in]->keypairs[*kp]->type==KEYTYPE_CRYPTOBOX) - { - /* Compare SIDs */ - if (!memcmp(sid,(char *)k->contexts[*cn]->identities[*in] - ->keypairs[*kp]->public_key,SID_SIZE)) - { - /* match */ - return 1; - } - } - (*kp)++; - if (keyring_sanitise_position(k,cn,in,kp)) return 0; - } - + for (; !keyring_sanitise_position(k, cn, in, kp); ++*kp) + if (k->contexts[*cn]->identities[*in]->keypairs[*kp]->type == KEYTYPE_CRYPTOBOX + && memcmp(sid, k->contexts[*cn]->identities[*in]->keypairs[*kp]->public_key, SID_SIZE) == 0) + return 1; return 0; } +void keyring_identity_extract(const keyring_identity *id, const unsigned char **sidp, const char **didp, const char **namep) +{ + int todo = (sidp ? 1 : 0) | (didp ? 2 : 0) || (namep ? 4 : 0); + int kpn; + for (kpn = 0; todo && kpn < id->keypair_count; ++kpn) { + keypair *kp = id->keypairs[kpn]; + switch (kp->type) { + case KEYTYPE_CRYPTOBOX: + if (sidp) + *sidp = kp->public_key; + todo &= ~1; + break; + case KEYTYPE_DID: + if (didp) + *didp = (const char *) kp->private_key; + if (namep) + *namep = (const char *) kp->public_key; + todo &= ~6; + break; + } + } +} int keyring_enter_pins(keyring_file *k, const char *pinlist) { diff --git a/serval.h b/serval.h index df315965..985b16e3 100755 --- a/serval.h +++ b/serval.h @@ -263,9 +263,9 @@ unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid, unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid); int keyring_commit(keyring_file *k); -keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c, - char *pin); +keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c, const char *pin); int keyring_seed(keyring_file *k); +void keyring_identity_extract(const keyring_identity *id, const unsigned char **sidp, const char **didp, const char **namep); /* Packet format: diff --git a/server.c b/server.c index 85df6470..4525722a 100644 --- a/server.c +++ b/server.c @@ -490,8 +490,7 @@ int processRequest(unsigned char *packet,int len, if (debug&DEBUG_HLR) DEBUG("Verified that create request supplies DID but not SID"); /* Creating an identity is nice and easy now with the new keyring */ - keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0], - ""); + keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0], ""); if (id) keyring_set_did(id,did,"Mr. Smith"); if (id==NULL||keyring_commit(keyring)) return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,recvttl,