diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-10-17 14:34:10 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-10-29 23:41:16 +0200 |
commit | 1b8d9a237c39b6041196a6750e5901b18fb22843 (patch) | |
tree | 1df061b6a889d3a157e4aa699e191ea384550c05 | |
parent | de9ec95d53acf5b0f330987462973af3ba6386b7 (diff) | |
download | gnutls-1b8d9a237c39b6041196a6750e5901b18fb22843.tar.gz |
tests: introduced checks for gnutls_rnd() in multi-threaded scenario
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/rng-pthread.c | 126 |
2 files changed, 128 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 62faaeb384..45bb8979af 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -108,7 +108,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \ dtls1.2-cert-key-exchange dtls1.0-cert-key-exchange x509-cert-callback-legacy \ keylog-env ssl2-hello tlsfeature-ext dtls-rehandshake-cert-2 \ tlsfeature-crt dtls-rehandshake-cert-3 resume-with-false-start \ - set_x509_key_file_ocsp client-fastopen rng-sigint srp \ + set_x509_key_file_ocsp client-fastopen rng-sigint srp rng-pthread \ safe-renegotiation/srn0 safe-renegotiation/srn1 safe-renegotiation/srn2 \ safe-renegotiation/srn3 safe-renegotiation/srn4 safe-renegotiation/srn5 \ rsa-illegal-import set_x509_key_file_ocsp_multi set_key set_x509_key_file_ocsp_multi2 \ @@ -134,6 +134,7 @@ conv_utf8_LDADD = $(CMOCKA_LDADD) endif mini_dtls_pthread_LDADD = $(LDADD) -lpthread +rng_pthread_LDADD = $(LDADD) -lpthread # These tests need gnulib for memmem() resume_psk_CFLAGS = -DUSE_PSK diff --git a/tests/rng-pthread.c b/tests/rng-pthread.c new file mode 100644 index 0000000000..2928bb7f2d --- /dev/null +++ b/tests/rng-pthread.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <errno.h> +#include <gnutls/gnutls.h> +#include <gnutls/crypto.h> +#include <signal.h> +#include <unistd.h> +#ifndef _WIN32 +# include <netinet/in.h> +# include <sys/types.h> +# include <sys/socket.h> +# include <sys/wait.h> +# include <pthread.h> +#endif +#include "utils.h" + +#ifdef _WIN32 + +void doit(void) +{ + exit(77); +} + +#else + +/* Tests whether we can use gnutls_rnd() under mutliple threads. + * We do a basic checking of random data match when gnutls_rnd() + * is called in parallel. + */ + +typedef struct thread_data_st { + unsigned level; + pthread_t id; + char buf[32]; +} thread_data_st; + +static void *start_thread(void *arg) +{ + thread_data_st *data = arg; + int ret; + + ret = gnutls_rnd(data->level, data->buf, sizeof(data->buf)); + if (ret < 0) { + fail("gnutls_rnd: wrong size returned (%d)\n", ret); + } + if (debug) + hexprint(data->buf, sizeof(data->buf)); + + pthread_exit(0); +} + +#define MAX_THREADS 48 + +static +void do_thread_stuff(unsigned level) +{ + int ret; + thread_data_st *data; + unsigned i, j; + + data = calloc(1, sizeof(thread_data_st)*MAX_THREADS); + if (data == NULL) + abort(); + + for (i=0;i<MAX_THREADS;i++) { + data[i].level = level; + ret = pthread_create(&data[i].id, NULL, start_thread, &data[i]); + if (ret != 0) { + abort(); + } + } + + for (i=0;i<MAX_THREADS;i++) { + pthread_join(data[i].id, NULL); + for (j=0;j<MAX_THREADS;j++) { + if (i!=j) { + if (memcmp(data[i].buf, data[j].buf, sizeof(data[i].buf)) == 0) { + fail("identical data found in thread %d and %d\n", i,j); + } + } + } + } + free(data); + +} + +void doit(void) +{ + unsigned i; + signal(SIGPIPE, SIG_IGN); + gnutls_global_deinit(); + for (i = GNUTLS_RND_NONCE; i <= GNUTLS_RND_KEY; i++) { + gnutls_global_init(); + do_thread_stuff(i); + gnutls_global_deinit(); + } +} +#endif /* _WIN32 */ |