... | ... |
@@ -747,6 +747,7 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg |
747 | 747 |
unsigned int dsize, message_size, attrs_size; |
748 | 748 |
cli_crt_hashtype hashtype; |
749 | 749 |
SHA1Context ctx; |
750 |
+ cli_crt *x509; |
|
750 | 751 |
int result; |
751 | 752 |
|
752 | 753 |
cli_dbgmsg("in asn1_parse_mscat\n"); |
... | ... |
@@ -835,22 +836,23 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg |
835 | 835 |
if(dsize) |
836 | 836 |
break; |
837 | 837 |
if(newcerts.crts) { |
838 |
- cli_crt *x509 = newcerts.crts; |
|
838 |
+ x509 = newcerts.crts; |
|
839 | 839 |
cli_dbgmsg("asn1_parse_mscat: %u new certificates collected\n", newcerts.items); |
840 | 840 |
while(x509) { |
841 | 841 |
cli_crt *parent = crtmgr_verify_crt(cmgr, x509); |
842 | 842 |
if(parent) { |
843 | 843 |
x509->codeSign &= parent->codeSign; |
844 | 844 |
x509->timeSign &= parent->timeSign; |
845 |
- if(crtmgr_add(cmgr, x509)) { |
|
846 |
- /* FIXME handle error */ |
|
847 |
- } |
|
845 |
+ if(crtmgr_add(cmgr, x509)) |
|
846 |
+ break; |
|
848 | 847 |
crtmgr_del(&newcerts, x509); |
849 | 848 |
x509 = newcerts.crts; |
850 | 849 |
continue; |
851 | 850 |
} |
852 | 851 |
x509 = x509->next; |
853 | 852 |
} |
853 |
+ if(x509) |
|
854 |
+ break; |
|
854 | 855 |
if(newcerts.items) |
855 | 856 |
cli_dbgmsg("asn1_parse_mscat: %u certificates did not verify\n", newcerts.items); |
856 | 857 |
crtmgr_free(&newcerts); |
... | ... |
@@ -1020,7 +1022,7 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg |
1020 | 1020 |
cli_dbgmsg("asn1_parse_mscat: failed to read encryptedDigest\n"); |
1021 | 1021 |
break; |
1022 | 1022 |
} |
1023 |
- if(crtmgr_verify_pkcs7(cmgr, issuer, serial, asn1.content, asn1.size, CLI_SHA1RSA, sha1, VRFY_CODE)) { |
|
1023 |
+ if(!(x509 = crtmgr_verify_pkcs7(cmgr, issuer, serial, asn1.content, asn1.size, CLI_SHA1RSA, sha1, VRFY_CODE))) { |
|
1024 | 1024 |
cli_dbgmsg("asn1_parse_mscat: pkcs7 signature verification failed\n"); |
1025 | 1025 |
break; |
1026 | 1026 |
} |
... | ... |
@@ -1193,6 +1195,10 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg |
1193 | 1193 |
deep.size = 1; |
1194 | 1194 |
else if(deep.size) |
1195 | 1195 |
cli_dbgmsg("asn1_parse_mscat: extra data in countersignature signing-time\n"); |
1196 |
+ else if(sigdate < x509->not_before || sigdate > x509->not_after) { |
|
1197 |
+ cli_dbgmsg("asn1_parse_mscat: countersignature timestamp outside cert validity\n"); |
|
1198 |
+ deep.size = 1; |
|
1199 |
+ } |
|
1196 | 1200 |
break; |
1197 | 1201 |
} |
1198 | 1202 |
} |
... | ... |
@@ -1264,7 +1270,7 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg |
1264 | 1264 |
cli_dbgmsg("asn1_parse_mscat: failed to read countersignature encryptedDigest\n"); |
1265 | 1265 |
break; |
1266 | 1266 |
} |
1267 |
- if(crtmgr_verify_pkcs7(cmgr, issuer, serial, asn1.content, asn1.size, hashtype, sha1, VRFY_TIME)) { |
|
1267 |
+ if(!crtmgr_verify_pkcs7(cmgr, issuer, serial, asn1.content, asn1.size, hashtype, sha1, VRFY_TIME)) { |
|
1268 | 1268 |
cli_dbgmsg("asn1_parse_mscat: pkcs7 countersignature verification failed\n"); |
1269 | 1269 |
break; |
1270 | 1270 |
} |
... | ... |
@@ -1279,7 +1285,6 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg |
1279 | 1279 |
|
1280 | 1280 |
int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) { |
1281 | 1281 |
struct cli_asn1 c; |
1282 |
- char *virname; |
|
1283 | 1282 |
unsigned int size; |
1284 | 1283 |
struct cli_matcher *db; |
1285 | 1284 |
int i; |
... | ... |
@@ -1406,11 +1411,6 @@ int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) { |
1406 | 1406 |
sprintf(&sha1[i*2], "%02x", ((uint8_t *)(tagval3.content))[i]); |
1407 | 1407 |
cli_dbgmsg("asn1_load_mscat: got hash %s (%s)\n", sha1, (hashtype == 2) ? "PE" : "CAB"); |
1408 | 1408 |
} |
1409 |
- /* FIXME might as well use a static buf */ |
|
1410 |
- virname = cli_mpool_virname(engine->mempool, "CAT", 1); |
|
1411 |
- if(!virname) |
|
1412 |
- return 1; |
|
1413 |
- |
|
1414 | 1409 |
if(!engine->hm_fp) { |
1415 | 1410 |
if(!(engine->hm_fp = mpool_calloc(engine->mempool, 1, sizeof(*db)))) { |
1416 | 1411 |
tag.size = 1;; |
... | ... |
@@ -1420,10 +1420,8 @@ int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) { |
1420 | 1420 |
engine->hm_fp->mempool = engine->mempool; |
1421 | 1421 |
#endif |
1422 | 1422 |
} |
1423 |
- |
|
1424 |
- if(hm_addhash_bin(engine->hm_fp, tagval3.content, CLI_HASH_SHA1, hashtype, virname)) { |
|
1423 |
+ if(hm_addhash_bin(engine->hm_fp, tagval3.content, CLI_HASH_SHA1, hashtype, NULL)) { |
|
1425 | 1424 |
cli_warnmsg("asn1_load_mscat: failed to add hash\n"); |
1426 |
- mpool_free(engine->mempool, (void *)virname); |
|
1427 | 1425 |
return 1; |
1428 | 1426 |
} |
1429 | 1427 |
} |
... | ... |
@@ -87,6 +87,7 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) { |
87 | 87 |
i->certSign |= x509->certSign; |
88 | 88 |
i->codeSign |= x509->codeSign; |
89 | 89 |
i->timeSign |= x509->timeSign; |
90 |
+ return 0; |
|
90 | 91 |
} |
91 | 92 |
} |
92 | 93 |
|
... | ... |
@@ -260,39 +261,45 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty |
260 | 260 |
|
261 | 261 |
|
262 | 262 |
cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) { |
263 |
- cli_crt *i = m->crts; |
|
263 |
+ cli_crt *i = m->crts, *best = NULL; |
|
264 |
+ int score = 0; |
|
264 | 265 |
|
265 | 266 |
for(i = m->crts; i; i = i->next) { |
266 | 267 |
if(i->certSign && |
267 |
- (x509->codeSign & i->codeSign) == x509->codeSign && |
|
268 |
- (x509->timeSign & i->timeSign) == x509->timeSign && |
|
269 | 268 |
!memcmp(i->subject, x509->issuer, sizeof(i->subject)) && |
270 |
- !crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash)) |
|
271 |
- return i; |
|
269 |
+ !crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash)) { |
|
270 |
+ int curscore; |
|
271 |
+ if((x509->codeSign & i->codeSign) == x509->codeSign && (x509->timeSign & i->timeSign) == x509->timeSign) |
|
272 |
+ return i; |
|
273 |
+ curscore = (x509->codeSign & i->codeSign) + (x509->timeSign & i->timeSign); |
|
274 |
+ if(curscore > score) { |
|
275 |
+ best = i; |
|
276 |
+ score = curscore; |
|
277 |
+ } |
|
278 |
+ } |
|
272 | 279 |
} |
273 |
- return NULL; |
|
280 |
+ return best; |
|
274 | 281 |
} |
275 | 282 |
|
276 |
-int crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype) { |
|
283 |
+cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype) { |
|
277 | 284 |
cli_crt *i; |
278 | 285 |
mp_int sig; |
279 | 286 |
int ret; |
280 | 287 |
|
281 | 288 |
if(signature_len < 1024/8 || signature_len > 4096/8+1) { |
282 | 289 |
cli_dbgmsg("crtmgr_verify_pkcs7: unsupported sig len: %u\n", signature_len); |
283 |
- return 1; |
|
290 |
+ return NULL; |
|
284 | 291 |
} |
285 | 292 |
if((ret = mp_init(&sig))) { |
286 | 293 |
cli_errmsg("crtmgr_verify_pkcs7: mp_init failed with %d\n", ret); |
287 |
- return 1; |
|
294 |
+ return NULL; |
|
288 | 295 |
} |
289 | 296 |
|
290 | 297 |
if((ret=mp_read_unsigned_bin(&sig, signature, signature_len))) { |
291 | 298 |
cli_warnmsg("crtmgr_verify_pkcs7: mp_read_unsigned_bin failed with %d\n", ret); |
292 |
- return 1; |
|
299 |
+ return NULL; |
|
293 | 300 |
} |
294 | 301 |
|
295 |
- ret = 1; |
|
296 | 302 |
for(i = m->crts; i; i = i->next) { |
297 | 303 |
if(vrfytype == VRFY_CODE && !i->codeSign) |
298 | 304 |
continue; |
... | ... |
@@ -300,13 +307,11 @@ int crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, |
300 | 300 |
continue; |
301 | 301 |
if(!memcmp(i->issuer, issuer, sizeof(i->issuer)) && |
302 | 302 |
!memcmp(i->serial, serial, sizeof(i->serial)) && |
303 |
- !crtmgr_rsa_verify(i, &sig, hashtype, refhash)) { |
|
304 |
- ret = 0; |
|
303 |
+ !crtmgr_rsa_verify(i, &sig, hashtype, refhash)) |
|
305 | 304 |
break; |
306 |
- } |
|
307 | 305 |
} |
308 | 306 |
mp_clear(&sig); |
309 |
- return ret; |
|
307 |
+ return i; |
|
310 | 308 |
} |
311 | 309 |
|
312 | 310 |
/* DC=com, DC=microsoft, CN=Microsoft Root Certificate Authority */ |
... | ... |
@@ -61,7 +61,7 @@ int crtmgr_add(crtmgr *m, cli_crt *x509); |
61 | 61 |
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509); |
62 | 62 |
void crtmgr_del(crtmgr *m, cli_crt *x509); |
63 | 63 |
cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509); |
64 |
-int crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype); |
|
64 |
+cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype); |
|
65 | 65 |
int crtmgr_add_roots(crtmgr *m); |
66 | 66 |
|
67 | 67 |
|