3 * Copyright (C) 2006-2014 wolfSSL Inc.
5 * This file is part of CyaSSL.
7 * CyaSSL 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 * CyaSSL 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 <cyassl/ctaocrypt/settings.h>
31 #include <cyassl/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 CYASSL_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 (CyaSSL_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 func_args cliArgs = {cli_argc, cli_argv, 0, NULL, NULL};
125 func_args svrArgs = {svr_argc, svr_argv, 0, NULL, NULL};
128 THREAD_TYPE serverThread;
129 char commandLine[MAX_COMMAND_SZ];
130 char cipherSuite[MAX_SUITE_SZ+1];
133 static int tests = 1;
135 commandLine[0] = '\0';
136 for (i = 0; i < svr_argc; i++) {
137 added += strlen(svr_argv[i]) + 2;
138 if (added >= MAX_COMMAND_SZ) {
139 printf("server command line too long\n");
142 strcat(commandLine, svr_argv[i]);
143 strcat(commandLine, flagSep);
146 if (IsValidCipherSuite(commandLine, cipherSuite) == 0) {
147 #ifdef DEBUG_SUITE_TESTS
148 printf("cipher suite %s not supported in build\n", cipherSuite);
154 if (IsOldTlsVersion(commandLine) == 1) {
155 #ifdef DEBUG_SUITE_TESTS
156 printf("protocol version on line %s is too old\n", commandLine);
158 return VERSION_TOO_OLD;
163 printf("repeating test with client cert request off\n");
164 added += 4; /* -d plus space plus terminator */
165 if (added >= MAX_COMMAND_SZ || svr_argc >= MAX_ARGS)
166 printf("server command line too long\n");
168 svr_argv[svr_argc++] = noVerifyFlag;
169 svrArgs.argc = svr_argc;
170 strcat(commandLine, noVerifyFlag);
171 strcat(commandLine, flagSep);
174 if (addNonBlocking) {
175 printf("repeating test with non blocking on\n");
176 added += 4; /* -N plus terminator */
177 if (added >= MAX_COMMAND_SZ || svr_argc >= MAX_ARGS)
178 printf("server command line too long\n");
180 svr_argv[svr_argc++] = nonblockFlag;
181 svrArgs.argc = svr_argc;
182 strcat(commandLine, nonblockFlag);
183 strcat(commandLine, flagSep);
186 #ifndef USE_WINDOWS_API
188 if (svr_argc + 2 > MAX_ARGS)
189 printf("cannot add the magic port number flag to server\n");
192 svr_argv[svr_argc++] = portFlag;
193 svr_argv[svr_argc++] = svrPort;
194 svrArgs.argc = svr_argc;
197 printf("trying server command line[%d]: %s\n", tests, commandLine);
199 commandLine[0] = '\0';
201 for (i = 0; i < cli_argc; i++) {
202 added += strlen(cli_argv[i]) + 2;
203 if (added >= MAX_COMMAND_SZ) {
204 printf("client command line too long\n");
207 strcat(commandLine, cli_argv[i]);
208 strcat(commandLine, flagSep);
210 if (addNonBlocking) {
211 added += 4; /* -N plus space plus terminator */
212 if (added >= MAX_COMMAND_SZ)
213 printf("client command line too long\n");
215 cli_argv[cli_argc++] = nonblockFlag;
216 strcat(commandLine, nonblockFlag);
217 strcat(commandLine, flagSep);
218 cliArgs.argc = cli_argc;
221 printf("trying client command line[%d]: %s\n", tests++, commandLine);
223 InitTcpReady(&ready);
226 svrArgs.signal = &ready;
227 start_thread(server_test, &svrArgs, &serverThread);
228 wait_tcp_ready(&svrArgs);
229 #ifndef USE_WINDOWS_API
232 if (cli_argc + 2 > MAX_ARGS)
233 printf("cannot add the magic port number flag to client\n");
236 snprintf(portNumber, sizeof(portNumber), "%d", ready.port);
237 cli_argv[cli_argc++] = portFlag;
238 cli_argv[cli_argc++] = portNumber;
239 cliArgs.argc = cli_argc;
244 client_test(&cliArgs);
247 if (cliArgs.return_code != 0) {
248 printf("client_test failed\n");
252 join_thread(serverThread);
253 if (svrArgs.return_code != 0) {
254 printf("server_test failed\n");
258 FreeTcpReady(&ready);
263 static void test_harness(void* vargs)
265 func_args* args = (func_args*)vargs;
268 int cliMode = 0; /* server or client command flag, server first */
271 char* svrArgs[MAX_ARGS];
273 char* cliArgs[MAX_ARGS];
277 const char* fname = "tests/test.conf";
279 if (args->argc == 1) {
280 printf("notice: using default file %s\n", fname);
282 else if(args->argc != 2) {
283 printf("usage: harness [FILE]\n");
284 args->return_code = 1;
288 fname = args->argv[1];
291 file = fopen(fname, "r");
293 fprintf(stderr, "unable to open %s\n", fname);
294 args->return_code = 1;
297 fseek(file, 0, SEEK_END);
301 fprintf(stderr, "%s is empty\n", fname);
303 args->return_code = 1;
307 script = (char*)malloc(sz+1);
309 fprintf(stderr, "unable to allocte script buffer\n");
311 args->return_code = 1;
315 len = fread(script, 1, sz, file);
317 fprintf(stderr, "read error\n");
320 args->return_code = 1;
329 svrArgs[0] = args->argv[0];
331 cliArgs[0] = args->argv[0];
333 while (*cursor != 0) {
338 /* A blank line triggers test case execution or switches
339 to client mode if we don't have the client command yet */
341 cliMode = 1; /* switch to client mode processing */
343 do_it = 1; /* Do It, we have server and client */
347 /* Ignore lines that start with a #. */
348 comment = strsep(&cursor, "\n");
349 #ifdef DEBUG_SUITE_TESTS
350 printf("%s\n", comment);
356 /* Parameters start with a -. They end in either a newline
357 * or a space. Capture until either, save in Args list. */
359 cliArgs[cliArgsSz++] = strsep(&cursor, " \n");
361 svrArgs[svrArgsSz++] = strsep(&cursor, " \n");
364 /* Anything from cursor until end of line that isn't the above
365 * is data for a paramter. Just up until the next newline in
368 cliArgs[cliArgsSz++] = strsep(&cursor, "\n");
370 svrArgs[svrArgsSz++] = strsep(&cursor, "\n");
371 if (*cursor == 0) /* eof */
375 if (svrArgsSz == MAX_ARGS || cliArgsSz == MAX_ARGS) {
376 fprintf(stderr, "too many arguments, forcing test run\n");
381 ret = execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs,0,0);
382 /* don't repeat if not supported in build */
384 execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 0, 1);
385 execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 0);
386 execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 1);
395 args->return_code = 0;
405 printf(" Begin Cipher Suite Tests\n");
408 myArgv[0] = argv0[0];
409 myArgv[1] = argv0[1];
411 strcpy(argv0[0], "SuiteTest");
415 cipherSuiteCtx = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
416 if (cipherSuiteCtx == NULL) {
417 printf("can't get cipher suite ctx\n");
423 printf("starting default cipher suite tests\n");
425 if (args.return_code != 0) {
426 printf("error from script %d\n", args.return_code);
430 /* any extra cases will need another argument */
434 /* add dtls extra suites */
435 strcpy(argv0[1], "tests/test-dtls.conf");
436 printf("starting dtls extra cipher suite tests\n");
438 if (args.return_code != 0) {
439 printf("error from script %d\n", args.return_code);
444 printf(" End Cipher Suite Tests\n");
446 CyaSSL_CTX_free(cipherSuiteCtx);
448 return args.return_code;