diff options
Diffstat (limited to 'tests/psk-file.c')
-rw-r--r-- | tests/psk-file.c | 151 |
1 files changed, 125 insertions, 26 deletions
diff --git a/tests/psk-file.c b/tests/psk-file.c index ee6f8c533e..a6df3f0467 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,15 @@ 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; + const char *pskid; char buffer[MAX_BUF + 1]; char *psk_file = getenv("PSK_FILE"); + char *desc; /* this must be called once in the program */ @@ -197,17 +214,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 +257,32 @@ 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"); + + pskid = gnutls_psk_server_get_username(session); + if (pskid == NULL || strcmp(pskid, user) != 0) { + fail("server: username (%s), does not match expected (%s)\n", + pskid, user); + } + + 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 +295,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 +326,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 */ |