Browse code

extract hashes from cats

aCaB authored on 2011/12/20 01:17:32
Showing 3 changed files
... ...
@@ -108,48 +108,80 @@ int asn1_expect_algo(fmap_t *map, void **asn1data, unsigned int *asn1len, unsign
108 108
     return 0;
109 109
 }
110 110
 
111
-int ms_asn1_get_sha1(fmap_t *map, void *asn1data, unsigned int avail, uint8_t sha1[SHA1_HASH_SIZE]) {
112
-    struct cli_asn1 obj;
113
-
114
-    if(asn1_expect_obj(map, asn1data, &avail, &obj, 0x06, 10, "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x04")) /* OBJECT 1.3.6.1.4.1.311.2.1.4 - SPC_INDIRECT_DATA_OBJID */
115
-	return 1;
111
+int ms_asn1_get_sha1(fmap_t *map, void *asn1data, unsigned int avail, unsigned int emb, uint8_t sha1[SHA1_HASH_SIZE], unsigned int *type) {
112
+    /* ret
113
+     * 0 - success
114
+     * 1 - unexpected obj (ok for cat)
115
+     * 2 - severe
116
+     */
117
+    struct cli_asn1 obj, obj2;
118
+    unsigned int avail2;
116 119
 
117
-    if(asn1_get_obj(map, obj.next, &avail, &obj))
118
-	return 1;
119
-    if(obj.type != 0xa0 && obj.type != 0x31) {
120
-	cli_dbgmsg("ms_asn1_get_sha1: expected [0] or SET - got %02x\n", obj.type);
120
+    /* Manual parsing to avoid spamming */
121
+    if(asn1_expect_objtype(map, asn1data, &avail, &obj, 0x06))
122
+	return 2;
123
+    if(obj.size != 10)
121 124
 	return 1;
125
+    if(!fmap_need_ptr_once(map, obj.content, 10)) {
126
+	cli_dbgmsg("ms_asn1_get_sha1: failed to read content\n");
127
+	return 2;
122 128
     }
129
+    if(memcmp(obj.content, "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x04", 10)) /* OBJECT 1.3.6.1.4.1.311.2.1.4 - SPC_INDIRECT_DATA_OBJID */
130
+	return 1;
131
+
132
+    if(asn1_expect_objtype(map, obj.next, &avail, &obj, emb ? 0xa0 : 0x31))
133
+	return 2;
123 134
 
124 135
     avail = obj.size;
125 136
     if(asn1_expect_objtype(map, obj.content, &avail, &obj, 0x30)) /* SEQUENCE */
126
-	return 1;
137
+	return 2;
127 138
 
128 139
     avail = obj.size;
129
-    if(asn1_get_obj(map, obj.content, &avail, &obj)) /* data - contains an objid 1.3.6.1.4.1.311.2.1.15 or 1.3.6.1.4.1.311.2.1.25 for embedded or detached */
130
-	return 1;
140
+    if(asn1_get_obj(map, obj.content, &avail, &obj)) /* data - contains an objid 1.3.6.1.4.1.311.2.1.15 or 1.3.6.1.4.1.311.2.1.25 */
141
+	return 2;
142
+    avail2 = obj.size;
143
+    if(asn1_expect_objtype(map, obj.content, &avail2, &obj2, 0x06)) /* OBJECT */
144
+	return 2;
145
+    if(obj2.size != 10) {
146
+	cli_dbgmsg("ms_asn1_get_sha1: expected data object size 10, got %u\n", obj2.size);
147
+	return 2;
148
+    }
149
+    if(!fmap_need_ptr_once(map, obj2.content, 10)) {
150
+	cli_dbgmsg("ms_asn1_get_sha1: failed to read data content\n");
151
+	return 2;
152
+    }
153
+    if(!memcmp(obj2.content, "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x0f", 10)) {
154
+	/* SPC_PE_IMAGE_DATA_OBJID */
155
+	if(type) *type = 1;
156
+    } else if (!emb && !memcmp(obj2.content, "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x19", 10)) {
157
+	/* SPC_CAB_DATA_OBJID */
158
+	if(type) *type = 0;
159
+    } else {
160
+	cli_dbgmsg("ms_asn1_get_sha1: data object id mismatch\n");
161
+	return 2;
162
+    }
131 163
 
132 164
     if(asn1_expect_objtype(map, obj.next, &avail, &obj, 0x30)) /* messageDigest */
133
-	return 1;
165
+	return 2;
134 166
 
135 167
     avail = obj.size;
136 168
     if(asn1_expect_algo(map, &obj.content, &avail, 5, "\x2b\x0e\x03\x02\x1a")) /* objid 1.3.14.3.2.26 - sha1 */
137
-       return 1;
169
+       return 2;
138 170
 
139 171
     if(asn1_expect_objtype(map, obj.content, &avail, &obj, 0x04))
140
-	return 1;
172
+	return 2;
141 173
     if(avail) {
142 174
 	cli_dbgmsg("ms_asn1_get_sha1: found unexpected extra data\n");
143
-	return 1;
175
+	return 2;
144 176
     }
145 177
     if(obj.size != SHA1_HASH_SIZE) {
146 178
 	cli_dbgmsg("ms_asn1_get_sha1: expected sha1 lenght(%u), but got %u\n", SHA1_HASH_SIZE, obj.size);
147
-	return 1;
179
+	return 2;
148 180
     }
149 181
 
150 182
     if(!fmap_need_ptr_once(map, obj.content, SHA1_HASH_SIZE)) {
151 183
 	cli_dbgmsg("ms_asn1_get_sha1: failed to read sha1 content\n");
152
-	return 1;
184
+	return 2;
153 185
     }
154 186
     memcpy(sha1, obj.content, SHA1_HASH_SIZE);
155 187
 
... ...
@@ -423,8 +455,8 @@ int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size) {
423 423
 
424 424
 
425 425
 int asn1_parse_mscat(FILE *f) {
426
-    struct cli_asn1 asn1;
427
-    unsigned int size;
426
+    struct cli_asn1 asn1, deep, deeper;
427
+    unsigned int size, dsize;
428 428
     fmap_t *map;
429 429
     void *next;
430 430
 
... ...
@@ -474,21 +506,114 @@ int asn1_parse_mscat(FILE *f) {
474 474
 	    break;
475 475
 	}
476 476
 
477
-	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x30)) /* SEQUENCE */
477
+	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0x30)) /* SEQUENCE - contentInfo */
478 478
 	    break;
