Browse code

embedded authenticode verification

aCaB authored on 2011/12/31 00:07:53
Showing 5 changed files
... ...
@@ -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;