diff --git a/commandline.c b/commandline.c index 9d8923c5..fd4013a2 100644 --- a/commandline.c +++ b/commandline.c @@ -1109,12 +1109,14 @@ int app_keyring_add(int argc, const char *const *argv, struct command_line_optio int app_keyring_set_did(int argc, const char *const *argv, struct command_line_option *o) { - const char *sid, *did, *pin; + const char *sid, *did, *pin, *name; cli_arg(argc, argv, o, "sid", &sid, NULL, ""); cli_arg(argc, argv, o, "did", &did, NULL, ""); + cli_arg(argc, argv, o, "name", &name, NULL, ""); cli_arg(argc, argv, o, "pin", &pin, NULL, ""); if (strlen(did)>31) return WHY("DID too long (31 digits max)"); + if (strlen(name)>63) return WHY("Name too long (31 char max)"); keyring=keyring_open_with_pins((char *)pin); if (!keyring) return WHY("Could not open keyring file"); @@ -1125,7 +1127,8 @@ int app_keyring_set_did(int argc, const char *const *argv, struct command_line_o int cn=0,in=0,kp=0; int r=keyring_find_sid(keyring,&cn,&in,&kp,packedSid); if (!r) return WHY("No matching SID"); - if (keyring_set_did(keyring->contexts[cn]->identities[in],(char *)did)) + if (keyring_set_did(keyring->contexts[cn]->identities[in], + (char *)did,(char *)name)) return WHY("Could not set DID"); if (keyring_commit(keyring)) return WHY("Could not write updated keyring record"); @@ -1239,9 +1242,10 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option if (!overlay_mdp_send(&m2,MDP_AWAITREPLY,125)) { int bytes=m2.in.payload_length; - if ((bytes+1)]",NULL},CLIFLAG_STANDALONE, "Create a new identity in the keyring protected by the provided PIN"}, - {app_keyring_set_did,{"set","did","","","[]",NULL},CLIFLAG_STANDALONE, + {app_keyring_set_did,{"set","did","","","","[]",NULL},CLIFLAG_STANDALONE, "Set the DID for the specified SID. Optionally supply PIN to unlock the SID record in the keyring."}, {app_vomp_status,{"vomp","status",NULL},0, "Display status of any VoMP calls"}, diff --git a/keyring.c b/keyring.c index fb684726..ce9d485c 100644 --- a/keyring.c +++ b/keyring.c @@ -425,9 +425,26 @@ int keyring_pack_identity(keyring_context *c,keyring_identity *i, switch(i->keypairs[kp]->type) { case KEYTYPE_RHIZOME: case KEYTYPE_DID: - /* Both of these are 32 bytes and only one value, - so the CRYPTOBOX case below works */ - /* fall through */ + /* 32 chars for unpacked DID/rhizome secret, + 64 chars for name (for DIDs only) */ + if ((ofs + +i->keypairs[kp]->private_key_len + +i->keypairs[kp]->public_key_len + )>=KEYRING_PAGE_SIZE) + { + WHY("too many or too long key pairs"); + ofs=0; + goto kpi_safeexit; + } + bcopy(i->keypairs[kp]->private_key,&packed[ofs], + i->keypairs[kp]->private_key_len); + ofs+=i->keypairs[kp]->private_key_len; + if (i->keypairs[kp]->type==KEYTYPE_DID) { + bcopy(i->keypairs[kp]->public_key,&packed[ofs], + i->keypairs[kp]->private_key_len); + ofs+=i->keypairs[kp]->public_key_len; + } + break; case KEYTYPE_CRYPTOBOX: /* For cryptobox we only need the private key, as we compute the public key from it when extracting the identity */ @@ -564,9 +581,12 @@ keyring_identity *keyring_unpack_identity(unsigned char *slot, const char *pin) kp->private_key_len=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES; kp->public_key_len=crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES; break; - case KEYTYPE_RHIZOME: case KEYTYPE_DID: + case KEYTYPE_RHIZOME: kp->private_key_len=32; kp->public_key_len=0; break; + case KEYTYPE_DID: + kp->private_key_len=32; kp->public_key_len=64; + break; } kp->private_key=malloc(kp->private_key_len); if (!kp->private_key) { @@ -601,15 +621,18 @@ keyring_identity *keyring_unpack_identity(unsigned char *slot, const char *pin) */ crypto_scalarmult_curve25519_base(kp->public_key,kp->private_key); break; + case KEYTYPE_DID: case KEYTYPE_CRYPTOSIGN: /* While it is possible to compute the public key from the private key, NaCl currently does not provide a function to do this, so we have to store it, or else subvert the NaCl API, which I would rather not do. + So we just copy it out. We use the same code for extracting the + public key for a DID (i.e, subscriber name) */ for(i=0;ipublic_key_len;i++) kp->public_key[i]=slot_byte(ofs+i); ofs+=kp->public_key_len; break; - case KEYTYPE_RHIZOME: case KEYTYPE_DID: + case KEYTYPE_RHIZOME: /* no public key value for these, just do nothing */ break; } @@ -760,7 +783,8 @@ 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, + char *pin) { /* Check obvious abort conditions early */ if (!k) { WHY("keyring is NULL"); return NULL; } @@ -845,6 +869,8 @@ keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c,cha WHY("malloc() failed preparing second public key storage"); goto kci_safeexit; } +#warning XXX - Doesnt make sure that public key first nybl is >0 - 1 in 16 identities will be invalid + crypto_sign_edwards25519sha512batch_keypair(id->keypairs[1]->public_key, id->keypairs[1]->private_key); @@ -964,16 +990,19 @@ int keyring_commit(keyring_file *k) return errorCount; } -int keyring_set_did(keyring_identity *id,char *did) +int keyring_set_did(keyring_identity *id,char *did,char *name) { if (!id) return WHY("id is null"); if (!did) return WHY("did is null"); + if (!name) name="Mr. Smith"; /* Find where to put it */ int i; for(i=0;ikeypair_count;i++) - if (id->keypairs[i]->type==KEYTYPE_DID) + if (id->keypairs[i]->type==KEYTYPE_DID) { + WHY("Identity contains DID"); break; + } if (i>=PKR_MAX_KEYPAIRS) return WHY("Too many key pairs"); @@ -984,16 +1013,25 @@ int keyring_set_did(keyring_identity *id,char *did) id->keypairs[i]->type=KEYTYPE_DID; unsigned char *packedDid=calloc(32,1); if (!packedDid) return WHY("calloc() failed"); + unsigned char *packedName=calloc(64,1); + if (!packedName) return WHY("calloc() failed"); id->keypairs[i]->private_key=packedDid; id->keypairs[i]->private_key_len=32; + id->keypairs[i]->public_key=packedName; + id->keypairs[i]->public_key_len=64; id->keypair_count++; + WHY("Created DID record for identity"); } /* Store DID unpacked for ease of searching */ int len=strlen(did); if (len>31) len=31; bcopy(did,&id->keypairs[i]->private_key[0],len); bzero(&id->keypairs[i]->private_key[len],32-len); + len=strlen(name); if (len>63) len=63; + bcopy(name,&id->keypairs[i]->public_key[0],len); + bzero(&id->keypairs[i]->public_key[len],64-len); dump("storing did",&id->keypairs[i]->private_key[0],32); + dump("storing name",&id->keypairs[i]->public_key[0],64); return 0; } @@ -1344,14 +1382,15 @@ int keyring_seed(keyring_file *k) unsigned char did[65]; /* Securely generate random telephone number */ urandombytes((unsigned char *)did,10); - /* Make DID start with 2 through 9, as 1 is special in many number spaces. */ + /* Make DID start with 2 through 9, as 1 is special in many number spaces, + and 0 is commonly used for escaping to national or international dialling. */ did[0]='2'+(did[0]%8); /* Then add 10 more digits, which is what we do in the mobile phone software */ for(i=1;i<11;i++) did[i]='0'+(did[i]%10); did[11]=0; - + keyring_identity *id=keyring_create_identity(k,k->contexts[0],""); if (!id) return WHY("Could not create new identity"); - if (keyring_set_did(id,(char *)did)) return WHY("Could not set DID of new identity"); + if (keyring_set_did(id,(char *)did,"")) return WHY("Could not set DID of new identity"); if (keyring_commit(k)) return WHY("Could not commit new identity to keyring file"); return 0; } diff --git a/overlay_mdp.c b/overlay_mdp.c index 15d3413f..9d23caff 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -493,8 +493,9 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now) while(keyring_find_did(keyring,&cn,&in,&kp,did)) { WHYF("Found matching did"); - /* package DID plus SID into reply (we include the DID because - it could be a wild-card DID search). */ + /* 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 (keyring->contexts[cn]->identities[in]->keypairs[kp] ->private_key_len>64) /* skip excessively long DID records */ @@ -507,10 +508,20 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now) ->private_key,&mdp->out.payload[0], keyring->contexts[cn]->identities[in]->keypairs[kp] ->private_key_len); + bcopy(keyring->contexts[cn]->identities[in]->keypairs[kp] + ->public_key,&mdp->out.payload[keyring + ->contexts[cn] + ->identities[in] + ->keypairs[kp] + ->private_key_len], + keyring->contexts[cn]->identities[in]->keypairs[kp] + ->private_key_len); /* set length */ mdp->out.payload_length= keyring->contexts[cn]->identities[in]->keypairs[kp] - ->private_key_len; + ->private_key_len + +keyring->contexts[cn]->identities[in]->keypairs[kp] + ->public_key_len; /* mark as outgoing MDP message */ mdp->packetTypeAndFlags&=MDP_FLAG_MASK; mdp->packetTypeAndFlags|=MDP_TX; diff --git a/overlay_route.c b/overlay_route.c index 6aa8c977..51ac1bf4 100644 --- a/overlay_route.c +++ b/overlay_route.c @@ -1368,6 +1368,12 @@ int overlay_route_node_info(overlay_mdp_frame *mdp, &mdp->nodeinfo.did[0], keyring->contexts[cn]->identities[in] ->keypairs[k2]->private_key_len); + /* public key has name */ + bcopy(&keyring->contexts[cn]->identities[in] + ->keypairs[k2]->public_key[0], + &mdp->nodeinfo.name[0], + keyring->contexts[cn]->identities[in] + ->keypairs[k2]->public_key_len); mdp->nodeinfo.resolve_did=1; } } diff --git a/serval.h b/serval.h index 2242203a..a77991e7 100755 --- a/serval.h +++ b/serval.h @@ -241,7 +241,7 @@ keyring_file *keyring_open(char *file); keyring_file *keyring_open_with_pins(const char *pinlist); int keyring_enter_pin(keyring_file *k, const char *pin); int keyring_enter_pins(keyring_file *k, const char *pinlist); -int keyring_set_did(keyring_identity *id,char *did); +int keyring_set_did(keyring_identity *id,char *did,char *name); int keyring_sanitise_position(keyring_file *k,int *cn,int *in,int *kp); int keyring_next_identity(keyring_file *k,int *cn,int *in,int *kp); int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did); @@ -1198,6 +1198,7 @@ typedef struct overlay_mdp_nodeinfo { unsigned char sid[SID_SIZE]; int sid_prefix_length; /* allow wildcard matching */ char did[64]; + char name[64]; int foundP; int localP; int neighbourP; diff --git a/server.c b/server.c index 6801abb4..88cb216b 100644 --- a/server.c +++ b/server.c @@ -195,7 +195,7 @@ int processRequest(unsigned char *packet,int len, /* Creating an identity is nice and easy now with the new keyring */ keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0], ""); - if (id) keyring_set_did(id,did); + 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, sender,CRYPT_CIPHERED|CRYPT_SIGNED);