479
-
480 479
 	/* Here there is either a PKCS #7 ContentType Object Identifier for Certificate Trust List (szOID_CTL)
481
-	 * or a single SPC_INDIRECT_DATA_OBJID
482
-
483
-    /* 		if(ms_asn1_get_sha1(map, asn1.content, asn1.size, crt_sha1)) */
484
-    /* 		    break; */
480
+	 * or a single SPC_INDIRECT_DATA_OBJID */
481
+	if(asn1_expect_obj(map, asn1.content, &asn1.size, &deep, 0x06, 9, "\x2b\x06\x01\x04\x01\x82\x37\x0a\x01")) /* szOID_CTL - 1.3.6.1.4.1.311.10.1 */
482
+	    break;
483
+	if(asn1_expect_objtype(map, deep.next, &asn1.size, &deep, 0xa0))
484
+	    break;
485
+	if(asn1.size) {
486
+	    cli_dbgmsg("asn1_parse_mscat: found extra data in szOID_CTL\n");
487
+	    break;
488
+	}
489
+	dsize = deep.size;
490
+	if(asn1_expect_objtype(map, deep.content, &dsize, &deep, 0x30))
491
+	    break;
492
+	if(dsize) {
493
+	    cli_dbgmsg("asn1_parse_mscat: found extra data in szOID_CTL content\n");
494
+	    break;
495
+	}
485 496
 
486
-    /* 		for(i=0; i<sizeof(crt_sha1); i++) */
487
-    /* 		    sprintf(&shatxt[i*2], "%02x", crt_sha1[i]); */
488
-    /* 		cli_errmsg("CRT sha: %s\n", shatxt); */
497
+	dsize = deep.size;
498
+	if(asn1_expect_objtype(map, deep.content, &dsize, &deep, 0x30))
499
+	    break;
500
+	if(asn1_expect_obj(map, deep.content, &deep.size, &deeper, 0x06, 10, "\x2b\x06\x01\x04\x01\x82\x37\x0c\x01\x01")) /* szOID_CATALOG_LIST - 1.3.6.1.4.1.311.12.1.1 */
501
+	    break;
502
+	if(deep.size) {
503
+	    cli_dbgmsg("asn1_parse_mscat: found extra data in szOID_CATALOG_LIST content\n");
504
+	    break;
505
+	}
506
+	if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x4)) /* List ID */
507
+	    break;
508
+	if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x17)) /* Effective date - WTF?! */
509
+	    break;
510
+	if(asn1_expect_algo(map, &deep.next, &dsize, 10, "\x2b\x06\x01\x04\x01\x82\x37\x0c\x01\x02")) /* szOID_CATALOG_LIST_MEMBER */
511
+	    break;
512
+	if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x30)) /* hashes here */
513
+	    break;
514
+	while(deep.size) {
515
+	    struct cli_asn1 tag;
516
+	    if(asn1_expect_objtype(map, deep.content, &deep.size, &deeper, 0x30)) {
517
+		deep.size = 1;
518
+		break;
519
+	    }
520
+	    deep.content = deeper.next;
521
+	    if(asn1_expect_objtype(map, deeper.content, &deeper.size, &tag, 0x04)) { /* TAG NAME */
522
+		deep.size = 1;
523
+		break;
524
+	    }
525
+	    if(asn1_expect_objtype(map, tag.next, &deeper.size, &tag, 0x31)) { /* set */
526
+		deep.size = 1;
527
+		break;
528
+	    }
529
+	    if(deeper.size) {
530
+		cli_dbgmsg("asn1_parse_mscat: found extra data in tag\n");
531
+		deep.size = 1;
532
+		break;
533
+	    }
534
+	    while(tag.size) {
535
+		struct cli_asn1 tagval;
536
+		unsigned int tsize, tsize2;
537
+		uint8_t sha1[SHA1_HASH_SIZE];
538
+		void *tagc;
539
+		int i;
540
+
541
+		if(asn1_expect_objtype(map, tag.content, &tag.size, &tagval, 0x30)) {
542
+		    tag.size = 1;
543
+		    break;
544
+		}
545
+		tag.content = tagval.next;
546
+		tsize = tsize2 = tagval.size;
547
+		tagc = tagval.content;
548
+		if(asn1_expect_objtype(map, tagval.content, &tsize, &tagval, 0x06)) {
549
+		    tag.size = 1;
550
+		    break;
551
+		}
552
+		i = ms_asn1_get_sha1(map, tagc, tsize2, 0, sha1, NULL);
553
+		if(!i) {
554
+		    char sha1txt[SHA1_HASH_SIZE*2+1];
555
+		    for(i=0;i<SHA1_HASH_SIZE; i++)
556
+			sprintf(&sha1txt[i*2], "%02x", sha1[i]);
557
+		    cli_dbgmsg("asn1_parse_cat: found hash %s\n", sha1txt);
558
+		} else if(i==1){
559
+		    /* expect to hit here on CAT_NAMEVALUE_OBJID(1.3.6.1.4.1.311.12.2.1) and CAT_MEMBERINFO_OBJID(.2) */
560
+		} else {
561
+		    tag.size = 1;
562
+		    cli_dbgmsg("asn1_parse_mscat: bad field in tag value\n");
563
+		    break;
564
+		}
565
+		if(asn1_expect_objtype(map, tagval.next, &tsize, &tagval, 0x31)) {
566
+		    tag.size = 1;
567
+		    break;
568
+		}
569
+		if(tsize) {
570
+		    tag.size = 1;
571
+		    cli_dbgmsg("asn1_parse_mscat: extra data in value\n");
572
+		    break;
573
+		}
574
+	    }
575
+	    if(tag.size) {
576
+		deep.size = 1;
577
+		break;
578
+	    }
579
+	}
580
+	if(deep.size)
581
+	    break;
489 582
 
