]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
ext/pre_shared_key: prevent crash if no server credentials are set
authorDaiki Ueno <dueno@redhat.com>
Tue, 7 Aug 2018 12:45:07 +0000 (14:45 +0200)
committerDaiki Ueno <dueno@redhat.com>
Wed, 8 Aug 2018 09:19:20 +0000 (11:19 +0200)
Previously, if server is configured without PSK credentials and the
client authenticated with PSK, the server crashed with:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b190ba in server_recv_params (session=0x636fc0, data=0x634e6e "",
    len=46, pskcred=0x0) at pre_shared_key.c:523
523                             prf = pskcred->binder_algo;

Signed-off-by: Daiki Ueno <dueno@redhat.com>
lib/ext/pre_shared_key.c
tests/psk-file.c

index dc56d1dc4912f1b0722b05d6af3eac78355df2cd..b2f24bc3baacb677855fd1624e56f773b3ba0ae3 100644 (file)
@@ -515,7 +515,8 @@ static int server_recv_params(gnutls_session_t session,
 
                        resuming = 1;
                        break;
-               } else if (psk.ob_ticket_age == 0 &&
+               } else if (pskcred &&
+                          psk.ob_ticket_age == 0 &&
                           psk.identity.size > 0 && psk.identity.size <= MAX_USERNAME_SIZE) {
                        /* _gnutls_psk_pwd_find_entry() expects 0-terminated identities */
                        char identity_str[psk.identity.size + 1];
index 3defa28275189e6e8b22150ca8db576447b78e0a..28d45560b1f38ca8d00285b4c7e494862f77c248 100644 (file)
@@ -27,6 +27,7 @@
 #include <config.h>
 #endif
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -171,7 +172,8 @@ static void client(int sd, const char *prio, const char *user, const gnutls_datu
 
 #define MAX_BUF 1024
 
-static void server(int sd, const char *prio, const char *user, int expect_fail, int exp_kx)
+static void server(int sd, const char *prio, const char *user, bool no_cred,
+                  int expect_fail, int exp_kx)
 {
        gnutls_psk_server_credentials_t server_pskcred;
        int ret, kx;
@@ -206,7 +208,8 @@ static void server(int sd, const char *prio, const char *user, int expect_fail,
 
        assert(gnutls_priority_set_direct(session, prio, NULL)>=0);
 
-       gnutls_credentials_set(session, GNUTLS_CRD_PSK, server_pskcred);
+       if (!no_cred)
+               gnutls_credentials_set(session, GNUTLS_CRD_PSK, server_pskcred);
 
        gnutls_transport_set_int(session, sd);
        ret = gnutls_handshake(session);
@@ -267,10 +270,12 @@ static void server(int sd, const char *prio, const char *user, int expect_fail,
        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 (!no_cred) {
+               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) {
@@ -292,7 +297,7 @@ static void server(int sd, const char *prio, const char *user, int expect_fail,
 }
 
 static
-void run_test2(const char *prio, const char *sprio, const char *user, const gnutls_datum_t *key,
+void run_test3(const char *prio, const char *sprio, const char *user, const gnutls_datum_t *key, bool no_cred,
              unsigned expect_hint, int exp_kx, int expect_fail_cli, int expect_fail_serv)
 {
        pid_t child;
@@ -323,7 +328,7 @@ void run_test2(const char *prio, const char *sprio, const char *user, const gnut
                close(sockets[1]);
                int status;
                /* parent */
-               server(sockets[0], sprio?sprio:prio, user, expect_fail_serv, exp_kx);
+               server(sockets[0], sprio?sprio:prio, user, no_cred, expect_fail_serv, exp_kx);
                wait(&status);
                check_wait_status(status);
        } else {
@@ -333,22 +338,29 @@ void run_test2(const char *prio, const char *sprio, const char *user, const gnut
        }
 }
 
+static
+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)
+{
+       run_test3(prio, sprio, user, key, 0, expect_hint, exp_kx, expect_fail_cli, expect_fail_serv);
+}
+
 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);
+       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);
+       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);
+       run_test2(prio, NULL, user, key, expect_hint, GNUTLS_KX_DHE_PSK, expect_fail, expect_fail);
 }
 
 void doit(void)
@@ -398,6 +410,9 @@ void doit(void)
 
        /* try with HelloRetryRequest and PSK */
        run_test2("NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-FFDHE4096", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+DHE-PSK:-GROUP-ALL:+GROUP-FFDHE4096", "jas", &key, 0, GNUTLS_KX_DHE_PSK, 0, 0);
+
+       /* try without server credentials */
+       run_test3("NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:+DHE-PSK", NULL, "jas", &key, 1, 0, 0, GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_E_INSUFFICIENT_CREDENTIALS);
 }
 
 #endif                         /* _WIN32 */