From 4a014968106af27702ac5ead15e0e9bc48451212 Mon Sep 17 00:00:00 2001 From: Ben Toews Date: Thu, 14 Feb 2019 16:06:38 -0700 Subject: [PATCH] tests/unittests: test that signatures can be verified with certs Signed-off-by: Ben Toews Reviewed-by: Jakub Jelen --- tests/unittests/torture_pki.c | 93 ++++++++++++++++++++++++--- tests/unittests/torture_pki_dsa.c | 34 ++++++++++ tests/unittests/torture_pki_ecdsa.c | 40 ++++++++++++ tests/unittests/torture_pki_ed25519.c | 34 ++++++++++ tests/unittests/torture_pki_rsa.c | 21 +++++- 5 files changed, 209 insertions(+), 13 deletions(-) diff --git a/tests/unittests/torture_pki.c b/tests/unittests/torture_pki.c index 0a4b894c..5df79e21 100644 --- a/tests/unittests/torture_pki.c +++ b/tests/unittests/torture_pki.c @@ -7,12 +7,72 @@ #include "torture.h" #include "torture_pki.h" +#include "torture_key.h" #include "pki.c" - const unsigned char HASH[] = "1234567890123456789012345678901234567890" "123456789012345678901234"; +const char template[] = "temp_dir_XXXXXX"; + +struct pki_st { + char *cwd; + char *temp_dir; +}; + +static int setup_cert_dir(void **state) +{ + struct pki_st *test_state = NULL; + char *cwd = NULL; + char *tmp_dir = NULL; + int rc = 0; + + test_state = (struct pki_st *)malloc(sizeof(struct pki_st)); + assert_non_null(test_state); + + cwd = torture_get_current_working_dir(); + assert_non_null(cwd); + + tmp_dir = torture_make_temp_dir(template); + assert_non_null(tmp_dir); + + test_state->cwd = cwd; + test_state->temp_dir = tmp_dir; + + *state = test_state; + + rc = torture_change_dir(tmp_dir); + assert_int_equal(rc, 0); + + printf("Changed directory to: %s\n", tmp_dir); + + return 0; +} + +static int teardown_cert_dir(void **state) { + + struct pki_st *test_state = NULL; + int rc = 0; + + test_state = *((struct pki_st **)state); + + assert_non_null(test_state); + assert_non_null(test_state->cwd); + assert_non_null(test_state->temp_dir); + + rc = torture_change_dir(test_state->cwd); + assert_int_equal(rc, 0); + + rc = torture_rmdirs(test_state->temp_dir); + assert_int_equal(rc, 0); + + SAFE_FREE(test_state->temp_dir); + SAFE_FREE(test_state->cwd); + SAFE_FREE(test_state); + + return 0; +} + static void torture_pki_keytype(void **state) { enum ssh_keytypes_e type; const char *type_c; @@ -68,14 +128,18 @@ struct key_attrs key_attrs_list[] = { {0, 0, "", 0, 0, ""}, /* ECDSA */ {1, 1, "ssh-ed25519", 0, 33, "ssh-ed25519"}, /* ED25519 */ #ifdef HAVE_DSA - {0, 0, "", 0, 0, ""}, /* DSS CERT */ + {0, 1, "", 0, 0, ""}, /* DSS CERT */ #else {0, 0, "", 0, 0, ""}, /* DSS CERT */ #endif - {0, 0, "", 0, 0, ""}, /* RSA CERT */ + {0, 1, "", 0, 0, ""}, /* RSA CERT */ {1, 1, "ecdsa-sha2-nistp256", 0, 64, "ecdsa-sha2-nistp256"}, /* ECDSA P256 */ {1, 1, "ecdsa-sha2-nistp384", 0, 64, "ecdsa-sha2-nistp384"}, /* ECDSA P384 */ {1, 1, "ecdsa-sha2-nistp521", 0, 64, "ecdsa-sha2-nistp521"}, /* ECDSA P521 */ + {0, 1, "", 0, 0, ""}, /* ECDSA P256 CERT */ + {0, 1, "", 0, 0, ""}, /* ECDSA P384 CERT */ + {0, 1, "", 0, 0, ""}, /* ECDSA P521 CERT */ + {0, 1, "", 0, 0, ""}, /* ED25519 CERT */ }; /* Maps to enum ssh_digest_e */ @@ -173,7 +237,7 @@ static void torture_pki_verify_mismatch(void **state) assert_true(rc == SSH_OK); for (key_type = SSH_KEYTYPE_DSS; - key_type <= SSH_KEYTYPE_ED25519; + key_type <= SSH_KEYTYPE_ED25519_CERT01; key_type++) { vkey_attrs = key_attrs_list[key_type]; if (!vkey_attrs.verify) { @@ -182,7 +246,13 @@ static void torture_pki_verify_mismatch(void **state) SSH_LOG(SSH_LOG_TRACE, "Trying key %d with signature %d", key_type, sig_type); - rc = ssh_pki_generate(key_type, vkey_attrs.size_arg, &verify_key); + if (is_cert_type(key_type)) { + torture_write_file("libssh_testkey-cert.pub", + torture_get_testkey_pub(key_type)); + rc = ssh_pki_import_cert_file("libssh_testkey-cert.pub", &verify_key); + } else { + rc = ssh_pki_generate(key_type, vkey_attrs.size_arg, &verify_key); + } assert_true(rc == SSH_OK); assert_non_null(verify_key); @@ -207,13 +277,12 @@ static void torture_pki_verify_mismatch(void **state) blob, sig_type, import_sig->hash_type); - if (sig_type != key_type) { - assert_null(new_sig); - } else { + if (ssh_key_type_plain(key_type) == sig_type) { /* Importing with the same key type should work */ assert_non_null(new_sig); assert_int_equal(new_sig->type, key->type); - if (key_type == SSH_KEYTYPE_RSA && new_sig->hash_type != SSH_DIGEST_AUTO) { + if (ssh_key_type_plain(key_type) == SSH_KEYTYPE_RSA && + new_sig->hash_type != SSH_DIGEST_AUTO) { assert_string_equal(new_sig->type_c, hash_signatures[new_sig->hash_type]); } else { assert_string_equal(new_sig->type_c, key->type_c); @@ -228,6 +297,8 @@ static void torture_pki_verify_mismatch(void **state) assert_true(rc != SSH_OK); ssh_signature_free(new_sig); + } else { + assert_null(new_sig); } SSH_KEY_FREE(verify_key); } @@ -254,7 +325,9 @@ int torture_run_tests(void) { struct CMUnitTest tests[] = { cmocka_unit_test(torture_pki_keytype), cmocka_unit_test(torture_pki_signature), - cmocka_unit_test(torture_pki_verify_mismatch), + cmocka_unit_test_setup_teardown(torture_pki_verify_mismatch, + setup_cert_dir, + teardown_cert_dir), }; ssh_init(); diff --git a/tests/unittests/torture_pki_dsa.c b/tests/unittests/torture_pki_dsa.c index 094a07ac..d8d4b69d 100644 --- a/tests/unittests/torture_pki_dsa.c +++ b/tests/unittests/torture_pki_dsa.c @@ -651,6 +651,37 @@ static void torture_pki_dsa_generate_key(void **state) ssh_free(session); } +static void torture_pki_dsa_cert_verify(void **state) +{ + int rc; + ssh_key privkey = NULL, cert = NULL; + ssh_signature sign = NULL; + ssh_session session=ssh_new(); + (void) state; + + rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + assert_non_null(privkey); + + rc = ssh_pki_import_cert_file(LIBSSH_DSA_TESTKEY "-cert.pub", &cert); + assert_true(rc == 0); + assert_non_null(cert); + + sign = pki_do_sign(privkey, DSA_HASH, 20); + assert_non_null(sign); + rc = pki_signature_verify(session, sign, cert, DSA_HASH, 20); + assert_true(rc == SSH_OK); + ssh_signature_free(sign); + SSH_KEY_FREE(privkey); + SSH_KEY_FREE(cert); + + ssh_free(session); +} + int torture_run_tests(void) { int rc; @@ -695,6 +726,9 @@ int torture_run_tests(void) setup_dsa_key, teardown), cmocka_unit_test(torture_pki_dsa_generate_key), + cmocka_unit_test_setup_teardown(torture_pki_dsa_cert_verify, + setup_dsa_key, + teardown), }; ssh_init(); diff --git a/tests/unittests/torture_pki_ecdsa.c b/tests/unittests/torture_pki_ecdsa.c index 43803a74..138ee267 100644 --- a/tests/unittests/torture_pki_ecdsa.c +++ b/tests/unittests/torture_pki_ecdsa.c @@ -579,6 +579,37 @@ static void torture_pki_generate_key_ecdsa(void **state) ssh_free(session); } +static void torture_pki_ecdsa_cert_verify(void **state) +{ + int rc; + ssh_key privkey = NULL, cert = NULL; + ssh_signature sign = NULL; + ssh_session session=ssh_new(); + (void) state; + + rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + assert_non_null(privkey); + + rc = ssh_pki_import_cert_file(LIBSSH_ECDSA_TESTKEY "-cert.pub", &cert); + assert_true(rc == 0); + assert_non_null(cert); + + sign = pki_do_sign(privkey, ECDSA_HASH, 20); + assert_non_null(sign); + rc = pki_signature_verify(session, sign, cert, ECDSA_HASH, 20); + assert_true(rc == SSH_OK); + ssh_signature_free(sign); + SSH_KEY_FREE(privkey); + SSH_KEY_FREE(cert); + + ssh_free(session); +} + #ifdef HAVE_LIBCRYPTO static void torture_pki_ecdsa_write_privkey(void **state) { @@ -788,6 +819,15 @@ int torture_run_tests(void) { setup_ecdsa_key_521, teardown), cmocka_unit_test(torture_pki_generate_key_ecdsa), + cmocka_unit_test_setup_teardown(torture_pki_ecdsa_cert_verify, + setup_ecdsa_key_256, + teardown), + cmocka_unit_test_setup_teardown(torture_pki_ecdsa_cert_verify, + setup_ecdsa_key_384, + teardown), + cmocka_unit_test_setup_teardown(torture_pki_ecdsa_cert_verify, + setup_ecdsa_key_521, + teardown), #ifdef HAVE_LIBCRYPTO cmocka_unit_test_setup_teardown(torture_pki_ecdsa_write_privkey, setup_ecdsa_key_256, diff --git a/tests/unittests/torture_pki_ed25519.c b/tests/unittests/torture_pki_ed25519.c index b348793a..7baea924 100644 --- a/tests/unittests/torture_pki_ed25519.c +++ b/tests/unittests/torture_pki_ed25519.c @@ -369,6 +369,37 @@ static void torture_pki_ed25519_generate_key(void **state) ssh_free(session); } +static void torture_pki_ed25519_cert_verify(void **state) +{ + int rc; + ssh_key privkey = NULL, cert = NULL; + ssh_signature sign = NULL; + ssh_session session=ssh_new(); + (void) state; + + rc = ssh_pki_import_privkey_file(LIBSSH_ED25519_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + assert_non_null(privkey); + + rc = ssh_pki_import_cert_file(LIBSSH_ED25519_TESTKEY "-cert.pub", &cert); + assert_true(rc == 0); + assert_non_null(cert); + + sign = pki_do_sign(privkey, HASH, 20); + assert_non_null(sign); + rc = pki_signature_verify(session, sign, cert, HASH, 20); + assert_true(rc == SSH_OK); + ssh_signature_free(sign); + SSH_KEY_FREE(privkey); + SSH_KEY_FREE(cert); + + ssh_free(session); +} + static void torture_pki_ed25519_write_privkey(void **state) { ssh_key origkey = NULL; @@ -715,6 +746,9 @@ int torture_run_tests(void) { setup_ed25519_key, teardown), cmocka_unit_test(torture_pki_ed25519_generate_key), + cmocka_unit_test_setup_teardown(torture_pki_ed25519_cert_verify, + setup_ed25519_key, + teardown), cmocka_unit_test_setup_teardown(torture_pki_ed25519_write_privkey, setup_ed25519_key, teardown), diff --git a/tests/unittests/torture_pki_rsa.c b/tests/unittests/torture_pki_rsa.c index af7571a1..9333e8c3 100644 --- a/tests/unittests/torture_pki_rsa.c +++ b/tests/unittests/torture_pki_rsa.c @@ -505,7 +505,7 @@ static void torture_pki_rsa_generate_key(void **state) static void torture_pki_rsa_sha2(void **state) { int rc; - ssh_key key = NULL; + ssh_key key = NULL, cert = NULL; ssh_signature sign; ssh_session session=ssh_new(); (void) state; @@ -513,15 +513,21 @@ static void torture_pki_rsa_sha2(void **state) assert_non_null(session); /* Setup */ - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key); + rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, NULL, NULL, NULL, &key); assert_true(rc == SSH_OK); assert_non_null(key); + rc = ssh_pki_import_cert_file(LIBSSH_RSA_TESTKEY "-cert.pub", &cert); + assert_true(rc == SSH_OK); + assert_non_null(cert); + /* Sign using automatic digest */ sign = pki_do_sign_hash(key, RSA_HASH, 20, SSH_DIGEST_AUTO); assert_non_null(sign); rc = pki_signature_verify(session, sign, key, RSA_HASH, 20); assert_ssh_return_code(session, rc); + rc = pki_signature_verify(session, sign, cert, RSA_HASH, 20); + assert_ssh_return_code(session, rc); ssh_signature_free(sign); /* Sign using old SHA1 digest */ @@ -529,6 +535,8 @@ static void torture_pki_rsa_sha2(void **state) assert_non_null(sign); rc = pki_signature_verify(session, sign, key, RSA_HASH, 20); assert_ssh_return_code(session, rc); + rc = pki_signature_verify(session, sign, cert, RSA_HASH, 20); + assert_ssh_return_code(session, rc); ssh_signature_free(sign); /* Sign using new SHA256 digest */ @@ -536,6 +544,8 @@ static void torture_pki_rsa_sha2(void **state) assert_non_null(sign); rc = pki_signature_verify(session, sign, key, SHA256_HASH, 32); assert_ssh_return_code(session, rc); + rc = pki_signature_verify(session, sign, cert, SHA256_HASH, 32); + assert_ssh_return_code(session, rc); ssh_signature_free(sign); /* Sign using rsa-sha2-512 algorithm */ @@ -543,10 +553,13 @@ static void torture_pki_rsa_sha2(void **state) assert_non_null(sign); rc = pki_signature_verify(session, sign, key, SHA512_HASH, 64); assert_ssh_return_code(session, rc); + rc = pki_signature_verify(session, sign, cert, SHA512_HASH, 64); + assert_ssh_return_code(session, rc); ssh_signature_free(sign); /* Cleanup */ SSH_KEY_FREE(key); + SSH_KEY_FREE(cert); ssh_free(session); } @@ -769,7 +782,9 @@ int torture_run_tests(void) { setup_rsa_key, teardown), #endif /* HAVE_LIBCRYPTO */ - cmocka_unit_test(torture_pki_rsa_sha2), + cmocka_unit_test_setup_teardown(torture_pki_rsa_sha2, + setup_rsa_key, + teardown), }; ssh_init();