]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/examples/client/client.c
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Source / WolfSSL / examples / client / client.c
1 /* client.c
2  *
3  * Copyright (C) 2006-2015 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL. (formerly known as CyaSSL)
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #ifdef HAVE_CONFIG_H
23         #include <config.h>
24 #endif
25
26 #include <wolfssl/ssl.h>
27
28 #if defined(WOLFSSL_MDK_ARM)
29         #include <stdio.h>
30         #include <string.h>
31
32         #if defined(WOLFSSL_MDK5)
33             #include "cmsis_os.h"
34             #include "rl_fs.h" 
35             #include "rl_net.h" 
36         #else
37             #include "rtl.h"
38         #endif
39
40         #include "wolfssl_MDK_ARM.h"
41 #endif
42
43 #include <wolfssl/wolfcrypt/settings.h>
44
45 #if !defined(WOLFSSL_TRACK_MEMORY) && !defined(NO_MAIN_DRIVER)
46     /* in case memory tracker wants stats */
47     #define WOLFSSL_TRACK_MEMORY
48 #endif
49
50 #include <wolfssl/ssl.h>
51
52 #include <wolfssl/test.h>
53
54 #include "examples/client/client.h"
55
56
57 #ifdef WOLFSSL_CALLBACKS
58     int handShakeCB(HandShakeInfo*);
59     int timeoutCB(TimeoutInfo*);
60     Timeval timeout;
61 #endif
62
63 #ifdef HAVE_SESSION_TICKET
64     int sessionTicketCB(WOLFSSL*, const unsigned char*, int, void*);
65 #endif
66
67
68 static void NonBlockingSSL_Connect(WOLFSSL* ssl)
69 {
70 #ifndef WOLFSSL_CALLBACKS
71     int ret = wolfSSL_connect(ssl);
72 #else
73     int ret = wolfSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
74 #endif
75     int error = wolfSSL_get_error(ssl, 0);
76     SOCKET_T sockfd = (SOCKET_T)wolfSSL_get_fd(ssl);
77     int select_ret;
78
79     while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
80                                   error == SSL_ERROR_WANT_WRITE)) {
81         int currTimeout = 1;
82
83         if (error == SSL_ERROR_WANT_READ)
84             printf("... client would read block\n");
85         else
86             printf("... client would write block\n");
87
88 #ifdef WOLFSSL_DTLS
89         currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
90 #endif
91         select_ret = tcp_select(sockfd, currTimeout);
92
93         if ((select_ret == TEST_RECV_READY) ||
94                                         (select_ret == TEST_ERROR_READY)) {
95             #ifndef WOLFSSL_CALLBACKS
96                     ret = wolfSSL_connect(ssl);
97             #else
98                 ret = wolfSSL_connect_ex(ssl,handShakeCB,timeoutCB,timeout);
99             #endif
100             error = wolfSSL_get_error(ssl, 0);
101         }
102         else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
103             error = SSL_ERROR_WANT_READ;
104         }
105 #ifdef WOLFSSL_DTLS
106         else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
107                                             wolfSSL_dtls_got_timeout(ssl) >= 0) {
108             error = SSL_ERROR_WANT_READ;
109         }
110 #endif
111         else {
112             error = SSL_FATAL_ERROR;
113         }
114     }
115     if (ret != SSL_SUCCESS)
116         err_sys("SSL_connect failed");
117 }
118
119
120 static void Usage(void)
121 {
122     printf("client "    LIBWOLFSSL_VERSION_STRING
123            " NOTE: All files relative to wolfSSL home dir\n");
124     printf("-?          Help, print this usage\n");
125     printf("-h <host>   Host to connect to, default %s\n", wolfSSLIP);
126     printf("-p <num>    Port to connect on, not 0, default %d\n", wolfSSLPort);
127     printf("-v <num>    SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
128                                  CLIENT_DEFAULT_VERSION);
129     printf("-l <str>    Cipher list\n");
130     printf("-c <file>   Certificate file,           default %s\n", cliCert);
131     printf("-k <file>   Key file,                   default %s\n", cliKey);
132     printf("-A <file>   Certificate Authority file, default %s\n", caCert);
133 #ifndef NO_DH
134     printf("-Z <num>    Minimum DH key bits,        default %d\n",
135                                  DEFAULT_MIN_DHKEY_BITS);
136 #endif
137     printf("-b <num>    Benchmark <num> connections and print stats\n");
138     printf("-s          Use pre Shared keys\n");
139     printf("-t          Track wolfSSL memory use\n");
140     printf("-d          Disable peer checks\n");
141     printf("-D          Override Date Errors example\n");
142     printf("-g          Send server HTTP GET\n");
143     printf("-u          Use UDP DTLS,"
144            " add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2\n");
145     printf("-m          Match domain name in cert\n");
146     printf("-N          Use Non-blocking sockets\n");
147     printf("-r          Resume session\n");
148     printf("-w          Wait for bidirectional shutdown\n");
149 #ifdef HAVE_SECURE_RENEGOTIATION
150     printf("-R          Allow Secure Renegotiation\n");
151     printf("-i          Force client Initiated Secure Renegotiation\n");
152 #endif
153     printf("-f          Fewer packets/group messages\n");
154     printf("-x          Disable client cert/key loading\n");
155     printf("-X          Driven by eXternal test case\n");
156 #ifdef SHOW_SIZES
157     printf("-z          Print structure sizes\n");
158 #endif
159 #ifdef HAVE_SNI
160     printf("-S <str>    Use Host Name Indication\n");
161 #endif
162 #ifdef HAVE_MAX_FRAGMENT
163     printf("-L <num>    Use Maximum Fragment Length [1-5]\n");
164 #endif
165 #ifdef HAVE_TRUNCATED_HMAC
166     printf("-T          Use Truncated HMAC\n");
167 #endif
168 #ifdef HAVE_OCSP
169     printf("-o          Perform OCSP lookup on peer certificate\n");
170     printf("-O <url>    Perform OCSP lookup using <url> as responder\n");
171 #endif
172 #ifdef ATOMIC_USER
173     printf("-U          Atomic User Record Layer Callbacks\n");
174 #endif
175 #ifdef HAVE_PK_CALLBACKS 
176     printf("-P          Public Key Callbacks\n");
177 #endif
178 #ifdef HAVE_ANON
179     printf("-a          Anonymous client\n");
180 #endif
181 #ifdef HAVE_CRL
182     printf("-C          Disable CRL\n");
183 #endif
184 }
185
186 THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
187 {
188     SOCKET_T sockfd = 0;
189
190     WOLFSSL_METHOD*  method  = 0;
191     WOLFSSL_CTX*     ctx     = 0;
192     WOLFSSL*         ssl     = 0;
193     
194     WOLFSSL*         sslResume = 0;
195     WOLFSSL_SESSION* session = 0;
196     char         resumeMsg[] = "resuming wolfssl!";
197     int          resumeSz    = sizeof(resumeMsg);
198
199     char msg[32] = "hello wolfssl!";   /* GET may make bigger */
200     char reply[80];
201     int  input;
202     int  msgSz = (int)strlen(msg);
203
204     word16 port   = wolfSSLPort;
205     char* host   = (char*)wolfSSLIP;
206     const char* domain = "www.wolfssl.com";
207
208     int    ch;
209     int    version = CLIENT_INVALID_VERSION;
210     int    usePsk   = 0;
211     int    useAnon  = 0;
212     int    sendGET  = 0;
213     int    benchmark = 0;
214     int    doDTLS    = 0;
215     int    matchName = 0;
216     int    doPeerCheck = 1;
217     int    nonBlocking = 0;
218     int    resumeSession = 0;
219     int    wc_shutdown   = 0;
220     int    disableCRL    = 0;
221     int    externalTest  = 0;
222     int    ret;
223     int    scr           = 0;    /* allow secure renegotiation */
224     int    forceScr      = 0;    /* force client initiaed scr */
225     int    trackMemory   = 0;
226     int    useClientCert = 1;
227     int    fewerPackets  = 0;
228     int    atomicUser    = 0;
229     int    pkCallbacks   = 0;
230     int    overrideDateErrors = 0;
231     int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
232     char*  cipherList = NULL;
233     const char* verifyCert = caCert;
234     const char* ourCert    = cliCert;
235     const char* ourKey     = cliKey;
236
237 #ifdef HAVE_SNI
238     char*  sniHostName = NULL;
239 #endif
240 #ifdef HAVE_MAX_FRAGMENT
241     byte maxFragment = 0;
242 #endif
243 #ifdef HAVE_TRUNCATED_HMAC
244     byte  truncatedHMAC = 0;
245 #endif
246
247
248 #ifdef HAVE_OCSP
249     int    useOcsp  = 0;
250     char*  ocspUrl  = NULL;
251 #endif
252
253     int     argc = ((func_args*)args)->argc;
254     char**  argv = ((func_args*)args)->argv;
255
256     ((func_args*)args)->return_code = -1; /* error state */
257
258 #ifdef NO_RSA
259     verifyCert = (char*)eccCert;
260     ourCert    = (char*)cliEccCert;
261     ourKey     = (char*)cliEccKey;
262 #endif
263     (void)resumeSz;
264     (void)session;
265     (void)sslResume;
266     (void)trackMemory;
267     (void)atomicUser;
268     (void)pkCallbacks;
269     (void)scr;
270     (void)forceScr;
271     (void)ourKey;
272     (void)ourCert;
273     (void)verifyCert;
274     (void)useClientCert;
275     (void)overrideDateErrors;
276     (void)disableCRL;
277     (void)minDhKeyBits;
278
279     StackTrap();
280
281     while ((ch = mygetopt(argc, argv,
282                           "?gdDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:a"))
283                                                                         != -1) {
284         switch (ch) {
285             case '?' :
286                 Usage();
287                 exit(EXIT_SUCCESS);
288
289             case 'g' :
290                 sendGET = 1;
291                 break;
292
293             case 'd' :
294                 doPeerCheck = 0;
295                 break;
296
297             case 'D' :
298                 overrideDateErrors = 1;
299                 break;
300
301             case 'C' :
302                 #ifdef HAVE_CRL
303                     disableCRL = 1;
304                 #endif
305                 break;
306
307             case 'u' :
308                 doDTLS  = 1;
309                 break;
310
311             case 's' :
312                 usePsk = 1;
313                 break;
314
315             case 't' :
316             #ifdef USE_WOLFSSL_MEMORY
317                 trackMemory = 1;
318             #endif
319                 break;
320
321             case 'm' :
322                 matchName = 1;
323                 break;
324
325             case 'x' :
326                 useClientCert = 0;
327                 break;
328
329             case 'X' :
330                 externalTest = 1;
331                 break;
332
333             case 'f' :
334                 fewerPackets = 1;
335                 break;
336
337             case 'U' :
338             #ifdef ATOMIC_USER
339                 atomicUser = 1;
340             #endif
341                 break;
342
343             case 'P' :
344             #ifdef HAVE_PK_CALLBACKS 
345                 pkCallbacks = 1;
346             #endif
347                 break;
348
349             case 'h' :
350                 host   = myoptarg;
351                 domain = myoptarg;
352                 break;
353
354             case 'p' :
355                 port = (word16)atoi(myoptarg);
356                 #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
357                     if (port == 0)
358                         err_sys("port number cannot be 0");
359                 #endif
360                 break;
361
362             case 'v' :
363                 version = atoi(myoptarg);
364                 if (version < 0 || version > 3) {
365                     Usage();
366                     exit(MY_EX_USAGE);
367                 }
368                 break;
369
370             case 'l' :
371                 cipherList = myoptarg;
372                 break;
373
374             case 'A' :
375                 verifyCert = myoptarg;
376                 break;
377
378             case 'c' :
379                 ourCert = myoptarg;
380                 break;
381
382             case 'k' :
383                 ourKey = myoptarg;
384                 break;
385
386             case 'Z' :
387                 #ifndef NO_DH
388                     minDhKeyBits = atoi(myoptarg);
389                     if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
390                         Usage();
391                         exit(MY_EX_USAGE);
392                     }
393                 #endif
394                 break;
395
396             case 'b' :
397                 benchmark = atoi(myoptarg);
398                 if (benchmark < 0 || benchmark > 1000000) {
399                     Usage();
400                     exit(MY_EX_USAGE);
401                 }
402                 break;
403
404             case 'N' :
405                 nonBlocking = 1;
406                 break;
407
408             case 'r' :
409                 resumeSession = 1;
410                 break;
411
412             case 'w' :
413                 wc_shutdown = 1;
414                 break;
415
416             case 'R' :
417                 #ifdef HAVE_SECURE_RENEGOTIATION
418                     scr = 1;
419                 #endif
420                 break;
421
422             case 'i' :
423                 #ifdef HAVE_SECURE_RENEGOTIATION
424                     scr      = 1;
425                     forceScr = 1;
426                 #endif
427                 break;
428
429             case 'z' :
430                 #ifndef WOLFSSL_LEANPSK
431                     wolfSSL_GetObjectSize();
432                 #endif
433                 break;
434
435             case 'S' :
436                 #ifdef HAVE_SNI
437                     sniHostName = myoptarg;
438                 #endif
439                 break;
440
441             case 'L' :
442                 #ifdef HAVE_MAX_FRAGMENT
443                     maxFragment = atoi(myoptarg);
444                     if (maxFragment < WOLFSSL_MFL_2_9 ||
445                                                 maxFragment > WOLFSSL_MFL_2_13) {
446                         Usage();
447                         exit(MY_EX_USAGE);
448                     }
449                 #endif
450                 break;
451
452             case 'T' :
453                 #ifdef HAVE_TRUNCATED_HMAC
454                     truncatedHMAC = 1;
455                 #endif
456                 break;
457
458             case 'o' :
459                 #ifdef HAVE_OCSP
460                     useOcsp = 1;
461                 #endif
462                 break;
463
464             case 'O' :
465                 #ifdef HAVE_OCSP
466                     useOcsp = 1;
467                     ocspUrl = myoptarg;
468                 #endif
469                 break;
470
471             case 'a' :
472                 #ifdef HAVE_ANON
473                     useAnon = 1;
474                 #endif
475                 break;
476
477             default:
478                 Usage();
479                 exit(MY_EX_USAGE);
480         }
481     }
482
483     myoptind = 0;      /* reset for test cases */
484
485     if (externalTest) {
486         /* detect build cases that wouldn't allow test against wolfssl.com */
487         int done = 0;
488         (void)done;
489
490         #ifdef NO_RSA
491             done = 1;
492         #endif
493
494         #ifndef NO_PSK
495             done = 1;
496         #endif
497
498         #ifdef NO_SHA
499             done = 1;  /* external cert chain most likely has SHA */
500         #endif
501
502         if (done) {
503             printf("external test can't be run in this mode");
504
505             ((func_args*)args)->return_code = 0;
506             exit(EXIT_SUCCESS);
507         }
508     }
509
510     /* sort out DTLS versus TLS versions */
511     if (version == CLIENT_INVALID_VERSION) {
512         if (doDTLS)
513             version = CLIENT_DTLS_DEFAULT_VERSION;
514         else
515             version = CLIENT_DEFAULT_VERSION;
516     }
517     else {
518         if (doDTLS) {
519             if (version == 3)
520                 version = -2;
521             else
522                 version = -1;
523         }
524     }
525
526 #ifdef USE_WOLFSSL_MEMORY
527     if (trackMemory)
528         InitMemoryTracker(); 
529 #endif
530
531     switch (version) {
532 #ifndef NO_OLD_TLS
533         case 0:
534             method = wolfSSLv3_client_method();
535             break;
536                 
537                 
538     #ifndef NO_TLS
539         case 1:
540             method = wolfTLSv1_client_method();
541             break;
542
543         case 2:
544             method = wolfTLSv1_1_client_method();
545             break;
546     #endif /* NO_TLS */
547                 
548 #endif  /* NO_OLD_TLS */
549                 
550 #ifndef NO_TLS
551         case 3:
552             method = wolfTLSv1_2_client_method();
553             break;
554 #endif
555
556 #ifdef WOLFSSL_DTLS
557         #ifndef NO_OLD_TLS
558         case -1:
559             method = wolfDTLSv1_client_method();
560             break;
561         #endif
562
563         case -2:
564             method = wolfDTLSv1_2_client_method();
565             break;
566 #endif
567
568         default:
569             err_sys("Bad SSL version");
570             break;
571     }
572
573     if (method == NULL)
574         err_sys("unable to get method");
575
576     ctx = wolfSSL_CTX_new(method);
577     if (ctx == NULL)
578         err_sys("unable to get ctx");
579
580     if (cipherList)
581         if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
582             err_sys("client can't set cipher list 1");
583
584 #ifdef WOLFSSL_LEANPSK
585     usePsk = 1;
586 #endif
587
588 #if defined(NO_RSA) && !defined(HAVE_ECC)
589     usePsk = 1;
590 #endif
591
592     if (fewerPackets)
593         wolfSSL_CTX_set_group_messages(ctx);
594
595 #ifndef NO_DH
596     wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits);
597 #endif
598
599     if (usePsk) {
600 #ifndef NO_PSK
601         wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
602         if (cipherList == NULL) {
603             const char *defaultCipherList;
604             #if defined(HAVE_AESGCM) && !defined(NO_DH)
605                 defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
606             #elif defined(HAVE_NULL_CIPHER)
607                 defaultCipherList = "PSK-NULL-SHA256";
608             #else
609                 defaultCipherList = "PSK-AES128-CBC-SHA256";
610             #endif
611             if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)
612                                                                   !=SSL_SUCCESS)
613                 err_sys("client can't set cipher list 2");
614         }
615 #endif
616         useClientCert = 0;
617     }
618
619     if (useAnon) {
620 #ifdef HAVE_ANON
621         if (cipherList == NULL) {
622             wolfSSL_CTX_allow_anon_cipher(ctx);
623             if (wolfSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA") != SSL_SUCCESS)
624                 err_sys("client can't set cipher list 4");
625         }
626 #endif
627         useClientCert = 0;
628     }
629
630 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
631     wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
632 #endif
633
634 #if defined(WOLFSSL_SNIFFER)
635     if (cipherList == NULL) {
636         /* don't use EDH, can't sniff tmp keys */
637         if (wolfSSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS) {
638             err_sys("client can't set cipher list 3");
639         }
640     }
641 #endif
642
643 #ifdef HAVE_OCSP
644     if (useOcsp) {
645         if (ocspUrl != NULL) {
646             wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
647             wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
648                                                     | WOLFSSL_OCSP_URL_OVERRIDE);
649         }
650         else
651             wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE);
652     }
653 #endif
654
655 #ifdef USER_CA_CB
656     wolfSSL_CTX_SetCACb(ctx, CaCb);
657 #endif
658
659 #ifdef VERIFY_CALLBACK
660     wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
661 #endif
662 #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
663     if (useClientCert){
664         if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS)
665             err_sys("can't load client cert file, check file and run from"
666                     " wolfSSL home dir");
667
668         if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
669                                          != SSL_SUCCESS)
670             err_sys("can't load client private key file, check file and run "
671                     "from wolfSSL home dir");
672     }
673
674     if (!usePsk && !useAnon) {
675         if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0) != SSL_SUCCESS)
676             err_sys("can't load ca file, Please run from wolfSSL home dir");
677 #ifdef HAVE_ECC
678         /* load ecc verify too, echoserver uses it by default w/ ecc */
679         if (wolfSSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
680             err_sys("can't load ecc ca file, Please run from wolfSSL home dir");
681 #endif /* HAVE_ECC */
682     }
683 #endif /* !NO_FILESYSTEM && !NO_CERTS */
684 #if !defined(NO_CERTS)
685     if (!usePsk && !useAnon && doPeerCheck == 0)
686         wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
687     if (!usePsk && !useAnon && overrideDateErrors == 1)
688         wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb);
689 #endif
690
691 #ifdef HAVE_CAVIUM
692     wolfSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID);
693 #endif
694
695 #ifdef HAVE_SNI
696     if (sniHostName)
697         if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName))
698                                                                  != SSL_SUCCESS)
699             err_sys("UseSNI failed");
700 #endif
701 #ifdef HAVE_MAX_FRAGMENT
702     if (maxFragment)
703         if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != SSL_SUCCESS)
704             err_sys("UseMaxFragment failed");
705 #endif
706 #ifdef HAVE_TRUNCATED_HMAC
707     if (truncatedHMAC)
708         if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
709             err_sys("UseTruncatedHMAC failed");
710 #endif
711 #ifdef HAVE_SESSION_TICKET
712     if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS)
713         err_sys("UseSessionTicket failed");
714 #endif
715
716     if (benchmark) {
717         /* time passed in number of connects give average */
718         int times = benchmark;
719         int loops = resumeSession ? 2 : 1;
720         int i = 0;
721         WOLFSSL_SESSION* benchSession = NULL;
722
723         while (loops--) {
724             int benchResume = resumeSession && loops == 0;
725             double start = current_time(), avg;
726
727             for (i = 0; i < times; i++) {
728                 tcp_connect(&sockfd, host, port, doDTLS);
729
730                 ssl = wolfSSL_new(ctx);
731                 if (benchResume)
732                     wolfSSL_set_session(ssl, benchSession);
733                 wolfSSL_set_fd(ssl, sockfd);
734                 if (wolfSSL_connect(ssl) != SSL_SUCCESS)
735                     err_sys("SSL_connect failed");
736
737                 wolfSSL_shutdown(ssl);
738                 if (i == (times-1) && resumeSession) {
739                     benchSession = wolfSSL_get_session(ssl);
740                 }
741                 wolfSSL_free(ssl);
742                 CloseSocket(sockfd);
743             }
744             avg = current_time() - start;
745             avg /= times;
746             avg *= 1000;   /* milliseconds */
747             if (benchResume)
748                 printf("wolfSSL_resume  avg took: %8.3f milliseconds\n", avg);
749             else
750                 printf("wolfSSL_connect avg took: %8.3f milliseconds\n", avg);
751         }
752
753         wolfSSL_CTX_free(ctx);
754         ((func_args*)args)->return_code = 0;
755
756         exit(EXIT_SUCCESS);
757     }
758     
759     #if defined(WOLFSSL_MDK_ARM)
760     wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
761     #endif
762     
763     ssl = wolfSSL_new(ctx);
764     if (ssl == NULL)
765         err_sys("unable to get SSL object");
766     #ifdef HAVE_SESSION_TICKET
767     wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session");
768     #endif
769     if (doDTLS) {
770         SOCKADDR_IN_T addr;
771         build_addr(&addr, host, port, 1);
772         wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
773         tcp_socket(&sockfd, 1);
774     }
775     else {
776         tcp_connect(&sockfd, host, port, 0);
777     }
778
779 #ifdef HAVE_POLY1305
780     /* use old poly to connect with google server */
781     if (!XSTRNCMP(domain, "www.google.com", 14)) {
782         if (wolfSSL_use_old_poly(ssl, 1) != 0)
783             err_sys("unable to set to old poly");
784     }
785 #endif
786
787     wolfSSL_set_fd(ssl, sockfd);
788 #ifdef HAVE_CRL
789     if (disableCRL == 0) {
790         if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != SSL_SUCCESS)
791             err_sys("can't enable crl check");
792         if (wolfSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS)
793             err_sys("can't load crl, check crlfile and date validity");
794         if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
795             err_sys("can't set crl callback");
796     }
797 #endif
798 #ifdef HAVE_SECURE_RENEGOTIATION
799     if (scr) {
800         if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
801             err_sys("can't enable secure renegotiation");
802     }
803 #endif
804 #ifdef ATOMIC_USER
805     if (atomicUser)
806         SetupAtomicUser(ctx, ssl);
807 #endif
808 #ifdef HAVE_PK_CALLBACKS
809     if (pkCallbacks)
810         SetupPkCallbacks(ctx, ssl);
811 #endif
812     if (matchName && doPeerCheck)
813         wolfSSL_check_domain_name(ssl, domain);
814 #ifndef WOLFSSL_CALLBACKS
815     if (nonBlocking) {
816         wolfSSL_set_using_nonblock(ssl, 1);
817         tcp_set_nonblocking(&sockfd);
818         NonBlockingSSL_Connect(ssl);
819     }
820     else if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
821         /* see note at top of README */
822         int  err = wolfSSL_get_error(ssl, 0);
823         char buffer[WOLFSSL_MAX_ERROR_SZ];
824         printf("err = %d, %s\n", err,
825                                 wolfSSL_ERR_error_string(err, buffer));
826         err_sys("SSL_connect failed");
827         /* if you're getting an error here  */
828     }
829 #else
830     timeout.tv_sec  = 2;
831     timeout.tv_usec = 0;
832     NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
833 #endif
834     showPeer(ssl);
835
836 #ifdef HAVE_SECURE_RENEGOTIATION
837     if (scr && forceScr) {
838         if (nonBlocking) {
839             printf("not doing secure renegotiation on example with"
840                    " nonblocking yet");
841         } else {
842             if (wolfSSL_Rehandshake(ssl) != SSL_SUCCESS) {
843                 int  err = wolfSSL_get_error(ssl, 0);
844                 char buffer[WOLFSSL_MAX_ERROR_SZ];
845                 printf("err = %d, %s\n", err,
846                                 wolfSSL_ERR_error_string(err, buffer));
847                 err_sys("wolfSSL_Rehandshake failed");
848             }
849         }
850     }
851 #endif /* HAVE_SECURE_RENEGOTIATION */
852
853     if (sendGET) {
854         printf("SSL connect ok, sending GET...\n");
855         msgSz = 28;
856         strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
857         msg[msgSz] = '\0';
858     }
859     if (wolfSSL_write(ssl, msg, msgSz) != msgSz)
860         err_sys("SSL_write failed");
861
862     input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
863     if (input > 0) {
864         reply[input] = 0;
865         printf("Server response: %s\n", reply);
866
867         if (sendGET) {  /* get html */
868             while (1) {
869                 input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
870                 if (input > 0) {
871                     reply[input] = 0;
872                     printf("%s\n", reply);
873                 }
874                 else
875                     break;
876             }
877         }
878     }
879     else if (input < 0) {
880         int readErr = wolfSSL_get_error(ssl, 0);
881         if (readErr != SSL_ERROR_WANT_READ)
882             err_sys("wolfSSL_read failed");
883     }
884
885 #ifndef NO_SESSION_CACHE
886     if (resumeSession) {
887         session   = wolfSSL_get_session(ssl);
888         sslResume = wolfSSL_new(ctx);
889     }
890 #endif
891
892     if (doDTLS == 0) {           /* don't send alert after "break" command */
893         ret = wolfSSL_shutdown(ssl);
894         if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
895             wolfSSL_shutdown(ssl);    /* bidirectional shutdown */
896     }
897 #ifdef ATOMIC_USER
898     if (atomicUser)
899         FreeAtomicUser(ssl);
900 #endif
901     wolfSSL_free(ssl);
902     CloseSocket(sockfd);
903
904 #ifndef NO_SESSION_CACHE
905     if (resumeSession) {
906         if (doDTLS) {
907             SOCKADDR_IN_T addr;
908             #ifdef USE_WINDOWS_API 
909                 Sleep(500);
910             #elif defined(WOLFSSL_TIRTOS)
911                 Task_sleep(1);
912             #else
913                 sleep(1);
914             #endif
915             build_addr(&addr, host, port, 1);
916             wolfSSL_dtls_set_peer(sslResume, &addr, sizeof(addr));
917             tcp_socket(&sockfd, 1);
918         }
919         else {
920             tcp_connect(&sockfd, host, port, 0);
921         }
922         wolfSSL_set_fd(sslResume, sockfd);
923 #ifdef HAVE_SECURE_RENEGOTIATION
924         if (scr) {
925             if (wolfSSL_UseSecureRenegotiation(sslResume) != SSL_SUCCESS)
926                 err_sys("can't enable secure renegotiation");
927         }
928 #endif
929         wolfSSL_set_session(sslResume, session);
930 #ifdef HAVE_SESSION_TICKET
931         wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB,
932                                     (void*)"resumed session");
933 #endif
934        
935         showPeer(sslResume);
936 #ifndef WOLFSSL_CALLBACKS
937         if (nonBlocking) {
938             wolfSSL_set_using_nonblock(sslResume, 1);
939             tcp_set_nonblocking(&sockfd);
940             NonBlockingSSL_Connect(sslResume);
941         }
942         else if (wolfSSL_connect(sslResume) != SSL_SUCCESS)
943             err_sys("SSL resume failed");
944 #else
945         timeout.tv_sec  = 2;
946         timeout.tv_usec = 0;
947         NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
948 #endif
949
950         if (wolfSSL_session_reused(sslResume))
951             printf("reused session id\n");
952         else
953             printf("didn't reuse session id!!!\n");
954
955         if (wolfSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
956             err_sys("SSL_write failed");
957
958         if (nonBlocking) {
959             /* give server a chance to bounce a message back to client */
960             #ifdef USE_WINDOWS_API
961                 Sleep(500);
962             #elif defined(WOLFSSL_TIRTOS)
963                 Task_sleep(1);
964             #else
965                 sleep(1);
966             #endif
967         }
968
969         input = wolfSSL_read(sslResume, reply, sizeof(reply)-1);
970         if (input > 0) {
971             reply[input] = 0;
972             printf("Server resume response: %s\n", reply);
973         }
974
975         /* try to send session break */
976         wolfSSL_write(sslResume, msg, msgSz); 
977
978         ret = wolfSSL_shutdown(sslResume);
979         if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
980             wolfSSL_shutdown(sslResume);    /* bidirectional shutdown */
981
982         wolfSSL_free(sslResume);
983         CloseSocket(sockfd);
984     }
985 #endif /* NO_SESSION_CACHE */
986
987     wolfSSL_CTX_free(ctx);
988
989     ((func_args*)args)->return_code = 0;
990
991 #ifdef USE_WOLFSSL_MEMORY
992     if (trackMemory)
993         ShowMemoryTracker();
994 #endif /* USE_WOLFSSL_MEMORY */
995
996 #if !defined(WOLFSSL_TIRTOS)
997     return 0;
998 #endif
999 }
1000
1001
1002 /* so overall tests can pull in test function */
1003 #ifndef NO_MAIN_DRIVER
1004
1005     int main(int argc, char** argv)
1006     {
1007         func_args args;
1008
1009 #ifdef HAVE_CAVIUM
1010         int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID);
1011         if (ret != 0)
1012             err_sys("Cavium OpenNitroxDevice failed");
1013 #endif /* HAVE_CAVIUM */
1014
1015         StartTCP();
1016
1017         args.argc = argc;
1018         args.argv = argv;
1019
1020         wolfSSL_Init();
1021 #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL) && !defined(STACK_TRAP)
1022         wolfSSL_Debugging_ON();
1023 #endif
1024         if (CurrentDir("_build"))
1025             ChangeDirBack(1);
1026         else if (CurrentDir("client"))
1027             ChangeDirBack(2);
1028         else if (CurrentDir("Debug") || CurrentDir("Release"))
1029             ChangeDirBack(3);
1030   
1031 #ifdef HAVE_STACK_SIZE
1032         StackSizeCheck(&args, client_test);
1033 #else 
1034         client_test(&args);
1035 #endif
1036         wolfSSL_Cleanup();
1037
1038 #ifdef HAVE_CAVIUM
1039         CspShutdown(CAVIUM_DEV_ID);
1040 #endif
1041         return args.return_code;
1042     }
1043
1044     int myoptind = 0;
1045     char* myoptarg = NULL;
1046
1047 #endif /* NO_MAIN_DRIVER */
1048
1049
1050
1051 #ifdef WOLFSSL_CALLBACKS
1052
1053     int handShakeCB(HandShakeInfo* info)
1054     {
1055         (void)info;
1056         return 0;
1057     }
1058
1059
1060     int timeoutCB(TimeoutInfo* info)
1061     {
1062         (void)info;
1063         return 0;
1064     }
1065
1066 #endif
1067
1068
1069 #ifdef HAVE_SESSION_TICKET
1070
1071     int sessionTicketCB(WOLFSSL* ssl,
1072                         const unsigned char* ticket, int ticketSz,
1073                         void* ctx)
1074     {
1075         (void)ssl;
1076         (void)ticket;
1077         printf("Session Ticket CB: ticketSz = %d, ctx = %s\n",
1078                ticketSz, (char*)ctx);
1079         return 0;
1080     }
1081
1082 #endif
1083