libsec: improve thumbprint code

1) handle errors when loading thumbprint file.
initThumbprints() now returns nil and sets errstr
on error. a syntax error in a thumbprint file
should be reported instead of silently ignored!
(have to check users)

2) fix memory leak in initThumbprints(); we have to use
freeThumbprints() instead of free to release crltab.

3) use the actual head entries for thumbprint
storage in the thumbprints array. most thumbprint
files are rather sparse.

4) remove private emalloc() function. we shouldnt
just exit the calling process on allocation error,
instead handle error properly. this is a library!
This commit is contained in:
cinap_lenrek 2014-02-28 01:23:11 +01:00
parent ff5ac0c5cb
commit dd076567a4

View file

@ -7,26 +7,21 @@
enum{ ThumbTab = 1<<10 }; enum{ ThumbTab = 1<<10 };
static void * static Thumbprint*
emalloc(int n) tablehead(uchar *sum, Thumbprint *table)
{ {
void *p; return &table[((sum[0]<<8) + sum[1]) & (ThumbTab-1)];
if(n==0)
n=1;
p = malloc(n);
if(p == nil){
exits("out of memory");
}
memset(p, 0, n);
return p;
} }
void void
freeThumbprints(Thumbprint *table) freeThumbprints(Thumbprint *table)
{ {
Thumbprint *hd, *p, *q; Thumbprint *hd, *p, *q;
if(table == nil)
return;
for(hd = table; hd < table+ThumbTab; hd++){ for(hd = table; hd < table+ThumbTab; hd++){
for(p = hd->next; p; p = q){ for(p = hd->next; p && p != hd; p = q){
q = p->next; q = p->next;
free(p); free(p);
} }
@ -37,61 +32,86 @@ freeThumbprints(Thumbprint *table)
int int
okThumbprint(uchar *sum, Thumbprint *table) okThumbprint(uchar *sum, Thumbprint *table)
{ {
Thumbprint *p; Thumbprint *hd, *p;
int i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1);
for(p = table[i].next; p; p = p->next) hd = tablehead(sum, table);
for(p = hd->next; p; p = p->next){
if(memcmp(sum, p->sha1, SHA1dlen) == 0) if(memcmp(sum, p->sha1, SHA1dlen) == 0)
return 1; return 1;
if(p == hd)
break;
}
return 0; return 0;
} }
static void static int
loadThumbprints(char *file, Thumbprint *table, Thumbprint *crltab) loadThumbprints(char *file, Thumbprint *table, Thumbprint *crltab)
{ {
Thumbprint *entry; Thumbprint *hd, *entry;
Biobuf *bin;
char *line, *field[50]; char *line, *field[50];
uchar sum[SHA1dlen]; uchar sum[SHA1dlen];
int i; Biobuf *bin;
bin = Bopen(file, OREAD); if((bin = Bopen(file, OREAD)) == nil)
if(bin == nil) return -1;
return; for(; (line = Brdstr(bin, '\n', 1)) != nil; free(line)){
for(; (line = Brdstr(bin, '\n', 1)) != 0; free(line)){
if(tokenize(line, field, nelem(field)) < 2) if(tokenize(line, field, nelem(field)) < 2)
continue; continue;
if(strcmp(field[0], "#include") == 0){ if(strcmp(field[0], "#include") == 0){
loadThumbprints(field[1], table, crltab); if(loadThumbprints(field[1], table, crltab) < 0)
goto err;
continue; continue;
} }
if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", strlen("sha1=")) != 0) if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", 5) != 0)
continue; continue;
field[1] += strlen("sha1="); field[1] += 5;
dec16(sum, sizeof(sum), field[1], strlen(field[1])); if(dec16(sum, SHA1dlen, field[1], strlen(field[1])) != SHA1dlen){
werrstr("malformed x509 entry in %s: %s", file, field[1]);
goto err;
}
if(crltab && okThumbprint(sum, crltab)) if(crltab && okThumbprint(sum, crltab))
continue; continue;
entry = (Thumbprint*)emalloc(sizeof(*entry)); hd = tablehead(sum, table);
if(hd->next == nil)
entry = hd;
else {
if((entry = malloc(sizeof(*entry))) == nil)
goto err;
entry->next = hd->next;
}
hd->next = entry;
memcpy(entry->sha1, sum, SHA1dlen); memcpy(entry->sha1, sum, SHA1dlen);
i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1);
entry->next = table[i].next;
table[i].next = entry;
} }
Bterm(bin); Bterm(bin);
return 0;
err:
free(line);
Bterm(bin);
return -1;
} }
Thumbprint * Thumbprint *
initThumbprints(char *ok, char *crl) initThumbprints(char *ok, char *crl)
{ {
Thumbprint *table, *crltab = nil; Thumbprint *table, *crltab;
table = crltab = nil;
if(crl){ if(crl){
crltab = emalloc(ThumbTab * sizeof(*table)); if((crltab = malloc(ThumbTab * sizeof(*crltab))) == nil)
loadThumbprints(crl, crltab, nil); goto err;
memset(crltab, 0, ThumbTab * sizeof(*crltab));
if(loadThumbprints(crl, crltab, nil) < 0)
goto err;
} }
table = emalloc(ThumbTab * sizeof(*table)); if((table = malloc(ThumbTab * sizeof(*table))) == nil)
loadThumbprints(ok, table, crltab); goto err;
free(crltab); memset(table, 0, ThumbTab * sizeof(*table));
if(loadThumbprints(ok, table, crltab) < 0){
freeThumbprints(table);
table = nil;
}
err:
freeThumbprints(crltab);
return table; return table;
} }