... | ... |
@@ -657,7 +657,7 @@ static int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, crtmg |
657 | 657 |
return 1; |
658 | 658 |
} |
659 | 659 |
|
660 |
-static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr *cmgr, int embedded, void *hashes, unsigned int *hashes_size) { |
|
660 |
+static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr *cmgr, int embedded, void **hashes, unsigned int *hashes_size) { |
|
661 | 661 |
struct cli_asn1 asn1, deep, deeper; |
662 | 662 |
uint8_t sha1[SHA1_HASH_SIZE], issuer[SHA1_HASH_SIZE], md[SHA1_HASH_SIZE], *message, *attrs; |
663 | 663 |
unsigned int dsize, message_size, attrs_size; |
... | ... |
@@ -713,7 +713,7 @@ static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr |
713 | 713 |
(embedded && asn1_expect_obj(map, &asn1.content, &asn1.size, 0x06, lenof(OID_SPC_INDIRECT_DATA_OBJID), OID_SPC_INDIRECT_DATA_OBJID)) |
714 | 714 |
) |
715 | 715 |
break; |
716 |
- |
|
716 |
+ |
|
717 | 717 |
if(asn1_expect_objtype(map, asn1.content, &asn1.size, &deep, 0xa0)) |
718 | 718 |
break; |
719 | 719 |
if(asn1.size) { |
... | ... |
@@ -727,8 +727,8 @@ static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr |
727 | 727 |
cli_dbgmsg("asn1_parse_mscat: found extra data in content\n"); |
728 | 728 |
break; |
729 | 729 |
} |
730 |
- message = deep.content; |
|
731 |
- message_size = deep.size; |
|
730 |
+ *hashes = deep.content; |
|
731 |
+ *hashes_size = deep.size; |
|
732 | 732 |
|
733 | 733 |
if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0xa0)) /* certificates */ |
734 | 734 |
break; |
... | ... |
@@ -762,11 +762,7 @@ static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr |
762 | 762 |
} |
763 | 763 |
if(newcerts.items) |
764 | 764 |
cli_errmsg("asn1_parse_mscat: got %u certs, %u left unverified\n", orig, newcerts.items); |
765 |
- for(x509 = newcerts.crts; x509; ) { |
|
766 |
- cli_crt *next = x509->next; |
|
767 |
- crtmgr_del(&newcerts, x509); |
|
768 |
- x509 = next; |
|
769 |
- } |
|
765 |
+ crtmgr_free(&newcerts); |
|
770 | 766 |
} |
771 | 767 |
} |
772 | 768 |
|
... | ... |
@@ -907,7 +903,7 @@ static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr |
907 | 907 |
if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x04)) /* encryptedDigest */ |
908 | 908 |
break; |
909 | 909 |
|
910 |
- if(map_sha1(map, message, message_size, sha1)) |
|
910 |
+ if(map_sha1(map, *hashes, *hashes_size, sha1)) |
|
911 | 911 |
break; |
912 | 912 |
if(memcmp(sha1, md, sizeof(sha1))) { |
913 | 913 |
cli_dbgmsg("asn1_parse_mscat: messageDigest mismatch\n"); |
... | ... |
@@ -1158,7 +1154,7 @@ static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr |
1158 | 1158 |
cli_md5_update(&ctx, attrs + 1, attrs_size - 1); |
1159 | 1159 |
cli_md5_final(sha1, &ctx); |
1160 | 1160 |
} |
1161 |
- |
|
1161 |
+ |
|
1162 | 1162 |
if(!fmap_need_ptr_once(map, asn1.content, asn1.size)) { |
1163 | 1163 |
cli_dbgmsg("asn1_parse_mscat: failed to read countersignature encryptedDigest\n"); |
1164 | 1164 |
break; |
... | ... |
@@ -1183,10 +1179,42 @@ int asn1_load_mscat(fmap_t *map, void *start, unsigned int size, struct cl_engin |
1183 | 1183 |
return asn1_parse_mscat(map, start, size, &engine->cmgr, 0, &hashes, &hashes_size); |
1184 | 1184 |
} |
1185 | 1185 |
|
1186 |
-int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, struct cl_engine *engine) { |
|
1187 |
- void *hashes; |
|
1188 |
- unsigned int hashes_size; |
|
1189 |
- return asn1_parse_mscat(map, start, size, &engine->cmgr, 1, &hashes, &hashes_size); |
|
1186 |
+int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, const struct cl_engine *engine, uint8_t *computed_sha1) { |
|
1187 |
+ unsigned int content_size; |
|
1188 |
+ struct cli_asn1 c; |
|
1189 |
+ void *content; |
|
1190 |
+ crtmgr certs; |
|
1191 |
+ int ret; |
|
1192 |
+ |
|
1193 |
+ crtmgr_init(&certs); |
|
1194 |
+ if(crtmgr_add_roots(&certs)) { |
|
1195 |
+ /* FIXME: do smthng here */ |
|
1196 |
+ crtmgr_free(&certs); |
|
1197 |
+ return CL_CLEAN; |
|
1198 |
+ } |
|
1199 |
+ ret = asn1_parse_mscat(map, start, size, &certs, 1, &content, &content_size); |
|
1200 |
+ crtmgr_free(&certs); |
|
1201 |
+ if(ret) |
|
1202 |
+ return CL_VIRUS; /* FIXME */ |
|
1203 |
+ |
|
1204 |
+ if(asn1_expect_objtype(map, content, &content_size, &c, 0x30)) |
|
1205 |
+ return CL_VIRUS; |
|
1206 |
+ if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_SPC_PE_IMAGE_DATA_OBJID), OID_SPC_PE_IMAGE_DATA_OBJID)) |
|
1207 |
+ return CL_VIRUS; |
|
1208 |
+ if(asn1_expect_objtype(map, c.next, &content_size, &c, 0x30)) |
|
1209 |
+ return CL_VIRUS; |
|
1210 |
+ if(content_size) { |
|
1211 |
+ cli_dbgmsg("asn1_check_mscat: extra data in content\n"); |
|
1212 |
+ return CL_VIRUS; |
|
1213 |
+ } |
|
1214 |
+ if(asn1_expect_algo(map, &c.content, &c.size, lenof(OID_sha1), OID_sha1)) |
|
1215 |
+ return CL_VIRUS; |
|
1216 |
+ |
|
1217 |
+ if(asn1_expect_obj(map, &c.content, &c.size, 0x04, SHA1_HASH_SIZE, computed_sha1)) |
|
1218 |
+ return CL_VIRUS; |
|
1219 |
+ |
|
1220 |
+ cli_dbgmsg("asn1_check_mscat: file with valid authenicode signature, whitelisted\n"); |
|
1221 |
+ return CL_CLEAN; |
|
1190 | 1222 |
} |
1191 | 1223 |
|
1192 | 1224 |
/* dsize = deep.size; */ |
... | ... |
@@ -25,6 +25,6 @@ |
25 | 25 |
#include "fmap.h" |
26 | 26 |
|
27 | 27 |
int asn1_load_mscat(fmap_t *map, void *start, unsigned int size, struct cl_engine *engine); |
28 |
-int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, struct cl_engine *engine); |
|
28 |
+int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, const struct cl_engine *engine, uint8_t *computed_sha1); |
|
29 | 29 |
|
30 | 30 |
#endif |
... | ... |
@@ -128,6 +128,10 @@ void crtmgr_del(crtmgr *m, cli_crt *x509) { |
128 | 128 |
} |
129 | 129 |
} |
130 | 130 |
|
131 |
+void crtmgr_free(crtmgr *m) { |
|
132 |
+ while(m->items) |
|
133 |
+ crtmgr_del(m, m->crts); |
|
134 |
+} |
|
131 | 135 |
|
132 | 136 |
static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashtype, const uint8_t *refhash) { |
133 | 137 |
int keylen = mp_unsigned_bin_size(&x509->n), siglen = mp_unsigned_bin_size(sig); |
... | ... |
@@ -52,6 +52,7 @@ typedef struct { |
52 | 52 |
int cli_crt_init(cli_crt *x509); |
53 | 53 |
void cli_crt_clear(cli_crt *x509); |
54 | 54 |
void crtmgr_init(crtmgr *m); |
55 |
+void crtmgr_free(crtmgr *m); |
|
55 | 56 |
int crtmgr_add(crtmgr *m, cli_crt *x509); |
56 | 57 |
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509); |
57 | 58 |
void crtmgr_del(crtmgr *m, cli_crt *x509); |
... | ... |
@@ -2653,7 +2653,7 @@ int cli_scanpe(cli_ctx *ctx) { |
2653 | 2653 |
hlen = optional_hdr32.DataDirectory[4].Size; |
2654 | 2654 |
hlen -= 8; |
2655 | 2655 |
hptr = fmap_need_off_once(map, hsize + 8, hlen); |
2656 |
- asn1_check_mscat(map, hptr, hlen - 4, ctx->engine); |
|
2656 |
+ asn1_check_mscat(map, hptr, hlen - 4, ctx->engine, shash1); |
|
2657 | 2657 |
#if 0 |
2658 | 2658 |
{ |
2659 | 2659 |
struct cli_asn1 asn1; |