... | ... |
@@ -1,4 +1,5 @@ |
1 | 1 |
#include "asn1.h" |
2 |
+#include "md5.h" |
|
2 | 3 |
#include "others.h" |
3 | 4 |
#include "bignum.h" |
4 | 5 |
|
... | ... |
@@ -14,6 +15,18 @@ static int map_sha1(fmap_t *map, void *data, unsigned int len, uint8_t sha1[SHA1 |
14 | 14 |
return 0; |
15 | 15 |
} |
16 | 16 |
|
17 |
+static int map_md5(fmap_t *map, void *data, unsigned int len, uint8_t *md5) { |
|
18 |
+ cli_md5_ctx ctx; |
|
19 |
+ if(!fmap_need_ptr_once(map, data, len)) { |
|
20 |
+ cli_dbgmsg("map_md5: failed to read hash data\n"); |
|
21 |
+ return 1; |
|
22 |
+ } |
|
23 |
+ cli_md5_init(&ctx); |
|
24 |
+ cli_md5_update(&ctx, data, len); |
|
25 |
+ cli_md5_final(md5, &ctx); |
|
26 |
+ return 0; |
|
27 |
+} |
|
28 |
+ |
|
17 | 29 |
|
18 | 30 |
int asn1_get_obj(fmap_t *map, void *asn1data, unsigned int *asn1len, struct cli_asn1 *obj) { |
19 | 31 |
unsigned int asn1_sz = *asn1len; |
... | ... |
@@ -422,15 +435,18 @@ int asn1_get_rsa_pubkey(fmap_t *map, void **asn1data, unsigned int *size, cli_cr |
422 | 422 |
|
423 | 423 |
int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, cli_crt *x509) { |
424 | 424 |
struct cli_asn1 crt, tbs, obj; |
425 |
- unsigned int avail; |
|
425 |
+ unsigned int avail, tbssize; |
|
426 | 426 |
cli_crt_hashtype hashtype1, hashtype2; |
427 |
+ uint8_t *tbsdata; |
|
427 | 428 |
void *next; |
428 | 429 |
|
429 | 430 |
if(asn1_expect_objtype(map, *asn1data, size, &crt, 0x30)) /* SEQUENCE */ |
430 | 431 |
return 1; |
431 | 432 |
|
433 |
+ tbsdata = crt.content; |
|
432 | 434 |
if(asn1_expect_objtype(map, crt.content, &crt.size, &tbs, 0x30)) /* SEQUENCE - TBSCertificate */ |
433 | 435 |
return 1; |
436 |
+ tbssize = (uint8_t *)tbs.next - tbsdata; |
|
434 | 437 |
|
435 | 438 |
if(asn1_expect_objtype(map, tbs.content, &tbs.size, &obj, 0xa0)) /* [0] */ |
436 | 439 |
return 1; |
... | ... |
@@ -494,6 +510,7 @@ int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, cli_crt *x50 |
494 | 494 |
cli_dbgmsg("asn1_get_x509: found conglicting rsa hash types\n"); |
495 | 495 |
return 1; |
496 | 496 |
} |
497 |
+ x509->hashtype = hashtype1; |
|
497 | 498 |
|
498 | 499 |
if(asn1_expect_objtype(map, tbs.next, &crt.size, &obj, 0x03)) /* signature */ |
499 | 500 |
return 1; |
... | ... |
@@ -509,12 +526,14 @@ int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, cli_crt *x50 |
509 | 509 |
cli_dbgmsg("asn1_get_x509: cannot convert signature to big number\n"); |
510 | 510 |
return 1; |
511 | 511 |
} |
512 |
- |
|
513 | 512 |
if(crt.size) { |
514 | 513 |
cli_dbgmsg("asn1_get_x509: found unexpected extra data in signature\n"); |
515 | 514 |
return 1; |
516 | 515 |
} |
517 | 516 |
|
517 |
+ if((x509->hashtype == CLI_SHA1RSA && map_sha1(map, tbsdata, tbssize, x509->tbshash)) || (x509->hashtype == CLI_MD5RSA && (map_md5(map, tbsdata, tbssize, x509->tbshash)))) |
|
518 |
+ return 1; |
|
519 |
+ |
|
518 | 520 |
*asn1data = crt.next; |
519 | 521 |
return 0; |
520 | 522 |
} |
... | ... |
@@ -697,6 +716,7 @@ int asn1_parse_mscat(FILE *f, crtmgr *cmgr) { |
697 | 697 |
break; |
698 | 698 |
} |
699 | 699 |
crtmgr_add(cmgr, &x509); |
700 |
+ crtmgr_verify(cmgr, &x509); |
|
700 | 701 |
cli_crt_clear(&x509); |
701 | 702 |
} |
702 | 703 |
if(dsize) |
... | ... |
@@ -6,8 +6,11 @@ |
6 | 6 |
#include "others.h" |
7 | 7 |
|
8 | 8 |
int cli_crt_init(cli_crt *x509) { |
9 |
- if(mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL)) |
|
9 |
+ int ret; |
|
10 |
+ if((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) { |
|
11 |
+ cli_errmsg("cli_crt_init: mp_init_multi failed with %d\n", ret); |
|
10 | 12 |
return 1; |
13 |
+ } |
|
11 | 14 |
x509->not_before = x509->not_after = 0; |
12 | 15 |
x509->prev = x509->next = NULL; |
13 | 16 |
return 0; |
... | ... |
@@ -17,16 +20,24 @@ void cli_crt_clear(cli_crt *x509) { |
17 | 17 |
mp_clear_multi(&x509->n, &x509->e, &x509->sig, NULL); |
18 | 18 |
} |
19 | 19 |
|
20 |
-int crtmgr_add(crtmgr *m, cli_crt *x509) { |
|
20 |
+static cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509) { |
|
21 | 21 |
cli_crt *i = m->crts; |
22 | 22 |
while(i) { |
23 | 23 |
if(x509->not_before == i->not_before && x509->not_after == i->not_after && !memcmp(x509->subject, i->subject, sizeof(i->subject))) { |
24 | 24 |
if(mp_cmp(&x509->n, &i->n) || mp_cmp(&x509->e, &i->e)) |
25 | 25 |
cli_dbgmsg("crtmgr_add: conflicting pk for the same cert\n"); |
26 |
- return 0; |
|
26 |
+ return i; |
|
27 | 27 |
} |
28 | 28 |
i = i->next; |
29 | 29 |
} |
30 |
+ return NULL; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+int crtmgr_add(crtmgr *m, cli_crt *x509) { |
|
34 |
+ cli_crt *i = crtmgr_lookup(m, x509); |
|
35 |
+ |
|
36 |
+ if(i) |
|
37 |
+ return 0; |
|
30 | 38 |
i = cli_malloc(sizeof(*i)); |
31 | 39 |
if(!i) |
32 | 40 |
return 1; |
... | ... |
@@ -50,10 +61,152 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) { |
50 | 50 |
if(m->crts) |
51 | 51 |
m->crts->prev = i; |
52 | 52 |
m->crts = i; |
53 |
- cli_dbgmsg("crtmgr_add: added cert\n"); |
|
53 |
+ |
|
54 |
+ { |
|
55 |
+ char issuer[SHA1_HASH_SIZE*2+1], subject[SHA1_HASH_SIZE*2+1], mod[1024], exp[1024]; |
|
56 |
+ int j; |
|
57 |
+ mp_toradix_n(&i->n, mod, 16, sizeof(mod)); |
|
58 |
+ mp_toradix_n(&i->e, exp, 16, sizeof(exp)); |
|
59 |
+ for(j=0; j<SHA1_HASH_SIZE; j++) { |
|
60 |
+ sprintf(&issuer[j*2], "%02x", i->issuer[j]); |
|
61 |
+ sprintf(&subject[j*2], "%02x", i->subject[j]); |
|
62 |
+ } |
|
63 |
+ cli_dbgmsg("crtmgr_add: added cert s:%s i:%s n:%s e:%s\n", subject, issuer, mod, exp); |
|
64 |
+ } |
|
54 | 65 |
return 0; |
55 | 66 |
} |
56 | 67 |
|
68 |
+ |
|
69 |
+int crtmgr_verify(crtmgr *m, cli_crt *x509) { |
|
70 |
+ uint8_t d[513]; |
|
71 |
+ cli_crt *i = m->crts; |
|
72 |
+ mp_int x; |
|
73 |
+ int ret, j, siglen = mp_unsigned_bin_size(&x509->sig), hashlen; |
|
74 |
+ |
|
75 |
+ if((ret = mp_init(&x))) { |
|
76 |
+ cli_errmsg("crtmgr_verify: mp_init failed with %d\n", ret); |
|
77 |
+ return 1; |
|
78 |
+ } |
|
79 |
+ for(i = m->crts; i; i = i->next) { |
|
80 |
+ if(!memcmp(x509->issuer, i->subject, sizeof(i->subject)) && siglen == mp_unsigned_bin_size(&i->n)) { |
|
81 |
+ if((ret = mp_exptmod(&x509->sig, &i->e, &i->n, &x))) { |
|
82 |
+ cli_warnmsg("crtmgr_verify: verification failed: mp_exptmod failed with %d\n", ret); |
|
83 |
+ continue; |
|
84 |
+ } |
|
85 |
+ if(mp_unsigned_bin_size(&x) != siglen - 1) |
|
86 |
+ continue; |
|
87 |
+ if((ret = mp_to_unsigned_bin(&x, d))) { |
|
88 |
+ cli_warnmsg("crtmgr_verify: mp_unsigned_bin_size failed with %d\n", ret); |
|
89 |
+ continue; |
|
90 |
+ } |
|
91 |
+ if(*d != 1) /* block type 1 */ |
|
92 |
+ continue; |
|
93 |
+ |
|
94 |
+ siglen -= 1; /* sizeof(x) */ |
|
95 |
+ for(j=1; j<siglen-2; j++) /* upto sizeof(x) - 2 */ |
|
96 |
+ if(d[j] != 0xff) |
|
97 |
+ break; |
|
98 |
+ if(j == siglen - 2) |
|
99 |
+ continue; |
|
100 |
+ if(d[j] != 0) |
|
101 |
+ continue; |
|
102 |
+ |
|
103 |
+ j++; |
|
104 |
+ siglen -= j; /* asn1 size */ |
|
105 |
+ |
|
106 |
+ if(siglen < 2 || d[j] != 0x30 || d[j+1] + 2 != siglen) |
|
107 |
+ continue; |
|
108 |
+ siglen -= 2; |
|
109 |
+ j+=2; |
|
110 |
+ |
|
111 |
+ if(siglen <2 || d[j] != 0x30 || (hashlen = d[j+1]) != 9) {/* FIXME - md5 */ |
|
112 |
+ cli_errmsg("crtmgr_verify: ACAB HERE MD5 MISSING!!!\n"); |
|
113 |
+ continue; |
|
114 |
+ } |
|
115 |
+ siglen -= 2; |
|
116 |
+ j+=2; |
|
117 |
+ if(siglen < hashlen || memcmp(&d[j], "\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00", hashlen)) { |
|
118 |
+ cli_errmsg("crtmgr_verify: ACAB HERE MD5 MISSING!!!\n"); |
|
119 |
+ continue; |
|
120 |
+ } |
|
121 |
+ siglen -= hashlen; |
|
122 |
+ j += hashlen; |
|
123 |
+ hashlen = x509->hashtype == CLI_SHA1RSA ? SHA1_HASH_SIZE : 16; |
|
124 |
+ if(siglen < 2 || d[j] != 0x04 || d[j+1] != hashlen) |
|
125 |
+ continue; |
|
126 |
+ siglen -= 2; |
|
127 |
+ j+=2; |
|
128 |
+ if(siglen != hashlen) |
|
129 |
+ continue; |
|
130 |
+ if(memcmp(&d[j], x509->tbshash, hashlen)) |
|
131 |
+ continue; |
|
132 |
+ /* SEQ { SEQ { OID, NULL }, OCTET STRING */ |
|
133 |
+ { |
|
134 |
+ char buf[1024]; |
|
135 |
+ mp_toradix_n(&x, buf, 16, sizeof(buf)); |
|
136 |
+ cli_dbgmsg("crtmgr_verify: %u, %u, %u, %s\n", siglen, d[j+1], hashlen, buf); |
|
137 |
+ } |
|
138 |
+ return 0; |
|
139 |
+ } |
|
140 |
+ } |
|
141 |
+ return 1; |
|
142 |
+} |
|
143 |
+ |
|
144 |
+ |
|
145 |
+const uint8_t MSCA_SUBJECT[] = "\x11\x3b\xd8\x6b\xed\xde\xbc\xd4\xc5\xf1\x0a\xa0\x7a\xb2\x02\x6b\x98\x2f\x4b\x92"; |
|
146 |
+const uint8_t MSCA_MOD[] = "\ |
|
147 |
+\x00\xf3\x5d\xfa\x80\x67\xd4\x5a\xa7\xa9\x0c\x2c\x90\x20\xd0\ |
|
148 |
+\x35\x08\x3c\x75\x84\xcd\xb7\x07\x89\x9c\x89\xda\xde\xce\xc3\ |
|
149 |
+\x60\xfa\x91\x68\x5a\x9e\x94\x71\x29\x18\x76\x7c\xc2\xe0\xc8\ |
|
150 |
+\x25\x76\x94\x0e\x58\xfa\x04\x34\x36\xe6\xdf\xaf\xf7\x80\xba\ |
|
151 |
+\xe9\x58\x0b\x2b\x93\xe5\x9d\x05\xe3\x77\x22\x91\xf7\x34\x64\ |
|
152 |
+\x3c\x22\x91\x1d\x5e\xe1\x09\x90\xbc\x14\xfe\xfc\x75\x58\x19\ |
|
153 |
+\xe1\x79\xb7\x07\x92\xa3\xae\x88\x59\x08\xd8\x9f\x07\xca\x03\ |
|
154 |
+\x58\xfc\x68\x29\x6d\x32\xd7\xd2\xa8\xcb\x4b\xfc\xe1\x0b\x48\ |
|
155 |
+\x32\x4f\xe6\xeb\xb8\xad\x4f\xe4\x5c\x6f\x13\x94\x99\xdb\x95\ |
|
156 |
+\xd5\x75\xdb\xa8\x1a\xb7\x94\x91\xb4\x77\x5b\xf5\x48\x0c\x8f\ |
|
157 |
+\x6a\x79\x7d\x14\x70\x04\x7d\x6d\xaf\x90\xf5\xda\x70\xd8\x47\ |
|
158 |
+\xb7\xbf\x9b\x2f\x6c\xe7\x05\xb7\xe1\x11\x60\xac\x79\x91\x14\ |
|
159 |
+\x7c\xc5\xd6\xa6\xe4\xe1\x7e\xd5\xc3\x7e\xe5\x92\xd2\x3c\x00\ |
|
160 |
+\xb5\x36\x82\xde\x79\xe1\x6d\xf3\xb5\x6e\xf8\x9f\x33\xc9\xcb\ |
|
161 |
+\x52\x7d\x73\x98\x36\xdb\x8b\xa1\x6b\xa2\x95\x97\x9b\xa3\xde\ |
|
162 |
+\xc2\x4d\x26\xff\x06\x96\x67\x25\x06\xc8\xe7\xac\xe4\xee\x12\ |
|
163 |
+\x33\x95\x31\x99\xc8\x35\x08\x4e\x34\xca\x79\x53\xd5\xb5\xbe\ |
|
164 |
+\x63\x32\x59\x40\x36\xc0\xa5\x4e\x04\x4d\x3d\xdb\x5b\x07\x33\ |
|
165 |
+\xe4\x58\xbf\xef\x3f\x53\x64\xd8\x42\x59\x35\x57\xfd\x0f\x45\ |
|
166 |
+\x7c\x24\x04\x4d\x9e\xd6\x38\x74\x11\x97\x22\x90\xce\x68\x44\ |
|
167 |
+\x74\x92\x6f\xd5\x4b\x6f\xb0\x86\xe3\xc7\x36\x42\xa0\xd0\xfc\ |
|
168 |
+\xc1\xc0\x5a\xf9\xa3\x61\xb9\x30\x47\x71\x96\x0a\x16\xb0\x91\ |
|
169 |
+\xc0\x42\x95\xef\x10\x7f\x28\x6a\xe3\x2a\x1f\xb1\xe4\xcd\x03\ |
|
170 |
+\x3f\x77\x71\x04\xc7\x20\xfc\x49\x0f\x1d\x45\x88\xa4\xd7\xcb\ |
|
171 |
+\x7e\x88\xad\x8e\x2d\xec\x45\xdb\xc4\x51\x04\xc9\x2a\xfc\xec\ |
|
172 |
+\x86\x9e\x9a\x11\x97\x5b\xde\xce\x53\x88\xe6\xe2\xb7\xfd\xac\ |
|
173 |
+\x95\xc2\x28\x40\xdb\xef\x04\x90\xdf\x81\x33\x39\xd9\xb2\x45\ |
|
174 |
+\xa5\x23\x87\x06\xa5\x55\x89\x31\xbb\x06\x2d\x60\x0e\x41\x18\ |
|
175 |
+\x7d\x1f\x2e\xb5\x97\xcb\x11\xeb\x15\xd5\x24\xa5\x94\xef\x15\ |
|
176 |
+\x14\x89\xfd\x4b\x73\xfa\x32\x5b\xfc\xd1\x33\x00\xf9\x59\x62\ |
|
177 |
+\x70\x07\x32\xea\x2e\xab\x40\x2d\x7b\xca\xdd\x21\x67\x1b\x30\ |
|
178 |
+\x99\x8f\x16\xaa\x23\xa8\x41\xd1\xb0\x6e\x11\x9b\x36\xc4\xde\ |
|
179 |
+\x40\x74\x9c\xe1\x58\x65\xc1\x60\x1e\x7a\x5b\x38\xc8\x8f\xbb\ |
|
180 |
+\x04\x26\x7c\xd4\x16\x40\xe5\xb6\x6b\x6c\xaa\x86\xfd\x00\xbf\ |
|
181 |
+\xce\xc1\x35"; |
|
182 |
+const uint8_t MSCA_EXP[] = "\x01\x00\x01"; |
|
183 |
+ |
|
184 |
+int crtmgr_add_roots(crtmgr *m) { |
|
185 |
+ cli_crt msca; |
|
186 |
+ if(cli_crt_init(&msca)) |
|
187 |
+ return 1; |
|
188 |
+ memset(msca.issuer, '\xca', sizeof(msca.issuer)); |
|
189 |
+ memcpy(msca.subject, MSCA_SUBJECT, sizeof(msca.subject)); |
|
190 |
+ if(mp_read_unsigned_bin(&msca.n, MSCA_MOD, sizeof(MSCA_MOD)-1) || mp_read_unsigned_bin(&msca.e, MSCA_EXP, sizeof(MSCA_EXP)-1)) { |
|
191 |
+ cli_crt_clear(&msca); |
|
192 |
+ return 1; |
|
193 |
+ } |
|
194 |
+ msca.not_before = 989450362; /* May 9 23:19:22 2001 GMT */ |
|
195 |
+ msca.not_after = 1620602293; /* May 9 23:28:13 2021 GMT */ |
|
196 |
+ return crtmgr_add(m, &msca); |
|
197 |
+} |
|
198 |
+ |
|
57 | 199 |
/* typedef struct { */ |
58 | 200 |
/* cli_crt *certs; */ |
59 | 201 |
/* unsigned int ncerts; */ |
... | ... |
@@ -12,6 +12,7 @@ typedef enum { CLI_SHA1RSA, CLI_MD5RSA } cli_crt_hashtype; |
12 | 12 |
typedef struct cli_crt_t { |
13 | 13 |
uint8_t subject[SHA1_HASH_SIZE]; |
14 | 14 |
uint8_t issuer[SHA1_HASH_SIZE]; |
15 |
+ uint8_t tbshash[SHA1_HASH_SIZE]; |
|
15 | 16 |
mp_int n; |
16 | 17 |
mp_int e; |
17 | 18 |
mp_int sig; |
... | ... |
@@ -29,7 +30,8 @@ typedef struct { |
29 | 29 |
|
30 | 30 |
int cli_crt_init(cli_crt *x509); |
31 | 31 |
void cli_crt_clear(cli_crt *x509); |
32 |
- |
|
33 | 32 |
int crtmgr_add(crtmgr *m, cli_crt *x509); |
33 |
+int crtmgr_verify(crtmgr *m, cli_crt *x509); |
|
34 |
+int crtmgr_add_roots(crtmgr *m); |
|
34 | 35 |
|
35 | 36 |
#endif |
... | ... |
@@ -2353,6 +2353,7 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
2353 | 2353 |
} |
2354 | 2354 |
|
2355 | 2355 |
static int cli_loadmscat(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio) { |
2356 |
+ crtmgr_add_roots(&engine->cmgr); |
|
2356 | 2357 |
asn1_parse_mscat(fs, &engine->cmgr); |
2357 | 2358 |
return 0; |
2358 | 2359 |
} |