Restrict child cert key usages to those of the parent

remotes/push_mirror/guardrails
aCaB 14 years ago
parent 01e4650b04
commit 2501f747c3
  1. 13
      libclamav/asn1.c
  2. 92
      libclamav/crtmgr.c
  3. 2
      libclamav/crtmgr.h
  4. 11
      libclamav/others.c

@ -529,7 +529,6 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
avail = 0;
while(tbs.size) {
/* FIXME parse extensions */
if(asn1_get_obj(map, obj.next, &tbs.size, &obj)) {
tbs.size = 1;
break;
@ -542,6 +541,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
avail = obj.type - 0xa0;
if(obj.type == 0xa3) {
struct cli_asn1 exts;
int have_ext_key = 0;
if(asn1_expect_objtype(map, obj.content, &obj.size, &exts, 0x30)) {
tbs.size = 1;
break;
@ -621,6 +621,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
if(!memcmp("\x55\x1d\x25", id.content, 3)) {
/* ExtKeyUsage 2.5.29.37 */
struct cli_asn1 keypurp;
have_ext_key = 1;
if(asn1_expect_objtype(map, value.content, &value.size, &keypurp, 0x30)) {
exts.size = 1;
break;
@ -656,7 +657,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
exts.size = 1;
break;
}
if(!constr.size)
if(!constr.size)
x509.certSign = 0;
else {
if(asn1_expect_objtype(map, constr.content, &constr.size, &ext, 0x01)) {
@ -680,11 +681,14 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
tbs.size = 1;
break;
}
if(!have_ext_key)
x509.codeSign = x509.timeSign = 1;
}
}
if(tbs.size)
break;
if(crtmgr_lookup(master, &x509) || crtmgr_lookup(other, &x509)) {
cli_dbgmsg("asn1_get_x509: certificate already exists\n");
cli_crt_clear(&x509);
@ -827,7 +831,10 @@ static int asn1_parse_mscat(fmap_t *map, const void *start, unsigned int size, c
cli_crt *x509 = newcerts.crts;
cli_dbgmsg("asn1_parse_mscat: %u new certificates collected\n", newcerts.items);
while(x509) {
if(!crtmgr_verify_crt(cmgr, x509)) {
cli_crt *parent = crtmgr_verify_crt(cmgr, x509);
if(parent) {
x509->codeSign &= parent->codeSign;
x509->timeSign &= parent->timeSign;
if(crtmgr_add(cmgr, x509)) {
/* FIXME handle error */
}

@ -142,7 +142,7 @@ void crtmgr_del(crtmgr *m, cli_crt *x509) {
cli_crt *i;
for(i = m->crts; i; i = i->next) {
if(i==x509) {
if(i->prev)
if(i->prev)
i->prev->next = i->next;
else
m->crts = i->next;
@ -256,15 +256,18 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
}
int crtmgr_verify_crt(crtmgr *m, cli_crt *x509) {
cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) {
cli_crt *i = m->crts;
for(i = m->crts; i; i = i->next) {
if(i->certSign && !memcmp(i->subject, x509->issuer, sizeof(i->subject)) &&
if(i->certSign &&
(x509->codeSign & i->codeSign) == x509->codeSign &&
(x509->timeSign & i->timeSign) == x509->timeSign &&
!memcmp(i->subject, x509->issuer, sizeof(i->subject)) &&
!crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash))
return 0;
return i;
}
return 1;
return NULL;
}
int crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype) {
@ -300,7 +303,6 @@ int crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const void *signature,
}
mp_clear(&sig);
return ret;
}
/* DC=com, DC=microsoft, CN=Microsoft Root Certificate Authority */
@ -402,45 +404,51 @@ int crtmgr_add_roots(crtmgr *m) {
if(cli_crt_init(&ca))
return 1;
/* FIXME proper error check and error path cleanup */
do {
memset(ca.issuer, '\xca', sizeof(ca.issuer));
memcpy(ca.subject, MSCA_SUBJECT, sizeof(ca.subject));
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;
memset(ca.issuer, '\xca', sizeof(ca.issuer));
memcpy(ca.subject, MSCA_SUBJECT, sizeof(ca.subject));
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_crt_clear(&ca);
return 1;
}
ca.not_before = 0;
ca.not_after = (-1U)>>1;
ca.certSign = 1;
ca.codeSign = 1;
ca.timeSign = 1;
crtmgr_add(m, &ca);
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_crt_clear(&ca);
return 1;
}
crtmgr_add(m, &ca);
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_crt_clear(&ca);
return 1;
}
ca.timeSign = 0;
crtmgr_add(m, &ca);
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_crt_clear(&ca);
return 1;
}
ca.codeSign = 0;
ca.timeSign = 1;
crtmgr_add(m, &ca);
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);
return 0;
crtmgr_free(m);
return 1;
}

@ -59,7 +59,7 @@ void crtmgr_free(crtmgr *m);
int crtmgr_add(crtmgr *m, cli_crt *x509);
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509);
void crtmgr_del(crtmgr *m, cli_crt *x509);
int crtmgr_verify_crt(crtmgr *m, cli_crt *x509);
cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509);
int crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, 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);

@ -352,7 +352,16 @@ struct cl_engine *cl_engine_new(void)
}
crtmgr_init(&new->cmgr);
crtmgr_add_roots(&new->cmgr);
if(crtmgr_add_roots(&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);
#ifdef USE_MPOOL
mpool_destroy(new->mempool);
#endif
free(new);
return NULL;
}
cli_dbgmsg("Initialized %s engine\n", cl_retver());
return new;

Loading…
Cancel
Save