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:
gardners 2012-04-12 23:15:21 +09:30
parent 7b53fd6782
commit 7b8d78533d
3 changed files with 146 additions and 59 deletions

View File

@ -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) int app_keyring_create(int argc, char **argv, struct command_line_option *o)
{ {
if (create_serval_instance_dir() == -1) char *pin = cli_arg(argc, argv, o, "pin,pin ...", "");
return -1; keyring_file *k=keyring_open_with_pins(pin);
char *instancePath = serval_instancepath(); if (!k) fprintf(stderr,"keyring create:Failed to create/open keyring file\n");
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");
return 0; return 0;
} }
int app_keyring_list(int argc, char **argv, struct command_line_option *o) int app_keyring_list(int argc, char **argv, struct command_line_option *o)
{ {
if (create_serval_instance_dir() == -1) char *pin = cli_arg(argc, argv, o, "pin,pin ...", "");
return -1; keyring_file *k=keyring_open_with_pins(pin);
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,",");
}
int cn=0; int cn=0;
int in=0; int in=0;
@ -724,17 +705,20 @@ int app_keyring_list(int argc, char **argv, struct command_line_option *o)
{ {
int kpn; int kpn;
keypair *kp; keypair *kp;
unsigned char *sid=NULL,*did=NULL;
for(kpn=0;kpn<k->contexts[cn]->identities[in]->keypair_count;kpn++) for(kpn=0;kpn<k->contexts[cn]->identities[in]->keypair_count;kpn++)
{ {
kp=k->contexts[cn]->identities[in]->keypairs[kpn]; kp=k->contexts[cn]->identities[in]->keypairs[kpn];
if (!kpn) if (kp->type==KEYTYPE_CRYPTOBOX) sid=kp->public_key;
printf("Identity accessed with pin='%s'\n", if (kp->type==KEYTYPE_DID) did=kp->private_key;
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 (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; 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", ""); const char *pin = cli_arg(argc, argv, o, "pin", "");
if (create_serval_instance_dir() == -1) keyring_file *k=keyring_open_with_pins("");
return -1; if (!k) { fprintf(stderr,"keyring add:Failed to create/open keyring file\n");
char *instancePath = serval_instancepath(); return -1; }
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; }
if (keyring_create_identity(k,k->contexts[0],(char *)pin)) 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); keyring_free(k);
return 0; 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. /* NULL marks ends of command structure.
@ -813,7 +815,9 @@ command_line_option command_line_options[]={
"Create a new keyring file."}, "Create a new keyring file."},
{app_keyring_list,{"keyring","list","[<pin,pin ...>]",NULL},0, {app_keyring_list,{"keyring","list","[<pin,pin ...>]",NULL},0,
"List identites in specified key ring that can be accessed using the specified PINs"}, "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"}, "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}} {NULL,{NULL}}
}; };

112
keyring.c
View File

@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "serval.h" #include "serval.h"
#include "nacl.h" #include "nacl.h"
#define NO_ROTATION
static int urandomfd = -1; static int urandomfd = -1;
int urandombytes(unsigned char *x,unsigned long long xlen) 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"); WHY("too many or too long key pairs");
ofs=0; goto kpi_safeexit; ofs=0; goto kpi_safeexit;
} }
printf("key type 0x%02x @ 0x%x\n",i->keypairs[kp]->type,ofs);
packed[ofs++]=i->keypairs[kp]->type; packed[ofs++]=i->keypairs[kp]->type;
switch(i->keypairs[kp]->type) { switch(i->keypairs[kp]->type) {
case KEYTYPE_RHIZOME: 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)); KEYRING_PAGE_SIZE-(PKR_SALT_BYTES+PKR_MAC_BYTES+2));
packed[rotate_ofs]=rotation>>8; packed[rotate_ofs]=rotation>>8;
packed[rotate_ofs+1]=rotation&0xff; packed[rotate_ofs+1]=rotation&0xff;
printf("Writing record with rotation = 0x%x\n",rotation);
return exit_code; return exit_code;
} }
@ -614,15 +610,12 @@ keyring_identity *keyring_unpack_identity(unsigned char *slot,char *pin)
break; break;
} }
id->keypair_count++; id->keypair_count++;
printf("keypair_count=%d\n",id->keypair_count);
fflush(stdout);
break; break;
default: default:
/* Invalid data, so invalid record. Free and return failure. /* Invalid data, so invalid record. Free and return failure.
We don't complain about this, however, as it is the natural We don't complain about this, however, as it is the natural
effect of trying a pin on an incorrect keyring slot. */ effect of trying a pin on an incorrect keyring slot. */
keyring_free_identity(id); keyring_free_identity(id);
WHY("PKR has invalid structure (wrong pin?)");
return NULL; 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. */ /* 3. Unpack contents of slot into a new identity in the provided context. */
id=keyring_unpack_identity(slot,pin); id=keyring_unpack_identity(slot,pin);
if (!id) { 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; goto kdp_safeexit;
} }
id->slot=slot_number;
/* 4. Verify that slot is self-consistent (check MAC) */ /* 4. Verify that slot is self-consistent (check MAC) */
if (keyring_identity_mac(k->contexts[0],id,&slot[0],hash)) { 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 off_t file_offset
=KEYRING_PAGE_SIZE =KEYRING_PAGE_SIZE
*k->contexts[cn]->identities[in]->slot; *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++; errorCount++;
else else
if (fwrite(pkr,KEYRING_PAGE_SIZE,1,k->file)!=1) 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 */ /* allocate if needed */
if (i>=id->keypair_count) { 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); unsigned char *packedDid=calloc(32,1);
if (!packedDid) return WHY("calloc() failed"); if (!packedDid) return WHY("calloc() failed");
id->keypairs[i]->private_key=packedDid; 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 */ /* Store DID unpacked for ease of searching */
int len=strlen(did); if (len>31) len=31; 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); bzero(&id->keypairs[i]->private_key[len],32-len);
dump("storing did",&id->keypairs[i]->private_key[0],32);
return 0; return 0;
} }
int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did) 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) {
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)++) for(*kp=0;*kp<k->contexts[*cn]->identities[*in]->keypair_count;(*kp)++)
{ {
if (k->contexts[*cn]->identities[*in]->keypairs[*kp]->type==KEYTYPE_DID) 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 */ /* Compare DIDs */
if (!strcasecmp(did,(char *)k->contexts[*cn]->identities[*in] if (!strcasecmp(did,(char *)k->contexts[*cn]->identities[*in]
->keypairs[*kp]->private_key)) ->keypairs[*kp]->private_key))
/* match */ {
return 1; /* match */
return 1;
}
} }
} }
/* See if there is still somewhere to search */ /* See if there is still somewhere to search */
(*in)++;
if ((*in)>=k->contexts[*cn]->identity_count) { if ((*in)>=k->contexts[*cn]->identity_count) {
(*cn)++; (*in)=0; (*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;
}

View File

@ -1158,8 +1158,11 @@ int keyring_identity_mac(keyring_context *c,keyring_identity *id,
/* Public calls to keyring management */ /* Public calls to keyring management */
keyring_file *keyring_open(char *file); keyring_file *keyring_open(char *file);
int keyring_commit(keyring_file *k); keyring_file *keyring_open_with_pins(char *pinlist);
int keyring_create_identity(keyring_file *k,keyring_context *c,char *pin);
int keyring_enter_pin(keyring_file *k,char *pin); 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_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_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);