diff options
author | Nicolas Viennot <nicolas@viennot.biz> | 2014-10-31 00:10:02 -0400 |
---|---|---|
committer | Nicolas Viennot <nicolas@viennot.biz> | 2014-10-31 00:30:36 -0400 |
commit | 6e4adcc140102b80883bba85dff05003620b0029 (patch) | |
tree | cf7c368b6dfb57c6c6be8b20bfe75995aae5ff63 /libssh/tests/unittests | |
parent | 0783022d6d77ab3716e2a754856d40497b4cfd76 (diff) |
Update libssh
Diffstat (limited to 'libssh/tests/unittests')
-rw-r--r-- | libssh/tests/unittests/torture_buffer.c | 142 | ||||
-rw-r--r-- | libssh/tests/unittests/torture_callbacks.c | 40 | ||||
-rw-r--r-- | libssh/tests/unittests/torture_channel.c | 1 | ||||
-rw-r--r-- | libssh/tests/unittests/torture_pki.c | 517 |
4 files changed, 584 insertions, 116 deletions
diff --git a/libssh/tests/unittests/torture_buffer.c b/libssh/tests/unittests/torture_buffer.c index dee6e7d4..ec87259d 100644 --- a/libssh/tests/unittests/torture_buffer.c +++ b/libssh/tests/unittests/torture_buffer.c @@ -9,6 +9,7 @@ static void setup(void **state) { ssh_buffer buffer; buffer = ssh_buffer_new(); + ssh_buffer_set_secure(buffer); *state = (void *) buffer; } @@ -25,7 +26,7 @@ static void torture_growing_buffer(void **state) { int i; for(i=0;i<LIMIT;++i){ - buffer_add_data(buffer,"A",1); + ssh_buffer_add_data(buffer,"A",1); if(buffer->used >= 128){ if(buffer_get_rest_len(buffer) * 2 < buffer->allocated){ assert_true(buffer_get_rest_len(buffer) * 2 >= buffer->allocated); @@ -43,11 +44,11 @@ static void torture_growing_buffer_shifting(void **state) { int i; unsigned char c; for(i=0; i<1024;++i){ - buffer_add_data(buffer,"S",1); + ssh_buffer_add_data(buffer,"S",1); } for(i=0;i<LIMIT;++i){ buffer_get_u8(buffer,&c); - buffer_add_data(buffer,"A",1); + ssh_buffer_add_data(buffer,"A",1); if(buffer->used >= 128){ if(buffer_get_rest_len(buffer) * 4 < buffer->allocated){ assert_true(buffer_get_rest_len(buffer) * 4 >= buffer->allocated); @@ -63,7 +64,7 @@ static void torture_growing_buffer_shifting(void **state) { static void torture_buffer_prepend(void **state) { ssh_buffer buffer = *state; uint32_t v; - buffer_add_data(buffer,"abcdef",6); + ssh_buffer_add_data(buffer,"abcdef",6); buffer_prepend_data(buffer,"xyz",3); assert_int_equal(buffer_get_rest_len(buffer),9); assert_memory_equal(buffer_get_rest(buffer), "xyzabcdef", 9); @@ -102,27 +103,150 @@ static void torture_buffer_get_ssh_string(void **state) { for(i=0; i < (int)(sizeof(values)/sizeof(values[0]));++i){ for(j=0; j< (int)sizeof(data);++j){ for(k=1;k<5;++k){ - buffer=buffer_new(); + buffer = ssh_buffer_new(); assert_non_null(buffer); for(l=0;l<k;++l){ rc = buffer_add_u32(buffer,htonl(values[i])); assert_int_equal(rc, 0); } - rc = buffer_add_data(buffer,data,j); + rc = ssh_buffer_add_data(buffer,data,j); assert_int_equal(rc, 0); for(l=0;l<k;++l){ ssh_string str = buffer_get_ssh_string(buffer); assert_null(str); ssh_string_free(str); } - buffer_free(buffer); + ssh_buffer_free(buffer); } } } } +static void torture_buffer_add_format(void **state) { + ssh_buffer buffer=*state; + uint8_t b; + uint16_t w; + uint32_t d; + uint64_t q; + ssh_string s; + int rc; + size_t len; + uint8_t verif[]="\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46" + "\xac\xbd\xce\xdf" + "\x00\x00\x00\x06" "libssh" + "\x00\x00\x00\x05" "rocks" + "So much" + "Fun!"; + + b=0x42; + w=0x1337; + d=0xbadc0de; + q=0x13243546acbdcedf; + s=ssh_string_from_char("libssh"); + rc=ssh_buffer_pack(buffer, "bwdqSsPt",b,w,d,q,s,"rocks",7,"So much","Fun!"); + assert_int_equal(rc, SSH_OK); + + len = buffer_get_rest_len(buffer); + assert_int_equal(len, sizeof(verif) - 1); + assert_memory_equal(buffer_get_rest(buffer), verif, sizeof(verif) -1); + + ssh_string_free(s); +} + +static void torture_buffer_get_format(void **state) { + ssh_buffer buffer=*state; + uint8_t b=0; + uint16_t w=0; + uint32_t d=0; + uint64_t q=0; + ssh_string s=NULL; + char *s1=NULL, *s2=NULL; + int rc; + size_t len; + uint8_t verif[]="\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46" + "\xac\xbd\xce\xdf" + "\x00\x00\x00\x06" "libssh" + "\x00\x00\x00\x05" "rocks" + "So much"; + + rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1); + assert_int_equal(rc, SSH_OK); + rc = ssh_buffer_unpack(buffer, "bwdqSsP",&b,&w,&d,&q,&s,&s1,(size_t)7,&s2); + assert_int_equal(rc, SSH_OK); + + assert_int_equal(b, 0x42); + assert_int_equal(w, 0x1337); + + assert_true(d == 0xbadc0de); + assert_true(q == 0x13243546acbdcedf); + + assert_true(s != NULL); + assert_int_equal(ssh_string_len(s), 6); + assert_memory_equal(ssh_string_data(s), "libssh", 6); + + assert_true(s1 != NULL); + assert_string_equal(s1, "rocks"); + + assert_true(s2 != NULL); + assert_memory_equal(s2, "So much", 7); + len = buffer_get_rest_len(buffer); + assert_int_equal(len, 0); + SAFE_FREE(s); + SAFE_FREE(s1); + SAFE_FREE(s2); +} + +static void torture_buffer_get_format_error(void **state) { + ssh_buffer buffer=*state; + uint8_t b=0; + uint16_t w=0; + uint32_t d=0; + uint64_t q=0; + ssh_string s=NULL; + char *s1=NULL, *s2=NULL; + int rc; + uint8_t verif[]="\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46" + "\xac\xbd\xce\xdf" + "\x00\x00\x00\x06" "libssh" + "\x00\x00\x00\x05" "rocks" + "So much"; + + rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1); + assert_int_equal(rc, SSH_OK); + rc = ssh_buffer_unpack(buffer, "bwdqSsPb",&b,&w,&d,&q,&s,&s1,(size_t)7,&s2,&b); + assert_int_equal(rc, SSH_ERROR); + + assert_true(s==NULL); + assert_true(s1 == NULL); + assert_true(s2 == NULL); +} + +static void torture_buffer_pack_badformat(void **state){ + ssh_buffer buffer = *state; + uint8_t b = 42; + int rc; + + /* first with missing format */ + rc = ssh_buffer_pack(buffer, "b", b, b); + assert_int_equal(rc, SSH_ERROR); + ssh_buffer_reinit(buffer); + + /* with additional format */ + rc = ssh_buffer_pack(buffer, "bb", b); + assert_int_equal(rc, SSH_ERROR); + + /* unpack with missing format */ + ssh_buffer_reinit(buffer); + rc = ssh_buffer_pack(buffer, "bb", 42, 43); + assert_int_equal(rc, SSH_OK); + rc = ssh_buffer_unpack(buffer, "b", &b, &b); + assert_int_equal(rc, SSH_ERROR); + + /* not doing the test with additional format as + * it could crash the process */ +} int torture_run_tests(void) { int rc; @@ -131,6 +255,10 @@ int torture_run_tests(void) { unit_test_setup_teardown(torture_growing_buffer_shifting, setup, teardown), unit_test_setup_teardown(torture_buffer_prepend, setup, teardown), unit_test(torture_buffer_get_ssh_string), + unit_test_setup_teardown(torture_buffer_add_format, setup, teardown), + unit_test_setup_teardown(torture_buffer_get_format, setup, teardown), + unit_test_setup_teardown(torture_buffer_get_format_error, setup, teardown), + unit_test_setup_teardown(torture_buffer_pack_badformat, setup, teardown) }; ssh_init(); diff --git a/libssh/tests/unittests/torture_callbacks.c b/libssh/tests/unittests/torture_callbacks.c index 97991899..3c836b79 100644 --- a/libssh/tests/unittests/torture_callbacks.c +++ b/libssh/tests/unittests/torture_callbacks.c @@ -57,11 +57,51 @@ static void torture_callbacks_exists(void **state) { assert_int_not_equal(ssh_callbacks_exists(cb, auth_function), 0); } +struct test_mock_state { + int executed; +}; + +static void test_mock_ssh_logging_callback(int priority, + const char *function, + const char *buffer, + void *userdata) +{ + struct test_mock_state *t = (struct test_mock_state *)userdata; + + check_expected(priority); + check_expected(function); + check_expected(buffer); + + t->executed++; +} + +static void torture_log_callback(void **state) +{ + struct test_mock_state t = { + .executed = 0, + }; + + (void)state; /* unused */ + + ssh_set_log_callback(test_mock_ssh_logging_callback); + ssh_set_log_userdata(&t); + ssh_set_log_level(1); + + expect_value(test_mock_ssh_logging_callback, priority, 1); + expect_string(test_mock_ssh_logging_callback, function, "torture_log_callback"); + expect_string(test_mock_ssh_logging_callback, buffer, "torture_log_callback: test"); + + SSH_LOG(SSH_LOG_WARN, "test"); + + assert_int_equal(t.executed, 1); +} + int torture_run_tests(void) { int rc; const UnitTest tests[] = { unit_test_setup_teardown(torture_callbacks_size, setup, teardown), unit_test_setup_teardown(torture_callbacks_exists, setup, teardown), + unit_test(torture_log_callback), }; ssh_init(); diff --git a/libssh/tests/unittests/torture_channel.c b/libssh/tests/unittests/torture_channel.c index 5bf34fd9..1d928b84 100644 --- a/libssh/tests/unittests/torture_channel.c +++ b/libssh/tests/unittests/torture_channel.c @@ -20,6 +20,7 @@ static void torture_channel_select(void **state) fd = open("/dev/null", 0); assert_true(fd > 2); + FD_ZERO(&readfds); FD_SET(fd, &readfds); for (i = 0; i < 10; i++) { diff --git a/libssh/tests/unittests/torture_pki.c b/libssh/tests/unittests/torture_pki.c index 7324177e..efcbb01b 100644 --- a/libssh/tests/unittests/torture_pki.c +++ b/libssh/tests/unittests/torture_pki.c @@ -8,64 +8,65 @@ #define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa" #define LIBSSH_DSA_TESTKEY "libssh_testkey.id_dsa" #define LIBSSH_ECDSA_TESTKEY "libssh_testkey.id_ecdsa" -#define LIBSSH_PASSPHRASE "libssh-rocks" + const unsigned char HASH[] = "12345678901234567890"; static void setup_rsa_key(void **state) { - int rc; - (void) state; /* unused */ unlink(LIBSSH_RSA_TESTKEY); unlink(LIBSSH_RSA_TESTKEY ".pub"); - rc = system("ssh-keygen -t rsa -q -N \"\" -f " LIBSSH_RSA_TESTKEY); - assert_true(rc == 0); + torture_write_file(LIBSSH_RSA_TESTKEY, + torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0)); + torture_write_file(LIBSSH_RSA_TESTKEY ".pub", + torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0)); } static void setup_dsa_key(void **state) { - int rc; - (void) state; /* unused */ unlink(LIBSSH_DSA_TESTKEY); unlink(LIBSSH_DSA_TESTKEY ".pub"); - rc = system("ssh-keygen -t dsa -q -N \"\" -f " LIBSSH_DSA_TESTKEY); - assert_true(rc == 0); + torture_write_file(LIBSSH_DSA_TESTKEY, + torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0)); + torture_write_file(LIBSSH_DSA_TESTKEY ".pub", + torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0)); } #ifdef HAVE_OPENSSL_ECC -static void setup_ecdsa_key(void **state) { - int rc; +static void setup_ecdsa_key(void **state, int ecdsa_bits) { (void) state; /* unused */ unlink(LIBSSH_ECDSA_TESTKEY); unlink(LIBSSH_ECDSA_TESTKEY ".pub"); - rc = system("ssh-keygen -t ecdsa -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY); - assert_true(rc == 0); + torture_write_file(LIBSSH_ECDSA_TESTKEY, + torture_get_testkey(SSH_KEYTYPE_ECDSA, ecdsa_bits, 0)); + torture_write_file(LIBSSH_ECDSA_TESTKEY ".pub", + torture_get_testkey_pub(SSH_KEYTYPE_ECDSA, ecdsa_bits)); } -#endif -static void setup_both_keys(void **state) { - (void) state; /* unused */ +static void setup_ecdsa_key_521(void **state) { + setup_ecdsa_key(state, 521); +} - setup_rsa_key(state); - setup_dsa_key(state); +static void setup_ecdsa_key_384(void **state) { + setup_ecdsa_key(state, 384); } -static void setup_both_keys_passphrase(void **state) { - int rc; +static void setup_ecdsa_key_256(void **state) { + setup_ecdsa_key(state, 256); +} +#endif +static void setup_both_keys(void **state) { (void) state; /* unused */ - rc = system("ssh-keygen -t rsa -q -N " LIBSSH_PASSPHRASE " -f " LIBSSH_RSA_TESTKEY); - assert_true(rc == 0); - - rc = system("ssh-keygen -t dsa -q -N " LIBSSH_PASSPHRASE " -f " LIBSSH_DSA_TESTKEY); - assert_true(rc == 0); + setup_rsa_key(state); + setup_dsa_key(state); } static void teardown(void **state) { @@ -111,24 +112,40 @@ static char *read_file(const char *filename) { static int torture_read_one_line(const char *filename, char *buffer, size_t len) { FILE *fp; - size_t rc; + size_t nmemb; fp = fopen(filename, "r"); if (fp == NULL) { return -1; } - rc = fread(buffer, len, 1, fp); - if (rc != 0 || ferror(fp)) { + nmemb = fread(buffer, len - 2, 1, fp); + if (nmemb != 0 || ferror(fp)) { fclose(fp); return -1; } + buffer[len - 1] = '\0'; fclose(fp); return 0; } +/** @internal + * returns the character len of a public key string, omitting the comment part + */ +static int torture_pubkey_len(const char *pubkey){ + const char *ptr; + ptr=strchr(pubkey, ' '); + if (ptr != NULL){ + ptr = strchr(ptr + 1, ' '); + if (ptr != NULL){ + return ptr - pubkey; + } + } + return 0; +} + static void torture_pki_keytype(void **state) { enum ssh_keytypes_e type; const char *type_c; @@ -167,7 +184,7 @@ static void torture_pki_import_privkey_base64_RSA(void **state) { int rc; char *key_str; ssh_key key; - const char *passphrase = LIBSSH_PASSPHRASE; + const char *passphrase = torture_get_testkey_passphrase(); enum ssh_keytypes_e type; (void) state; /* unused */ @@ -190,60 +207,48 @@ static void torture_pki_import_privkey_base64_RSA(void **state) { static void torture_pki_import_privkey_base64_NULL_key(void **state) { int rc; - char *key_str; - ssh_key key; - const char *passphrase = LIBSSH_PASSPHRASE; + const char *passphrase = torture_get_testkey_passphrase(); (void) state; /* unused */ - key_str = read_file(LIBSSH_RSA_TESTKEY); - assert_true(key_str != NULL); - - key = ssh_key_new(); - assert_true(key != NULL); - /* test if it returns -1 if key is NULL */ - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, NULL); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0), + passphrase, + NULL, + NULL, + NULL); assert_true(rc == -1); - free(key_str); - ssh_key_free(key); } static void torture_pki_import_privkey_base64_NULL_str(void **state) { int rc; - char *key_str; ssh_key key = NULL; - const char *passphrase = LIBSSH_PASSPHRASE; + const char *passphrase = torture_get_testkey_passphrase(); (void) state; /* unused */ - key_str = read_file(LIBSSH_RSA_TESTKEY); - assert_true(key_str != NULL); - /* test if it returns -1 if key_str is NULL */ rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key); assert_true(rc == -1); - free(key_str); ssh_key_free(key); } static void torture_pki_import_privkey_base64_DSA(void **state) { int rc; - char *key_str; ssh_key key; - const char *passphrase = LIBSSH_PASSPHRASE; + const char *passphrase = torture_get_testkey_passphrase(); (void) state; /* unused */ - key_str = read_file(LIBSSH_DSA_TESTKEY); - assert_true(key_str != NULL); - - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0), + passphrase, + NULL, + NULL, + &key); assert_true(rc == 0); - free(key_str); ssh_key_free(key); } @@ -252,7 +257,7 @@ static void torture_pki_import_privkey_base64_ECDSA(void **state) { int rc; char *key_str; ssh_key key; - const char *passphrase = LIBSSH_PASSPHRASE; + const char *passphrase = torture_get_testkey_passphrase(); (void) state; /* unused */ @@ -269,97 +274,110 @@ static void torture_pki_import_privkey_base64_ECDSA(void **state) { static void torture_pki_import_privkey_base64_passphrase(void **state) { int rc; - char *key_str; ssh_key key = NULL; - const char *passphrase = LIBSSH_PASSPHRASE; + const char *passphrase = torture_get_testkey_passphrase(); (void) state; /* unused */ - key_str = read_file(LIBSSH_RSA_TESTKEY); - assert_true(key_str != NULL); - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), + passphrase, + NULL, + NULL, + &key); assert_true(rc == 0); ssh_key_free(key); /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(key_str, "wrong passphrase !!", NULL, - NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), + "wrong passphrase !!", + NULL, + NULL, + &key); assert_true(rc == -1); #ifndef HAVE_LIBCRYPTO /* test if it returns -1 if passphrase is NULL */ /* libcrypto asks for a passphrase, so skip this test */ - rc = ssh_pki_import_privkey_base64(key_str, NULL, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), + NULL, + NULL, + NULL, + &key); assert_true(rc == -1); #endif - free(key_str); - /* same for DSA */ - key_str = read_file(LIBSSH_DSA_TESTKEY); - assert_true(key_str != NULL); - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), + passphrase, + NULL, + NULL, + &key); assert_true(rc == 0); ssh_key_free(key); /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(key_str, "wrong passphrase !!", NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), + "wrong passphrase !!", + NULL, + NULL, + &key); assert_true(rc == -1); #ifndef HAVE_LIBCRYPTO /* test if it returns -1 if passphrase is NULL */ /* libcrypto asks for a passphrase, so skip this test */ - rc = ssh_pki_import_privkey_base64(key_str, NULL, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), + NULL, + NULL, + NULL, + &key); assert_true(rc == -1); #endif - free(key_str); } static void torture_pki_pki_publickey_from_privatekey_RSA(void **state) { int rc; - char *key_str; ssh_key key; ssh_key pubkey; const char *passphrase = NULL; (void) state; /* unused */ - key_str = read_file(LIBSSH_RSA_TESTKEY); - assert_true(key_str != NULL); - - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0), + passphrase, + NULL, + NULL, + &key); assert_true(rc == 0); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); assert_true(rc == SSH_OK); - free(key_str); ssh_key_free(key); ssh_key_free(pubkey); } static void torture_pki_pki_publickey_from_privatekey_DSA(void **state) { int rc; - char *key_str; ssh_key key; ssh_key pubkey; const char *passphrase = NULL; (void) state; /* unused */ - key_str = read_file(LIBSSH_DSA_TESTKEY); - assert_true(key_str != NULL); - - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); + rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0), + passphrase, + NULL, + NULL, + &key); assert_true(rc == 0); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); assert_true(rc == SSH_OK); - free(key_str); ssh_key_free(key); ssh_key_free(pubkey); } @@ -399,7 +417,7 @@ static void torture_pki_publickey_dsa_base64(void **state) (void) state; /* unused */ - key_buf = read_file(LIBSSH_DSA_TESTKEY ".pub"); + key_buf = strdup(torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0)); assert_true(key_buf != NULL); q = p = key_buf; @@ -475,7 +493,7 @@ static void torture_pki_publickey_rsa_base64(void **state) (void) state; /* unused */ - key_buf = read_file(LIBSSH_RSA_TESTKEY ".pub"); + key_buf = strdup(torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0)); assert_true(key_buf != NULL); q = p = key_buf; @@ -504,19 +522,14 @@ static void torture_pki_publickey_rsa_base64(void **state) } static void torture_generate_pubkey_from_privkey_rsa(void **state) { - char pubkey_original[4096] = {0}; char pubkey_generated[4096] = {0}; ssh_key privkey; ssh_key pubkey; int rc; + int len; (void) state; /* unused */ - rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", - pubkey_original, - sizeof(pubkey_original)); - assert_true(rc == 0); - /* remove the public key, generate it from the private key and write it. */ unlink(LIBSSH_RSA_TESTKEY ".pub"); @@ -538,26 +551,24 @@ static void torture_generate_pubkey_from_privkey_rsa(void **state) { sizeof(pubkey_generated)); assert_true(rc == 0); - assert_string_equal(pubkey_original, pubkey_generated); + len = torture_pubkey_len(torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0)); + assert_memory_equal(torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0), + pubkey_generated, + len); ssh_key_free(privkey); ssh_key_free(pubkey); } static void torture_generate_pubkey_from_privkey_dsa(void **state) { - char pubkey_original[4096] = {0}; char pubkey_generated[4096] = {0}; ssh_key privkey; ssh_key pubkey; + int len; int rc; (void) state; /* unused */ - rc = torture_read_one_line(LIBSSH_DSA_TESTKEY ".pub", - pubkey_original, - sizeof(pubkey_original)); - assert_true(rc == 0); - /* remove the public key, generate it from the private key and write it. */ unlink(LIBSSH_DSA_TESTKEY ".pub"); @@ -579,7 +590,10 @@ static void torture_generate_pubkey_from_privkey_dsa(void **state) { sizeof(pubkey_generated)); assert_true(rc == 0); - assert_string_equal(pubkey_original, pubkey_generated); + len = torture_pubkey_len(torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0)); + assert_memory_equal(torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0), + pubkey_generated, + len); ssh_key_free(privkey); ssh_key_free(pubkey); @@ -592,6 +606,7 @@ static void torture_generate_pubkey_from_privkey_ecdsa(void **state) { ssh_key privkey; ssh_key pubkey; int rc; + int len; (void) state; /* unused */ @@ -620,8 +635,8 @@ static void torture_generate_pubkey_from_privkey_ecdsa(void **state) { pubkey_generated, sizeof(pubkey_generated)); assert_true(rc == 0); - - assert_string_equal(pubkey_original, pubkey_generated); + len = torture_pubkey_len(pubkey_original); + assert_int_equal(strncmp(pubkey_original, pubkey_generated, len), 0); ssh_key_free(privkey); ssh_key_free(pubkey); @@ -766,6 +781,39 @@ static void torture_pki_duplicate_key_ecdsa(void **state) ssh_string_free_char(b64_key); ssh_string_free_char(b64_key_gen); } + +/* Test case for bug #147: Private ECDSA key duplication did not carry + * over parts of the key that then caused subsequent key demotion to + * fail. + */ +static void torture_pki_ecdsa_duplicate_then_demote(void **state) +{ + ssh_key pubkey; + ssh_key privkey; + ssh_key privkey_dup; + int rc; + + (void) state; + + rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + + privkey_dup = ssh_key_dup(privkey); + assert_true(privkey_dup != NULL); + assert_int_equal(privkey->ecdsa_nid, privkey_dup->ecdsa_nid); + + rc = ssh_pki_export_privkey_to_pubkey(privkey_dup, &pubkey); + assert_true(rc == 0); + assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid); + + ssh_key_free(pubkey); + ssh_key_free(privkey); + ssh_key_free(privkey_dup); +} #endif static void torture_pki_generate_key_rsa(void **state) @@ -906,6 +954,9 @@ static void torture_pki_generate_key_ecdsa(void **state) int rc; ssh_key key; ssh_signature sign; + enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN; + const char *type_char = NULL; + const char *etype_char = NULL; ssh_session session=ssh_new(); (void) state; @@ -916,6 +967,13 @@ static void torture_pki_generate_key_ecdsa(void **state) assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); + type = ssh_key_type(key); + assert_true(type == SSH_KEYTYPE_ECDSA); + type_char = ssh_key_type_to_char(type); + assert_true(strcmp(type_char, "ssh-ecdsa") == 0); + etype_char = ssh_pki_key_ecdsa_name(key); + assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0); + ssh_signature_free(sign); ssh_key_free(key); key=NULL; @@ -927,6 +985,13 @@ static void torture_pki_generate_key_ecdsa(void **state) assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); + type = ssh_key_type(key); + assert_true(type == SSH_KEYTYPE_ECDSA); + type_char = ssh_key_type_to_char(type); + assert_true(strcmp(type_char, "ssh-ecdsa") == 0); + etype_char =ssh_pki_key_ecdsa_name(key); + assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0); + ssh_signature_free(sign); ssh_key_free(key); key=NULL; @@ -938,6 +1003,13 @@ static void torture_pki_generate_key_ecdsa(void **state) assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); + type = ssh_key_type(key); + assert_true(type == SSH_KEYTYPE_ECDSA); + type_char = ssh_key_type_to_char(type); + assert_true(strcmp(type_char, "ssh-ecdsa") == 0); + etype_char =ssh_pki_key_ecdsa_name(key); + assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0); + ssh_signature_free(sign); ssh_key_free(key); key=NULL; @@ -946,6 +1018,166 @@ static void torture_pki_generate_key_ecdsa(void **state) } #endif +#ifdef HAVE_LIBCRYPTO +static void torture_pki_write_privkey_rsa(void **state) +{ + ssh_key origkey; + ssh_key privkey; + int rc; + + (void) state; /* unused */ + + ssh_set_log_level(5); + + rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, + NULL, + NULL, + NULL, + &origkey); + assert_true(rc == 0); + + unlink(LIBSSH_RSA_TESTKEY); + + rc = ssh_pki_export_privkey_file(origkey, + "", + NULL, + NULL, + LIBSSH_RSA_TESTKEY); + assert_true(rc == 0); + + rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + + rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); + assert_true(rc == 0); + + ssh_key_free(origkey); + ssh_key_free(privkey); +} + +static void torture_pki_write_privkey_dsa(void **state) +{ + ssh_key origkey; + ssh_key privkey; + int rc; + + (void) state; /* unused */ + + ssh_set_log_level(5); + + rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, + NULL, + NULL, + NULL, + &origkey); + assert_true(rc == 0); + + unlink(LIBSSH_DSA_TESTKEY); + + rc = ssh_pki_export_privkey_file(origkey, + "", + NULL, + NULL, + LIBSSH_DSA_TESTKEY); + assert_true(rc == 0); + + rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + + rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); + assert_true(rc == 0); + + ssh_key_free(origkey); + ssh_key_free(privkey); +} + +#ifdef HAVE_ECC +static void torture_pki_write_privkey_ecdsa(void **state) +{ + ssh_key origkey; + ssh_key privkey; + int rc; + + (void) state; /* unused */ + + ssh_set_log_level(5); + + rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, + NULL, + NULL, + NULL, + &origkey); + assert_true(rc == 0); + + unlink(LIBSSH_ECDSA_TESTKEY); + + rc = ssh_pki_export_privkey_file(origkey, + "", + NULL, + NULL, + LIBSSH_ECDSA_TESTKEY); + assert_true(rc == 0); + + rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, + NULL, + NULL, + NULL, + &privkey); + assert_true(rc == 0); + + rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); + assert_true(rc == 0); + + ssh_key_free(origkey); + ssh_key_free(privkey); +} +#endif +#endif /* HAVE_LIBCRYPTO */ + +#ifdef HAVE_ECC +static void torture_pki_ecdsa_name(void **state, const char *expected_name) +{ + int rc; + ssh_key key; + const char *etype_char = NULL; + + (void) state; /* unused */ + + ssh_set_log_level(5); + + rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, NULL, NULL, NULL, &key); + assert_true(rc == 0); + + etype_char =ssh_pki_key_ecdsa_name(key); + assert_true(strcmp(etype_char, expected_name) == 0); + + ssh_key_free(key); +} + +static void torture_pki_ecdsa_name256(void **state) +{ + torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp256"); +} + +static void torture_pki_ecdsa_name384(void **state) +{ + torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp384"); +} + +static void torture_pki_ecdsa_name521(void **state) +{ + torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp521"); +} +#endif + int torture_run_tests(void) { int rc; const UnitTest tests[] = { @@ -968,12 +1200,16 @@ int torture_run_tests(void) { teardown), #ifdef HAVE_ECC unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, - setup_ecdsa_key, + setup_ecdsa_key_256, teardown), -#endif - unit_test_setup_teardown(torture_pki_import_privkey_base64_passphrase, - setup_both_keys_passphrase, + unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, + setup_ecdsa_key_384, + teardown), + unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, + setup_ecdsa_key_521, teardown), +#endif + unit_test(torture_pki_import_privkey_base64_passphrase), /* ssh_pki_export_privkey_to_pubkey */ unit_test_setup_teardown(torture_pki_pki_publickey_from_privatekey_RSA, |