From: Nikos Mavrogiannopoulos Date: Tue, 12 Apr 2016 13:26:42 +0000 (+0200) Subject: tests: combined the resume checks for Anonymous and PSK ciphersuites X-Git-Tag: gnutls_3_5_0~173 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=071912e070167ada794fbd9923d36def7e714d4a;p=thirdparty%2Fgnutls.git tests: combined the resume checks for Anonymous and PSK ciphersuites In addition enhanced it to check the resumption on the certificate ciphersuites as well. --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 432c1d54bc..36d3b22c6f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -90,7 +90,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \ sign-md5-rep keygen mini-tls-nonblock no-signal pkcs7-gen \ x509sign-verify2 mini-alignment oids atfork prf psk-file \ status-request status-request-ok fallback-scsv pkcs8-key-decode \ - key-usage resume-psk mini-session-verify-function auto-verify \ + key-usage mini-session-verify-function auto-verify \ record-timeouts mini-dtls-hello-verify-48 mini-x509-default-prio \ mini-x509-dual mini-x509-kx global-init-override tlsext-decoding \ rehandshake-switch-cert rehandshake-switch-cert-allow rehandshake-switch-cert-client \ @@ -106,6 +106,14 @@ endif mini_dtls_pthread_LDADD = $(LDADD) -lpthread +resume_psk_CFLAGS = -DUSE_PSK +resume_psk_SOURCES = resume.c + +resume_anon_CFLAGS = -DUSE_ANON +resume_anon_SOURCES = resume.c + +resume_x509_CFLAGS = -DUSE_X509 +resume_x509_SOURCES = resume.c if ENABLE_OCSP ctests += ocsp @@ -130,7 +138,7 @@ endif if HAVE_FORK ctests += x509self x509dn anonself pskself dhepskself \ - resume setcredcrash + setcredcrash resume-x509 resume-psk resume-anon if ENABLE_OPENPGP ctests += openpgpself diff --git a/tests/resume-psk.c b/tests/resume-psk.c deleted file mode 100644 index 0132b9a21f..0000000000 --- a/tests/resume-psk.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (C) 2004-2012 Free Software Foundation, Inc. - * Copyright (C) 2013 Adam Sampson - * - * Author: Simon Josefsson - * - * This file is part of GnuTLS. - * - * GnuTLS is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuTLS is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GnuTLS; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* Parts copied from GnuTLS example programs. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#if defined(_WIN32) - -/* socketpair isn't supported on Win32. */ -int main(int argc, char **argv) -{ - exit(77); -} - -#else - -#include -#include -#include -#if !defined(_WIN32) -#include -#endif -#include -#include -#include -#include - -#include "utils.h" - -static void wrap_db_init(void); -static void wrap_db_deinit(void); -static int wrap_db_store(void *dbf, gnutls_datum_t key, - gnutls_datum_t data); -static gnutls_datum_t wrap_db_fetch(void *dbf, gnutls_datum_t key); -static int wrap_db_delete(void *dbf, gnutls_datum_t key); - -#define TLS_SESSION_CACHE 50 - -struct params_res { - const char *desc; - int enable_db; - int enable_session_ticket_server; - int enable_session_ticket_client; - int expect_resume; -}; - -pid_t child; - -struct params_res resume_tests[] = { - {"try to resume from db", 1, 0, 0, 1}, - {"try to resume from session ticket", 0, 1, 1, 1}, - {"try to resume from session ticket (server only)", 0, 1, 0, 0}, - {"try to resume from session ticket (client only)", 0, 0, 1, 0}, - {"try to resume from db and ticket", 1, 1, 1, 1}, - {NULL, -1} -}; - -/* A very basic TLS client, with anonymous authentication. - */ - -#define SESSIONS 3 -#define MAX_BUF 5*1024 -#define MSG "Hello TLS" - -static void tls_log_func(int level, const char *str) -{ - fprintf(stderr, "%s |<%d>| %s", child ? "server" : "client", level, - str); -} - -static void client(int sds[], struct params_res *params) -{ - int ret, ii; - gnutls_session_t session; - char buffer[MAX_BUF + 1]; - gnutls_psk_client_credentials_t pskcred; - const gnutls_datum_t key = { (void *) "DEADBEEF", 8 }; - - /* variables used in session resuming - */ - int t; - gnutls_datum_t session_data = {NULL, 0}; - - if (debug) { - gnutls_global_set_log_function(tls_log_func); - gnutls_global_set_log_level(2); - } - global_init(); - - gnutls_psk_allocate_client_credentials(&pskcred); - gnutls_psk_set_client_credentials(pskcred, "test", &key, GNUTLS_PSK_KEY_HEX); - - for (t = 0; t < SESSIONS; t++) { - int sd = sds[t]; - - /* Initialize TLS session - */ - gnutls_init(&session, - GNUTLS_CLIENT); - - /* Use default priorities */ - if (params->enable_session_ticket_client) { - gnutls_priority_set_direct(session, - "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+PSK", - NULL); - } else { - gnutls_priority_set_direct(session, - "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+PSK:%NO_TICKETS", - NULL); - } - - /* put the anonymous credentials to the current session - */ - gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred); - - if (t > 0) { - /* if this is not the first time we connect */ - gnutls_session_set_data(session, session_data.data, - session_data.size); - } - - gnutls_transport_set_int(session, sd); - - /* Perform the TLS handshake - */ - gnutls_handshake_set_timeout(session, 20 * 1000); - do { - ret = gnutls_handshake(session); - } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); - - if (ret < 0) { - fail("client: Handshake failed\n"); - gnutls_perror(ret); - goto end; - } else { - if (debug) - success - ("client: Handshake was completed\n"); - } - - if (t == 0) { /* the first time we connect */ - /* get the session data size */ - ret = - gnutls_session_get_data2(session, - &session_data); - if (ret < 0) - fail("Getting resume data failed\n"); - } else { /* the second time we connect */ - - /* check if we actually resumed the previous session */ - if (gnutls_session_is_resumed(session) != 0) { - if (params->expect_resume) { - if (debug) - success - ("- Previous session was resumed\n"); - } else - fail("- Previous session was resumed\n"); - } else { - if (params->expect_resume) { - fail("*** Previous session was NOT resumed\n"); - } else { - if (debug) - success - ("*** Previous session was NOT resumed (expected)\n"); - } - } - } - - gnutls_record_send(session, MSG, strlen(MSG)); - - ret = gnutls_record_recv(session, buffer, MAX_BUF); - if (ret == 0) { - if (debug) - success - ("client: Peer has closed the TLS connection\n"); - goto end; - } else if (ret < 0) { - fail("client: Error: %s\n", gnutls_strerror(ret)); - goto end; - } - - if (debug) { - printf("- Received %d bytes: ", ret); - for (ii = 0; ii < ret; ii++) { - fputc(buffer[ii], stdout); - } - fputs("\n", stdout); - } - - gnutls_bye(session, GNUTLS_SHUT_RDWR); - - close(sd); - - gnutls_deinit(session); - } - gnutls_free(session_data.data); - - end: - gnutls_psk_free_client_credentials(pskcred); -} - -/* This is a sample TLS 1.0 echo server, for anonymous authentication only. - */ - -#define DH_BITS 1024 - -/* These are global */ -gnutls_psk_server_credentials_t pskcred; -static gnutls_datum_t session_ticket_key = { NULL, 0 }; - -static gnutls_session_t initialize_tls_session(struct params_res *params) -{ - gnutls_session_t session; - - gnutls_init(&session, GNUTLS_SERVER); - - /* avoid calling all the priority functions, since the defaults - * are adequate. - */ - gnutls_priority_set_direct(session, - "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+PSK", - NULL); - - gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred); - - gnutls_dh_set_prime_bits(session, DH_BITS); - - if (params->enable_db) { - gnutls_db_set_retrieve_function(session, wrap_db_fetch); - gnutls_db_set_remove_function(session, wrap_db_delete); - gnutls_db_set_store_function(session, wrap_db_store); - gnutls_db_set_ptr(session, NULL); - } - - if (params->enable_session_ticket_server) - gnutls_session_ticket_enable_server(session, - &session_ticket_key); - - return session; -} - -static void global_stop(void) -{ - if (debug) - success("global stop\n"); - - gnutls_psk_free_server_credentials(pskcred); - - gnutls_global_deinit(); -} - -static int -pskfunc(gnutls_session_t session, const char *username, - gnutls_datum_t * key) -{ - if (debug) - printf("psk: username %s\n", username); - key->data = gnutls_malloc(4); - key->data[0] = 0xDE; - key->data[1] = 0xAD; - key->data[2] = 0xBE; - key->data[3] = 0xEF; - key->size = 4; - return 0; -} - -static void server(int sds[], struct params_res *params) -{ - int ret; - gnutls_session_t session; - char buffer[MAX_BUF + 1]; - size_t t; - - /* this must be called once in the program, it is mostly for the server. - */ - if (debug) { - gnutls_global_set_log_function(tls_log_func); - gnutls_global_set_log_level(2); - } - - global_init(); - gnutls_psk_allocate_server_credentials(&pskcred); - gnutls_psk_set_server_credentials_function(pskcred, pskfunc); - - if (debug) - success("Launched, generating DH parameters...\n"); - - if (params->enable_db) { - wrap_db_init(); - } - - if (params->enable_session_ticket_server) - gnutls_session_ticket_key_generate(&session_ticket_key); - - for (t = 0; t < SESSIONS; t++) { - int sd = sds[t]; - - session = initialize_tls_session(params); - - gnutls_transport_set_int(session, sd); - gnutls_handshake_set_timeout(session, 20 * 1000); - do { - ret = gnutls_handshake(session); - } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); - if (ret < 0) { - close(sd); - gnutls_deinit(session); - kill(child, SIGTERM); - fail("server: Handshake has failed (%s)\n\n", - gnutls_strerror(ret)); - return; - } - if (debug) - success("server: Handshake was completed\n"); - - /* see the Getting peer's information example */ - /* print_info(session); */ - - for (;;) { - memset(buffer, 0, MAX_BUF + 1); - ret = gnutls_record_recv(session, buffer, MAX_BUF); - - if (ret == 0) { - if (debug) - success - ("server: Peer has closed the GnuTLS connection\n"); - break; - } else if (ret < 0) { - kill(child, SIGTERM); - fail("server: Received corrupted data(%d). Closing...\n", ret); - break; - } else if (ret > 0) { - /* echo data back to the client - */ - gnutls_record_send(session, buffer, - strlen(buffer)); - } - } - /* do not wait for the peer to close the connection. - */ - gnutls_bye(session, GNUTLS_SHUT_WR); - - close(sd); - - gnutls_deinit(session); - } - - if (params->enable_db) { - wrap_db_deinit(); - } - - gnutls_free(session_ticket_key.data); - session_ticket_key.data = NULL; - - if (debug) - success("server: finished\n"); -} - -void doit(void) -{ - int i, err; - - signal(SIGCHLD, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - - for (i = 0; resume_tests[i].desc; i++) { - int client_sds[SESSIONS], server_sds[SESSIONS]; - int j; - - printf("%s\n", resume_tests[i].desc); - - for (j = 0; j < SESSIONS; j++) { - int sockets[2]; - - err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); - if (err == -1) { - perror("socketpair"); - fail("socketpair failed\n"); - return; - } - - server_sds[j] = sockets[0]; - client_sds[j] = sockets[1]; - } - - child = fork(); - if (child < 0) { - perror("fork"); - fail("fork"); - return; - } - - if (child) { - int status = 0; - /* parent */ - for (j = 0; j < SESSIONS; j++) - close(client_sds[j]); - server(server_sds, &resume_tests[i]); - - waitpid(child, &status, 0); - if (WEXITSTATUS(status) != 0 || (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)) - exit(1); - global_stop(); - } else { - for (j = 0; j < SESSIONS; j++) - close(server_sds[j]); - client(client_sds, &resume_tests[i]); - gnutls_global_deinit(); - exit(0); - } - } -} - -/* Functions and other stuff needed for session resuming. - * This is done using a very simple list which holds session ids - * and session data. - */ - -#define MAX_SESSION_ID_SIZE 32 -#define MAX_SESSION_DATA_SIZE 1024 - -typedef struct { - unsigned char session_id[MAX_SESSION_ID_SIZE]; - unsigned int session_id_size; - - char session_data[MAX_SESSION_DATA_SIZE]; - int session_data_size; -} CACHE; - -static CACHE *cache_db; -static int cache_db_ptr = 0; - -static void wrap_db_init(void) -{ - - /* allocate cache_db */ - cache_db = calloc(1, TLS_SESSION_CACHE * sizeof(CACHE)); -} - -static void wrap_db_deinit(void) -{ - free(cache_db); - cache_db = NULL; - return; -} - -static int -wrap_db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data) -{ - time_t t, now = time(0); - -#ifdef DEBUG_CACHE - if (debug) { - unsigned int i; - fprintf(stderr, "resume db storing (%d-%d): ", key.size, - data.size); - for (i = 0; i < key.size; i++) { - fprintf(stderr, "%02x", key.data[i] & 0xFF); - } - fprintf(stderr, "\n"); - fprintf(stderr, "data: "); - for (i = 0; i < data.size; i++) { - fprintf(stderr, "%02x", data.data[i] & 0xFF); - } - fprintf(stderr, "\n"); - } -#endif - - /* check the correctness of gnutls_db_check_entry_time() */ - t = gnutls_db_check_entry_time(&data); - if (t < now - 10 || t > now + 10) { - fail("Time returned by gnutls_db_check_entry_time is bogus\n"); - exit(1); - } - - if (cache_db == NULL) - return -1; - - if (key.size > MAX_SESSION_ID_SIZE) { - fail("Key size is too large\n"); - return -1; - } - - if (data.size > MAX_SESSION_DATA_SIZE) { - fail("Data size is too large\n"); - return -1; - } - - memcpy(cache_db[cache_db_ptr].session_id, key.data, key.size); - cache_db[cache_db_ptr].session_id_size = key.size; - - memcpy(cache_db[cache_db_ptr].session_data, data.data, data.size); - cache_db[cache_db_ptr].session_data_size = data.size; - - cache_db_ptr++; - cache_db_ptr %= TLS_SESSION_CACHE; - - return 0; -} - -static gnutls_datum_t wrap_db_fetch(void *dbf, gnutls_datum_t key) -{ - gnutls_datum_t res = { NULL, 0 }; - unsigned i; - - if (debug) { - fprintf(stderr, "resume db looking for (%d): ", key.size); - for (i = 0; i < key.size; i++) { - fprintf(stderr, "%02x", key.data[i] & 0xFF); - } - fprintf(stderr, "\n"); - } - - if (cache_db == NULL) - return res; - - for (i = 0; i < TLS_SESSION_CACHE; i++) { - if (key.size == cache_db[i].session_id_size && - memcmp(key.data, cache_db[i].session_id, - key.size) == 0) { - if (debug) - success - ("resume db fetch... return info\n"); - - res.size = cache_db[i].session_data_size; - - res.data = gnutls_malloc(res.size); - if (res.data == NULL) - return res; - - memcpy(res.data, cache_db[i].session_data, - res.size); - -#ifdef DEBUG_CACHE - if (debug) { - unsigned int j; - printf("data:\n"); - for (j = 0; j < res.size; j++) { - printf("%02x ", - res.data[j] & 0xFF); - if ((j + 1) % 16 == 0) - printf("\n"); - } - printf("\n"); - } -#endif - return res; - } - } - - if (debug) - success("resume db fetch... NOT FOUND\n"); - return res; -} - -static int wrap_db_delete(void *dbf, gnutls_datum_t key) -{ - int i; - - if (cache_db == NULL) - return -1; - - for (i = 0; i < TLS_SESSION_CACHE; i++) { - if (key.size == cache_db[i].session_id_size && - memcmp(key.data, cache_db[i].session_id, - key.size) == 0) { - - cache_db[i].session_id_size = 0; - cache_db[i].session_data_size = 0; - - return 0; - } - } - - return -1; - -} - -#endif /* _WIN32 */ diff --git a/tests/resume.c b/tests/resume.c index d7951036a3..ed4f8aa6d2 100644 --- a/tests/resume.c +++ b/tests/resume.c @@ -51,8 +51,8 @@ int main(int argc, char **argv) #include #include #include - #include "utils.h" +#include "cert-common.h" static void wrap_db_init(void); static void wrap_db_deinit(void); @@ -250,9 +250,19 @@ static void client(int sds[], struct params_res *params) int ret, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; - gnutls_anon_client_credentials_t anoncred; unsigned int ext_master_secret_check = 0; char prio_str[256]; +#ifdef USE_PSK +# define PRIO_STR "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+PSK:+CURVE-ALL" + const gnutls_datum_t pskkey = { (void *) "DEADBEEF", 8 }; + gnutls_psk_client_credentials_t pskcred; +#elif defined(USE_ANON) +# define PRIO_STR "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+ANON-DH:+CURVE-ALL" + gnutls_anon_client_credentials_t anoncred; +#elif defined(USE_X509) +# define PRIO_STR "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-RSA:+RSA:+CURVE-ALL" + gnutls_certificate_credentials_t clientx509cred; +#endif /* Need to enable anonymous KX specifically. */ @@ -267,7 +277,15 @@ static void client(int sds[], struct params_res *params) } global_init(); +#ifdef USE_PSK + gnutls_psk_allocate_client_credentials(&pskcred); + gnutls_psk_set_client_credentials(pskcred, "test", &pskkey, GNUTLS_PSK_KEY_HEX); +#elif defined(USE_ANON) gnutls_anon_allocate_client_credentials(&anoncred); +#elif defined(USE_X509) + gnutls_certificate_allocate_credentials(&clientx509cred); +#endif + for (t = 0; t < SESSIONS; t++) { int sd = sds[t]; @@ -276,7 +294,7 @@ static void client(int sds[], struct params_res *params) */ gnutls_init(&session, GNUTLS_CLIENT); - snprintf(prio_str, sizeof(prio_str), "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH"); + snprintf(prio_str, sizeof(prio_str), "%s", PRIO_STR); /* Use default priorities */ if (params->enable_session_ticket_client == 0) { @@ -302,7 +320,13 @@ static void client(int sds[], struct params_res *params) /* put the anonymous credentials to the current session */ +#ifdef USE_PSK + gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred); +#elif defined(USE_ANON) gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); +#elif defined(USE_X509) + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, clientx509cred); +#endif if (t > 0) { /* if this is not the first time we connect */ @@ -403,7 +427,13 @@ static void client(int sds[], struct params_res *params) gnutls_free(session_data.data); end: +#ifdef USE_PSK + gnutls_psk_free_client_credentials(pskcred); +#elif defined(USE_ANON) gnutls_anon_free_client_credentials(anoncred); +#elif defined(USE_X509) + gnutls_certificate_free_credentials(clientx509cred); +#endif } /* This is a sample TLS 1.0 echo server, for anonymous authentication only. @@ -424,7 +454,7 @@ static gnutls_session_t initialize_tls_session(struct params_res *params) * are adequate. */ gnutls_priority_set_direct(session, - "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", + PRIO_STR, NULL); @@ -445,7 +475,14 @@ static gnutls_session_t initialize_tls_session(struct params_res *params) } static gnutls_dh_params_t dh_params; + +#ifdef USE_PSK +gnutls_psk_server_credentials_t pskcred; +#elif defined(USE_ANON) gnutls_anon_server_credentials_t anoncred; +#elif defined(USE_X509) +gnutls_certificate_credentials_t serverx509cred; +#endif static int generate_dh_params(void) { @@ -466,13 +503,35 @@ static void global_stop(void) if (debug) success("global stop\n"); +#ifdef USE_PSK + gnutls_psk_free_server_credentials(pskcred); +#elif defined(USE_ANON) gnutls_anon_free_server_credentials(anoncred); - +#elif defined(USE_X509) + gnutls_certificate_free_credentials(serverx509cred); +#endif gnutls_dh_params_deinit(dh_params); gnutls_global_deinit(); } +#ifdef USE_PSK +static int +pskfunc(gnutls_session_t session, const char *username, + gnutls_datum_t * key) +{ + if (debug) + printf("psk: username %s\n", username); + key->data = gnutls_malloc(4); + key->data[0] = 0xDE; + key->data[1] = 0xAD; + key->data[2] = 0xBE; + key->data[3] = 0xEF; + key->size = 4; + return 0; +} +#endif + static void server(int sds[], struct params_res *params) { size_t t; @@ -488,14 +547,26 @@ static void server(int sds[], struct params_res *params) } global_init(); + +#ifdef USE_PSK + gnutls_psk_allocate_server_credentials(&pskcred); + gnutls_psk_set_server_credentials_function(pskcred, pskfunc); +#elif defined(USE_ANON) gnutls_anon_allocate_server_credentials(&anoncred); +#elif defined(USE_X509) + gnutls_certificate_allocate_credentials(&serverx509cred); + gnutls_certificate_set_x509_key_mem(serverx509cred, + &server_cert, &server_key, GNUTLS_X509_FMT_PEM); +#endif if (debug) success("Launched, generating DH parameters...\n"); generate_dh_params(); +#if USE_ANON gnutls_anon_set_server_dh_params(anoncred, dh_params); +#endif if (params->enable_db) { wrap_db_init(); @@ -511,7 +582,13 @@ static void server(int sds[], struct params_res *params) append_alpn(session, params, t); +#ifdef USE_PSK + gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred); +#elif defined(USE_ANON) gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); +#elif defined(USE_X509) + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, serverx509cred); +#endif gnutls_transport_set_int(session, sd); gnutls_handshake_set_timeout(session, 20 * 1000);