From 56b4f4b0b933860f39d0b83b40d4f62acec93409 Mon Sep 17 00:00:00 2001 From: Shawn Webb Date: Sat, 27 Oct 2012 14:58:03 -0400 Subject: [PATCH] Change the cert management code to cache the trusted/revoked root certs in the engine struct --- libclamav/asn1.c | 4 +- libclamav/asn1.h | 2 +- libclamav/crtmgr.c | 122 ++++++++++++++++++++++++++------------------- libclamav/crtmgr.h | 2 +- libclamav/others.c | 4 +- libclamav/pe.c | 2 +- 6 files changed, 78 insertions(+), 58 deletions(-) diff --git a/libclamav/asn1.c b/libclamav/asn1.c index 59aa46cf4..72d85b278 100644 --- a/libclamav/asn1.c +++ b/libclamav/asn1.c @@ -1438,7 +1438,7 @@ int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) { return 0; } -int asn1_check_mscat(fmap_t *map, size_t offset, unsigned int size, uint8_t *computed_sha1) { +int asn1_check_mscat(struct cl_engine *engine, fmap_t *map, size_t offset, unsigned int size, uint8_t *computed_sha1) { unsigned int content_size; struct cli_asn1 c; const void *content; @@ -1447,7 +1447,7 @@ int asn1_check_mscat(fmap_t *map, size_t offset, unsigned int size, uint8_t *com cli_dbgmsg("in asn1_check_mscat (offset: %lu)\n", offset); crtmgr_init(&certs); - if(crtmgr_add_roots(&certs)) { + if(crtmgr_add_roots(engine, &certs)) { crtmgr_free(&certs); return CL_VIRUS; } diff --git a/libclamav/asn1.h b/libclamav/asn1.h index 1cd8f4fbb..03a50bff9 100644 --- a/libclamav/asn1.h +++ b/libclamav/asn1.h @@ -25,6 +25,6 @@ #include "fmap.h" int asn1_load_mscat(fmap_t *map, struct cl_engine *engine); -int asn1_check_mscat(fmap_t *map, size_t offset, unsigned int size, uint8_t *computed_sha1); +int asn1_check_mscat(struct cl_engine *engine, fmap_t *map, size_t offset, unsigned int size, uint8_t *computed_sha1); #endif diff --git a/libclamav/crtmgr.c b/libclamav/crtmgr.c index 730a0ff80..61e8f1d6f 100644 --- a/libclamav/crtmgr.c +++ b/libclamav/crtmgr.c @@ -22,8 +22,8 @@ #include "clamav-config.h" #endif -#include "crtmgr.h" #include "others.h" +#include "crtmgr.h" int cli_crt_init(cli_crt *x509) { int ret; @@ -418,57 +418,77 @@ static const uint8_t VER_MOD[] = "\ static const uint8_t VER_EXP[] = "\x01\x00\x01"; -int crtmgr_add_roots(crtmgr *m) { +int crtmgr_add_roots(struct cl_engine *engine, crtmgr *m) { cli_crt ca; - if(cli_crt_init(&ca)) - return 1; - - do { - memset(ca.issuer, '\xca', sizeof(ca.issuer)); - memcpy(ca.subject, MSCA_SUBJECT, sizeof(ca.subject)); - memset(ca.serial, '\xca', sizeof(ca.serial)); - if(mp_read_unsigned_bin(&ca.n, MSCA_MOD, sizeof(MSCA_MOD)-1) || mp_read_unsigned_bin(&ca.e, MSCA_EXP, sizeof(MSCA_EXP)-1)) { - cli_errmsg("crtmgr_add_roots: failed to read MSCA key\n"); - break; - } - ca.not_before = 0; - ca.not_after = (-1U)>>1; - ca.certSign = 1; - ca.codeSign = 1; - ca.timeSign = 1; - if(crtmgr_add(m, &ca)) - break; - - memcpy(ca.subject, MSA_SUBJECT, sizeof(ca.subject)); - if(mp_read_unsigned_bin(&ca.n, MSA_MOD, sizeof(MSA_MOD)-1) || mp_read_unsigned_bin(&ca.e, MSA_EXP, sizeof(MSA_EXP)-1)) { - cli_errmsg("crtmgr_add_roots: failed to read MSA key\n"); - break; - } - if(crtmgr_add(m, &ca)) - break; - - memcpy(ca.subject, VER_SUBJECT, sizeof(ca.subject)); - if(mp_read_unsigned_bin(&ca.n, VER_MOD, sizeof(VER_MOD)-1) || mp_read_unsigned_bin(&ca.e, VER_EXP, sizeof(VER_EXP)-1)) { - cli_errmsg("crtmgr_add_roots: failed to read VER key\n"); - break; - } - ca.timeSign = 0; - if(crtmgr_add(m, &ca)) - break; - - memcpy(ca.subject, THAW_SUBJECT, sizeof(ca.subject)); - if(mp_read_unsigned_bin(&ca.n, THAW_MOD, sizeof(THAW_MOD)-1) || mp_read_unsigned_bin(&ca.e, THAW_EXP, sizeof(THAW_EXP)-1)) { - cli_errmsg("crtmgr_add_roots: failed to read THAW key\n"); - break; - } - ca.codeSign = 0; - ca.timeSign = 1; - if(crtmgr_add(m, &ca)) - break; - return 0; - } while(0); + cli_crt *crt, *new_crt; + + /* + * Only add trusted (and revoked) root certs once. Copy certs + * from engine's root certs list. + */ + if (m == &(engine->cmgr)) { + do { + if(cli_crt_init(&ca)) + return 1; + + memset(ca.issuer, '\xca', sizeof(ca.issuer)); + memcpy(ca.subject, MSCA_SUBJECT, sizeof(ca.subject)); + memset(ca.serial, '\xca', sizeof(ca.serial)); + if(mp_read_unsigned_bin(&ca.n, MSCA_MOD, sizeof(MSCA_MOD)-1) || mp_read_unsigned_bin(&ca.e, MSCA_EXP, sizeof(MSCA_EXP)-1)) { + cli_errmsg("crtmgr_add_roots: failed to read MSCA key\n"); + break; + } + ca.not_before = 0; + ca.not_after = (-1U)>>1; + ca.certSign = 1; + ca.codeSign = 1; + ca.timeSign = 1; + if(crtmgr_add(m, &ca)) + break; + + memcpy(ca.subject, MSA_SUBJECT, sizeof(ca.subject)); + if(mp_read_unsigned_bin(&ca.n, MSA_MOD, sizeof(MSA_MOD)-1) || mp_read_unsigned_bin(&ca.e, MSA_EXP, sizeof(MSA_EXP)-1)) { + cli_errmsg("crtmgr_add_roots: failed to read MSA key\n"); + break; + } + if(crtmgr_add(m, &ca)) + break; + + memcpy(ca.subject, VER_SUBJECT, sizeof(ca.subject)); + if(mp_read_unsigned_bin(&ca.n, VER_MOD, sizeof(VER_MOD)-1) || mp_read_unsigned_bin(&ca.e, VER_EXP, sizeof(VER_EXP)-1)) { + cli_errmsg("crtmgr_add_roots: failed to read VER key\n"); + break; + } + ca.timeSign = 0; + if(crtmgr_add(m, &ca)) + break; + + memcpy(ca.subject, THAW_SUBJECT, sizeof(ca.subject)); + if(mp_read_unsigned_bin(&ca.n, THAW_MOD, sizeof(THAW_MOD)-1) || mp_read_unsigned_bin(&ca.e, THAW_EXP, sizeof(THAW_EXP)-1)) { + cli_errmsg("crtmgr_add_roots: failed to read THAW key\n"); + break; + } + ca.codeSign = 0; + ca.timeSign = 1; + if(crtmgr_add(m, &ca)) + break; + + return 0; + } while(0); + + cli_crt_clear(&ca); + crtmgr_free(m); + return 1; + } else { + for (crt = engine->cmgr.crts; crt != NULL; crt = crt->next) { + if (crtmgr_add(m, crt)) { + crtmgr_free(m); + return 1; + } + } + + return 0; + } - cli_crt_clear(&ca); - crtmgr_free(m); return 1; } diff --git a/libclamav/crtmgr.h b/libclamav/crtmgr.h index 007db16b8..ad65c68a3 100644 --- a/libclamav/crtmgr.h +++ b/libclamav/crtmgr.h @@ -63,7 +63,7 @@ cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509); void crtmgr_del(crtmgr *m, cli_crt *x509); cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509); cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype); -int crtmgr_add_roots(crtmgr *m); +int crtmgr_add_roots(struct cl_engine *engine, crtmgr *m); #endif diff --git a/libclamav/others.c b/libclamav/others.c index 87ce1ec77..b917df9b0 100644 --- a/libclamav/others.c +++ b/libclamav/others.c @@ -351,8 +351,8 @@ struct cl_engine *cl_engine_new(void) return NULL; } - crtmgr_init(&new->cmgr); - if(crtmgr_add_roots(&new->cmgr)) { + crtmgr_init(&(new->cmgr)); + if(crtmgr_add_roots(new, &(new->cmgr))) { cli_errmsg("cl_engine_new: Can't initialize root certificates\n"); mpool_free(new->mempool, new->dconf); mpool_free(new->mempool, new->root); diff --git a/libclamav/pe.c b/libclamav/pe.c index c11835582..643144864 100644 --- a/libclamav/pe.c +++ b/libclamav/pe.c @@ -2851,5 +2851,5 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) { if(hlen < 8) return CL_VIRUS; hlen -= 8; - return asn1_check_mscat(map, at + 8, hlen, authsha1); + return asn1_check_mscat(ctx->engine, map, at + 8, hlen, authsha1); }