diff options
author | Michael Brown <mcb30@ipxe.org> | 2014-03-28 15:45:10 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2014-03-28 17:09:40 +0000 |
commit | bc8ca6b8cea325e6507839e576d0d7eaa44e2af1 (patch) | |
tree | d74ee501d55b6dbaa5f5842c697e57295776b82e /src/tests | |
parent | 2dd3fffe18577baa9619623e627adacefd51fca9 (diff) | |
download | ipxe-bc8ca6b8cea325e6507839e576d0d7eaa44e2af1.tar.gz |
[crypto] Generalise X.509 cache to a full certificate store
Expand the concept of the X.509 cache to provide the functionality of
a certificate store. Certificates in the store will be automatically
used to complete certificate chains where applicable.
The certificate store may be prepopulated at build time using the
CERT=... build command line option. For example:
make bin/ipxe.usb CERT=mycert1.crt,mycert2.crt
Certificates within the certificate store are not implicitly trusted;
the trust list is specified using TRUST=... as before. For example:
make bin/ipxe.usb CERT=root.crt TRUST=root.crt
This can be used to embed the full trusted root certificate within the
iPXE binary, which is potentially useful in an HTTPS-only environment
in which there is no HTTP server from which to automatically download
cross-signed certificates or other certificate chain fragments.
This usage of CERT= extends the existing use of CERT= to specify the
client certificate. The client certificate is now identified
automatically by checking for a match against the private key. For
example:
make bin/ipxe.usb CERT=root.crt,client.crt TRUST=root.crt KEY=client.key
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/tests')
-rw-r--r-- | src/tests/cms_test.c | 46 | ||||
-rw-r--r-- | src/tests/x509_test.c | 58 |
2 files changed, 67 insertions, 37 deletions
diff --git a/src/tests/cms_test.c b/src/tests/cms_test.c index 9899b06a..b96decfc 100644 --- a/src/tests/cms_test.c +++ b/src/tests/cms_test.c @@ -1305,7 +1305,13 @@ static uint8_t root_crt_fingerprint[] = 0x96, 0xe7, 0xa8, 0x6d, 0x63, 0x2d, 0x32, 0x38, 0xaf, 0x00, 0xc4, 0x1a, 0xfc, 0xd8, 0xac, 0xc3 ); -/** Certificate store containing the iPXE self-test root CA */ +/** Empty certificate store */ +static struct x509_chain empty_store = { + .refcnt = REF_INIT ( ref_no_free ), + .links = LIST_HEAD_INIT ( empty_store.links ), +}; + +/** Root certificate list containing the iPXE self-test root CA */ static struct x509_root test_root = { .digest = &cms_test_algorithm, .count = 1, @@ -1349,12 +1355,13 @@ static time_t test_expired = 1375573111ULL; /* Sat Aug 3 23:38:31 2013 */ * @v code Test signed code * @v name Test verification name * @v time Test verification time - * @v root Test root certificate store + * @v store Test certificate store + * @v root Test root certificate list */ -#define cms_verify_ok( sgn, code, name, time, root ) do { \ +#define cms_verify_ok( sgn, code, name, time, store, root ) do { \ x509_invalidate_chain ( (sgn)->sig->certificates ); \ ok ( cms_verify ( (sgn)->sig, virt_to_user ( (code)->data ), \ - (code)->len, name, time, root ) == 0 ); \ + (code)->len, name, time, store, root ) == 0 );\ } while ( 0 ) /** @@ -1364,12 +1371,13 @@ static time_t test_expired = 1375573111ULL; /* Sat Aug 3 23:38:31 2013 */ * @v code Test signed code * @v name Test verification name * @v time Test verification time - * @v root Test root certificate store + * @v store Test certificate store + * @v root Test root certificate list */ -#define cms_verify_fail_ok( sgn, code, name, time, root ) do { \ +#define cms_verify_fail_ok( sgn, code, name, time, store, root ) do { \ x509_invalidate_chain ( (sgn)->sig->certificates ); \ ok ( cms_verify ( (sgn)->sig, virt_to_user ( (code)->data ), \ - (code)->len, name, time, root ) != 0 ); \ + (code)->len, name, time, store, root ) != 0 );\ } while ( 0 ) /** @@ -1385,38 +1393,42 @@ static void cms_test_exec ( void ) { cms_signature_ok ( &nonsigned_sig ); /* Check good signature */ + cms_verify_ok ( &codesigned_sig, &test_code, "codesign.test.ipxe.org", + test_time, &empty_store, &test_root ); cms_verify_ok ( &codesigned_sig, &test_code, - "codesign.test.ipxe.org", test_time, &test_root ); - cms_verify_ok ( &codesigned_sig, &test_code, - NULL, test_time, &test_root ); + NULL, test_time, &empty_store, &test_root ); /* Check incorrect signer name */ cms_verify_fail_ok ( &codesigned_sig, &test_code, - "wrongname.test.ipxe.org", test_time, &test_root ); + "wrongname.test.ipxe.org", test_time, + &empty_store, &test_root ); /* Check non-code-signing certificate */ cms_verify_fail_ok ( &genericsigned_sig, &test_code, - NULL, test_time, &test_root ); + NULL, test_time, &empty_store, &test_root ); /* Check non-signing certificate */ cms_verify_fail_ok ( &nonsigned_sig, &test_code, - NULL, test_time, &test_root ); + NULL, test_time, &empty_store, &test_root ); /* Check broken chain */ cms_verify_fail_ok ( &brokenchain_sig, &test_code, - NULL, test_time, &test_root ); + NULL, test_time, &empty_store, &test_root ); /* Check untrusted signature */ cms_verify_fail_ok ( &codesigned_sig, &test_code, - NULL, test_time, &dummy_root ); + NULL, test_time, &empty_store, &dummy_root ); /* Check incorrect signed content */ cms_verify_fail_ok ( &codesigned_sig, &bad_code, - NULL, test_time, &test_root ); + NULL, test_time, &empty_store, &test_root ); /* Check expired signature */ cms_verify_fail_ok ( &codesigned_sig, &test_code, - NULL, test_expired, &test_root ); + NULL, test_expired, &empty_store, &test_root ); + + /* Sanity check */ + assert ( list_empty ( &empty_store.links ) ); /* Drop signature references */ cms_put ( nonsigned_sig.sig ); diff --git a/src/tests/x509_test.c b/src/tests/x509_test.c index c014bd2e..fbf9fb40 100644 --- a/src/tests/x509_test.c +++ b/src/tests/x509_test.c @@ -654,14 +654,20 @@ CHAIN ( useless_chain, &useless_crt, &leaf_crt, &intermediate_crt, &root_crt ); CHAIN ( bad_path_len_chain, &bad_path_len_crt, &useless_crt, &leaf_crt, &intermediate_crt, &root_crt ); -/** Certificate store containing the iPXE self-test root CA */ +/** Empty certificate store */ +static struct x509_chain empty_store = { + .refcnt = REF_INIT ( ref_no_free ), + .links = LIST_HEAD_INIT ( empty_store.links ), +}; + +/** Root certificate list containing the iPXE self-test root CA */ static struct x509_root test_root = { .digest = &x509_test_algorithm, .count = 1, .fingerprints = root_crt_fingerprint, }; -/** Certificate store containing the iPXE self-test intermediate CA */ +/** Root certificate list containing the iPXE self-test intermediate CA */ static struct x509_root intermediate_root = { .digest = &x509_test_algorithm, .count = 1, @@ -813,12 +819,13 @@ static time_t test_ca_expired = 2205014905ULL; /* Wed Nov 16 00:08:25 2039 */ * * @v chn Test certificate chain * @v time Test certificate validation time - * @v root Test root certificate store + * @v store Test certificate store + * @v root Test root certificate list */ -#define x509_validate_chain_ok( chn, time, root ) do { \ +#define x509_validate_chain_ok( chn, time, store, root ) do { \ x509_invalidate_chain ( (chn)->chain ); \ ok ( x509_validate_chain ( (chn)->chain, (time), \ - (root) ) == 0 ); \ + (store), (root) ) == 0 ); \ } while ( 0 ) /** @@ -826,12 +833,13 @@ static time_t test_ca_expired = 2205014905ULL; /* Wed Nov 16 00:08:25 2039 */ * * @v chn Test certificate chain * @v time Test certificate validation time - * @v root Test root certificate store + * @v store Test certificate store + * @v root Test root certificate list */ -#define x509_validate_chain_fail_ok( chn, time, root ) do { \ +#define x509_validate_chain_fail_ok( chn, time, store, root ) do { \ x509_invalidate_chain ( (chn)->chain ); \ ok ( x509_validate_chain ( (chn)->chain, (time), \ - (root) ) != 0 ); \ + (store), (root) ) != 0 ); \ } while ( 0 ) /** @@ -898,25 +906,35 @@ static void x509_test_exec ( void ) { x509_chain_ok ( &bad_path_len_chain ); /* Check certificate chains */ - x509_validate_chain_ok ( &server_chain, test_time, &test_root ); - x509_validate_chain_ok ( &server_chain, test_time, &intermediate_root ); - x509_validate_chain_fail_ok ( &server_chain, test_time, &dummy_root ); + x509_validate_chain_ok ( &server_chain, test_time, + &empty_store, &test_root ); + x509_validate_chain_ok ( &server_chain, test_time, + &empty_store, &intermediate_root ); + x509_validate_chain_fail_ok ( &server_chain, test_time, + &empty_store, &dummy_root ); x509_validate_chain_fail_ok ( &broken_server_chain, test_time, - &test_root ); + &empty_store, &test_root ); x509_validate_chain_fail_ok ( &incomplete_server_chain, test_time, - &test_root ); + &empty_store, &test_root ); x509_validate_chain_ok ( &incomplete_server_chain, test_time, - &intermediate_root ); - x509_validate_chain_fail_ok ( ¬_ca_chain, test_time, &test_root ); - x509_validate_chain_ok ( &useless_chain, test_time, &test_root ); + &empty_store, &intermediate_root ); + x509_validate_chain_fail_ok ( ¬_ca_chain, test_time, + &empty_store, &test_root ); + x509_validate_chain_ok ( &useless_chain, test_time, + &empty_store, &test_root ); x509_validate_chain_fail_ok ( &bad_path_len_chain, test_time, - &test_root ); + &empty_store, &test_root ); /* Check certificate chain expiry times */ - x509_validate_chain_fail_ok ( &server_chain, test_expired, &test_root ); - x509_validate_chain_ok ( &useless_chain, test_expired, &test_root ); + x509_validate_chain_fail_ok ( &server_chain, test_expired, + &empty_store, &test_root ); + x509_validate_chain_ok ( &useless_chain, test_expired, + &empty_store, &test_root ); x509_validate_chain_fail_ok ( &useless_chain, test_ca_expired, - &test_root ); + &empty_store, &test_root ); + + /* Sanity check */ + assert ( list_empty ( &empty_store.links ) ); /* Drop chain references */ x509_chain_put ( bad_path_len_chain.chain ); |