... | ... |
@@ -529,7 +529,6 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size, |
529 | 529 |
|
530 | 530 |
avail = 0; |
531 | 531 |
while(tbs.size) { |
532 |
- /* FIXME parse extensions */ |
|
533 | 532 |
if(asn1_get_obj(map, obj.next, &tbs.size, &obj)) { |
534 | 533 |
tbs.size = 1; |
535 | 534 |
break; |
... | ... |
@@ -542,6 +541,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size, |
542 | 542 |
avail = obj.type - 0xa0; |
543 | 543 |
if(obj.type == 0xa3) { |
544 | 544 |
struct cli_asn1 exts; |
545 |
+ int have_ext_key = 0; |
|
545 | 546 |
if(asn1_expect_objtype(map, obj.content, &obj.size, &exts, 0x30)) { |
546 | 547 |
tbs.size = 1; |
547 | 548 |
break; |
... | ... |
@@ -621,6 +621,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size, |
621 | 621 |
if(!memcmp("\x55\x1d\x25", id.content, 3)) { |
622 | 622 |
/* ExtKeyUsage 2.5.29.37 */ |
623 | 623 |
struct cli_asn1 keypurp; |
624 |
+ have_ext_key = 1; |
|
624 | 625 |
if(asn1_expect_objtype(map, value.content, &value.size, &keypurp, 0x30)) { |
625 | 626 |
exts.size = 1; |
626 | 627 |
break; |
... | ... |
@@ -656,7 +657,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size, |
656 | 656 |
exts.size = 1; |
657 | 657 |
break; |
658 | 658 |
} |
659 |
- if(!constr.size) |
|
659 |
+ if(!constr.size) |
|
660 | 660 |
x509.certSign = 0; |
661 | 661 |
else { |
662 | 662 |
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, |
680 | 680 |
tbs.size = 1; |
681 | 681 |
break; |
682 | 682 |
} |
683 |
+ if(!have_ext_key) |
|
684 |
+ x509.codeSign = x509.timeSign = 1; |
|
683 | 685 |
} |
684 | 686 |
} |
685 | 687 |
if(tbs.size) |
686 | 688 |
break; |
687 | 689 |
|
690 |
+ |
|
688 | 691 |
if(crtmgr_lookup(master, &x509) || crtmgr_lookup(other, &x509)) { |
689 | 692 |
cli_dbgmsg("asn1_get_x509: certificate already exists\n"); |
690 | 693 |
cli_crt_clear(&x509); |
... | ... |
@@ -827,7 +831,10 @@ static int asn1_parse_mscat(fmap_t *map, const void *start, unsigned int size, c |
827 | 827 |
cli_crt *x509 = newcerts.crts; |
828 | 828 |
cli_dbgmsg("asn1_parse_mscat: %u new certificates collected\n", newcerts.items); |
829 | 829 |
while(x509) { |
830 |
- if(!crtmgr_verify_crt(cmgr, x509)) { |
|
830 |
+ cli_crt *parent = crtmgr_verify_crt(cmgr, x509); |
|
831 |
+ if(parent) { |
|
832 |
+ x509->codeSign &= parent->codeSign; |
|
833 |
+ x509->timeSign &= parent->timeSign; |
|
831 | 834 |
if(crtmgr_add(cmgr, x509)) { |
832 | 835 |
/* FIXME handle error */ |
833 | 836 |
} |
... | ... |
@@ -142,7 +142,7 @@ void crtmgr_del(crtmgr *m, cli_crt *x509) { |
142 | 142 |
cli_crt *i; |
143 | 143 |
for(i = m->crts; i; i = i->next) { |
144 | 144 |
if(i==x509) { |
145 |
- if(i->prev) |
|
145 |
+ if(i->prev) |
|
146 | 146 |
i->prev->next = i->next; |
147 | 147 |
else |
148 | 148 |
m->crts = i->next; |
... | ... |
@@ -256,15 +256,18 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty |
256 | 256 |
} |
257 | 257 |
|
258 | 258 |
|
259 |
-int crtmgr_verify_crt(crtmgr *m, cli_crt *x509) { |
|
259 |
+cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) { |
|
260 | 260 |
cli_crt *i = m->crts; |
261 | 261 |
|
262 | 262 |
for(i = m->crts; i; i = i->next) { |
263 |
- if(i->certSign && !memcmp(i->subject, x509->issuer, sizeof(i->subject)) && |
|
263 |
+ if(i->certSign && |
|
264 |
+ (x509->codeSign & i->codeSign) == x509->codeSign && |
|
265 |
+ (x509->timeSign & i->timeSign) == x509->timeSign && |
|
266 |
+ !memcmp(i->subject, x509->issuer, sizeof(i->subject)) && |
|
264 | 267 |
!crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash)) |
265 |
- return 0; |
|
268 |
+ return i; |
|
266 | 269 |
} |
267 |
- return 1; |
|
270 |
+ return NULL; |
|
268 | 271 |
} |
269 | 272 |
|
270 | 273 |
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, |
300 | 300 |
} |
301 | 301 |
mp_clear(&sig); |
302 | 302 |
return ret; |
303 |
- |
|
304 | 303 |
} |
305 | 304 |
|
306 | 305 |
/* DC=com, DC=microsoft, CN=Microsoft Root Certificate Authority */ |
... | ... |
@@ -402,45 +404,51 @@ int crtmgr_add_roots(crtmgr *m) { |
402 | 402 |
if(cli_crt_init(&ca)) |
403 | 403 |
return 1; |
404 | 404 |
|
405 |
- /* FIXME proper error check and error path cleanup */ |
|
405 |
+ do { |
|
406 |
+ memset(ca.issuer, '\xca', sizeof(ca.issuer)); |
|
407 |
+ memcpy(ca.subject, MSCA_SUBJECT, sizeof(ca.subject)); |
|
408 |
+ 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)) { |
|
409 |
+ cli_errmsg("crtmgr_add_roots: failed to read MSCA key\n"); |
|
410 |
+ break; |
|
411 |
+ } |
|
412 |
+ ca.not_before = 0; |
|
413 |
+ ca.not_after = (-1U)>>1; |
|
414 |
+ ca.certSign = 1; |
|
415 |
+ ca.codeSign = 1; |
|
416 |
+ ca.timeSign = 1; |
|
417 |
+ if(crtmgr_add(m, &ca)) |
|
418 |
+ break; |
|
406 | 419 |
|
407 |
- memset(ca.issuer, '\xca', sizeof(ca.issuer)); |
|
408 |
- memcpy(ca.subject, MSCA_SUBJECT, sizeof(ca.subject)); |
|
409 |
- 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)) { |
|
410 |
- cli_crt_clear(&ca); |
|
411 |
- return 1; |
|
412 |
- } |
|
413 |
- ca.not_before = 0; |
|
414 |
- ca.not_after = (-1U)>>1; |
|
415 |
- ca.certSign = 1; |
|
416 |
- ca.codeSign = 1; |
|
417 |
- ca.timeSign = 1; |
|
418 |
- crtmgr_add(m, &ca); |
|
419 |
- |
|
420 |
- memcpy(ca.subject, MSA_SUBJECT, sizeof(ca.subject)); |
|
421 |
- 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)) { |
|
422 |
- cli_crt_clear(&ca); |
|
423 |
- return 1; |
|
424 |
- } |
|
425 |
- crtmgr_add(m, &ca); |
|
420 |
+ memcpy(ca.subject, MSA_SUBJECT, sizeof(ca.subject)); |
|
421 |
+ 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)) { |
|
422 |
+ cli_errmsg("crtmgr_add_roots: failed to read MSA key\n"); |
|
423 |
+ break; |
|
424 |
+ } |
|
425 |
+ if(crtmgr_add(m, &ca)) |
|
426 |
+ break; |
|
426 | 427 |
|
427 |
- memcpy(ca.subject, VER_SUBJECT, sizeof(ca.subject)); |
|
428 |
- 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)) { |
|
429 |
- cli_crt_clear(&ca); |
|
430 |
- return 1; |
|
431 |
- } |
|
432 |
- ca.timeSign = 0; |
|
433 |
- crtmgr_add(m, &ca); |
|
428 |
+ memcpy(ca.subject, VER_SUBJECT, sizeof(ca.subject)); |
|
429 |
+ 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)) { |
|
430 |
+ cli_errmsg("crtmgr_add_roots: failed to read VER key\n"); |
|
431 |
+ break; |
|
432 |
+ } |
|
433 |
+ ca.timeSign = 0; |
|
434 |
+ if(crtmgr_add(m, &ca)) |
|
435 |
+ break; |
|
434 | 436 |
|
435 |
- memcpy(ca.subject, THAW_SUBJECT, sizeof(ca.subject)); |
|
436 |
- 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)) { |
|
437 |
- cli_crt_clear(&ca); |
|
438 |
- return 1; |
|
439 |
- } |
|
440 |
- ca.codeSign = 0; |
|
441 |
- ca.timeSign = 1; |
|
442 |
- crtmgr_add(m, &ca); |
|
437 |
+ memcpy(ca.subject, THAW_SUBJECT, sizeof(ca.subject)); |
|
438 |
+ 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)) { |
|
439 |
+ cli_errmsg("crtmgr_add_roots: failed to read THAW key\n"); |
|
440 |
+ break; |
|
441 |
+ } |
|
442 |
+ ca.codeSign = 0; |
|
443 |
+ ca.timeSign = 1; |
|
444 |
+ if(crtmgr_add(m, &ca)) |
|
445 |
+ break; |
|
446 |
+ return 0; |
|
447 |
+ } while(0); |
|
443 | 448 |
|
444 | 449 |
cli_crt_clear(&ca); |
445 |
- return 0; |
|
450 |
+ crtmgr_free(m); |
|
451 |
+ return 1; |
|
446 | 452 |
} |
... | ... |
@@ -59,7 +59,7 @@ void crtmgr_free(crtmgr *m); |
59 | 59 |
int crtmgr_add(crtmgr *m, cli_crt *x509); |
60 | 60 |
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509); |
61 | 61 |
void crtmgr_del(crtmgr *m, cli_crt *x509); |
62 |
-int crtmgr_verify_crt(crtmgr *m, cli_crt *x509); |
|
62 |
+cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509); |
|
63 | 63 |
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); |
64 | 64 |
int crtmgr_add_roots(crtmgr *m); |
65 | 65 |
|
... | ... |
@@ -352,7 +352,16 @@ struct cl_engine *cl_engine_new(void) |
352 | 352 |
} |
353 | 353 |
|
354 | 354 |
crtmgr_init(&new->cmgr); |
355 |
- crtmgr_add_roots(&new->cmgr); |
|
355 |
+ if(crtmgr_add_roots(&new->cmgr)) { |
|
356 |
+ cli_errmsg("cl_engine_new: Can't initialize root certificates\n"); |
|
357 |
+ mpool_free(new->mempool, new->dconf); |
|
358 |
+ mpool_free(new->mempool, new->root); |
|
359 |
+#ifdef USE_MPOOL |
|
360 |
+ mpool_destroy(new->mempool); |
|
361 |
+#endif |
|
362 |
+ free(new); |
|
363 |
+ return NULL; |
|
364 |
+ } |
|
356 | 365 |
|
357 | 366 |
cli_dbgmsg("Initialized %s engine\n", cl_retver()); |
358 | 367 |
return new; |