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)
|
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
112
keyring.c
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
/* 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user