mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-13 13:53:16 +00:00
Added keyring.c and begun work on routines to manipulate keyrings.
This commit is contained in:
parent
ce5dc011b8
commit
2b260402b5
@ -5,7 +5,7 @@ SRCS= dna.c server.c client.c peers.c ciphers.c responses.c packetformats.c data
|
||||
rhizome.c rhizome_http.c rhizome_bundle.c rhizome_database.c rhizome_crypto.c \
|
||||
rhizome_packetformats.c rhizome_fetch.c sqlite3.c encode.c sha2.c randombytes.c \
|
||||
overlay_broadcast.c dna_identity.c commandline.c serval_packetvisualise.c \
|
||||
trans_cache.c
|
||||
trans_cache.c keyring.c
|
||||
|
||||
OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o dataformats.o \
|
||||
hlrdata.o srandomdev.o simulate.o batman.o export.o gateway.o \
|
||||
@ -14,7 +14,7 @@ OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o data
|
||||
rhizome.o rhizome_http.o rhizome_bundle.o rhizome_database.o rhizome_crypto.o \
|
||||
rhizome_packetformats.o rhizome_fetch.o sqlite3.o encode.o sha2.o randombytes.o \
|
||||
overlay_broadcast.o dna_identity.o commandline.o serval_packetvisualise.o \
|
||||
trans_cache.o
|
||||
trans_cache.o keyring.o
|
||||
|
||||
HDRS= Makefile serval.h sqlite-amalgamation-3070900/sqlite3.h sha2.h rhizome.h
|
||||
|
||||
|
207
keyring.c
Normal file
207
keyring.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright (C) 2010-2012 Paul Gardner-Stephen, Serval Project.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
|
||||
|
||||
/*
|
||||
Open keyring file, read BAM and create initial context using the
|
||||
stored salt. */
|
||||
keyring_file *keyring_open(char *file)
|
||||
{
|
||||
/* Allocate structure */
|
||||
keyring_file *k=calloc(sizeof(keyring_file),1);
|
||||
if (!k) { WHY("calloc() failed"); return NULL; }
|
||||
|
||||
/* Open keyring file read-write if we can, else use it read-only */
|
||||
k->file=fopen(file,"r+");
|
||||
if (!k->file) k->file=fopen(file,"r");
|
||||
if (!k->file) {
|
||||
WHY("Could not open keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
if (fseeko(k->file,0,SEEK_END))
|
||||
{
|
||||
WHY("Could not seek to end of keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
k->file_size=ftello(k->file);
|
||||
|
||||
/* Read BAMs for each slab in the file */
|
||||
keyring_bam **b=&k->bam;
|
||||
off_t offset=0;
|
||||
while(offset<k->file_size) {
|
||||
/* Read bitmap from slab.
|
||||
Also, if offset is zero, read the salt */
|
||||
if (fseeko(k->file,offset,SEEK_SET))
|
||||
{
|
||||
WHY("Could not seek to BAM in keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
*b=calloc(sizeof(keyring_bam),1);
|
||||
if (!(*b))
|
||||
{
|
||||
WHY("Could not allocate keyring_bam structure for key ring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
(*b)->file_offset=offset;
|
||||
/* Read bitmap */
|
||||
int r=fread(&(*b)->bitmap[0],KEYRING_BAM_BYTES,1,k->file);
|
||||
if (r!=1)
|
||||
{
|
||||
WHY("Could not read BAM from keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read salt if this is the first bitmap block.
|
||||
We setup a context for this self-supplied key-ring salt.
|
||||
(other keyring salts may be provided later on, resulting in
|
||||
multiple contexts being loaded) */
|
||||
if (!offset) {
|
||||
k->contexts[0]=calloc(sizeof(keyring_context),1);
|
||||
if (!k->contexts[0])
|
||||
{
|
||||
WHY("Could not allocate keyring_context for keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
k->contexts[0]->KeyRingSaltLen=KEYRING_PAGE_SIZE-KEYRING_BAM_BYTES;
|
||||
k->contexts[0]->KeyRingSalt=malloc(k->contexts[0]->KeyRingSaltLen);
|
||||
if (!k->contexts[0]->KeyRingSalt)
|
||||
{
|
||||
WHY("Could not allocate keyring_context->salt for keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r=fread(&k->contexts[0]->KeyRingSalt[0],k->contexts[0]->KeyRingSaltLen,1,k->file);
|
||||
if (r!=1)
|
||||
{
|
||||
WHY("Could not read salt from keyring file");
|
||||
keyring_free(k);
|
||||
return NULL;
|
||||
}
|
||||
k->context_count=1;
|
||||
}
|
||||
|
||||
/* Skip to next slab, and find next bam pointer. */
|
||||
offset+=KEYRING_PAGE_SIZE*(KEYRING_BAM_BYTES<<3);
|
||||
b=&(*b)->next;
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
void keyring_free(keyring_file *k)
|
||||
{
|
||||
int i;
|
||||
if (!k) return;
|
||||
|
||||
/* Close keyring file handle */
|
||||
if (k->file) fclose(k->file);
|
||||
k->file=NULL;
|
||||
|
||||
/* Free BAMs (no substructure, so easy) */
|
||||
keyring_bam *b=k->bam;
|
||||
while(b) {
|
||||
keyring_bam *last_bam=b;
|
||||
b=b->next;
|
||||
/* Clear out any private data */
|
||||
bzero(last_bam,sizeof(keyring_bam));
|
||||
/* release structure */
|
||||
free(last_bam);
|
||||
}
|
||||
|
||||
/* Free contexts (including subordinate identities and dynamically allocated salt strings).
|
||||
Don't forget to overwrite any private data. */
|
||||
for(i=0;i<KEYRING_MAX_CONTEXTS;i++)
|
||||
if (k->contexts[i]) {
|
||||
keyring_free_context(k->contexts[i]);
|
||||
k->contexts[i]=NULL;
|
||||
}
|
||||
|
||||
/* Wipe everything, just to be sure. */
|
||||
bzero(k,sizeof(keyring_file));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void keyring_free_context(keyring_context *c)
|
||||
{
|
||||
int i;
|
||||
if (!c) return;
|
||||
|
||||
if (c->KeyRingPin) {
|
||||
/* Wipe pin before freeing (slightly tricky since this is a variable length string */
|
||||
for(i=0;c->KeyRingPin[i];i++) c->KeyRingPin[i]=' '; i=0;
|
||||
free(c->KeyRingPin); c->KeyRingPin=NULL;
|
||||
}
|
||||
if (c->KeyRingSalt) {
|
||||
bzero(c->KeyRingSalt,c->KeyRingSaltLen);
|
||||
c->KeyRingSalt=NULL;
|
||||
c->KeyRingSaltLen=0;
|
||||
}
|
||||
|
||||
/* Wipe out any loaded identities */
|
||||
for(i=0;i<KEYRING_MAX_IDENTITIES;i++)
|
||||
if (c->identities[i]) keyring_free_identity(c->identities[i]);
|
||||
|
||||
/* Make sure any private data is wiped out */
|
||||
bzero(c,sizeof(keyring_context));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void keyring_free_identity(keyring_identity *id)
|
||||
{
|
||||
int i;
|
||||
if (id->PKRPin) {
|
||||
/* Wipe pin before freeing (slightly tricky since this is a variable length string */
|
||||
for(i=0;id->PKRPin[i];i++) id->PKRPin[i]=' '; i=0;
|
||||
free(id->PKRPin); id->PKRPin=NULL;
|
||||
}
|
||||
|
||||
for(i=0;i<PKR_MAX_KEYPAIRS;i++)
|
||||
if (id->keypairs[i])
|
||||
keyring_free_keypair(id->keypairs[i]);
|
||||
|
||||
bzero(id,sizeof(keyring_identity));
|
||||
return;
|
||||
}
|
||||
|
||||
void keyring_free_keypair(keypair *kp)
|
||||
{
|
||||
if (kp->private_key) {
|
||||
bzero(kp->private_key,kp->private_key_len);
|
||||
free(kp->private_key);
|
||||
kp->private_key=NULL;
|
||||
}
|
||||
if (kp->public_key) {
|
||||
bzero(kp->public_key,kp->public_key_len);
|
||||
free(kp->public_key);
|
||||
kp->public_key=NULL;
|
||||
}
|
||||
|
||||
bzero(kp,sizeof(keypair));
|
||||
return;
|
||||
}
|
65
serval.h
65
serval.h
@ -1009,11 +1009,12 @@ typedef struct sockaddr_mdp {
|
||||
#define MDP_NOSIGN 0x0400
|
||||
#define MDP_TX 1
|
||||
#define MDP_RX 2
|
||||
typedef struct overlay_mdp_outgoing_frame {
|
||||
typedef struct overlay_mdp_data_frame {
|
||||
sockaddr_mdp src;
|
||||
sockaddr_mdp dst;
|
||||
unsigned short payload_length;
|
||||
unsigned char payload[1900];
|
||||
#define MDP_MTU 2000
|
||||
unsigned char payload[MDP_MTU-100];
|
||||
} overlay_mdp_data_frame;
|
||||
|
||||
#define MDP_BIND 3
|
||||
@ -1036,7 +1037,7 @@ typedef struct overlay_mdp_addrlist {
|
||||
unsigned int last_sid;
|
||||
unsigned char frame_sid_count; /* how many of the following 59 slots are
|
||||
populated */
|
||||
/* 59*32 < 1900, so up to 59 SIDs in a single reply.
|
||||
/* 59*32 < (MDP_MTU-100), so up to 59 SIDs in a single reply.
|
||||
Multiple replies can be used to respond with more. */
|
||||
#define MDP_MAX_SID_REQUEST 59
|
||||
unsigned char sids[MDP_MAX_SID_REQUEST][SID_SIZE];
|
||||
@ -1053,7 +1054,7 @@ typedef struct overlay_mdp_frame {
|
||||
overlay_mdp_error error;
|
||||
/* 2048 is too large (causes EMSGSIZE errors on OSX, but probably fine on
|
||||
Linux) */
|
||||
char raw[2000];
|
||||
char raw[MDP_MTU];
|
||||
};
|
||||
} overlay_mdp_frame;
|
||||
|
||||
@ -1087,3 +1088,59 @@ void *_serval_debug_malloc(unsigned int bytes,char *file,const char *func,int li
|
||||
void *_serval_debug_calloc(unsigned int bytes,unsigned int count,char *file,const char *func,int line);
|
||||
void _serval_debug_free(void *p,char *file,const char *func,int line);
|
||||
#endif
|
||||
|
||||
typedef struct keypair {
|
||||
int type;
|
||||
unsigned char *private_key;
|
||||
int private_key_len;
|
||||
unsigned char *public_key;
|
||||
int public_key_len;
|
||||
} keypair;
|
||||
|
||||
/* Contains just the list of private:public key pairs and types,
|
||||
the pin used to extract them, and the slot in the keyring file
|
||||
(so that it can be replaced/rewritten as required). */
|
||||
#define PKR_MAX_KEYPAIRS 64
|
||||
typedef struct keyring_identity {
|
||||
char *PKRPin;
|
||||
unsigned int slot;
|
||||
keypair *keypairs[PKR_MAX_KEYPAIRS];
|
||||
} keyring_identity;
|
||||
|
||||
/* 64K identities, can easily be increased should the need arise,
|
||||
but keep it low-ish for now so that the 64K pointers don't eat too
|
||||
much ram on a small device. Should probably think about having
|
||||
small and large device settings for some of these things */
|
||||
#define KEYRING_MAX_IDENTITIES 65536
|
||||
typedef struct keyring_context {
|
||||
char *KeyRingPin;
|
||||
unsigned char *KeyRingSalt;
|
||||
int KeyRingSaltLen;
|
||||
|
||||
int identity_count;
|
||||
keyring_identity *identities[KEYRING_MAX_IDENTITIES];
|
||||
} keyring_context;
|
||||
|
||||
#define KEYRING_PAGE_SIZE 4096
|
||||
#define KEYRING_BAM_BYTES 2048
|
||||
#define KEYRING_SLAB_SIZE (KEYRING_PAGE_SIZE*(KEYRING_BAM_BYTES<<3))
|
||||
typedef struct keyring_bam {
|
||||
unsigned long file_offset;
|
||||
unsigned char bitmap[KEYRING_BAM_BYTES];
|
||||
struct keyring_bam *next;
|
||||
} keyring_bam;
|
||||
|
||||
#define KEYRING_MAX_CONTEXTS 256
|
||||
typedef struct keyring_file {
|
||||
int context_count;
|
||||
keyring_bam *bam;
|
||||
keyring_context *contexts[KEYRING_MAX_CONTEXTS];
|
||||
FILE *file;
|
||||
off_t file_size;
|
||||
} keyring_file;
|
||||
|
||||
keyring_file *keyring_open(char *file);
|
||||
void keyring_free(keyring_file *k);
|
||||
void keyring_free_context(keyring_context *c);
|
||||
void keyring_free_identity(keyring_identity *id);
|
||||
void keyring_free_keypair(keypair *kp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user