diff --git a/test/build.info b/test/build.info index cbdc0d9a94..d7cfd7e6c4 100644 --- a/test/build.info +++ b/test/build.info @@ -46,7 +46,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \ recordlentest drbgtest sslbuffertest \ time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ - servername_test + servername_test ocspapitest SOURCE[aborttest]=aborttest.c INCLUDE[aborttest]=../include @@ -277,6 +277,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN INCLUDE[sslapitest]=../include .. DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a + SOURCE[ocspapitest]=ocspapitest.c + INCLUDE[ocspapitest]=../include .. + DEPEND[ocspapitest]=../libcrypto libtestutil.a + SOURCE[dtlstest]=dtlstest.c ssltestlib.c INCLUDE[dtlstest]=../include . DEPEND[dtlstest]=../libcrypto ../libssl libtestutil.a diff --git a/test/ocspapitest.c b/test/ocspapitest.c new file mode 100644 index 0000000000..e76f724343 --- /dev/null +++ b/test/ocspapitest.c @@ -0,0 +1,137 @@ +/* + * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "testutil.h" + +static const char *certstr; +static const char *privkeystr; + +static int get_cert_and_key(X509 **cert_out, EVP_PKEY **key_out) +{ + BIO *certbio, *keybio; + X509 *cert = NULL; + EVP_PKEY *key = NULL; + + if (!TEST_ptr(certbio = BIO_new_file(certstr, "r"))) + return 0; + cert = PEM_read_bio_X509(certbio, NULL, NULL, NULL); + BIO_free(certbio); + if (!TEST_ptr(keybio = BIO_new_file(privkeystr, "r"))) + goto end; + key = PEM_read_bio_PrivateKey(keybio, NULL, NULL, NULL); + BIO_free(keybio); + if (!TEST_ptr(cert) || !TEST_ptr(key)) + goto end; + *cert_out = cert; + *key_out = key; + return 1; + end: + X509_free(cert); + EVP_PKEY_free(key); + return 0; +} + +static OCSP_BASICRESP *make_dummy_resp(void) +{ + const unsigned char namestr[] = "openssl.example.com"; + unsigned char keybytes[128] = {7}; + OCSP_BASICRESP *bs = OCSP_BASICRESP_new(); + OCSP_CERTID *cid; + ASN1_TIME *thisupd = ASN1_TIME_set(NULL, time(NULL)); + ASN1_TIME *nextupd = ASN1_TIME_set(NULL, time(NULL) + 200); + X509_NAME *name = X509_NAME_new(); + ASN1_BIT_STRING *key = ASN1_BIT_STRING_new(); + ASN1_INTEGER *serial = ASN1_INTEGER_new(); + + if (!X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC, + namestr, -1, -1, 1) + || !ASN1_BIT_STRING_set(key, keybytes, sizeof(keybytes) + || !ASN1_INTEGER_set_uint64(serial, (uint64_t)1))) + return NULL; + cid = OCSP_cert_id_new(EVP_sha256(), name, key, serial); + if (!TEST_ptr(bs) + || !TEST_ptr(thisupd) + || !TEST_ptr(nextupd) + || !TEST_ptr(cid) + || !TEST_true(OCSP_basic_add1_status(bs, cid, + V_OCSP_CERTSTATUS_UNKNOWN, + 0, NULL, thisupd, nextupd))) + return NULL; + ASN1_TIME_free(thisupd); + ASN1_TIME_free(nextupd); + ASN1_BIT_STRING_free(key); + ASN1_INTEGER_free(serial); + OCSP_CERTID_free(cid); + X509_NAME_free(name); + return bs; +} + +#ifndef OPENSSL_NO_OCSP +static int test_resp_signer(void) +{ + OCSP_BASICRESP *bs; + X509 *signer = NULL, *tmp; + EVP_PKEY *key = NULL; + STACK_OF(X509) *extra_certs; + + /* + * Test a response with no certs at all; get the signer from the + * extra certs given to OCSP_resp_get0_signer(). + */ + bs = make_dummy_resp(); + extra_certs = sk_X509_new_null(); + if (!TEST_ptr(bs) + || !TEST_ptr(extra_certs) + || !TEST_true(get_cert_and_key(&signer, &key)) + || !TEST_true(sk_X509_push(extra_certs, signer)) + || !TEST_true(OCSP_basic_sign(bs, signer, key, EVP_sha1(), + NULL, OCSP_NOCERTS))) + return 0; + if (!TEST_true(OCSP_resp_get0_signer(bs, &tmp, extra_certs)) + || !TEST_int_eq(X509_cmp(tmp, signer), 0)) + return 0; + OCSP_BASICRESP_free(bs); + + /* Do it again but include the signer cert */ + bs = make_dummy_resp(); + tmp = NULL; + if (!TEST_ptr(bs) + || !TEST_true(OCSP_basic_sign(bs, signer, key, EVP_sha1(), + NULL, 0))) + return 0; + if (!TEST_true(OCSP_resp_get0_signer(bs, &tmp, NULL)) + || !TEST_int_eq(X509_cmp(tmp, signer), 0)) + return 0; + OCSP_BASICRESP_free(bs); + sk_X509_free(extra_certs); + X509_free(signer); + EVP_PKEY_free(key); + return 1; +} +#endif + +int setup_tests(void) +{ + if (!TEST_ptr(certstr = test_get_argument(0)) + || !TEST_ptr(privkeystr = test_get_argument(1))) + return 0; +#ifndef OPENSSL_NO_OCSP + ADD_TEST(test_resp_signer); +#endif + return 1; +} diff --git a/test/recipes/80-test_ocsp.t b/test/recipes/80-test_ocsp.t index 9f178dec62..e9ed7b4d51 100644 --- a/test/recipes/80-test_ocsp.t +++ b/test/recipes/80-test_ocsp.t @@ -13,7 +13,7 @@ use warnings; use POSIX; use File::Spec::Functions qw/devnull catfile/; use File::Copy; -use OpenSSL::Test qw/:DEFAULT with pipe srctop_dir/; +use OpenSSL::Test qw/:DEFAULT with pipe srctop_dir data_file/; use OpenSSL::Test::Utils; setup("test_ocsp"); @@ -48,7 +48,7 @@ sub test_ocsp { unlink "ocsp-resp-fff.dat"; } -plan tests => 10; +plan tests => 11; subtest "=== VALID OCSP RESPONSES ===" => sub { plan tests => 7; @@ -210,3 +210,10 @@ subtest "=== INVALID SIGNATURE on the ISSUER CERTIFICATE ===" => sub { test_ocsp("DELEGATED; Root CA -> EE", "D3.ors", "ISIC_D3_Issuer_Root.pem", "", 0); }; + +subtest "=== OCSP API TESTS===" => sub { + plan tests => 1; + + ok(run(test(["ocspapitest", data_file("cert.pem"), data_file("key.pem")])), + "running ocspapitest"); +} diff --git a/test/recipes/80-test_ocsp_data/cert.pem b/test/recipes/80-test_ocsp_data/cert.pem new file mode 100644 index 0000000000..f70e7925e7 --- /dev/null +++ b/test/recipes/80-test_ocsp_data/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgICFs8wDQYJKoZIhvcNAQELBQAwSzEQMA4GA1UECgwHT3Bl +blNTTDETMBEGA1UECwwKVGVzdCBTdWl0ZTEiMCAGA1UEAwwZVGVzdCBPQ1NQIHJl +c3BvbnNlIHNpZ25lcjAeFw0xNzEwMjMxNDA4MDlaFw0yNjAxMDkxNDA4MDlaMEsx +EDAOBgNVBAoMB09wZW5TU0wxEzARBgNVBAsMClRlc3QgU3VpdGUxIjAgBgNVBAMM +GVRlc3QgT0NTUCByZXNwb25zZSBzaWduZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC81prq23FY2YDuwiXetb/NCs/cSm/afVnPsdSseRKi/GHi9d7b +EEgWnQOJmz4zTuU+Bw2duHZ1X2WUR/Pjy4CvWNRq417aJ3IfyQHf8cxEplk9Ifd0 +5VEq6WzWVWAX6ki/CZIJUihzj3AAn/SYfvXw2wd319OQGvwYiQVt3Is5k4E4rAI2 +zXf5BdE9XkayM3jq6Ewc/VZ05EA/LaBLy5ujQljjfAFEy/qopYx3AJ4G8t2a5rvM +dbNOyJCx9NNeryZMv2wRzEaYp6jYao+xxqbm5lgnwfE3jJ4aA9/oC1sUM8FokOGW +9KAK3UEptoxux8JHH9R8X5bTVE7HADHhG5s7AgMBAAGjGjAYMAkGA1UdEwQCMAAw +CwYDVR0PBAQDAgXgMA0GCSqGSIb3DQEBCwUAA4IBAQCPkojVPBFNT9DGpLq9Y/Hl +XhcA+vSdt83EFzPD/nxIMp/QYSnZ9w2SWL21AH4C+HWd4JuKX5Zlsd6qYobYZLcT +TyVfw0OMwwPUI6Mxbz395EAnVLmtddN2RDsEYvThSMMoSfhtUwyANpA0Q6M8RcGt +LwnaC69iXhBh1xcTVVg97yEJ22yIrwQ1GhX4F1PRJIAQ/QmQhnoTGlhl2VAQ3LIk +lNFxkWbx0rqPIcor27QDNa2DPqioyvHMlkjC1h5EPhL9Ynu011r4Dn9A34+vFxeu +Q+emRwl/JjCNZX4l/AripU/Cy/+J2YGKilKzRcB1QMMVSl0VaeLSCwkNDQtdlwWO +-----END CERTIFICATE----- diff --git a/test/recipes/80-test_ocsp_data/key.pem b/test/recipes/80-test_ocsp_data/key.pem new file mode 100644 index 0000000000..cd211dc31f --- /dev/null +++ b/test/recipes/80-test_ocsp_data/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC81prq23FY2YDu +wiXetb/NCs/cSm/afVnPsdSseRKi/GHi9d7bEEgWnQOJmz4zTuU+Bw2duHZ1X2WU +R/Pjy4CvWNRq417aJ3IfyQHf8cxEplk9Ifd05VEq6WzWVWAX6ki/CZIJUihzj3AA +n/SYfvXw2wd319OQGvwYiQVt3Is5k4E4rAI2zXf5BdE9XkayM3jq6Ewc/VZ05EA/ +LaBLy5ujQljjfAFEy/qopYx3AJ4G8t2a5rvMdbNOyJCx9NNeryZMv2wRzEaYp6jY +ao+xxqbm5lgnwfE3jJ4aA9/oC1sUM8FokOGW9KAK3UEptoxux8JHH9R8X5bTVE7H +ADHhG5s7AgMBAAECggEBAJLp946eeVmhpiCa5XGWPwlbzwlY1BrNCRGADbC9ZRVu +ew1jMiWGTj9hmr31DHhIeis+u4YoW+jG9jVdoU5pJc3Fs0URbdsVc0FtVcsPyFbk +gGsCQQ4t1m8nOaiqtV8Fw+D0piwgQh5dysqBp374z4i6Lt47CHqFs/m2qIWnXp3E +YF3xX2Zz9rIgejERRxrUnp5998NqxSYHPF7Ts4VQ/+UezUqEpA2jBs6cJ2tWVNR9 +uf+3Fklpo7Uau+xG5xkiRYxx4mSIg6EREz5+XMPkSOcXi6tyinoKsafxTNQDil0q +pdurVlHNgZb2QdJjHugVmbalydHIQ5c0CU1RO5CP97kCgYEA7RqrRooniil0iAKR +6scFct0juVBW1Uw05Ejt97RtwQRf/m9SU5mSs0PfFx/l3PeNDSWnpmwunL1igYQb ++tVqDQQ9xR4owyl6/qDJSP2bS84jb+3MCR4UE/b2YR2rCDBllXeyQsDT7KMoW8lX +gliWmYd6HYddRDOKNM/tzccFG1cCgYEAy+M6yv0ublrpTj4o8DcOi6JJrQbPSAWx +R7zKDXSvSq5lLjfXmqX4s/jgZWgQ+kYoYZrIOqIygcZ2U6tBMCP2LAhbf86I6r27 +loMyQg7lhC5GCztpGes4/JmUvnvjTUIFspB6ReaXlBFAstzzJirgI1wmoO6+GiG/ +OUDmvCjFdL0CgYALQGa8VDYIImt7QNP31jX1+3SEiMF2IcWox6UzSgajUDfV9SZs +/S6u/xuJF2RrFfxFkXHhPeUAXyRbjQ9e2d3MfFUKE6JPkJpblvm2UwKZmFCqMRir +nhfJ0sBiX2wMWW+YpjN5Y3krE5sIsAdNEjMjWgB7gj70y5VVaECasUUWxQKBgQDB +aauqSIc1VLSh7sGzLudzet5db2pPLmdAYE1kel6Xf9yn/X1gTTYitGNaj2Abq1Y/ +US/Ev30eMwCo2nqaimLK3pq+IVUtKhO78nVIyQzdWXBE03Uei0+iAKdkE+5Kqejx +vbDggqEka0Fu678VY/MAWDikzhY0f/MBAxpfQGYgGQKBgC0tR1ymvCLkk6J5e4/G +OD1D9m2JJjcK4eWUS4rAiEH61sI5CKQRU2pQ3f3cIGekDZZt3XzHLYwc9W2UnN2J +glMmKXp0qqt2HoE/XKLrIc1dEDXsZxFnMZ6nmWKsl4AHxM/gyXqfDo/AUXyEGcVu +8TbVs3nlISUy7vwjpaW1KOs1 +-----END PRIVATE KEY-----