Subversion Repositories planix.SVN

Rev

Rev 33 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 7u83 1
#include "os.h"
2 - 2
#include <bio.h>
3
#include <libsec.h>
4
 
5
enum{ ThumbTab = 1<<10 };
6
 
33 7u83 7
static Thumbprint*
8
tablehead(uchar *hash, Thumbprint *table)
2 - 9
{
33 7u83 10
	return &table[((hash[0]<<8) + hash[1]) & (ThumbTab-1)];
2 - 11
}
12
 
13
void
14
freeThumbprints(Thumbprint *table)
15
{
16
	Thumbprint *hd, *p, *q;
33 7u83 17
 
18
	if(table == nil)
19
		return;
2 - 20
	for(hd = table; hd < table+ThumbTab; hd++){
33 7u83 21
		for(p = hd->next; p && p != hd; p = q){
2 - 22
			q = p->next;
23
			free(p);
24
		}
25
	}
26
	free(table);
27
}
28
 
29
int
33 7u83 30
okThumbprint(uchar *hash, int len, Thumbprint *table)
2 - 31
{
33 7u83 32
	Thumbprint *hd, *p;
2 - 33
 
33 7u83 34
	if(table == nil)
35
		return 0;
36
	hd = tablehead(hash, table);
37
	for(p = hd->next; p; p = p->next){
38
		if(p->len == len && memcmp(hash, p->hash, len) == 0)
2 - 39
			return 1;
33 7u83 40
		if(p == hd)
41
			break;
42
	}
2 - 43
	return 0;
44
}
45
 
33 7u83 46
int
47
okCertificate(uchar *cert, int len, Thumbprint *table)
2 - 48
{
33 7u83 49
	uchar hash[SHA2_256dlen];
50
	char thumb[2*SHA2_256dlen+1];
51
 
52
	if(table == nil){
53
		werrstr("no thumbprints provided");
54
		return 0;
55
	}
56
	if(cert == nil || len <= 0){
57
		werrstr("no certificate provided");
58
		return 0;
59
	}
60
 
61
	sha1(cert, len, hash, nil);
62
	if(okThumbprint(hash, SHA1dlen, table))
63
		return 1;
64
 
65
	sha2_256(cert, len, hash, nil);
66
	if(okThumbprint(hash, SHA2_256dlen, table))
67
		return 1;
68
 
69
	if(X509digestSPKI(cert, len, sha2_256, hash) < 0)
70
		return 0;
71
	if(okThumbprint(hash, SHA2_256dlen, table))
72
		return 1;
73
 
74
	len = enc64(thumb, sizeof(thumb), hash, SHA2_256dlen);
75
	while(len > 0 && thumb[len-1] == '=')
76
		len--;
77
	thumb[len] = '\0';
78
	werrstr("sha256=%s", thumb);
79
 
80
	return 0;
81
}
82
 
83
static int
84
loadThumbprints(char *file, char *tag, Thumbprint *table, Thumbprint *crltab, int depth)
85
{
86
	Thumbprint *hd, *entry;
87
	char *line, *field[50];
88
	uchar hash[SHA2_256dlen];
2 - 89
	Biobuf *bin;
33 7u83 90
	int len, n;
2 - 91
 
33 7u83 92
	if(depth > 8){
93
		werrstr("too many includes, last file %s", file);
94
		return -1;
95
	}
96
	if(access(file, AEXIST) < 0)
97
		return 0;	/* not an error */
98
	if((bin = Bopen(file, OREAD)) == nil)
99
		return -1;
100
	for(; (line = Brdstr(bin, '\n', 1)) != nil; free(line)){
2 - 101
		if(tokenize(line, field, nelem(field)) < 2)
102
			continue;
103
		if(strcmp(field[0], "#include") == 0){
33 7u83 104
			if(loadThumbprints(field[1], tag, table, crltab, depth+1) < 0)
105
				goto err;
2 - 106
			continue;
107
		}
33 7u83 108
		if(strcmp(field[0], tag) != 0)
2 - 109
			continue;
33 7u83 110
		if(strncmp(field[1], "sha1=", 5) == 0){
111
			field[1] += 5;
112
			len = SHA1dlen;
113
		} else if(strncmp(field[1], "sha256=", 7) == 0){
114
			field[1] += 7;
115
			len = SHA2_256dlen;
116
		} else {
2 - 117
			continue;
33 7u83 118
		}
119
		n = strlen(field[1]);
120
		if((n != len*2 || dec16(hash, len, field[1], n) != len)
121
		&& dec64(hash, len, field[1], n) != len){
122
			werrstr("malformed %s entry in %s: %s", tag, file, field[1]);
123
			goto err;
124
		}
125
		if(crltab && okThumbprint(hash, len, crltab))
126
			continue;
127
		hd = tablehead(hash, table);
128
		if(hd->next == nil)
129
			entry = hd;
130
		else {
131
			if((entry = malloc(sizeof(*entry))) == nil)
132
				goto err;
133
			entry->next = hd->next;
134
		}
135
		hd->next = entry;
136
		entry->len = len;
137
		memcpy(entry->hash, hash, len);
2 - 138
	}
139
	Bterm(bin);
33 7u83 140
	return 0;
141
err:
142
	free(line);
143
	Bterm(bin);
144
	return -1;
2 - 145
}
146
 
147
Thumbprint *
33 7u83 148
initThumbprints(char *ok, char *crl, char *tag)
2 - 149
{
33 7u83 150
	Thumbprint *table, *crltab;
2 - 151
 
33 7u83 152
	table = crltab = nil;
2 - 153
	if(crl){
33 7u83 154
		if((crltab = malloc(ThumbTab * sizeof(*crltab))) == nil)
155
			goto err;
156
		memset(crltab, 0, ThumbTab * sizeof(*crltab));
157
		if(loadThumbprints(crl, tag, crltab, nil, 0) < 0)
158
			goto err;
2 - 159
	}
33 7u83 160
	if((table = malloc(ThumbTab * sizeof(*table))) == nil)
161
		goto err;
162
	memset(table, 0, ThumbTab * sizeof(*table));
163
	if(loadThumbprints(ok, tag, table, crltab, 0) < 0){
164
		freeThumbprints(table);
165
		table = nil;
166
	}
167
err:
168
	freeThumbprints(crltab);
2 - 169
	return table;
170
}