mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-24 07:16:43 +00:00
Added commandline interface to set a did.
Re-enabled payload rotation in keyring PKRs. Getting and setting dids now works. keyring list displays SID:DID pairs.
This commit is contained in:
parent
7b53fd6782
commit
7b8d78533d
@ -686,35 +686,16 @@ int app_rhizome_list(int argc, char **argv, struct command_line_option *o)
|
||||
|
||||
int app_keyring_create(int argc, char **argv, struct command_line_option *o)
|
||||
{
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return -1;
|
||||
char *instancePath = serval_instancepath();
|
||||
char keyringFile[1024];
|
||||
snprintf(keyringFile,1024,"%s/serval.keyring",instancePath);
|
||||
if (!keyring_open(keyringFile))
|
||||
fprintf(stderr,"keyring create:Failed to create/open keyring file\n");
|
||||
char *pin = cli_arg(argc, argv, o, "pin,pin ...", "");
|
||||
keyring_file *k=keyring_open_with_pins(pin);
|
||||
if (!k) fprintf(stderr,"keyring create:Failed to create/open keyring file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_keyring_list(int argc, char **argv, struct command_line_option *o)
|
||||
{
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return -1;
|
||||
char *instancePath = serval_instancepath();
|
||||
char keyringFile[1024];
|
||||
keyring_file *k=NULL;
|
||||
snprintf(keyringFile,1024,"%s/serval.keyring",instancePath);
|
||||
if ((k=keyring_open(keyringFile))==NULL)
|
||||
{ fprintf(stderr,"keyring list:Failed to create/open keyring file\n");
|
||||
return -1; }
|
||||
|
||||
char *pinlist = strdup(cli_arg(argc, argv, o, "pin,pin ...", ""));
|
||||
char *pin=strtok((char *)pinlist,",");
|
||||
if (!pin) pin=cli_arg(argc, argv, o, "pin,pin ...", "");
|
||||
while(pin) {
|
||||
keyring_enter_pin(k,pin);
|
||||
pin=strtok(NULL,",");
|
||||
}
|
||||
char *pin = cli_arg(argc, argv, o, "pin,pin ...", "");
|
||||
keyring_file *k=keyring_open_with_pins(pin);
|
||||
|
||||
int cn=0;
|
||||
int in=0;
|
||||
@ -724,17 +705,20 @@ int app_keyring_list(int argc, char **argv, struct command_line_option *o)
|
||||
{
|
||||
int kpn;
|
||||
keypair *kp;
|
||||
unsigned char *sid=NULL,*did=NULL;
|
||||
for(kpn=0;kpn<k->contexts[cn]->identities[in]->keypair_count;kpn++)
|
||||
{
|
||||
kp=k->contexts[cn]->identities[in]->keypairs[kpn];
|
||||
if (!kpn)
|
||||
printf("Identity accessed with pin='%s'\n",
|
||||
k->contexts[cn]->identities[in]->PKRPin);
|
||||
printf(" %02x:",kp->type);
|
||||
int i;
|
||||
for(i=0;i<kp->public_key_len;i++) printf("%02x",kp->public_key[i]);
|
||||
printf("\n");
|
||||
if (kp->type==KEYTYPE_CRYPTOBOX) sid=kp->public_key;
|
||||
if (kp->type==KEYTYPE_DID) did=kp->private_key;
|
||||
}
|
||||
if (sid||did) {
|
||||
int i;
|
||||
if (sid) for(i=0;i<SID_SIZE;i++) printf("%02x",sid[i]);
|
||||
else printf("<blank SID>");
|
||||
if (did) printf(":%s",did); else printf(":<no phone number set>");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -743,15 +727,9 @@ int app_keyring_add(int argc, char **argv, struct command_line_option *o)
|
||||
{
|
||||
const char *pin = cli_arg(argc, argv, o, "pin", "");
|
||||
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return -1;
|
||||
char *instancePath = serval_instancepath();
|
||||
char keyringFile[1024];
|
||||
keyring_file *k=NULL;
|
||||
snprintf(keyringFile,1024,"%s/serval.keyring",instancePath);
|
||||
if ((k=keyring_open(keyringFile))==NULL)
|
||||
{ fprintf(stderr,"keyring add:Failed to create/open keyring file\n");
|
||||
return -1; }
|
||||
keyring_file *k=keyring_open_with_pins("");
|
||||
if (!k) { fprintf(stderr,"keyring add:Failed to create/open keyring file\n");
|
||||
return -1; }
|
||||
|
||||
if (keyring_create_identity(k,k->contexts[0],(char *)pin))
|
||||
{
|
||||
@ -764,7 +742,31 @@ int app_keyring_add(int argc, char **argv, struct command_line_option *o)
|
||||
}
|
||||
keyring_free(k);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_keyring_set_did(int argc, char **argv, struct command_line_option *o)
|
||||
{
|
||||
const char *sid = cli_arg(argc, argv, o, "sid", "");
|
||||
const char *did = cli_arg(argc, argv, o, "did", "");
|
||||
const char *pin = cli_arg(argc, argv, o, "pin", "");
|
||||
|
||||
if (strlen(did)>31) return WHY("DID too long (31 digits max)");
|
||||
|
||||
keyring_file *k=keyring_open_with_pins((char *)pin);
|
||||
if (!k) return WHY("Could not open keyring file");
|
||||
|
||||
unsigned char packedSid[SID_SIZE];
|
||||
stowSid(packedSid,0,(char *)sid);
|
||||
|
||||
int cn=0,in=0,kp=0;
|
||||
int r=keyring_find_sid(k,&cn,&in,&kp,packedSid);
|
||||
if (!r) return WHY("No matching SID");
|
||||
if (keyring_set_did(k->contexts[cn]->identities[in],(char *)did))
|
||||
return WHY("Could not set DID");
|
||||
if (keyring_commit(k))
|
||||
return WHY("Could not write updated keyring record");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NULL marks ends of command structure.
|
||||
@ -813,7 +815,9 @@ command_line_option command_line_options[]={
|
||||
"Create a new keyring file."},
|
||||
{app_keyring_list,{"keyring","list","[<pin,pin ...>]",NULL},0,
|
||||
"List identites in specified key ring that can be accessed using the specified PINs"},
|
||||
{app_keyring_add,{"keyring","add","[<pin>]",NULL},0,
|
||||
{app_keyring_add,{"keyring","add","[<pin>]",NULL},CLIFLAG_STANDALONE,
|
||||
"Create a new identity in the keyring protected by the provided PIN"},
|
||||
{app_keyring_set_did,{"set","did","<sid>","<did>","[<pin>]",NULL},CLIFLAG_STANDALONE,
|
||||
"Set the DID for the specified SID. Optionally supply PIN to unlock the SID record in the keyring."},
|
||||
{NULL,{NULL}}
|
||||
};
|
||||
|
112
keyring.c
112
keyring.c
@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "nacl.h"
|
||||
|
||||
#define NO_ROTATION
|
||||
|
||||
static int urandomfd = -1;
|
||||
|
||||
int urandombytes(unsigned char *x,unsigned long long xlen)
|
||||
@ -419,7 +417,6 @@ int keyring_pack_identity(keyring_context *c,keyring_identity *i,
|
||||
WHY("too many or too long key pairs");
|
||||
ofs=0; goto kpi_safeexit;
|
||||
}
|
||||
printf("key type 0x%02x @ 0x%x\n",i->keypairs[kp]->type,ofs);
|
||||
packed[ofs++]=i->keypairs[kp]->type;
|
||||
switch(i->keypairs[kp]->type) {
|
||||
case KEYTYPE_RHIZOME:
|
||||
@ -504,7 +501,6 @@ int keyring_pack_identity(keyring_context *c,keyring_identity *i,
|
||||
KEYRING_PAGE_SIZE-(PKR_SALT_BYTES+PKR_MAC_BYTES+2));
|
||||
packed[rotate_ofs]=rotation>>8;
|
||||
packed[rotate_ofs+1]=rotation&0xff;
|
||||
printf("Writing record with rotation = 0x%x\n",rotation);
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
@ -614,15 +610,12 @@ keyring_identity *keyring_unpack_identity(unsigned char *slot,char *pin)
|
||||
break;
|
||||
}
|
||||
id->keypair_count++;
|
||||
printf("keypair_count=%d\n",id->keypair_count);
|
||||
fflush(stdout);
|
||||
break;
|
||||
default:
|
||||
/* Invalid data, so invalid record. Free and return failure.
|
||||
We don't complain about this, however, as it is the natural
|
||||
effect of trying a pin on an incorrect keyring slot. */
|
||||
keyring_free_identity(id);
|
||||
WHY("PKR has invalid structure (wrong pin?)");
|
||||
keyring_free_identity(id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -679,9 +672,11 @@ int keyring_decrypt_pkr(keyring_file *k,keyring_context *c,
|
||||
/* 3. Unpack contents of slot into a new identity in the provided context. */
|
||||
id=keyring_unpack_identity(slot,pin);
|
||||
if (!id) {
|
||||
WHY("keyring_unpack_identity() failed");
|
||||
// Don't complain, because this happens routinely when trying pins against slots.
|
||||
// WHY("keyring_unpack_identity() failed");
|
||||
goto kdp_safeexit;
|
||||
}
|
||||
id->slot=slot_number;
|
||||
|
||||
/* 4. Verify that slot is self-consistent (check MAC) */
|
||||
if (keyring_identity_mac(k->contexts[0],id,&slot[0],hash)) {
|
||||
@ -947,7 +942,11 @@ int keyring_commit(keyring_file *k)
|
||||
off_t file_offset
|
||||
=KEYRING_PAGE_SIZE
|
||||
*k->contexts[cn]->identities[in]->slot;
|
||||
if (fseeko(k->file,file_offset,SEEK_SET))
|
||||
if (!file_offset) {
|
||||
fprintf(stderr,"ID %d:%d has slot=0\n",
|
||||
cn,in);
|
||||
}
|
||||
else if (fseeko(k->file,file_offset,SEEK_SET))
|
||||
errorCount++;
|
||||
else
|
||||
if (fwrite(pkr,KEYRING_PAGE_SIZE,1,k->file)!=1)
|
||||
@ -975,6 +974,9 @@ int keyring_set_did(keyring_identity *id,char *did)
|
||||
|
||||
/* allocate if needed */
|
||||
if (i>=id->keypair_count) {
|
||||
id->keypairs[i]=calloc(sizeof(keypair),1);
|
||||
if (!id->keypairs[i]) return WHY("calloc() failed");
|
||||
id->keypairs[i]->type=KEYTYPE_DID;
|
||||
unsigned char *packedDid=calloc(32,1);
|
||||
if (!packedDid) return WHY("calloc() failed");
|
||||
id->keypairs[i]->private_key=packedDid;
|
||||
@ -984,17 +986,23 @@ int keyring_set_did(keyring_identity *id,char *did)
|
||||
|
||||
/* Store DID unpacked for ease of searching */
|
||||
int len=strlen(did); if (len>31) len=31;
|
||||
bcopy(did,&id->keypairs[i]->private_key,len);
|
||||
bcopy(did,&id->keypairs[i]->private_key[0],len);
|
||||
bzero(&id->keypairs[i]->private_key[len],32-len);
|
||||
dump("storing did",&id->keypairs[i]->private_key[0],32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did)
|
||||
{
|
||||
if (!k) return -1;
|
||||
if (!k) return 0;
|
||||
|
||||
while ((*cn)<k->context_count) {
|
||||
while (((*cn)<k->context_count)&&((*in)>=k->contexts[*cn]->identity_count)) {
|
||||
(*cn)++; (*in)=0;
|
||||
}
|
||||
if ((*cn)>=k->context_count) return 0;
|
||||
|
||||
for(*kp=0;*kp<k->contexts[*cn]->identities[*in]->keypair_count;(*kp)++)
|
||||
{
|
||||
if (k->contexts[*cn]->identities[*in]->keypairs[*kp]->type==KEYTYPE_DID)
|
||||
@ -1002,16 +1010,88 @@ int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did)
|
||||
/* Compare DIDs */
|
||||
if (!strcasecmp(did,(char *)k->contexts[*cn]->identities[*in]
|
||||
->keypairs[*kp]->private_key))
|
||||
/* match */
|
||||
return 1;
|
||||
{
|
||||
/* match */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* See if there is still somewhere to search */
|
||||
(*in)++;
|
||||
if ((*in)>=k->contexts[*cn]->identity_count) {
|
||||
(*cn)++; (*in)=0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp,unsigned char *sid)
|
||||
{
|
||||
if (!k) return 0;
|
||||
|
||||
while ((*cn)<k->context_count) {
|
||||
while (((*cn)<k->context_count)&&((*in)>=k->contexts[*cn]->identity_count)) {
|
||||
(*cn)++; (*in)=0;
|
||||
}
|
||||
if ((*cn)>=k->context_count) return 0;
|
||||
|
||||
for((*kp)=0;*kp<k->contexts[*cn]->identities[*in]->keypair_count;(*kp)++)
|
||||
{
|
||||
if (k->contexts[*cn]->identities[*in]->keypairs[*kp]->type==KEYTYPE_CRYPTOBOX)
|
||||
{
|
||||
/* Compare SIDs */
|
||||
if (!bcmp(sid,(char *)k->contexts[*cn]->identities[*in]
|
||||
->keypairs[*kp]->public_key,SID_SIZE))
|
||||
{
|
||||
/* match */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See if there is still somewhere to search */
|
||||
(*in)++;
|
||||
if ((*in)>=k->contexts[*cn]->identity_count) {
|
||||
(*cn)++; (*in)=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int keyring_enter_pins(keyring_file *k,char *pinlist)
|
||||
{
|
||||
char pin[1024];
|
||||
int i,j=0;
|
||||
|
||||
for(i=0;i<=strlen(pinlist);i++)
|
||||
if (pinlist[i]==','||pinlist[i]==0)
|
||||
{
|
||||
pin[j]=0;
|
||||
keyring_enter_pin(k,pin);
|
||||
j=0;
|
||||
}
|
||||
else
|
||||
if (j<1023) pin[j++]=pinlist[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
keyring_file *keyring_open_with_pins(char *pinlist)
|
||||
{
|
||||
keyring_file *k=NULL;
|
||||
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return NULL;
|
||||
char *instancePath = serval_instancepath();
|
||||
char keyringFile[1024];
|
||||
snprintf(keyringFile,1024,"%s/serval.keyring",instancePath);
|
||||
if ((k=keyring_open(keyringFile))==NULL)
|
||||
{ fprintf(stderr,"keyring list:Failed to create/open keyring file\n");
|
||||
return NULL; }
|
||||
|
||||
keyring_enter_pins(k,pinlist);
|
||||
return k;
|
||||
}
|
||||
|
||||
|
7
serval.h
7
serval.h
@ -1158,8 +1158,11 @@ int keyring_identity_mac(keyring_context *c,keyring_identity *id,
|
||||
|
||||
/* Public calls to keyring management */
|
||||
keyring_file *keyring_open(char *file);
|
||||
int keyring_commit(keyring_file *k);
|
||||
int keyring_create_identity(keyring_file *k,keyring_context *c,char *pin);
|
||||
keyring_file *keyring_open_with_pins(char *pinlist);
|
||||
int keyring_enter_pin(keyring_file *k,char *pin);
|
||||
int keyring_enter_pins(keyring_file *k,char *pinlist);
|
||||
int keyring_set_did(keyring_identity *id,char *did);
|
||||
int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did);
|
||||
int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp,unsigned char *sid);
|
||||
int keyring_commit(keyring_file *k);
|
||||
int keyring_create_identity(keyring_file *k,keyring_context *c,char *pin);
|
||||
|
Loading…
Reference in New Issue
Block a user