get_x509 error path cleanup

remotes/push_mirror/guardrails
aCaB 14 years ago
parent 0f24014689
commit a616029e68
  1. 310
      libclamav/asn1.c

@ -3,6 +3,66 @@
#include "others.h"
#include "bignum.h"
/* --------------------------------------------------------------------------- OIDS */
#define OID_1_3_14_3_2_26 "\x2b\x0e\x03\x02\x1a"
#define OID_sha1 OID_1_3_14_3_2_26
#define OID_1_3_14_3_2_29 "\x2b\x0e\x03\x02\x1d"
#define OID_sha1WithRSA OID_1_3_14_3_2_29
#define OID_1_2_840_113549_1_1_1 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01"
#define OID_rsaEncryption OID_1_2_840_113549_1_1_1
#define OID_1_2_840_113549_1_1_4 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x04"
#define OID_md5WithRSAEncryption OID_1_2_840_113549_1_1_4
#define OID_1_2_840_113549_1_1_5 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05"
#define OID_sha1WithRSAEncryption OID_1_2_840_113549_1_1_5
#define OID_1_2_840_113549_1_7_1 "\x2a\x86\x48\x86\xf7\x0d\x01\x07\x01"
#define OID_pkcs7_data OID_1_2_840_113549_1_7_1
#define OID_1_2_840_113549_1_7_2 "\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02"
#define OID_signedData OID_1_2_840_113549_1_7_2
#define OID_1_2_840_113549_1_9_3 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x03"
#define OID_contentType OID_1_2_840_113549_1_9_3
#define OID_1_2_840_113549_1_9_4 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x04"
#define OID_messageDigest OID_1_2_840_113549_1_9_4
#define OID_1_2_840_113549_1_9_5 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x05"
#define OID_signingTime OID_1_2_840_113549_1_9_5
#define OID_1_2_840_113549_2_5 "\x2a\x86\x48\x86\xf7\x0d\x02\x05"
#define OID_md5 OID_1_2_840_113549_2_5
#define OID_1_2_840_113549_1_9_6 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x06"
#define OID_countersignature OID_1_2_840_113549_1_9_6
#define OID_1_3_6_1_4_1_311_2_1_4 "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x04"
#define OID_SPC_INDIRECT_DATA_OBJID OID_1_3_6_1_4_1_311_2_1_4
#define OID_1_3_6_1_4_1_311_2_1_15 "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x0f"
#define OID_SPC_PE_IMAGE_DATA_OBJID OID_1_3_6_1_4_1_311_2_1_15
#define OID_1_3_6_1_4_1_311_2_1_25 "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x19"
#define OID_SPC_CAB_DATA_OBJID OID_1_3_6_1_4_1_311_2_1_25
#define OID_1_3_6_1_4_1_311_10_1 "\x2b\x06\x01\x04\x01\x82\x37\x0a\x01"
#define OID_szOID_CTL OID_1_3_6_1_4_1_311_10_1
#define OID_1_3_6_1_4_1_311_12_1_1 "\x2b\x06\x01\x04\x01\x82\x37\x0c\x01\x01"
#define OID_szOID_CATALOG_LIST OID_1_3_6_1_4_1_311_12_1_1
#define OID_1_3_6_1_4_1_311_12_1_2 "\x2b\x06\x01\x04\x01\x82\x37\x0c\x01\x02"
#define OID_szOID_CATALOG_LIST_MEMBER OID_1_3_6_1_4_1_311_12_1_2
#define lenof(x) (sizeof((x))-1)
/* --------------------------------------------------------------------------- OIDS */
static int map_sha1(fmap_t *map, void *data, unsigned int len, uint8_t sha1[SHA1_HASH_SIZE]) {
SHA1Context ctx;
if(!fmap_need_ptr_once(map, data, len)) {
@ -135,64 +195,6 @@ int asn1_expect_algo(fmap_t *map, void **asn1data, unsigned int *asn1len, unsign
return 0;
}
#define OID_1_3_14_3_2_26 "\x2b\x0e\x03\x02\x1a"
#define OID_sha1 OID_1_3_14_3_2_26
#define OID_1_3_14_3_2_29 "\x2b\x0e\x03\x02\x1d"
#define OID_sha1WithRSA OID_1_3_14_3_2_29
#define OID_1_2_840_113549_1_1_1 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01"
#define OID_rsaEncryption OID_1_2_840_113549_1_1_1
#define OID_1_2_840_113549_1_1_4 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x04"
#define OID_md5WithRSAEncryption OID_1_2_840_113549_1_1_4
#define OID_1_2_840_113549_1_1_5 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05"
#define OID_sha1WithRSAEncryption OID_1_2_840_113549_1_1_5
#define OID_1_2_840_113549_1_7_1 "\x2a\x86\x48\x86\xf7\x0d\x01\x07\x01"
#define OID_pkcs7_data OID_1_2_840_113549_1_7_1
#define OID_1_2_840_113549_1_7_2 "\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02"
#define OID_signedData OID_1_2_840_113549_1_7_2
#define OID_1_2_840_113549_1_9_3 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x03"
#define OID_contentType OID_1_2_840_113549_1_9_3
#define OID_1_2_840_113549_1_9_4 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x04"
#define OID_messageDigest OID_1_2_840_113549_1_9_4
#define OID_1_2_840_113549_1_9_5 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x05"
#define OID_signingTime OID_1_2_840_113549_1_9_5
#define OID_1_2_840_113549_2_5 "\x2a\x86\x48\x86\xf7\x0d\x02\x05"
#define OID_md5 OID_1_2_840_113549_2_5
#define OID_1_2_840_113549_1_9_6 "\x2a\x86\x48\x86\xf7\x0d\x01\x09\x06"
#define OID_countersignature OID_1_2_840_113549_1_9_6
#define OID_1_3_6_1_4_1_311_2_1_4 "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x04"
#define OID_SPC_INDIRECT_DATA_OBJID OID_1_3_6_1_4_1_311_2_1_4
#define OID_1_3_6_1_4_1_311_2_1_15 "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x0f"
#define OID_SPC_PE_IMAGE_DATA_OBJID OID_1_3_6_1_4_1_311_2_1_15
#define OID_1_3_6_1_4_1_311_2_1_25 "\x2b\x06\x01\x04\x01\x82\x37\x02\x01\x19"
#define OID_SPC_CAB_DATA_OBJID OID_1_3_6_1_4_1_311_2_1_25
#define OID_1_3_6_1_4_1_311_10_1 "\x2b\x06\x01\x04\x01\x82\x37\x0a\x01"
#define OID_szOID_CTL OID_1_3_6_1_4_1_311_10_1
#define OID_1_3_6_1_4_1_311_12_1_1 "\x2b\x06\x01\x04\x01\x82\x37\x0c\x01\x01"
#define OID_szOID_CATALOG_LIST OID_1_3_6_1_4_1_311_12_1_1
#define OID_1_3_6_1_4_1_311_12_1_2 "\x2b\x06\x01\x04\x01\x82\x37\x0c\x01\x02"
#define OID_szOID_CATALOG_LIST_MEMBER OID_1_3_6_1_4_1_311_12_1_2
#define lenof(x) (sizeof((x))-1)
static int asn1_expect_rsa(fmap_t *map, void **asn1data, unsigned int *asn1len, cli_crt_hashtype *hashtype) {
struct cli_asn1 obj;
@ -504,117 +506,123 @@ int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, crtmgr *mast
if(cli_crt_init(&x509))
return 1;
/* FIXME cli_crt_clear(&x509) on error path */
if(asn1_expect_objtype(map, *asn1data, size, &crt, 0x30)) /* SEQUENCE */
return 1;
*asn1data = crt.next;
do {
if(asn1_expect_objtype(map, *asn1data, size, &crt, 0x30)) /* SEQUENCE */
break;
*asn1data = crt.next;
tbsdata = crt.content;
if(asn1_expect_objtype(map, crt.content, &crt.size, &tbs, 0x30)) /* SEQUENCE - TBSCertificate */
return 1;
tbssize = (uint8_t *)tbs.next - tbsdata;
tbsdata = crt.content;
if(asn1_expect_objtype(map, crt.content, &crt.size, &tbs, 0x30)) /* SEQUENCE - TBSCertificate */
break;
tbssize = (uint8_t *)tbs.next - tbsdata;
if(asn1_expect_objtype(map, tbs.content, &tbs.size, &obj, 0xa0)) /* [0] */
return 1;
avail = obj.size;
next = obj.next;
if(asn1_expect_obj(map, &obj.content, &avail, 0x02, 1, "\x02")) /* version 3 only */
return 1;
if(avail) {
cli_dbgmsg("asn1_get_x509: found unexpected extra data in version\n");
return 1;
}
if(asn1_expect_objtype(map, tbs.content, &tbs.size, &obj, 0xa0)) /* [0] */
break;
avail = obj.size;
next = obj.next;
if(asn1_expect_obj(map, &obj.content, &avail, 0x02, 1, "\x02")) /* version 3 only */
break;
if(avail) {
cli_dbgmsg("asn1_get_x509: found unexpected extra data in version\n");
break;
}
if(asn1_expect_objtype(map, next, &tbs.size, &obj, 0x02)) /* serialNumber */
return 1;
if(asn1_expect_objtype(map, next, &tbs.size, &obj, 0x02)) /* serialNumber */
break;
if(asn1_expect_rsa(map, &obj.next, &tbs.size, &hashtype1)) /* algo = sha1WithRSAEncryption | md5WithRSAEncryption */
return 1;
if(asn1_expect_rsa(map, &obj.next, &tbs.size, &hashtype1)) /* algo = sha1WithRSAEncryption | md5WithRSAEncryption */
break;
if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, 0x30)) /* issuer */
return 1;
issuer = obj.content;
issuersize = obj.size;
if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, 0x30)) /* issuer */
break;
issuer = obj.content;
issuersize = obj.size;
if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, 0x30)) /* validity */
return 1;
avail = obj.size;
next = obj.content;
if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, 0x30)) /* validity */
break;
avail = obj.size;
next = obj.content;
if(asn1_get_time(map, &next, &avail, &x509.not_before)) /* notBefore */
return 1;
if(asn1_get_time(map, &next, &avail, &x509.not_after)) /* notAfter */
return 1;
if(avail) {
cli_dbgmsg("asn1_get_x509: found unexpected extra data in validity\n");
return 1;
}
if(asn1_get_time(map, &next, &avail, &x509.not_before)) /* notBefore */
break;
if(asn1_get_time(map, &next, &avail, &x509.not_after)) /* notAfter */
break;
if(avail) {
cli_dbgmsg("asn1_get_x509: found unexpected extra data in validity\n");
break;
}
if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, 0x30)) /* subject */
return 1;
if(map_sha1(map, obj.content, obj.size, x509.subject))
return 1;
if(asn1_get_rsa_pubkey(map, &obj.next, &tbs.size, &x509))
return 1;
if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, 0x30)) /* subject */
break;
if(map_sha1(map, obj.content, obj.size, x509.subject))
break;
if(asn1_get_rsa_pubkey(map, &obj.next, &tbs.size, &x509))
break;
if(crtmgr_lookup(master, &x509) || crtmgr_lookup(other, &x509)) { /* FIXME lookup on other or blindly add? */
cli_dbgmsg("asn1_get_x509: certificate already exists\n");
return 0;
}
if(crtmgr_lookup(master, &x509) || crtmgr_lookup(other, &x509)) {
cli_dbgmsg("asn1_get_x509: certificate already exists\n");
cli_crt_clear(&x509);
return 0;
}
if(map_sha1(map, issuer, issuersize, x509.issuer))
return 1;
if(map_sha1(map, issuer, issuersize, x509.issuer))
break;
avail = 0;
while(tbs.size) {
/* FIXME parse extensions */
if(asn1_get_obj(map, obj.next, &tbs.size, &obj))
return 1;
if(obj.type <= 0xa0 + avail || obj.type > 0xa3) {
cli_dbgmsg("asn1_get_x509: found type %02x in extensions, expecting a1, a2 or a3\n", obj.type);
return 1;
avail = 0;
while(tbs.size) {
/* FIXME parse extensions */
if(asn1_get_obj(map, obj.next, &tbs.size, &obj)) {
tbs.size = 1;
break;
}
if(obj.type <= 0xa0 + avail || obj.type > 0xa3) {
cli_dbgmsg("asn1_get_x509: found type %02x in extensions, expecting a1, a2 or a3\n", obj.type);
tbs.size = 1;
break;
}
avail = obj.type - 0xa0;
}
avail = obj.type - 0xa0;
}
if(asn1_expect_rsa(map, &tbs.next, &crt.size, &hashtype2)) /* signature algo = sha1WithRSAEncryption | md5WithRSAEncryption */
return 1;
if(tbs.size)
break;
if(hashtype1 != hashtype2) {
cli_dbgmsg("asn1_get_x509: found conflicting rsa hash types\n");
return 1;
}
x509.hashtype = hashtype1;
if(asn1_expect_rsa(map, &tbs.next, &crt.size, &hashtype2)) /* signature algo = sha1WithRSAEncryption | md5WithRSAEncryption */
break;
if(asn1_expect_objtype(map, tbs.next, &crt.size, &obj, 0x03)) /* signature */
return 1;
if(obj.size > 513) {
cli_dbgmsg("asn1_get_x509: signature too long\n");
return 1;
}
if(!fmap_need_ptr_once(map, obj.content, obj.size)) {
cli_dbgmsg("asn1_get_x509: cannot read signature\n");
return 1;
}
if(mp_read_unsigned_bin(&x509.sig, obj.content, obj.size)) {
cli_dbgmsg("asn1_get_x509: cannot convert signature to big number\n");
return 1;
}
if(crt.size) {
cli_dbgmsg("asn1_get_x509: found unexpected extra data in signature\n");
return 1;
}
if(hashtype1 != hashtype2) {
cli_dbgmsg("asn1_get_x509: found conflicting rsa hash types\n");
break;
}
x509.hashtype = hashtype1;
/* FIXME skip hashing if we have the cert already */
if((x509.hashtype == CLI_SHA1RSA && map_sha1(map, tbsdata, tbssize, x509.tbshash)) || (x509.hashtype == CLI_MD5RSA && (map_md5(map, tbsdata, tbssize, x509.tbshash))))
return 1;
if(asn1_expect_objtype(map, tbs.next, &crt.size, &obj, 0x03)) /* signature */
break;
if(obj.size > 513) {
cli_dbgmsg("asn1_get_x509: signature too long\n");
break;
}
if(!fmap_need_ptr_once(map, obj.content, obj.size)) {
cli_dbgmsg("asn1_get_x509: cannot read signature\n");
break;
}
if(mp_read_unsigned_bin(&x509.sig, obj.content, obj.size)) {
cli_dbgmsg("asn1_get_x509: cannot convert signature to big number\n");
break;
}
if(crt.size) {
cli_dbgmsg("asn1_get_x509: found unexpected extra data in signature\n");
break;
}
if(crtmgr_add(other, &x509))
return 1;
if((x509.hashtype == CLI_SHA1RSA && map_sha1(map, tbsdata, tbssize, x509.tbshash)) || (x509.hashtype == CLI_MD5RSA && (map_md5(map, tbsdata, tbssize, x509.tbshash))))
break;
if(crtmgr_add(other, &x509))
break;
cli_crt_clear(&x509);
return 0;
} while(0);
cli_crt_clear(&x509);
return 0;
return 1;
}

Loading…
Cancel
Save