Subversion Repositories planix.SVN

Rev

Rev 22 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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