clamav/libclamav/crtmgr.c

241 lines
7.6 KiB
C
Raw Normal View History

2011-12-21 22:52:46 +01:00
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
2011-12-21 19:52:34 +01:00
#include "crtmgr.h"
2011-12-21 22:52:46 +01:00
#include "others.h"
2011-12-21 19:52:34 +01:00
int cli_crt_init(cli_crt *x509) {
2011-12-22 20:57:43 +01:00
int ret;
if((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) {
cli_errmsg("cli_crt_init: mp_init_multi failed with %d\n", ret);
2011-12-21 19:52:34 +01:00
return 1;
2011-12-22 20:57:43 +01:00
}
2011-12-21 19:52:34 +01:00
x509->not_before = x509->not_after = 0;
2011-12-21 22:52:46 +01:00
x509->prev = x509->next = NULL;
2011-12-21 19:52:34 +01:00
return 0;
}
void cli_crt_clear(cli_crt *x509) {
mp_clear_multi(&x509->n, &x509->e, &x509->sig, NULL);
}
2011-12-22 20:57:43 +01:00
static cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509) {
2011-12-21 22:52:46 +01:00
cli_crt *i = m->crts;
while(i) {
if(x509->not_before == i->not_before && x509->not_after == i->not_after && !memcmp(x509->subject, i->subject, sizeof(i->subject))) {
if(mp_cmp(&x509->n, &i->n) || mp_cmp(&x509->e, &i->e))
cli_dbgmsg("crtmgr_add: conflicting pk for the same cert\n");
2011-12-22 20:57:43 +01:00
return i;
2011-12-21 22:52:46 +01:00
}
i = i->next;
}
2011-12-22 20:57:43 +01:00
return NULL;
}
int crtmgr_add(crtmgr *m, cli_crt *x509) {
cli_crt *i = crtmgr_lookup(m, x509);
if(i)
return 0;
2011-12-21 22:52:46 +01:00
i = cli_malloc(sizeof(*i));
if(!i)
return 1;
if(mp_init_multi(&i->n, &i->e, &i->sig, NULL)) {
free(i);
return 1;
}
if(mp_copy(&x509->n, &i->n) || mp_copy(&x509->e, &i->e) || mp_copy(&x509->sig, &i->sig)) {
cli_crt_clear(i);
free(i);
return 1;
}
memcpy(i->subject, x509->subject, sizeof(i->subject));
memcpy(i->issuer, x509->issuer, sizeof(i->issuer));
i->not_before = x509->not_before;
i->not_after = x509->not_after;
i->hashtype = x509->hashtype;
i->next = m->crts;
i->prev = NULL;
if(m->crts)
m->crts->prev = i;
m->crts = i;
2011-12-22 20:57:43 +01:00
{
char issuer[SHA1_HASH_SIZE*2+1], subject[SHA1_HASH_SIZE*2+1], mod[1024], exp[1024];
int j;
mp_toradix_n(&i->n, mod, 16, sizeof(mod));
mp_toradix_n(&i->e, exp, 16, sizeof(exp));
for(j=0; j<SHA1_HASH_SIZE; j++) {
sprintf(&issuer[j*2], "%02x", i->issuer[j]);
sprintf(&subject[j*2], "%02x", i->subject[j]);
}
cli_dbgmsg("crtmgr_add: added cert s:%s i:%s n:%s e:%s\n", subject, issuer, mod, exp);
}
2011-12-21 22:52:46 +01:00
return 0;
}
2011-12-22 20:57:43 +01:00
int crtmgr_verify(crtmgr *m, cli_crt *x509) {
uint8_t d[513];
cli_crt *i = m->crts;
mp_int x;
int ret, j, siglen = mp_unsigned_bin_size(&x509->sig), hashlen;
if((ret = mp_init(&x))) {
cli_errmsg("crtmgr_verify: mp_init failed with %d\n", ret);
return 1;
}
for(i = m->crts; i; i = i->next) {
if(!memcmp(x509->issuer, i->subject, sizeof(i->subject)) && siglen == mp_unsigned_bin_size(&i->n)) {
if((ret = mp_exptmod(&x509->sig, &i->e, &i->n, &x))) {
cli_warnmsg("crtmgr_verify: verification failed: mp_exptmod failed with %d\n", ret);
continue;
}
if(mp_unsigned_bin_size(&x) != siglen - 1)
continue;
if((ret = mp_to_unsigned_bin(&x, d))) {
cli_warnmsg("crtmgr_verify: mp_unsigned_bin_size failed with %d\n", ret);
continue;
}
if(*d != 1) /* block type 1 */
continue;
siglen -= 1; /* sizeof(x) */
for(j=1; j<siglen-2; j++) /* upto sizeof(x) - 2 */
if(d[j] != 0xff)
break;
if(j == siglen - 2)
continue;
if(d[j] != 0)
continue;
j++;
siglen -= j; /* asn1 size */
if(siglen < 2 || d[j] != 0x30 || d[j+1] + 2 != siglen)
continue;
siglen -= 2;
j+=2;
if(siglen <2 || d[j] != 0x30 || (hashlen = d[j+1]) != 9) {/* FIXME - md5 */
cli_errmsg("crtmgr_verify: ACAB HERE MD5 MISSING!!!\n");
continue;
}
siglen -= 2;
j+=2;
if(siglen < hashlen || memcmp(&d[j], "\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00", hashlen)) {
cli_errmsg("crtmgr_verify: ACAB HERE MD5 MISSING!!!\n");
continue;
}
siglen -= hashlen;
j += hashlen;
hashlen = x509->hashtype == CLI_SHA1RSA ? SHA1_HASH_SIZE : 16;
if(siglen < 2 || d[j] != 0x04 || d[j+1] != hashlen)
continue;
siglen -= 2;
j+=2;
if(siglen != hashlen)
continue;
if(memcmp(&d[j], x509->tbshash, hashlen))
continue;
/* SEQ { SEQ { OID, NULL }, OCTET STRING */
{
char buf[1024];
mp_toradix_n(&x, buf, 16, sizeof(buf));
cli_dbgmsg("crtmgr_verify: %u, %u, %u, %s\n", siglen, d[j+1], hashlen, buf);
}
return 0;
}
}
return 1;
}
const uint8_t MSCA_SUBJECT[] = "\x11\x3b\xd8\x6b\xed\xde\xbc\xd4\xc5\xf1\x0a\xa0\x7a\xb2\x02\x6b\x98\x2f\x4b\x92";
const uint8_t MSCA_MOD[] = "\
\x00\xf3\x5d\xfa\x80\x67\xd4\x5a\xa7\xa9\x0c\x2c\x90\x20\xd0\
\x35\x08\x3c\x75\x84\xcd\xb7\x07\x89\x9c\x89\xda\xde\xce\xc3\
\x60\xfa\x91\x68\x5a\x9e\x94\x71\x29\x18\x76\x7c\xc2\xe0\xc8\
\x25\x76\x94\x0e\x58\xfa\x04\x34\x36\xe6\xdf\xaf\xf7\x80\xba\
\xe9\x58\x0b\x2b\x93\xe5\x9d\x05\xe3\x77\x22\x91\xf7\x34\x64\
\x3c\x22\x91\x1d\x5e\xe1\x09\x90\xbc\x14\xfe\xfc\x75\x58\x19\
\xe1\x79\xb7\x07\x92\xa3\xae\x88\x59\x08\xd8\x9f\x07\xca\x03\
\x58\xfc\x68\x29\x6d\x32\xd7\xd2\xa8\xcb\x4b\xfc\xe1\x0b\x48\
\x32\x4f\xe6\xeb\xb8\xad\x4f\xe4\x5c\x6f\x13\x94\x99\xdb\x95\
\xd5\x75\xdb\xa8\x1a\xb7\x94\x91\xb4\x77\x5b\xf5\x48\x0c\x8f\
\x6a\x79\x7d\x14\x70\x04\x7d\x6d\xaf\x90\xf5\xda\x70\xd8\x47\
\xb7\xbf\x9b\x2f\x6c\xe7\x05\xb7\xe1\x11\x60\xac\x79\x91\x14\
\x7c\xc5\xd6\xa6\xe4\xe1\x7e\xd5\xc3\x7e\xe5\x92\xd2\x3c\x00\
\xb5\x36\x82\xde\x79\xe1\x6d\xf3\xb5\x6e\xf8\x9f\x33\xc9\xcb\
\x52\x7d\x73\x98\x36\xdb\x8b\xa1\x6b\xa2\x95\x97\x9b\xa3\xde\
\xc2\x4d\x26\xff\x06\x96\x67\x25\x06\xc8\xe7\xac\xe4\xee\x12\
\x33\x95\x31\x99\xc8\x35\x08\x4e\x34\xca\x79\x53\xd5\xb5\xbe\
\x63\x32\x59\x40\x36\xc0\xa5\x4e\x04\x4d\x3d\xdb\x5b\x07\x33\
\xe4\x58\xbf\xef\x3f\x53\x64\xd8\x42\x59\x35\x57\xfd\x0f\x45\
\x7c\x24\x04\x4d\x9e\xd6\x38\x74\x11\x97\x22\x90\xce\x68\x44\
\x74\x92\x6f\xd5\x4b\x6f\xb0\x86\xe3\xc7\x36\x42\xa0\xd0\xfc\
\xc1\xc0\x5a\xf9\xa3\x61\xb9\x30\x47\x71\x96\x0a\x16\xb0\x91\
\xc0\x42\x95\xef\x10\x7f\x28\x6a\xe3\x2a\x1f\xb1\xe4\xcd\x03\
\x3f\x77\x71\x04\xc7\x20\xfc\x49\x0f\x1d\x45\x88\xa4\xd7\xcb\
\x7e\x88\xad\x8e\x2d\xec\x45\xdb\xc4\x51\x04\xc9\x2a\xfc\xec\
\x86\x9e\x9a\x11\x97\x5b\xde\xce\x53\x88\xe6\xe2\xb7\xfd\xac\
\x95\xc2\x28\x40\xdb\xef\x04\x90\xdf\x81\x33\x39\xd9\xb2\x45\
\xa5\x23\x87\x06\xa5\x55\x89\x31\xbb\x06\x2d\x60\x0e\x41\x18\
\x7d\x1f\x2e\xb5\x97\xcb\x11\xeb\x15\xd5\x24\xa5\x94\xef\x15\
\x14\x89\xfd\x4b\x73\xfa\x32\x5b\xfc\xd1\x33\x00\xf9\x59\x62\
\x70\x07\x32\xea\x2e\xab\x40\x2d\x7b\xca\xdd\x21\x67\x1b\x30\
\x99\x8f\x16\xaa\x23\xa8\x41\xd1\xb0\x6e\x11\x9b\x36\xc4\xde\
\x40\x74\x9c\xe1\x58\x65\xc1\x60\x1e\x7a\x5b\x38\xc8\x8f\xbb\
\x04\x26\x7c\xd4\x16\x40\xe5\xb6\x6b\x6c\xaa\x86\xfd\x00\xbf\
\xce\xc1\x35";
const uint8_t MSCA_EXP[] = "\x01\x00\x01";
int crtmgr_add_roots(crtmgr *m) {
cli_crt msca;
if(cli_crt_init(&msca))
return 1;
memset(msca.issuer, '\xca', sizeof(msca.issuer));
memcpy(msca.subject, MSCA_SUBJECT, sizeof(msca.subject));
if(mp_read_unsigned_bin(&msca.n, MSCA_MOD, sizeof(MSCA_MOD)-1) || mp_read_unsigned_bin(&msca.e, MSCA_EXP, sizeof(MSCA_EXP)-1)) {
cli_crt_clear(&msca);
return 1;
}
msca.not_before = 989450362; /* May 9 23:19:22 2001 GMT */
msca.not_after = 1620602293; /* May 9 23:28:13 2021 GMT */
return crtmgr_add(m, &msca);
}
2011-12-21 19:52:34 +01:00
/* typedef struct { */
/* cli_crt *certs; */
/* unsigned int ncerts; */
/* } *crtmgr; */
/* /\* if(mp_init(&n) || mp_read_signed_bin(&n, obj.content, obj.size)) *\/ */
/* void crt_destroy(cli_crt *crt) { */
/* mp_clear_multi(&crt->n, &crt->e); */
/* free(crt); */
/* } */
/* void crt_set_issuer(cli_crt *crt, const char issuer[SHA1_HASH_SIZE]) { */
/* memcpy(crt->issuer, issuer, sizeof(issuer)); */
/* } */
/* int crt_set_rsa(cli_crt *crt, int exp, void *bn, unsigned int bn_len) { */
/* if(mp_read_signed_bin(exp ? &crt->e : &crt->n, bn, bn_len)) */
/* return 1; */
/* return 0; */
/* } */
/* void crt_set_validity(cli_crt *crt, int before, time_t t) { */
/* if(before) */
/* crt->not_before = t; */
/* else */
/* crt->not_after = t; */
/* } */