Browse code

Restrict child cert key usages to those of the parent

aCaB authored on 2012/01/07 06:17:59
Showing 4 changed files
... ...
@@ -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;