490
-    /* 		if(memcmp(crt_sha1, shash1, sizeof(crt_sha1))) */
491
-    /* 		    break; */
583
+	if(asn1_expect_objtype(map, asn1.next, &size, &asn1, 0xa0)) /* certificates */
584
+	    break;
492 585
 
493 586
     /* 		if(asn1_expect_objtype(map, asn1.next, &hlen, &asn1, 0xa0)) /\* certificates *\/ */
494 587
     /* 		    break; */
... ...
@@ -517,6 +642,8 @@ int asn1_parse_mscat(FILE *f) {
517 517
     /* 		    break; */
518 518
 
519 519
     /* 		cli_errmsg("good %u - %p\n", hlen, asn1.next); */
520
+	cli_errmsg("asn1: parsing ok\n");
521
+
520 522
     } while(0);
521 523
     return 1;
522 524
 }
... ...
@@ -592,3 +719,4 @@ SEQ {
592 592
                         }
593 593
 
594 594
 */
595
+
... ...
@@ -18,7 +18,7 @@ int asn1_get_obj(fmap_t *map, void *asn1data, unsigned int *asn1len, struct cli_
18 18
 int asn1_expect_objtype(fmap_t *map, void *asn1data, unsigned int *asn1len, struct cli_asn1 *obj, uint8_t type);
19 19
 int asn1_expect_obj(fmap_t *map, void *asn1data, unsigned int *asn1len, struct cli_asn1 *obj, uint8_t type, unsigned int size, const void *content);
20 20
 int asn1_expect_algo(fmap_t *map, void **asn1data, unsigned int *asn1len, unsigned int algo_size, const void *algo);
21
-int ms_asn1_get_sha1(fmap_t *map, void *asn1data, unsigned int avail, uint8_t sha1[SHA1_HASH_SIZE]);
21
+int ms_asn1_get_sha1(fmap_t *map, void *asn1data, unsigned int avail, unsigned int emb, uint8_t sha1[SHA1_HASH_SIZE], unsigned int *len);
22 22
 int asn1_get_time(fmap_t *map, void **asn1data, unsigned int *size, time_t *time);
23 23
 int asn1_get_rsa_pubkey(fmap_t *map, void **asn1data, unsigned int *size);
24 24
 int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size);
... ...
@@ -2707,7 +2707,7 @@ int cli_scanpe(cli_ctx *ctx) {
2707 2707
 		if(asn1_expect_objtype(map, asn1.next, &hlen, &asn1, 0x30)) /* SEQUENCE */
2708 2708
 		    break;
2709 2709
 
2710
-		if(ms_asn1_get_sha1(map, asn1.content, asn1.size, crt_sha1))
2710
+		if(ms_asn1_get_sha1(map, asn1.content, asn1.size, 1, crt_sha1, NULL))
2711 2711
 		    break;
2712 2712
 
2713 2713
 		for(i=0; i<sizeof(crt_sha1); i++)