| /* testsuite.c |
| * |
| * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. |
| * |
| * This file is part of CyaSSL. |
| * |
| * CyaSSL 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 2 of the License, or |
| * (at your option) any later version. |
| * |
| * CyaSSL 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 this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #include <cyassl/openssl/ssl.h> |
| #include <cyassl/test.h> |
| #include <cyassl/ctaocrypt/md5.h> |
| |
| #ifdef SINGLE_THREADED |
| #error testsuite needs threads to run, please run ctaocrypt/test, \ |
| and the examples/ individually |
| #endif |
| |
| void ctaocrypt_test(void*); |
| |
| void client_test(void*); |
| void echoclient_test(void*); |
| |
| THREAD_RETURN CYASSL_THREAD server_test(void*); |
| THREAD_RETURN CYASSL_THREAD echoserver_test(void*); |
| |
| void file_test(char* file, byte* hash); |
| |
| enum { |
| NUMARGS = 3 |
| }; |
| |
| |
| int myoptind = 0; |
| char* myoptarg = NULL; |
| |
| |
| int main(int argc, char** argv) |
| { |
| func_args args; |
| func_args server_args; |
| |
| tcp_ready ready; |
| THREAD_TYPE serverThread; |
| |
| StartTCP(); |
| |
| args.argc = server_args.argc = argc; |
| args.argv = server_args.argv = argv; |
| |
| CyaSSL_Init(); |
| #ifdef DEBUG_CYASSL |
| CyaSSL_Debugging_ON(); |
| #endif |
| |
| if (CurrentDir("testsuite")) |
| ChangeDirBack(1); |
| else if (CurrentDir("build")) /* Xcode->Preferences->Locations->Build */ |
| ChangeDirBack(2); /* Location "Place build product in locations |
| specified by targets", uses build/Debug */ |
| /* CTaoCrypt test */ |
| ctaocrypt_test(&args); |
| if (args.return_code != 0) return args.return_code; |
| |
| /* Simple CyaSSL client server test */ |
| InitTcpReady(&ready); |
| server_args.signal = &ready; |
| start_thread(server_test, &server_args, &serverThread); |
| wait_tcp_ready(&server_args); |
| |
| client_test(&args); |
| if (args.return_code != 0) return args.return_code; |
| join_thread(serverThread); |
| if (server_args.return_code != 0) return server_args.return_code; |
| |
| /* Echo input yaSSL client server test */ |
| start_thread(echoserver_test, &server_args, &serverThread); |
| wait_tcp_ready(&server_args); |
| { |
| func_args echo_args; |
| char* myArgv[NUMARGS]; |
| |
| char argc0[32]; |
| char argc1[32]; |
| char argc2[32]; |
| |
| myArgv[0] = argc0; |
| myArgv[1] = argc1; |
| myArgv[2] = argc2; |
| |
| echo_args.argc = NUMARGS; |
| echo_args.argv = myArgv; |
| |
| strcpy(echo_args.argv[0], "echoclient"); |
| strcpy(echo_args.argv[1], "input"); |
| strcpy(echo_args.argv[2], "output"); |
| remove("output"); |
| |
| /* make sure OK */ |
| echoclient_test(&echo_args); |
| if (echo_args.return_code != 0) return echo_args.return_code; |
| |
| #ifdef CYASSL_DTLS |
| wait_tcp_ready(&server_args); |
| #endif |
| /* send quit to echoserver */ |
| echo_args.argc = 2; |
| strcpy(echo_args.argv[1], "quit"); |
| |
| echoclient_test(&echo_args); |
| if (echo_args.return_code != 0) return echo_args.return_code; |
| join_thread(serverThread); |
| if (server_args.return_code != 0) return server_args.return_code; |
| } |
| |
| /* validate output equals input */ |
| { |
| byte input[MD5_DIGEST_SIZE]; |
| byte output[MD5_DIGEST_SIZE]; |
| |
| file_test("input", input); |
| file_test("output", output); |
| if (memcmp(input, output, sizeof(input)) != 0) |
| return EXIT_FAILURE; |
| } |
| |
| CyaSSL_Cleanup(); |
| FreeTcpReady(&ready); |
| |
| printf("\nAll tests passed!\n"); |
| return EXIT_SUCCESS; |
| } |
| |
| |
| |
| void wait_tcp_ready(func_args* args) |
| { |
| #ifdef _POSIX_THREADS |
| pthread_mutex_lock(&args->signal->mutex); |
| |
| if (!args->signal->ready) |
| pthread_cond_wait(&args->signal->cond, &args->signal->mutex); |
| args->signal->ready = 0; /* reset */ |
| |
| pthread_mutex_unlock(&args->signal->mutex); |
| #endif |
| } |
| |
| |
| void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread) |
| { |
| #ifdef _POSIX_THREADS |
| pthread_create(thread, 0, fun, args); |
| return; |
| #else |
| *thread = (THREAD_TYPE)_beginthreadex(0, 0, fun, args, 0, 0); |
| #endif |
| } |
| |
| |
| void join_thread(THREAD_TYPE thread) |
| { |
| #ifdef _POSIX_THREADS |
| pthread_join(thread, 0); |
| #else |
| int res = WaitForSingleObject(thread, INFINITE); |
| assert(res == WAIT_OBJECT_0); |
| res = CloseHandle(thread); |
| assert(res); |
| #endif |
| } |
| |
| |
| void InitTcpReady(tcp_ready* ready) |
| { |
| ready->ready = 0; |
| #ifdef _POSIX_THREADS |
| pthread_mutex_init(&ready->mutex, 0); |
| pthread_cond_init(&ready->cond, 0); |
| #endif |
| } |
| |
| |
| void FreeTcpReady(tcp_ready* ready) |
| { |
| #ifdef _POSIX_THREADS |
| pthread_mutex_destroy(&ready->mutex); |
| pthread_cond_destroy(&ready->cond); |
| #endif |
| } |
| |
| |
| void file_test(char* file, byte* check) |
| { |
| FILE* f; |
| int i = 0, j; |
| Md5 md5; |
| byte buf[1024]; |
| byte md5sum[MD5_DIGEST_SIZE]; |
| |
| InitMd5(&md5); |
| if( !( f = fopen( file, "rb" ) )) { |
| printf("Can't open %s\n", file); |
| return; |
| } |
| while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) |
| Md5Update(&md5, buf, i); |
| |
| Md5Final(&md5, md5sum); |
| memcpy(check, md5sum, sizeof(md5sum)); |
| |
| for(j = 0; j < MD5_DIGEST_SIZE; ++j ) |
| printf( "%02x", md5sum[j] ); |
| |
| printf(" %s\n", file); |
| |
| fclose(f); |
| } |
| |
| |