int hm_addhash_str(struct cli_matcher *root, const char *strhash, uint32_t size, const char *virusname) { enum CLI_HASH_TYPE type; char binhash[CLI_HASHLEN_MAX]; int hlen; if(!root || !strhash) { cli_errmsg("hm_addhash_str: NULL root or hash\n"); return CL_ENULLARG; } /* size 0 here is now a wildcard size match */ if(size == (uint32_t)-1) { cli_errmsg("hm_addhash_str: null or invalid size (%u)\n", size); return CL_EARG; } hlen = strlen(strhash); switch(hlen) { case 32: type = CLI_HASH_MD5; break; case 40: type = CLI_HASH_SHA1; break; case 64: type = CLI_HASH_SHA256; break; default: cli_errmsg("hm_addhash_str: invalid hash %s -- FIXME!\n", strhash); return CL_EARG; } if(cli_hex2str_to(strhash, (char *)binhash, hlen)) { cli_errmsg("hm_addhash_str: invalid hash %s\n", strhash); return CL_EARG; } return hm_addhash_bin(root, binhash, type, size, virusname); }
int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) { struct cli_asn1 c; unsigned int size; struct cli_matcher *db; int i; if(asn1_parse_mscat(map, 0, map->len, &engine->cmgr, 0, &c.next, &size, engine)) return 1; if(asn1_expect_objtype(map, c.next, &size, &c, 0x30)) return 1; if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_szOID_CATALOG_LIST), OID_szOID_CATALOG_LIST)) return 1; if(c.size) { cli_dbgmsg("asn1_load_mscat: found extra data in szOID_CATALOG_LIST content\n"); return 1; } if(asn1_expect_objtype(map, c.next, &size, &c, 0x4)) /* List ID */ return 1; if(asn1_expect_objtype(map, c.next, &size, &c, 0x17)) /* Effective date - WTF?! */ return 1; if(asn1_expect_algo(map, &c.next, &size, lenof(OID_szOID_CATALOG_LIST_MEMBER), OID_szOID_CATALOG_LIST_MEMBER)) /* szOID_CATALOG_LIST_MEMBER */ return 1; if(asn1_expect_objtype(map, c.next, &size, &c, 0x30)) /* hashes here */ return 1; /* [0] is next but we don't care as it's really descriptives stuff */ size = c.size; c.next = c.content; while(size) { struct cli_asn1 tag; if(asn1_expect_objtype(map, c.next, &size, &c, 0x30)) return 1; if(asn1_expect_objtype(map, c.content, &c.size, &tag, 0x04)) /* TAG NAME */ return 1; if(asn1_expect_objtype(map, tag.next, &c.size, &tag, 0x31)) /* set */ return 1; if(c.size) { cli_dbgmsg("asn1_load_mscat: found extra data in tag\n"); return 1; } while(tag.size) { struct cli_asn1 tagval1, tagval2, tagval3; int hashtype; if(asn1_expect_objtype(map, tag.content, &tag.size, &tagval1, 0x30)) return 1; tag.content = tagval1.next; if(asn1_expect_objtype(map, tagval1.content, &tagval1.size, &tagval2, 0x06)) return 1; if(tagval2.size != lenof(OID_SPC_INDIRECT_DATA_OBJID)) continue; if(!fmap_need_ptr_once(map, tagval2.content, lenof(OID_SPC_INDIRECT_DATA_OBJID))) { cli_dbgmsg("asn1_load_mscat: cannot read SPC_INDIRECT_DATA\n"); return 1; } if(memcmp(tagval2.content, OID_SPC_INDIRECT_DATA_OBJID, lenof(OID_SPC_INDIRECT_DATA_OBJID))) continue; /* stuff like CAT_NAMEVALUE_OBJID(1.3.6.1.4.1.311.12.2.1) and CAT_MEMBERINFO_OBJID(.2).. */ if(asn1_expect_objtype(map, tagval2.next, &tagval1.size, &tagval2, 0x31)) return 1; if(tagval1.size) { cli_dbgmsg("asn1_load_mscat: found extra data in tag value\n"); return 1; } if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval1, 0x30)) return 1; if(tagval2.size) { cli_dbgmsg("asn1_load_mscat: found extra data in SPC_INDIRECT_DATA_OBJID tag\n"); return 1; } if(asn1_expect_objtype(map, tagval1.content, &tagval1.size, &tagval2, 0x30)) return 1; if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval3, 0x06)) /* shall have an obj 1.3.6.1.4.1.311.2.1.15 or 1.3.6.1.4.1.311.2.1.25 inside */ return 1; if(tagval3.size != lenof(OID_SPC_PE_IMAGE_DATA_OBJID)) { /* lenof(OID_SPC_PE_IMAGE_DATA_OBJID) = lenof(OID_SPC_CAB_DATA_OBJID) = 10*/ cli_dbgmsg("asn1_load_mscat: bad hash type size\n"); return 1; } if(!fmap_need_ptr_once(map, tagval3.content, lenof(OID_SPC_PE_IMAGE_DATA_OBJID))) { cli_dbgmsg("asn1_load_mscat: cannot read hash type\n"); return 1; } if(!memcmp(tagval3.content, OID_SPC_PE_IMAGE_DATA_OBJID, lenof(OID_SPC_PE_IMAGE_DATA_OBJID))) hashtype = 2; else if(!memcmp(tagval3.content, OID_SPC_CAB_DATA_OBJID, lenof(OID_SPC_CAB_DATA_OBJID))) hashtype = 1; else { cli_dbgmsg("asn1_load_mscat: unexpected hash type\n"); return 1; } if(asn1_expect_objtype(map, tagval2.next, &tagval1.size, &tagval2, 0x30)) return 1; if(tagval1.size) { cli_dbgmsg("asn1_load_mscat: found extra data after hash\n"); return 1; } if(asn1_expect_algo(map, &tagval2.content, &tagval2.size, lenof(OID_sha1), OID_sha1)) /* objid 1.3.14.3.2.26 - sha1 */ return 1; if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval3, 0x04)) return 1; if(tagval2.size) { cli_dbgmsg("asn1_load_mscat: found extra data in hash\n"); return 1; } if(tagval3.size != SHA1_HASH_SIZE) { cli_dbgmsg("asn1_load_mscat: bad hash size %u\n", tagval3.size); return 1; } if(!fmap_need_ptr_once(map, tagval3.content, SHA1_HASH_SIZE)) { cli_dbgmsg("asn1_load_mscat: cannot read hash\n"); return 1; } if(cli_debug_flag) { char sha1[SHA1_HASH_SIZE*2+1]; for(i=0;i<SHA1_HASH_SIZE;i++) sprintf(&sha1[i*2], "%02x", ((uint8_t *)(tagval3.content))[i]); cli_dbgmsg("asn1_load_mscat: got hash %s (%s)\n", sha1, (hashtype == 2) ? "PE" : "CAB"); } if(!engine->hm_fp) { if(!(engine->hm_fp = mpool_calloc(engine->mempool, 1, sizeof(*db)))) { tag.size = 1;; return 1; } #ifdef USE_MPOOL engine->hm_fp->mempool = engine->mempool; #endif } if(hm_addhash_bin(engine->hm_fp, tagval3.content, CLI_HASH_SHA1, hashtype, NULL)) { cli_warnmsg("asn1_load_mscat: failed to add hash\n"); return 1; } } } return 0; }