diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-03-22 10:02:36 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-04-06 13:28:55 +0200 |
commit | 3437fdde655a73af380018ce22435628d557036e (patch) | |
tree | 5a8a65ac98ecaf8464d2407b40a004fe95a8e2ed /tests/psk-file.c | |
parent | f09e8060b51881f9fefc0a82ec4656fb0e500ccb (diff) | |
download | gnutls-3437fdde655a73af380018ce22435628d557036e.tar.gz |
tests: enhanced test suite for TLS1.3 and PSK
That includes tests with unknown usernames and connections with wrong key
and updates to fastopen.sh to use certificate auth, making it applicable
under TLS1.3.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'tests/psk-file.c')
-rw-r--r-- | tests/psk-file.c | 144 |
1 files changed, 118 insertions, 26 deletions
diff --git a/tests/psk-file.c b/tests/psk-file.c index ee6f8c533e..59f6f2d4a2 100644 --- a/tests/psk-file.c +++ b/tests/psk-file.c @@ -65,14 +65,13 @@ static void tls_log_func(int level, const char *str) #define MAX_BUF 1024 #define MSG "Hello TLS" -static void client(int sd, const char *prio, const char *user, unsigned expect_fail) +static void client(int sd, const char *prio, const char *user, const gnutls_datum_t *key, + unsigned expect_hint, int expect_fail, int exp_kx) { - int ret, ii; + int ret, ii, kx; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_psk_client_credentials_t pskcred; - /* Need to enable anonymous KX specifically. */ - const gnutls_datum_t key = { (void *) "9e32cf7786321a828ef7668f09fb35db", 32 }; const char *hint; global_init(); @@ -83,7 +82,7 @@ static void client(int sd, const char *prio, const char *user, unsigned expect_f side = "client"; gnutls_psk_allocate_client_credentials(&pskcred); - gnutls_psk_set_client_credentials(pskcred, user, &key, + gnutls_psk_set_client_credentials(pskcred, user, key, GNUTLS_PSK_KEY_HEX); /* Initialize TLS session @@ -106,7 +105,10 @@ static void client(int sd, const char *prio, const char *user, unsigned expect_f if (ret < 0) { if (!expect_fail) fail("client: Handshake failed\n"); - gnutls_perror(ret); + if (ret != expect_fail) { + fail("expected cli error %d (%s), got %d (%s)\n", expect_fail, gnutls_strerror(expect_fail), + ret, gnutls_strerror(ret)); + } goto end; } else { if (debug) @@ -114,10 +116,12 @@ static void client(int sd, const char *prio, const char *user, unsigned expect_f } /* check the hint */ - hint = gnutls_psk_client_get_hint(session); - if (hint == NULL || strcmp(hint, "hint") != 0) { - fail("client: hint is not the expected: %s\n", gnutls_psk_client_get_hint(session)); - goto end; + if (expect_hint) { + hint = gnutls_psk_client_get_hint(session); + if (hint == NULL || strcmp(hint, "hint") != 0) { + fail("client: hint is not the expected: %s\n", gnutls_psk_client_get_hint(session)); + goto end; + } } gnutls_record_send(session, MSG, strlen(MSG)); @@ -133,6 +137,8 @@ static void client(int sd, const char *prio, const char *user, unsigned expect_f goto end; } + kx = gnutls_kx_get(session); + if (debug) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { @@ -143,6 +149,15 @@ static void client(int sd, const char *prio, const char *user, unsigned expect_f gnutls_bye(session, GNUTLS_SHUT_RDWR); + if (expect_fail) + fail("client: expected failure but connection succeeded!\n"); + + if (exp_kx && kx != exp_kx) { + fail("client: expected key exchange %s, but got %s\n", + gnutls_kx_get_name(exp_kx), + gnutls_kx_get_name(kx)); + } + end: close(sd); @@ -159,13 +174,14 @@ static void client(int sd, const char *prio, const char *user, unsigned expect_f #define MAX_BUF 1024 -static void server(int sd, const char *prio, const char *user, unsigned expect_fail) +static void server(int sd, const char *prio, const char *user, int expect_fail, int exp_kx) { gnutls_psk_server_credentials_t server_pskcred; - int ret; + int ret, kx; gnutls_session_t session; char buffer[MAX_BUF + 1]; char *psk_file = getenv("PSK_FILE"); + char *desc; /* this must be called once in the program */ @@ -197,17 +213,22 @@ static void server(int sd, const char *prio, const char *user, unsigned expect_f gnutls_transport_set_int(session, sd); ret = gnutls_handshake(session); if (ret < 0) { - close(sd); - gnutls_deinit(session); - gnutls_psk_free_server_credentials(server_pskcred); + gnutls_alert_send_appropriate(session, ret); if (expect_fail) { - success("server: Handshake has failed - expected (%s)\n\n", - gnutls_strerror(ret)); + if (ret != expect_fail) { + fail("expected error %d (%s), got %d (%s)\n", expect_fail, + gnutls_strerror(expect_fail), + ret, gnutls_strerror(ret)); + } + + if (debug) + success("server: Handshake has failed - expected (%s)\n\n", + gnutls_strerror(ret)); } else { fail("server: Handshake has failed (%s)\n\n", gnutls_strerror(ret)); } - return; + goto end; } if (debug) success("server: Handshake was completed\n"); @@ -235,10 +256,26 @@ static void server(int sd, const char *prio, const char *user, unsigned expect_f strlen(buffer)); } } + + kx = gnutls_kx_get(session); + + desc = gnutls_session_get_desc(session); + success(" - connected with: %s\n", desc); + gnutls_free(desc); /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); + if (expect_fail) + fail("server: expected failure but connection succeeded!\n"); + + if (exp_kx && kx != exp_kx) { + fail("server: expected key exchange %s, but got %s\n", + gnutls_kx_get_name(exp_kx), + gnutls_kx_get_name(kx)); + } + + end: close(sd); gnutls_deinit(session); @@ -251,13 +288,18 @@ static void server(int sd, const char *prio, const char *user, unsigned expect_f } static -void run_test(const char *prio, const char *user, unsigned expect_fail) +void run_test2(const char *prio, const char *sprio, const char *user, const gnutls_datum_t *key, + unsigned expect_hint, int exp_kx, int expect_fail_cli, int expect_fail_serv) { pid_t child; int err; int sockets[2]; - success("trying %s / user:%s\n", prio, user); + if (expect_fail_serv || expect_fail_cli) { + success("ntest %s (user:%s)\n", prio, user); + } else { + success("test %s (user:%s)\n", prio, user); + } err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); if (err == -1) { @@ -277,22 +319,72 @@ void run_test(const char *prio, const char *user, unsigned expect_fail) close(sockets[1]); int status; /* parent */ - server(sockets[0], prio, user, expect_fail); + server(sockets[0], sprio?sprio:prio, user, expect_fail_serv, exp_kx); wait(&status); check_wait_status(status); } else { close(sockets[0]); - client(sockets[1], prio, user, expect_fail); + client(sockets[1], prio, user, key, expect_hint, expect_fail_cli, exp_kx); exit(0); } } +static +void run_test_ok(const char *prio, const char *user, const gnutls_datum_t *key, unsigned expect_hint, int expect_fail) +{ + return run_test2(prio, NULL, user, key, expect_hint, GNUTLS_KX_PSK, expect_fail, expect_fail); +} + +static +void run_ectest_ok(const char *prio, const char *user, const gnutls_datum_t *key, unsigned expect_hint, int expect_fail) +{ + return run_test2(prio, NULL, user, key, expect_hint, GNUTLS_KX_ECDHE_PSK, expect_fail, expect_fail); +} + +static +void run_dhtest_ok(const char *prio, const char *user, const gnutls_datum_t *key, unsigned expect_hint, int expect_fail) +{ + return run_test2(prio, NULL, user, key, expect_hint, GNUTLS_KX_DHE_PSK, expect_fail, expect_fail); +} + void doit(void) { - run_test("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+PSK", "jas", 0); - run_test("NORMAL:-KX-ALL:+PSK", "jas", 0); - run_test("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+PSK", "non-hex", 1); - run_test("NORMAL:-KX-ALL:+PSK", "non-hex", 1); + const gnutls_datum_t key = { (void *) "9e32cf7786321a828ef7668f09fb35db", 32 }; + const gnutls_datum_t wrong_key = { (void *) "9e31cf7786321a828ef7668f09fb35db", 32 }; + + run_test_ok("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+PSK", "jas", &key, 1, 0); + run_dhtest_ok("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-PSK", "jas", &key, 1, 0); + run_ectest_ok("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-PSK", "jas", &key, 1, 0); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+PSK", NULL, "unknown", &key, 1, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_DECRYPTION_FAILED); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+PSK", NULL, "jas", &wrong_key, 1, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_DECRYPTION_FAILED); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+PSK", NULL, "non-hex", &key, 1, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_KEYFILE_ERROR); + + run_test_ok("NORMAL:-KX-ALL:+PSK", "jas", &key, 1, 0); + run_test2("NORMAL:+PSK", NULL, "unknown", &key, 1, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_DECRYPTION_FAILED); + run_test2("NORMAL:+PSK", NULL, "jas", &wrong_key, 1, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_DECRYPTION_FAILED); + run_test2("NORMAL:-KX-ALL:+PSK", NULL, "non-hex", &key, 1, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_KEYFILE_ERROR); + + run_dhtest_ok("NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:-GROUP-EC-ALL", "jas", &key, 0, 0); + run_test_ok("NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK", "jas", &key, 0, 0); + + /* test priorities of DHE-PSK and PSK */ + run_ectest_ok("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+DHE-PSK:+PSK:-GROUP-DH-ALL", "jas", &key, 0, 0); + run_test_ok("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+PSK:+DHE-PSK:-GROUP-DH-ALL", "jas", &key, 0, 0); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+DHE-PSK:+PSK:-GROUP-DH-ALL", + "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+PSK:+DHE-PSK:%SERVER_PRECEDENCE:-GROUP-DH-ALL", + "jas", &key, 0, GNUTLS_KX_PSK, 0, 0); + /* try with PRF that doesn't match binder (SHA256) */ + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM:+PSK:+DHE-PSK", NULL, "jas", &key, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_INSUFFICIENT_SECURITY); + /* try with no groups and PSK */ + run_test_ok("NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:-GROUP-ALL", "jas", &key, 0, 0); + /* try without any groups but DHE-PSK */ + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:-GROUP-ALL", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:+PSK", "jas", &key, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_NO_COMMON_KEY_SHARE); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:-GROUP-ALL", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:+PSK:-GROUP-ALL", "jas", &key, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_NO_COMMON_KEY_SHARE); + + /* if user invalid we continue without PSK */ + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:+DHE-PSK", NULL, "non-hex", &key, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_INSUFFICIENT_CREDENTIALS); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:+DHE-PSK", NULL, "unknown", &key, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:+DHE-PSK", NULL, "jas", &wrong_key, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); } #endif /* _WIN32 */ |