3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
26 #include <cyassl/ssl.h>
27 #include <cyassl/test.h>
34 #ifdef CYASSL_CALLBACKS
35 int handShakeCB(HandShakeInfo*);
36 int timeoutCB(TimeoutInfo*);
40 #if defined(NON_BLOCKING) || defined(CYASSL_CALLBACKS)
41 void NonBlockingSSL_Connect(CYASSL* ssl)
43 #ifndef CYASSL_CALLBACKS
44 int ret = CyaSSL_connect(ssl);
46 int ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
48 int error = CyaSSL_get_error(ssl, 0);
49 while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
50 error == SSL_ERROR_WANT_WRITE)) {
51 if (error == SSL_ERROR_WANT_READ)
52 printf("... client would read block\n");
54 printf("... client would write block\n");
55 #ifdef USE_WINDOWS_API
60 #ifndef CYASSL_CALLBACKS
61 ret = CyaSSL_connect(ssl);
63 ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
65 error = CyaSSL_get_error(ssl, 0);
67 if (ret != SSL_SUCCESS)
68 err_sys("SSL_connect failed");
73 static void Usage(void)
75 printf("client " LIBCYASSL_VERSION_STRING
76 " NOTE: All files relative to CyaSSL home dir\n");
77 printf("-? Help, print this usage\n");
78 printf("-h <host> Host to connect to, default %s\n", yasslIP);
79 printf("-p <num> Port to connect on, default %d\n", yasslPort);
80 printf("-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
81 CLIENT_DEFAULT_VERSION);
82 printf("-l <str> Cipher list\n");
83 printf("-c <file> Certificate file, default %s\n", cliCert);
84 printf("-k <file> Key file, default %s\n", cliKey);
85 printf("-A <file> Certificate Authority file, default %s\n", caCert);
86 printf("-b <num> Benchmark <num> connections and print stats\n");
87 printf("-s Use pre Shared keys\n");
88 printf("-d Disable peer checks\n");
89 printf("-g Send server HTTP GET\n");
90 printf("-u Use UDP DTLS\n");
91 printf("-m Match domain name in cert\n");
95 void client_test(void* args)
99 CYASSL_METHOD* method = 0;
104 CYASSL* sslResume = 0;
105 CYASSL_SESSION* session = 0;
106 char resumeMsg[] = "resuming cyassl!";
107 int resumeSz = sizeof(resumeMsg);
110 char msg[64] = "hello cyassl!";
113 int msgSz = strlen(msg);
115 int port = yasslPort;
116 char* host = (char*)yasslIP;
117 char* domain = "www.yassl.com";
120 int version = CLIENT_DEFAULT_VERSION;
127 char* cipherList = NULL;
128 char* verifyCert = (char*)caCert;
129 char* ourCert = (char*)cliCert;
130 char* ourKey = (char*)cliKey;
132 int argc = ((func_args*)args)->argc;
133 char** argv = ((func_args*)args)->argv;
135 ((func_args*)args)->return_code = -1; /* error state */
137 while ((ch = mygetopt(argc, argv, "?gdusmh:p:v:l:A:c:k:b:")) != -1) {
153 version = -1; /* DTLS flag */
170 port = atoi(myoptarg);
174 version = atoi(myoptarg);
175 if (version < 0 || version > 3) {
180 version = -1; /* DTLS flag */
184 cipherList = myoptarg;
188 verifyCert = myoptarg;
200 benchmark = atoi(myoptarg);
201 if (benchmark < 0 || benchmark > 1000000) {
215 myoptind = 0; /* reset for test cases */
219 method = CyaSSLv3_client_method();
223 method = CyaTLSv1_client_method();
227 method = CyaTLSv1_1_client_method();
231 method = CyaTLSv1_2_client_method();
236 method = CyaDTLSv1_client_method();
241 err_sys("Bad SSL version");
245 err_sys("unable to get method");
247 ctx = CyaSSL_CTX_new(method);
249 err_sys("unable to get ctx");
252 if (CyaSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
253 err_sys("can't set cipher list");
257 CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
261 CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
264 #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
265 /* don't use EDH, can't sniff tmp keys */
266 if (cipherList == NULL)
267 if (CyaSSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS)
268 err_sys("can't set cipher list");
272 CyaSSL_CTX_SetCACb(ctx, CaCb);
275 #ifdef VERIFY_CALLBACK
276 CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
279 if (CyaSSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
281 err_sys("can't load client cert file, check file and run from"
284 if (CyaSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
286 err_sys("can't load client cert file, check file and run from"
289 if (CyaSSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
290 err_sys("can't load ca file, Please run from CyaSSL home dir");
292 if (doPeerCheck == 0)
293 CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
296 /* time passed in number of connects give average */
297 int times = benchmark;
300 double start = current_time(), avg;
302 for (i = 0; i < times; i++) {
303 tcp_connect(&sockfd, host, port, doDTLS);
304 ssl = CyaSSL_new(ctx);
305 CyaSSL_set_fd(ssl, sockfd);
306 if (CyaSSL_connect(ssl) != SSL_SUCCESS)
307 err_sys("SSL_connect failed");
309 CyaSSL_shutdown(ssl);
313 avg = current_time() - start;
315 avg *= 1000; /* milliseconds */
316 printf("CyaSSL_connect avg took: %8.3f milliseconds\n", avg);
318 CyaSSL_CTX_free(ctx);
319 ((func_args*)args)->return_code = 0;
324 tcp_connect(&sockfd, host, port, doDTLS);
325 ssl = CyaSSL_new(ctx);
327 err_sys("unable to get SSL object");
328 CyaSSL_set_fd(ssl, sockfd);
330 if (CyaSSL_EnableCRL(ssl, CYASSL_CRL_CHECKALL) != SSL_SUCCESS)
331 err_sys("can't enable crl check");
332 if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS)
333 err_sys("can't load crl, check crlfile and date validity");
334 if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
335 err_sys("can't set crl callback");
337 if (matchName && doPeerCheck)
338 CyaSSL_check_domain_name(ssl, domain);
340 tcp_set_nonblocking(&sockfd);
341 NonBlockingSSL_Connect(ssl);
343 #ifndef CYASSL_CALLBACKS
344 if (CyaSSL_connect(ssl) != SSL_SUCCESS) {/* see note at top of README */
345 int err = CyaSSL_get_error(ssl, 0);
347 printf("err = %d, %s\n", err, CyaSSL_ERR_error_string(err, buffer));
348 err_sys("SSL_connect failed");/* if you're getting an error here */
353 NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */
359 printf("SSL connect ok, sending GET...\n");
361 strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
363 if (CyaSSL_write(ssl, msg, msgSz) != msgSz)
364 err_sys("SSL_write failed");
366 input = CyaSSL_read(ssl, reply, sizeof(reply));
369 printf("Server response: %s\n", reply);
371 if (sendGET) { /* get html */
373 input = CyaSSL_read(ssl, reply, sizeof(reply));
376 printf("%s\n", reply);
386 strncpy(msg, "break", 6);
387 msgSz = (int)strlen(msg);
388 /* try to send session close */
389 CyaSSL_write(ssl, msg, msgSz);
391 session = CyaSSL_get_session(ssl);
392 sslResume = CyaSSL_new(ctx);
395 CyaSSL_shutdown(ssl);
401 #ifdef USE_WINDOWS_API
407 tcp_connect(&sockfd, host, port);
408 CyaSSL_set_fd(sslResume, sockfd);
409 CyaSSL_set_session(sslResume, session);
412 if (CyaSSL_connect(sslResume) != SSL_SUCCESS) err_sys("SSL resume failed");
415 if (CyaSSL_session_reused(sslResume))
416 printf("reused session id\n");
418 printf("didn't reuse session id!!!\n");
421 if (CyaSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
422 err_sys("SSL_write failed");
424 input = CyaSSL_read(sslResume, reply, sizeof(reply));
427 printf("Server resume response: %s\n", reply);
430 /* try to send session break */
431 CyaSSL_write(sslResume, msg, msgSz);
433 CyaSSL_shutdown(sslResume);
434 CyaSSL_free(sslResume);
435 #endif /* TEST_RESUME */
437 CyaSSL_CTX_free(ctx);
440 ((func_args*)args)->return_code = 0;
444 /* so overall tests can pull in test function */
445 #ifndef NO_MAIN_DRIVER
447 int main(int argc, char** argv)
458 CyaSSL_Debugging_ON();
460 if (CurrentDir("client") || CurrentDir("build"))
466 return args.return_code;
470 char* myoptarg = NULL;
472 #endif /* NO_MAIN_DRIVER */
476 #ifdef CYASSL_CALLBACKS
478 int handShakeCB(HandShakeInfo* info)
485 int timeoutCB(TimeoutInfo* info)