3 * Copyright (C) 2006-2015 wolfSSL Inc.
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <wolfssl/wolfcrypt/settings.h>
31 #include <wolfssl/ssl.h>
32 #include <tests/unit.h>
36 #define MAX_COMMAND_SZ 240
37 #define MAX_SUITE_SZ 80
38 #define NOT_BUILT_IN -123
40 #define VERSION_TOO_OLD -124
43 #include "examples/client/client.h"
44 #include "examples/server/server.h"
47 static WOLFSSL_CTX* cipherSuiteCtx = NULL;
48 static char nonblockFlag[] = "-N";
49 static char noVerifyFlag[] = "-d";
50 static char portFlag[] = "-p";
51 static char flagSep[] = " ";
52 static char svrPort[] = "0";
56 /* if the protocol version is less than tls 1.2 return 1, else 0 */
57 static int IsOldTlsVersion(const char* line)
59 const char* find = "-v ";
60 char* begin = strstr(line, find);
67 version = atoi(begin);
75 #endif /* NO_OLD_TLS */
78 /* if the cipher suite on line is valid store in suite and return 1, else 0 */
79 static int IsValidCipherSuite(const char* line, char* suite)
84 const char* find = "-l ";
85 const char* begin = strstr(line, find);
93 end = strstr(begin, " ");
96 long len = end - begin;
97 if (len > MAX_SUITE_SZ) {
98 printf("suite too long!\n");
101 memcpy(suite, begin, len);
105 strncpy(suite, begin, MAX_SUITE_SZ);
107 suite[MAX_SUITE_SZ] = '\0';
112 if (wolfSSL_CTX_set_cipher_list(cipherSuiteCtx, suite) == SSL_SUCCESS)
120 static int execute_test_case(int svr_argc, char** svr_argv,
121 int cli_argc, char** cli_argv,
122 int addNoVerify, int addNonBlocking)
124 #ifdef WOLFSSL_TIRTOS
125 func_args cliArgs = {0};
126 func_args svrArgs = {0};
127 cliArgs.argc = cli_argc;
128 cliArgs.argv = cli_argv;
129 svrArgs.argc = svr_argc;
130 svrArgs.argv = svr_argv;
132 func_args cliArgs = {cli_argc, cli_argv, 0, NULL, NULL};
133 func_args svrArgs = {svr_argc, svr_argv, 0, NULL, NULL};
137 THREAD_TYPE serverThread;
138 char commandLine[MAX_COMMAND_SZ];
139 char cipherSuite[MAX_SUITE_SZ+1];
142 static int tests = 1;
144 commandLine[0] = '\0';
145 for (i = 0; i < svr_argc; i++) {
146 added += strlen(svr_argv[i]) + 2;
147 if (added >= MAX_COMMAND_SZ) {
148 printf("server command line too long\n");
151 strcat(commandLine, svr_argv[i]);
152 strcat(commandLine, flagSep);
155 if (IsValidCipherSuite(commandLine, cipherSuite) == 0) {
156 #ifdef DEBUG_SUITE_TESTS
157 printf("cipher suite %s not supported in build\n", cipherSuite);
163 if (IsOldTlsVersion(commandLine) == 1) {
164 #ifdef DEBUG_SUITE_TESTS
165 printf("protocol version on line %s is too old\n", commandLine);
167 return VERSION_TOO_OLD;
172 printf("repeating test with client cert request off\n");
173 added += 4; /* -d plus space plus terminator */
174 if (added >= MAX_COMMAND_SZ || svr_argc >= MAX_ARGS)
175 printf("server command line too long\n");
177 svr_argv[svr_argc++] = noVerifyFlag;
178 svrArgs.argc = svr_argc;
179 strcat(commandLine, noVerifyFlag);
180 strcat(commandLine, flagSep);
183 if (addNonBlocking) {
184 printf("repeating test with non blocking on\n");
185 added += 4; /* -N plus terminator */
186 if (added >= MAX_COMMAND_SZ || svr_argc >= MAX_ARGS)
187 printf("server command line too long\n");
189 svr_argv[svr_argc++] = nonblockFlag;
190 svrArgs.argc = svr_argc;
191 strcat(commandLine, nonblockFlag);
192 strcat(commandLine, flagSep);
195 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS)
197 if (svr_argc + 2 > MAX_ARGS)
198 printf("cannot add the magic port number flag to server\n");
201 svr_argv[svr_argc++] = portFlag;
202 svr_argv[svr_argc++] = svrPort;
203 svrArgs.argc = svr_argc;
206 printf("trying server command line[%d]: %s\n", tests, commandLine);
208 commandLine[0] = '\0';
210 for (i = 0; i < cli_argc; i++) {
211 added += strlen(cli_argv[i]) + 2;
212 if (added >= MAX_COMMAND_SZ) {
213 printf("client command line too long\n");
216 strcat(commandLine, cli_argv[i]);
217 strcat(commandLine, flagSep);
219 if (addNonBlocking) {
220 added += 4; /* -N plus space plus terminator */
221 if (added >= MAX_COMMAND_SZ)
222 printf("client command line too long\n");
224 cli_argv[cli_argc++] = nonblockFlag;
225 strcat(commandLine, nonblockFlag);
226 strcat(commandLine, flagSep);
227 cliArgs.argc = cli_argc;
230 printf("trying client command line[%d]: %s\n", tests++, commandLine);
232 InitTcpReady(&ready);
234 #ifdef WOLFSSL_TIRTOS
235 fdOpenSession(Task_self());
239 svrArgs.signal = &ready;
240 start_thread(server_test, &svrArgs, &serverThread);
241 wait_tcp_ready(&svrArgs);
242 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS)
245 if (cli_argc + 2 > MAX_ARGS)
246 printf("cannot add the magic port number flag to client\n");
249 snprintf(portNumber, sizeof(portNumber), "%d", ready.port);
250 cli_argv[cli_argc++] = portFlag;
251 cli_argv[cli_argc++] = portNumber;
252 cliArgs.argc = cli_argc;
257 client_test(&cliArgs);
260 if (cliArgs.return_code != 0) {
261 printf("client_test failed\n");
265 join_thread(serverThread);
266 if (svrArgs.return_code != 0) {
267 printf("server_test failed\n");
271 #ifdef WOLFSSL_TIRTOS
272 fdCloseSession(Task_self());
274 FreeTcpReady(&ready);
279 static void test_harness(void* vargs)
281 func_args* args = (func_args*)vargs;
284 int cliMode = 0; /* server or client command flag, server first */
287 char* svrArgs[MAX_ARGS];
289 char* cliArgs[MAX_ARGS];
293 const char* fname = "tests/test.conf";
295 if (args->argc == 1) {
296 printf("notice: using default file %s\n", fname);
298 else if(args->argc != 2) {
299 printf("usage: harness [FILE]\n");
300 args->return_code = 1;
304 fname = args->argv[1];
307 file = fopen(fname, "r");
309 fprintf(stderr, "unable to open %s\n", fname);
310 args->return_code = 1;
313 fseek(file, 0, SEEK_END);
317 fprintf(stderr, "%s is empty\n", fname);
319 args->return_code = 1;
323 script = (char*)malloc(sz+1);
325 fprintf(stderr, "unable to allocte script buffer\n");
327 args->return_code = 1;
331 len = fread(script, 1, sz, file);
333 fprintf(stderr, "read error\n");
336 args->return_code = 1;
345 svrArgs[0] = args->argv[0];
347 cliArgs[0] = args->argv[0];
349 while (*cursor != 0) {
354 /* A blank line triggers test case execution or switches
355 to client mode if we don't have the client command yet */
357 cliMode = 1; /* switch to client mode processing */
359 do_it = 1; /* Do It, we have server and client */
363 /* Ignore lines that start with a #. */
364 comment = strsep(&cursor, "\n");
365 #ifdef DEBUG_SUITE_TESTS
366 printf("%s\n", comment);
372 /* Parameters start with a -. They end in either a newline
373 * or a space. Capture until either, save in Args list. */
375 cliArgs[cliArgsSz++] = strsep(&cursor, " \n");
377 svrArgs[svrArgsSz++] = strsep(&cursor, " \n");
380 /* Anything from cursor until end of line that isn't the above
381 * is data for a paramter. Just up until the next newline in
384 cliArgs[cliArgsSz++] = strsep(&cursor, "\n");
386 svrArgs[svrArgsSz++] = strsep(&cursor, "\n");
387 if (*cursor == 0) /* eof */
391 if (svrArgsSz == MAX_ARGS || cliArgsSz == MAX_ARGS) {
392 fprintf(stderr, "too many arguments, forcing test run\n");
397 ret = execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs,0,0);
398 /* don't repeat if not supported in build */
400 execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 0, 1);
401 execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 0);
402 execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 1);
411 args->return_code = 0;
421 printf(" Begin Cipher Suite Tests\n");
424 myArgv[0] = argv0[0];
425 myArgv[1] = argv0[1];
427 strcpy(argv0[0], "SuiteTest");
431 cipherSuiteCtx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
432 if (cipherSuiteCtx == NULL) {
433 printf("can't get cipher suite ctx\n");
439 printf("starting default cipher suite tests\n");
441 if (args.return_code != 0) {
442 printf("error from script %d\n", args.return_code);
446 /* any extra cases will need another argument */
450 /* add dtls extra suites */
451 strcpy(argv0[1], "tests/test-dtls.conf");
452 printf("starting dtls extra cipher suite tests\n");
454 if (args.return_code != 0) {
455 printf("error from script %d\n", args.return_code);
460 printf(" End Cipher Suite Tests\n");
462 wolfSSL_CTX_free(cipherSuiteCtx);
465 return args.return_code;