... | ... |
@@ -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++) |