wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test.h Source File

test.h

00001 /* test.h */
00002 
00003 #ifndef wolfSSL_TEST_H
00004 #define wolfSSL_TEST_H
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <assert.h>
00009 #include <ctype.h>
00010 #include <wolfssl/wolfcrypt/types.h>
00011 #include <wolfssl/wolfcrypt/error-crypt.h>
00012 #include <wolfssl/wolfcrypt/random.h>
00013 
00014 #ifdef ATOMIC_USER
00015     #include <wolfssl/wolfcrypt/aes.h>
00016     #include <wolfssl/wolfcrypt/arc4.h>
00017     #include <wolfssl/wolfcrypt/hmac.h>
00018 #endif
00019 #ifdef HAVE_PK_CALLBACKS
00020     #include <wolfssl/wolfcrypt/asn.h>
00021     #ifndef NO_RSA
00022         #include <wolfssl/wolfcrypt/rsa.h>
00023     #endif
00024     #ifdef HAVE_ECC
00025         #include <wolfssl/wolfcrypt/ecc.h>
00026     #endif /* HAVE_ECC */
00027 #endif /*HAVE_PK_CALLBACKS */
00028 
00029 #ifdef USE_WINDOWS_API
00030     #include <winsock2.h>
00031     #include <process.h>
00032     #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
00033         #include <ws2tcpip.h>
00034         #include <wspiapi.h>
00035     #endif
00036     #define SOCKET_T SOCKET
00037     #define SNPRINTF _snprintf
00038 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00039     #include <string.h>
00040     #include "rl_net.h"
00041     #define SOCKET_T int
00042         typedef int socklen_t ;
00043         static unsigned long inet_addr(const char *cp)
00044     {
00045         unsigned int a[4] ; unsigned long ret ;
00046         sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
00047         ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
00048         return(ret) ;
00049     }
00050         #if defined(HAVE_KEIL_RTX)
00051         #define sleep(t) os_dly_wait(t/1000+1) ;
00052     #elif defined (WOLFSSL_CMSIS_RTOS)
00053         #define sleep(t)  osDelay(t/1000+1) ;
00054     #endif
00055 
00056     static int wolfssl_tcp_select(int sd, int timeout)
00057     {        return 0 ;  }
00058         #define tcp_select(sd,t)   wolfssl_tcp_select(sd, t)  /* avoid conflicting Keil TCP tcp_select */
00059 #elif defined(WOLFSSL_TIRTOS)
00060     #include <string.h>
00061     #include <netdb.h>
00062     #include <sys/types.h>
00063     #include <arpa/inet.h>
00064     #include <sys/socket.h>
00065     #include <ti/sysbios/knl/Task.h>
00066     struct hostent {
00067         char *h_name; /* official name of host */
00068         char **h_aliases; /* alias list */
00069         int h_addrtype; /* host address type */
00070         int h_length; /* length of address */
00071         char **h_addr_list; /* list of addresses from name server */
00072     };
00073     #define SOCKET_T int
00074 #elif defined(WOLFSSL_VXWORKS)
00075     #include <hostLib.h>
00076     #include <sockLib.h>
00077     #include <arpa/inet.h>
00078     #include <string.h>
00079     #include <selectLib.h>
00080     #include <sys/types.h>
00081     #include <netinet/in.h>
00082     #include <fcntl.h>
00083     #include <sys/time.h>
00084     #include <netdb.h>
00085     #include <pthread.h>
00086     #define SOCKET_T int
00087 #else
00088     #include <string.h>
00089     #include <sys/types.h>
00090 #ifndef WOLFSSL_LEANPSK
00091     #include <unistd.h>
00092     #include <netdb.h>
00093     #include <netinet/in.h>
00094     #include <netinet/tcp.h>
00095     #include <arpa/inet.h>
00096     #include <sys/ioctl.h>
00097     #include <sys/time.h>
00098     #include <sys/socket.h>
00099     #include <pthread.h>
00100     #include <fcntl.h>
00101     #ifdef TEST_IPV6
00102         #include <netdb.h>
00103     #endif
00104 #endif
00105     #define SOCKET_T int
00106     #ifndef SO_NOSIGPIPE
00107         #include <signal.h>  /* ignore SIGPIPE */
00108     #endif
00109     #define SNPRINTF snprintf
00110 #endif /* USE_WINDOWS_API */
00111 
00112 #ifdef WOLFSSL_ASYNC_CRYPT
00113     #include <wolfssl/wolfcrypt/async.h>
00114 #endif
00115 #ifdef HAVE_CAVIUM
00116     #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h>
00117 #endif
00118 
00119 #ifdef _MSC_VER
00120     /* disable conversion warning */
00121     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
00122     #pragma warning(disable:4244 4996)
00123 #endif
00124 
00125 /* Buffer for benchmark tests */
00126 #ifndef TEST_BUFFER_SIZE
00127 #define TEST_BUFFER_SIZE 16384
00128 #endif
00129 
00130 #ifndef WOLFSSL_HAVE_MIN
00131     #define WOLFSSL_HAVE_MIN
00132     static INLINE word32 min(word32 a, word32 b)
00133     {
00134         return a > b ? b : a;
00135     }
00136 #endif /* WOLFSSL_HAVE_MIN */
00137 
00138 /* Socket Handling */
00139 #ifndef WOLFSSL_SOCKET_INVALID
00140 #ifdef USE_WINDOWS_API
00141     #define WOLFSSL_SOCKET_INVALID  ((SOCKET_T)INVALID_SOCKET)
00142 #elif defined(WOLFSSL_TIRTOS)
00143     #define WOLFSSL_SOCKET_INVALID  ((SOCKET_T)-1)
00144 #else
00145     #define WOLFSSL_SOCKET_INVALID  (SOCKET_T)(0)
00146 #endif
00147 #endif /* WOLFSSL_SOCKET_INVALID */
00148 
00149 #ifndef WOLFSSL_SOCKET_IS_INVALID
00150 #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS)
00151     #define WOLFSSL_SOCKET_IS_INVALID(s)  ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
00152 #else
00153     #define WOLFSSL_SOCKET_IS_INVALID(s)  ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID)
00154 #endif
00155 #endif /* WOLFSSL_SOCKET_IS_INVALID */
00156 
00157 #if defined(__MACH__) || defined(USE_WINDOWS_API)
00158     #ifndef _SOCKLEN_T
00159         typedef int socklen_t;
00160     #endif
00161 #endif
00162 
00163 
00164 /* HPUX doesn't use socklent_t for third parameter to accept, unless
00165    _XOPEN_SOURCE_EXTENDED is defined */
00166 #if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\
00167  && !defined(WOLFSSL_ROWLEY_ARM)  && !defined(WOLFSSL_KEIL_TCP_NET)
00168     typedef socklen_t* ACCEPT_THIRD_T;
00169 #else
00170     #if defined _XOPEN_SOURCE_EXTENDED
00171         typedef socklen_t* ACCEPT_THIRD_T;
00172     #else
00173         typedef int*       ACCEPT_THIRD_T;
00174     #endif
00175 #endif
00176 
00177 
00178 #ifdef USE_WINDOWS_API
00179     #define CloseSocket(s) closesocket(s)
00180     #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
00181 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00182     #define CloseSocket(s) closesocket(s)
00183     #define StartTCP()
00184 #else
00185     #define CloseSocket(s) close(s)
00186     #define StartTCP()
00187 #endif
00188 
00189 
00190 #ifdef SINGLE_THREADED
00191     typedef unsigned int  THREAD_RETURN;
00192     typedef void*         THREAD_TYPE;
00193     #define WOLFSSL_THREAD
00194 #else
00195     #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00196         typedef void*         THREAD_RETURN;
00197         typedef pthread_t     THREAD_TYPE;
00198         #define WOLFSSL_THREAD
00199         #define INFINITE -1
00200         #define WAIT_OBJECT_0 0L
00201     #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
00202         typedef unsigned int  THREAD_RETURN;
00203         typedef int           THREAD_TYPE;
00204         #define WOLFSSL_THREAD
00205     #elif defined(WOLFSSL_TIRTOS)
00206         typedef void          THREAD_RETURN;
00207         typedef Task_Handle   THREAD_TYPE;
00208         #define WOLFSSL_THREAD
00209     #else
00210         typedef unsigned int  THREAD_RETURN;
00211         typedef intptr_t      THREAD_TYPE;
00212         #define WOLFSSL_THREAD __stdcall
00213     #endif
00214 #endif
00215 
00216 
00217 #ifdef TEST_IPV6
00218     typedef struct sockaddr_in6 SOCKADDR_IN_T;
00219     #define AF_INET_V    AF_INET6
00220 #else
00221     typedef struct sockaddr_in  SOCKADDR_IN_T;
00222     #define AF_INET_V    AF_INET
00223 #endif
00224 
00225 
00226 #define SERVER_DEFAULT_VERSION 3
00227 #define SERVER_DTLS_DEFAULT_VERSION (-2)
00228 #define SERVER_INVALID_VERSION (-99)
00229 #define CLIENT_DEFAULT_VERSION 3
00230 #define CLIENT_DTLS_DEFAULT_VERSION (-2)
00231 #define CLIENT_INVALID_VERSION (-99)
00232 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
00233     #define DEFAULT_MIN_DHKEY_BITS 2048
00234 #else
00235     #define DEFAULT_MIN_DHKEY_BITS 1024
00236 #endif
00237 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
00238     #define DEFAULT_MIN_RSAKEY_BITS 2048
00239 #else
00240     #define DEFAULT_MIN_RSAKEY_BITS 1024
00241 #endif
00242 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
00243     #define DEFAULT_MIN_ECCKEY_BITS 256
00244 #else
00245     #define DEFAULT_MIN_ECCKEY_BITS 224
00246 #endif
00247 
00248 /* all certs relative to wolfSSL home directory now */
00249 #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
00250 #define caCertFile     "certs/ca-cert.pem"
00251 #define eccCertFile    "certs/server-ecc.pem"
00252 #define eccKeyFile     "certs/ecc-key.pem"
00253 #define svrCertFile    "certs/server-cert.pem"
00254 #define svrKeyFile     "certs/server-key.pem"
00255 #define cliCertFile    "certs/client-cert.pem"
00256 #define cliKeyFile     "certs/client-key.pem"
00257 #define ntruCertFile   "certs/ntru-cert.pem"
00258 #define ntruKeyFile    "certs/ntru-key.raw"
00259 #define dhParamFile    "certs/dh2048.pem"
00260 #define cliEccKeyFile  "certs/ecc-client-key.pem"
00261 #define cliEccCertFile "certs/client-ecc-cert.pem"
00262 #define crlPemDir      "certs/crl"
00263 #ifdef HAVE_WNR
00264     /* Whitewood netRandom default config file */
00265     #define wnrConfig  "wnr-example.conf"
00266 #endif
00267 #else
00268 #define caCertFile     "./certs/ca-cert.pem"
00269 #define eccCertFile    "./certs/server-ecc.pem"
00270 #define eccKeyFile     "./certs/ecc-key.pem"
00271 #define svrCertFile    "./certs/server-cert.pem"
00272 #define svrKeyFile     "./certs/server-key.pem"
00273 #define cliCertFile    "./certs/client-cert.pem"
00274 #define cliKeyFile     "./certs/client-key.pem"
00275 #define ntruCertFile   "./certs/ntru-cert.pem"
00276 #define ntruKeyFile    "./certs/ntru-key.raw"
00277 #define dhParamFile    "./certs/dh2048.pem"
00278 #define cliEccKeyFile  "./certs/ecc-client-key.pem"
00279 #define cliEccCertFile "./certs/client-ecc-cert.pem"
00280 #define crlPemDir      "./certs/crl"
00281 #ifdef HAVE_WNR
00282     /* Whitewood netRandom default config file */
00283     #define wnrConfig  "./wnr-example.conf"
00284 #endif
00285 #endif
00286 
00287 typedef struct tcp_ready {
00288     word16 ready;              /* predicate */
00289     word16 port;
00290     char*  srfName;     /* server ready file name */
00291 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00292     pthread_mutex_t mutex;
00293     pthread_cond_t  cond;
00294 #endif
00295 } tcp_ready;
00296 
00297 
00298 static INLINE void InitTcpReady(tcp_ready* ready)
00299 {
00300     ready->ready = 0;
00301     ready->port = 0;
00302     ready->srfName = NULL;
00303 #ifdef SINGLE_THREADED
00304 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
00305     pthread_mutex_init(&ready->mutex, 0);
00306     pthread_cond_init(&ready->cond, 0);
00307 #endif
00308 }
00309 
00310 
00311 static INLINE void FreeTcpReady(tcp_ready* ready)
00312 {
00313 #ifdef SINGLE_THREADED
00314     (void)ready;
00315 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
00316     pthread_mutex_destroy(&ready->mutex);
00317     pthread_cond_destroy(&ready->cond);
00318 #else
00319     (void)ready;
00320 #endif
00321 }
00322 
00323 typedef WOLFSSL_METHOD* (*method_provider)(void);
00324 typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
00325 typedef void (*ssl_callback)(WOLFSSL* ssl);
00326 
00327 typedef struct callback_functions {
00328     method_provider method;
00329     ctx_callback ctx_ready;
00330     ssl_callback ssl_ready;
00331     ssl_callback on_result;
00332 } callback_functions;
00333 
00334 typedef struct func_args {
00335     int    argc;
00336     char** argv;
00337     int    return_code;
00338     tcp_ready* signal;
00339     callback_functions *callbacks;
00340 } func_args;
00341 
00342 
00343 
00344 
00345 void wait_tcp_ready(func_args*);
00346 
00347 typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
00348 
00349 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
00350 void join_thread(THREAD_TYPE);
00351 
00352 /* wolfSSL */
00353 #ifndef TEST_IPV6
00354     static const char* const wolfSSLIP   = "127.0.0.1";
00355 #else
00356     static const char* const wolfSSLIP   = "::1";
00357 #endif
00358 static const word16      wolfSSLPort = 11111;
00359 
00360 
00361 #if defined(__GNUC__)
00362     #define WC_NORETURN __attribute__((noreturn))
00363 #else
00364     #define WC_NORETURN
00365 #endif
00366 
00367 static INLINE WC_NORETURN void err_sys(const char* msg)
00368 {
00369     printf("wolfSSL error: %s\n", msg);
00370 
00371 #if !defined(__GNUC__)
00372     /* scan-build (which pretends to be gnuc) can get confused and think the
00373      * msg pointer can be null even when hardcoded and then it won't exit,
00374      * making null pointer checks above the err_sys() call useless.
00375      * We could just always exit() but some compilers will complain about no
00376      * possible return, with gcc we know the attribute to handle that with
00377      * WC_NORETURN. */
00378     if (msg)
00379 #endif
00380     {
00381         exit(EXIT_FAILURE);
00382     }
00383 }
00384 
00385 
00386 #define MY_EX_USAGE 2
00387 
00388 extern int   myoptind;
00389 extern char* myoptarg;
00390 
00391 static INLINE int mygetopt(int argc, char** argv, const char* optstring)
00392 {
00393     static char* next = NULL;
00394 
00395     char  c;
00396     char* cp;
00397 
00398     if (myoptind == 0)
00399         next = NULL;   /* we're starting new/over */
00400 
00401     if (next == NULL || *next == '\0') {
00402         if (myoptind == 0)
00403             myoptind++;
00404 
00405         if (myoptind >= argc || argv[myoptind][0] != '-' ||
00406                                 argv[myoptind][1] == '\0') {
00407             myoptarg = NULL;
00408             if (myoptind < argc)
00409                 myoptarg = argv[myoptind];
00410 
00411             return -1;
00412         }
00413 
00414         if (strcmp(argv[myoptind], "--") == 0) {
00415             myoptind++;
00416             myoptarg = NULL;
00417 
00418             if (myoptind < argc)
00419                 myoptarg = argv[myoptind];
00420 
00421             return -1;
00422         }
00423 
00424         next = argv[myoptind];
00425         next++;                  /* skip - */
00426         myoptind++;
00427     }
00428 
00429     c  = *next++;
00430     /* The C++ strchr can return a different value */
00431     cp = (char*)strchr(optstring, c);
00432 
00433     if (cp == NULL || c == ':')
00434         return '?';
00435 
00436     cp++;
00437 
00438     if (*cp == ':') {
00439         if (*next != '\0') {
00440             myoptarg = next;
00441             next     = NULL;
00442         }
00443         else if (myoptind < argc) {
00444             myoptarg = argv[myoptind];
00445             myoptind++;
00446         }
00447         else
00448             return '?';
00449     }
00450 
00451     return c;
00452 }
00453 
00454 
00455 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
00456 
00457 static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
00458 {
00459     (void)rw;
00460     (void)userdata;
00461     strncpy(passwd, "yassl123", sz);
00462     return 8;
00463 }
00464 
00465 #endif
00466 
00467 
00468 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
00469 
00470 static INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
00471 {
00472     char* altName;
00473     char* issuer;
00474     char* subject;
00475     byte  serial[32];
00476     int   ret;
00477     int   sz = sizeof(serial);
00478 
00479     if (x509 == NULL) {
00480         printf("%s No Cert\n", hdr);
00481         return;
00482     }
00483 
00484     issuer  = wolfSSL_X509_NAME_oneline(
00485                                       wolfSSL_X509_get_issuer_name(x509), 0, 0);
00486     subject = wolfSSL_X509_NAME_oneline(
00487                                      wolfSSL_X509_get_subject_name(x509), 0, 0);
00488 
00489     printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject);
00490 
00491     while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
00492         printf(" altname = %s\n", altName);
00493 
00494     ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
00495     if (ret == SSL_SUCCESS) {
00496         int  i;
00497         int  strLen;
00498         char serialMsg[80];
00499 
00500         /* testsuite has multiple threads writing to stdout, get output
00501            message ready to write once */
00502         strLen = sprintf(serialMsg, " serial number");
00503         for (i = 0; i < sz; i++)
00504             sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
00505         printf("%s\n", serialMsg);
00506     }
00507 
00508     XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
00509     XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
00510 }
00511 
00512 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
00513 
00514 
00515 static INLINE void showPeer(WOLFSSL* ssl)
00516 {
00517 
00518     WOLFSSL_CIPHER* cipher;
00519 #ifdef HAVE_ECC
00520     const char *name;
00521 #endif
00522 #ifndef NO_DH
00523     int bits;
00524 #endif
00525 #ifdef KEEP_PEER_CERT
00526     WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
00527     if (peer)
00528         ShowX509(peer, "peer's cert info:");
00529     else
00530         printf("peer has no cert!\n");
00531     wolfSSL_FreeX509(peer);
00532 #endif
00533 #if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT)
00534     ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
00535     printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
00536 #endif /* SHOW_CERTS */
00537     printf("SSL version is %s\n", wolfSSL_get_version(ssl));
00538 
00539     cipher = wolfSSL_get_current_cipher(ssl);
00540 #ifdef HAVE_QSH
00541     printf("SSL cipher suite is %s%s\n", (wolfSSL_isQSH(ssl))? "QSH:": "",
00542             wolfSSL_CIPHER_get_name(cipher));
00543 #else
00544     printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher));
00545 #endif
00546 #ifdef HAVE_ECC
00547     if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
00548         printf("SSL curve name is %s\n", name);
00549 #endif
00550 #ifndef NO_DH
00551     if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
00552         printf("SSL DH size is %d bits\n", bits);
00553 #endif
00554     if (wolfSSL_session_reused(ssl))
00555         printf("SSL reused session\n");
00556 
00557 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
00558     {
00559         WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl);
00560         int                count = wolfSSL_get_chain_count(chain);
00561         int i;
00562 
00563         for (i = 0; i < count; i++) {
00564             int length;
00565             unsigned char buffer[3072];
00566             WOLFSSL_X509* chainX509;
00567 
00568             wolfSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length);
00569             buffer[length] = 0;
00570             printf("cert %d has length %d data = \n%s\n", i, length, buffer);
00571 
00572             chainX509 = wolfSSL_get_chain_X509(chain, i);
00573             if (chainX509)
00574                 ShowX509(chainX509, "session cert info:");
00575             else
00576                 printf("get_chain_X509 failed\n");
00577             wolfSSL_FreeX509(chainX509);
00578         }
00579     }
00580 #endif
00581   (void)ssl;
00582 }
00583 
00584 
00585 static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
00586                               word16 port, int udp, int sctp)
00587 {
00588     int useLookup = 0;
00589     (void)useLookup;
00590     (void)udp;
00591     (void)sctp;
00592 
00593     if (addr == NULL)
00594         err_sys("invalid argument to build_addr, addr is NULL");
00595 
00596     memset(addr, 0, sizeof(SOCKADDR_IN_T));
00597 
00598 #ifndef TEST_IPV6
00599     /* peer could be in human readable form */
00600     if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) {
00601         #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00602             int err;
00603             struct hostent* entry = gethostbyname(peer, &err);
00604         #elif defined(WOLFSSL_TIRTOS)
00605             struct hostent* entry = DNSGetHostByName(peer);
00606         #elif defined(WOLFSSL_VXWORKS)
00607             struct hostent* entry = (struct hostent*)hostGetByName((char*)peer);
00608         #else
00609             struct hostent* entry = gethostbyname(peer);
00610         #endif
00611 
00612         if (entry) {
00613             XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0],
00614                    entry->h_length);
00615             useLookup = 1;
00616         }
00617         else
00618             err_sys("no entry for host");
00619     }
00620 #endif
00621 
00622 
00623 #ifndef TEST_IPV6
00624     #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00625         addr->sin_family = PF_INET;
00626     #else
00627         addr->sin_family = AF_INET_V;
00628     #endif
00629     addr->sin_port = XHTONS(port);
00630     if (peer == INADDR_ANY)
00631         addr->sin_addr.s_addr = INADDR_ANY;
00632     else {
00633         if (!useLookup)
00634             addr->sin_addr.s_addr = inet_addr(peer);
00635     }
00636 #else
00637     addr->sin6_family = AF_INET_V;
00638     addr->sin6_port = XHTONS(port);
00639     if (peer == INADDR_ANY)
00640         addr->sin6_addr = in6addr_any;
00641     else {
00642         #ifdef HAVE_GETADDRINFO
00643             struct addrinfo  hints;
00644             struct addrinfo* answer = NULL;
00645             int    ret;
00646             char   strPort[80];
00647 
00648             memset(&hints, 0, sizeof(hints));
00649 
00650             hints.ai_family   = AF_INET_V;
00651             if (udp) {
00652                 hints.ai_socktype = SOCK_DGRAM;
00653                 hints.ai_protocol = IPPROTO_UDP;
00654             }
00655         #ifdef WOLFSSL_SCTP
00656             else if (sctp) {
00657                 hints.ai_socktype = SOCK_STREAM;
00658                 hints.ai_protocol = IPPROTO_SCTP;
00659             }
00660         #endif
00661             else {
00662                 hints.ai_socktype = SOCK_STREAM;
00663                 hints.ai_protocol = IPPROTO_TCP;
00664             }
00665 
00666             SNPRINTF(strPort, sizeof(strPort), "%d", port);
00667             strPort[79] = '\0';
00668 
00669             ret = getaddrinfo(peer, strPort, &hints, &answer);
00670             if (ret < 0 || answer == NULL)
00671                 err_sys("getaddrinfo failed");
00672 
00673             XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen);
00674             freeaddrinfo(answer);
00675         #else
00676             printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
00677             addr->sin6_addr = in6addr_loopback;
00678         #endif
00679     }
00680 #endif
00681 }
00682 
00683 
00684 static INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
00685 {
00686     (void)sctp;
00687 
00688     if (udp)
00689         *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
00690 #ifdef WOLFSSL_SCTP
00691     else if (sctp)
00692         *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
00693 #endif
00694     else
00695         *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
00696 
00697     if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
00698         err_sys("socket failed\n");
00699     }
00700 
00701 #ifndef USE_WINDOWS_API
00702 #ifdef SO_NOSIGPIPE
00703     {
00704         int       on = 1;
00705         socklen_t len = sizeof(on);
00706         int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
00707         if (res < 0)
00708             err_sys("setsockopt SO_NOSIGPIPE failed\n");
00709     }
00710 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
00711                                           defined(WOLFSSL_KEIL_TCP_NET)
00712     /* nothing to define */
00713 #else  /* no S_NOSIGPIPE */
00714     signal(SIGPIPE, SIG_IGN);
00715 #endif /* S_NOSIGPIPE */
00716 
00717 #if defined(TCP_NODELAY)
00718     if (!udp && !sctp)
00719     {
00720         int       on = 1;
00721         socklen_t len = sizeof(on);
00722         int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
00723         if (res < 0)
00724             err_sys("setsockopt TCP_NODELAY failed\n");
00725     }
00726 #endif
00727 #endif  /* USE_WINDOWS_API */
00728 }
00729 
00730 static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
00731                                int udp, int sctp, WOLFSSL* ssl)
00732 {
00733     SOCKADDR_IN_T addr;
00734     build_addr(&addr, ip, port, udp, sctp);
00735     if (udp) {
00736         wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
00737     }
00738     tcp_socket(sockfd, udp, sctp);
00739 
00740     if (!udp) {
00741         if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00742             err_sys("tcp connect failed");
00743     }
00744 }
00745 
00746 
00747 static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
00748 {
00749     if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
00750         err_sys("tcp connect failed");
00751 }
00752 
00753 
00754 enum {
00755     TEST_SELECT_FAIL,
00756     TEST_TIMEOUT,
00757     TEST_RECV_READY,
00758     TEST_ERROR_READY
00759 };
00760 
00761 
00762 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
00763                                  !defined(WOLFSSL_TIRTOS)
00764 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
00765 {
00766     fd_set recvfds, errfds;
00767     SOCKET_T nfds = socketfd + 1;
00768     struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
00769     int result;
00770 
00771     FD_ZERO(&recvfds);
00772     FD_SET(socketfd, &recvfds);
00773     FD_ZERO(&errfds);
00774     FD_SET(socketfd, &errfds);
00775 
00776     result = select(nfds, &recvfds, NULL, &errfds, &timeout);
00777 
00778     if (result == 0)
00779         return TEST_TIMEOUT;
00780     else if (result > 0) {
00781         if (FD_ISSET(socketfd, &recvfds))
00782             return TEST_RECV_READY;
00783         else if(FD_ISSET(socketfd, &errfds))
00784             return TEST_ERROR_READY;
00785     }
00786 
00787     return TEST_SELECT_FAIL;
00788 }
00789 #elif defined(WOLFSSL_TIRTOS)
00790 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
00791 {
00792     return TEST_RECV_READY;
00793 }
00794 #endif /* !WOLFSSL_MDK_ARM */
00795 
00796 
00797 static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
00798                               int udp, int sctp)
00799 {
00800     SOCKADDR_IN_T addr;
00801 
00802     /* don't use INADDR_ANY by default, firewall may block, make user switch
00803        on */
00804     build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp);
00805     tcp_socket(sockfd, udp, sctp);
00806 
00807 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
00808                               && !defined(WOLFSSL_KEIL_TCP_NET)
00809     {
00810         int       res, on  = 1;
00811         socklen_t len = sizeof(on);
00812         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00813         if (res < 0)
00814             err_sys("setsockopt SO_REUSEADDR failed\n");
00815     }
00816 #endif
00817 
00818     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00819         err_sys("tcp bind failed");
00820     if (!udp) {
00821         if (listen(*sockfd, 5) != 0)
00822             err_sys("tcp listen failed");
00823     }
00824     #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS)
00825         if (*port == 0) {
00826             socklen_t len = sizeof(addr);
00827             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00828                 #ifndef TEST_IPV6
00829                     *port = XNTOHS(addr.sin_port);
00830                 #else
00831                     *port = XNTOHS(addr.sin6_port);
00832                 #endif
00833             }
00834         }
00835     #endif
00836 }
00837 
00838 
00839 #if 0
00840 static INLINE int udp_read_connect(SOCKET_T sockfd)
00841 {
00842     SOCKADDR_IN_T cliaddr;
00843     byte          b[1500];
00844     int           n;
00845     socklen_t     len = sizeof(cliaddr);
00846 
00847     n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
00848                       (struct sockaddr*)&cliaddr, &len);
00849     if (n > 0) {
00850         if (connect(sockfd, (const struct sockaddr*)&cliaddr,
00851                     sizeof(cliaddr)) != 0)
00852             err_sys("udp connect failed");
00853     }
00854     else
00855         err_sys("recvfrom failed");
00856 
00857     return sockfd;
00858 }
00859 #endif
00860 
00861 static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00862                               int useAnyAddr, word16 port, func_args* args)
00863 {
00864     SOCKADDR_IN_T addr;
00865 
00866     (void)args;
00867     build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0);
00868     tcp_socket(sockfd, 1, 0);
00869 
00870 
00871 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
00872                               && !defined(WOLFSSL_KEIL_TCP_NET)
00873     {
00874         int       res, on  = 1;
00875         socklen_t len = sizeof(on);
00876         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00877         if (res < 0)
00878             err_sys("setsockopt SO_REUSEADDR failed\n");
00879     }
00880 #endif
00881 
00882     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00883         err_sys("tcp bind failed");
00884 
00885     #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
00886         if (port == 0) {
00887             socklen_t len = sizeof(addr);
00888             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00889                 #ifndef TEST_IPV6
00890                     port = XNTOHS(addr.sin_port);
00891                 #else
00892                     port = XNTOHS(addr.sin6_port);
00893                 #endif
00894             }
00895         }
00896     #endif
00897 
00898 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00899     /* signal ready to accept data */
00900     {
00901     tcp_ready* ready = args->signal;
00902     pthread_mutex_lock(&ready->mutex);
00903     ready->ready = 1;
00904     ready->port = port;
00905     pthread_cond_signal(&ready->cond);
00906     pthread_mutex_unlock(&ready->mutex);
00907     }
00908 #elif defined (WOLFSSL_TIRTOS)
00909     /* Need mutex? */
00910     tcp_ready* ready = args->signal;
00911     ready->ready = 1;
00912     ready->port = port;
00913 #endif
00914 
00915     *clientfd = *sockfd;
00916 }
00917 
00918 static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00919                               func_args* args, word16 port, int useAnyAddr,
00920                               int udp, int sctp, int ready_file, int do_listen)
00921 {
00922     SOCKADDR_IN_T client;
00923     socklen_t client_len = sizeof(client);
00924     tcp_ready* ready = NULL;
00925 
00926     (void) ready; /* Account for case when "ready" is not used */
00927 
00928     if (udp) {
00929         udp_accept(sockfd, clientfd, useAnyAddr, port, args);
00930         return;
00931     }
00932 
00933     if(do_listen) {
00934         tcp_listen(sockfd, &port, useAnyAddr, udp, sctp);
00935 
00936     #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00937         /* signal ready to tcp_accept */
00938         if (args)
00939             ready = args->signal;
00940         if (ready) {
00941             pthread_mutex_lock(&ready->mutex);
00942             ready->ready = 1;
00943             ready->port = port;
00944             pthread_cond_signal(&ready->cond);
00945             pthread_mutex_unlock(&ready->mutex);
00946         }
00947     #elif defined (WOLFSSL_TIRTOS)
00948         /* Need mutex? */
00949         if (args)
00950             ready = args->signal;
00951         if (ready) {
00952             ready->ready = 1;
00953             ready->port = port;
00954         }
00955     #endif
00956 
00957         if (ready_file) {
00958         #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
00959             FILE* srf = NULL;
00960             if (args)
00961                 ready = args->signal;
00962 
00963             if (ready) {
00964                 srf = fopen(ready->srfName, "w");
00965 
00966                 if (srf) {
00967                     /* let's write port sever is listening on to ready file
00968                        external monitor can then do ephemeral ports by passing
00969                        -p 0 to server on supported platforms with -R ready_file
00970                        client can then wait for existence of ready_file and see
00971                        which port the server is listening on. */
00972                     fprintf(srf, "%d\n", (int)port);
00973                     fclose(srf);
00974                 }
00975             }
00976         #endif
00977         }
00978     }
00979 
00980     *clientfd = accept(*sockfd, (struct sockaddr*)&client,
00981                       (ACCEPT_THIRD_T)&client_len);
00982     if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
00983         err_sys("tcp accept failed");
00984     }
00985 }
00986 
00987 
00988 static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
00989 {
00990     #ifdef USE_WINDOWS_API
00991         unsigned long blocking = 1;
00992         int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
00993         if (ret == SOCKET_ERROR)
00994             err_sys("ioctlsocket failed");
00995     #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
00996         || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS)
00997          /* non blocking not supported, for now */
00998     #else
00999         int flags = fcntl(*sockfd, F_GETFL, 0);
01000         if (flags < 0)
01001             err_sys("fcntl get failed");
01002         flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
01003         if (flags < 0)
01004             err_sys("fcntl set failed");
01005     #endif
01006 }
01007 
01008 
01009 #ifndef NO_PSK
01010 
01011 /* identity is OpenSSL testing default for openssl s_client, keep same */
01012 static const char* kIdentityStr = "Client_identity";
01013 
01014 static INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
01015         char* identity, unsigned int id_max_len, unsigned char* key,
01016         unsigned int key_max_len)
01017 {
01018     (void)ssl;
01019     (void)hint;
01020     (void)key_max_len;
01021 
01022     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
01023     strncpy(identity, kIdentityStr, id_max_len);
01024 
01025     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
01026        unsigned binary */
01027     key[0] = 26;
01028     key[1] = 43;
01029     key[2] = 60;
01030     key[3] = 77;
01031 
01032     return 4;   /* length of key in octets or 0 for error */
01033 }
01034 
01035 
01036 static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
01037         unsigned char* key, unsigned int key_max_len)
01038 {
01039     (void)ssl;
01040     (void)key_max_len;
01041 
01042     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
01043     if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0)
01044         return 0;
01045 
01046     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
01047        unsigned binary */
01048     key[0] = 26;
01049     key[1] = 43;
01050     key[2] = 60;
01051     key[3] = 77;
01052 
01053     return 4;   /* length of key in octets or 0 for error */
01054 }
01055 
01056 #endif /* NO_PSK */
01057 
01058 
01059 #if defined(WOLFSSL_USER_CURRTIME)
01060     extern   double current_time(int reset);
01061 
01062 #elif defined(USE_WINDOWS_API)
01063 
01064     #define WIN32_LEAN_AND_MEAN
01065     #include <windows.h>
01066 
01067     static INLINE double current_time(int reset)
01068     {
01069         static int init = 0;
01070         static LARGE_INTEGER freq;
01071 
01072         LARGE_INTEGER count;
01073 
01074         if (!init) {
01075             QueryPerformanceFrequency(&freq);
01076             init = 1;
01077         }
01078 
01079         QueryPerformanceCounter(&count);
01080 
01081         (void)reset;
01082         return (double)count.QuadPart / freq.QuadPart;
01083     }
01084 
01085 #elif defined(WOLFSSL_TIRTOS)
01086     extern double current_time();
01087 #else
01088 
01089 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET)
01090     #include <sys/time.h>
01091 
01092     static INLINE double current_time(int reset)
01093     {
01094         struct timeval tv;
01095         gettimeofday(&tv, 0);
01096         (void)reset;
01097 
01098         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
01099     }
01100 #else
01101     extern double current_time(int reset);
01102 #endif
01103 #endif /* USE_WINDOWS_API */
01104 
01105 
01106 #if !defined(NO_CERTS)
01107     #if !defined(NO_FILESYSTEM) || \
01108         (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST))
01109 
01110     /* reads file size, allocates buffer, reads into buffer, returns buffer */
01111     static INLINE int load_file(const char* fname, byte** buf, size_t* bufLen)
01112     {
01113         int ret;
01114         long int fileSz;
01115         FILE* file;
01116 
01117         if (fname == NULL || buf == NULL || bufLen == NULL)
01118             return BAD_FUNC_ARG;
01119 
01120         /* set defaults */
01121         *buf = NULL;
01122         *bufLen = 0;
01123 
01124         /* open file (read-only binary) */
01125         file = fopen(fname, "rb");
01126         if (!file) {
01127             printf("Error loading %s\n", fname);
01128             return BAD_PATH_ERROR;
01129         }
01130 
01131         fseek(file, 0, SEEK_END);
01132         fileSz = (int)ftell(file);
01133         rewind(file);
01134         if (fileSz  > 0) {
01135             *bufLen = (size_t)fileSz;
01136             *buf = (byte*)malloc(*bufLen);
01137             if (*buf == NULL) {
01138                 ret = MEMORY_E;
01139                 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen);
01140             }
01141             else {
01142                 size_t readLen = fread(*buf, *bufLen, 1, file);
01143 
01144                 /* check response code */
01145                 ret = (readLen > 0) ? 0 : -1;
01146             }
01147         }
01148         else {
01149             ret = BUFFER_E;
01150         }
01151         fclose(file);
01152 
01153         return ret;
01154     }
01155 
01156     enum {
01157         WOLFSSL_CA   = 1,
01158         WOLFSSL_CERT = 2,
01159         WOLFSSL_KEY  = 3,
01160         WOLFSSL_CERT_CHAIN = 4,
01161     };
01162 
01163     static INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
01164     {
01165         int format = SSL_FILETYPE_PEM;
01166         byte* buff = NULL;
01167         size_t sz = 0;
01168 
01169         if (load_file(fname, &buff, &sz) != 0) {
01170             err_sys("can't open file for buffer load "
01171                     "Please run from wolfSSL home directory if not");
01172         }
01173 
01174         /* determine format */
01175         if (strstr(fname, ".der"))
01176             format = SSL_FILETYPE_ASN1;
01177 
01178         if (type == WOLFSSL_CA) {
01179             if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
01180                                               != SSL_SUCCESS)
01181                 err_sys("can't load buffer ca file");
01182         }
01183         else if (type == WOLFSSL_CERT) {
01184             if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz,
01185                         format) != SSL_SUCCESS)
01186                 err_sys("can't load buffer cert file");
01187         }
01188         else if (type == WOLFSSL_KEY) {
01189             if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz,
01190                         format) != SSL_SUCCESS)
01191                 err_sys("can't load buffer key file");
01192         }
01193         else if (type == WOLFSSL_CERT_CHAIN) {
01194             if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff,
01195                     (long)sz, format) != SSL_SUCCESS)
01196                 err_sys("can't load cert chain buffer");
01197         }
01198 
01199         if (buff)
01200             free(buff);
01201     }
01202     #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */
01203 #endif /* !NO_CERTS */
01204 
01205 #ifdef VERIFY_CALLBACK
01206 
01207 static INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
01208 {
01209     (void)preverify;
01210     char buffer[WOLFSSL_MAX_ERROR_SZ];
01211 
01212 #ifdef OPENSSL_EXTRA
01213     WOLFSSL_X509* peer;
01214 #endif
01215 
01216     printf("In verification callback, error = %d, %s\n", store->error,
01217                                  wolfSSL_ERR_error_string(store->error, buffer));
01218 #ifdef OPENSSL_EXTRA
01219     peer = store->current_cert;
01220     if (peer) {
01221         char* issuer  = wolfSSL_X509_NAME_oneline(
01222                                        wolfSSL_X509_get_issuer_name(peer), 0, 0);
01223         char* subject = wolfSSL_X509_NAME_oneline(
01224                                       wolfSSL_X509_get_subject_name(peer), 0, 0);
01225         printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer,
01226                                                                   subject);
01227         XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
01228         XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
01229     }
01230     else
01231         printf("\tPeer has no cert!\n");
01232 #else
01233     printf("\tPeer certs: %d\n", store->totalCerts);
01234     #ifdef VERIFY_CALLBACK_SHOW_PEER_CERTS
01235     {   int i;
01236         for (i=0; i<store->totalCerts; i++) {
01237             WOLFSSL_BUFFER_INFO* cert = &store->certs[i];
01238             printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length);
01239         }
01240     }
01241     #endif
01242 #endif
01243 
01244     printf("\tSubject's domain name is %s\n", store->domain);
01245 
01246     printf("\tAllowing to continue anyway (shouldn't do this, EVER!!!)\n");
01247     return 1;
01248 }
01249 
01250 #endif /* VERIFY_CALLBACK */
01251 
01252 
01253 static INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store)
01254 {
01255     char buffer[WOLFSSL_MAX_ERROR_SZ];
01256     (void)preverify;
01257 
01258     printf("In verification callback, error = %d, %s\n", store->error,
01259                                  wolfSSL_ERR_error_string(store->error, buffer));
01260     printf("Subject's domain name is %s\n", store->domain);
01261 
01262     if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
01263         printf("Overriding cert date error as example for bad clock testing\n");
01264         return 1;
01265     }
01266     printf("Cert error is not date error, not overriding\n");
01267 
01268     return 0;
01269 }
01270 
01271 
01272 #ifdef HAVE_CRL
01273 
01274 static INLINE void CRL_CallBack(const char* url)
01275 {
01276     printf("CRL callback url = %s\n", url);
01277 }
01278 
01279 #endif
01280 
01281 #ifndef NO_DH
01282 static INLINE void SetDH(WOLFSSL* ssl)
01283 {
01284     /* dh1024 p */
01285     static unsigned char p[] =
01286     {
01287         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
01288         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
01289         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
01290         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
01291         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
01292         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
01293         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
01294         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
01295         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
01296         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
01297         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
01298     };
01299 
01300     /* dh1024 g */
01301     static unsigned char g[] =
01302     {
01303       0x02,
01304     };
01305 
01306     wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
01307 }
01308 
01309 static INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
01310 {
01311     /* dh1024 p */
01312     static unsigned char p[] =
01313     {
01314         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
01315         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
01316         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
01317         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
01318         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
01319         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
01320         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
01321         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
01322         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
01323         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
01324         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
01325     };
01326 
01327     /* dh1024 g */
01328     static unsigned char g[] =
01329     {
01330       0x02,
01331     };
01332 
01333     wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
01334 }
01335 #endif /* NO_DH */
01336 
01337 #ifndef NO_CERTS
01338 
01339 static INLINE void CaCb(unsigned char* der, int sz, int type)
01340 {
01341     (void)der;
01342     printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
01343 }
01344 
01345 #endif /* !NO_CERTS */
01346 
01347 
01348 /* Wolf Root Directory Helper */
01349 /* KEIL-RL File System does not support relative directory */
01350 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS)
01351     /* Maximum depth to search for WolfSSL root */
01352     #define MAX_WOLF_ROOT_DEPTH 5
01353 
01354     static INLINE int ChangeToWolfRoot(void)
01355     {
01356         #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
01357             int depth, res;
01358             FILE* file;
01359             for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
01360                 file = fopen(ntruKeyFile, "rb");
01361                 if (file != NULL) {
01362                     fclose(file);
01363                     return depth;
01364                 }
01365             #ifdef USE_WINDOWS_API
01366                 res = SetCurrentDirectoryA("..\\");
01367             #else
01368                 res = chdir("../");
01369             #endif
01370                 if (res < 0) {
01371                     printf("chdir to ../ failed!\n");
01372                     break;
01373                 }
01374             }
01375 
01376             err_sys("wolf root not found");
01377             return -1;
01378         #else
01379             return 0;
01380         #endif
01381     }
01382 #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */
01383 
01384 #ifdef HAVE_STACK_SIZE
01385 
01386 typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
01387 
01388 
01389 static INLINE int StackSizeCheck(func_args* args, thread_func tf)
01390 {
01391     int            ret, i, used;
01392     void*          status;
01393     unsigned char* myStack = NULL;
01394     int            stackSize = 1024*128;
01395     pthread_attr_t myAttr;
01396     pthread_t      threadId;
01397 
01398 #ifdef PTHREAD_STACK_MIN
01399     if (stackSize < PTHREAD_STACK_MIN)
01400         stackSize = PTHREAD_STACK_MIN;
01401 #endif
01402 
01403     ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
01404     if (ret != 0 || myStack == NULL)
01405         err_sys("posix_memalign failed\n");
01406 
01407     XMEMSET(myStack, 0x01, stackSize);
01408 
01409     ret = pthread_attr_init(&myAttr);
01410     if (ret != 0)
01411         err_sys("attr_init failed");
01412 
01413     ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
01414     if (ret != 0)
01415         err_sys("attr_setstackaddr failed");
01416 
01417     ret = pthread_create(&threadId, &myAttr, tf, args);
01418     if (ret != 0) {
01419         perror("pthread_create failed");
01420         exit(EXIT_FAILURE);
01421     }
01422 
01423     ret = pthread_join(threadId, &status);
01424     if (ret != 0)
01425         err_sys("pthread_join failed");
01426 
01427     for (i = 0; i < stackSize; i++) {
01428         if (myStack[i] != 0x01) {
01429             break;
01430         }
01431     }
01432 
01433     free(myStack);
01434 
01435     used = stackSize - i;
01436     printf("stack used = %d\n", used);
01437 
01438     return (int)((size_t)status);
01439 }
01440 
01441 
01442 #endif /* HAVE_STACK_SIZE */
01443 
01444 
01445 #ifdef STACK_TRAP
01446 
01447 /* good settings
01448    --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
01449 
01450 */
01451 
01452 #ifdef HAVE_STACK_SIZE
01453     /* client only for now, setrlimit will fail if pthread_create() called */
01454     /* STACK_SIZE does pthread_create() on client */
01455     #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
01456 #endif /* HAVE_STACK_SIZE */
01457 
01458 static INLINE void StackTrap(void)
01459 {
01460     struct rlimit  rl;
01461     if (getrlimit(RLIMIT_STACK, &rl) != 0)
01462         err_sys("getrlimit failed");
01463     printf("rlim_cur = %llu\n", rl.rlim_cur);
01464     rl.rlim_cur = 1024*21;  /* adjust trap size here */
01465     if (setrlimit(RLIMIT_STACK, &rl) != 0) {
01466         perror("setrlimit");
01467         err_sys("setrlimit failed");
01468     }
01469 }
01470 
01471 #else /* STACK_TRAP */
01472 
01473 static INLINE void StackTrap(void)
01474 {
01475 }
01476 
01477 #endif /* STACK_TRAP */
01478 
01479 
01480 #ifdef ATOMIC_USER
01481 
01482 /* Atomic Encrypt Context example */
01483 typedef struct AtomicEncCtx {
01484     int  keySetup;           /* have we done key setup yet */
01485     Aes  aes;                /* for aes example */
01486 } AtomicEncCtx;
01487 
01488 
01489 /* Atomic Decrypt Context example */
01490 typedef struct AtomicDecCtx {
01491     int  keySetup;           /* have we done key setup yet */
01492     Aes  aes;                /* for aes example */
01493 } AtomicDecCtx;
01494 
01495 
01496 static INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut,
01497        const unsigned char* macIn, unsigned int macInSz, int macContent,
01498        int macVerify, unsigned char* encOut, const unsigned char* encIn,
01499        unsigned int encSz, void* ctx)
01500 {
01501     int  ret;
01502     Hmac hmac;
01503     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
01504     AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
01505     const char* tlsStr = "TLS";
01506 
01507     /* example supports (d)tls aes */
01508     if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
01509         printf("myMacEncryptCb not using AES\n");
01510         return -1;
01511     }
01512 
01513     if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
01514         printf("myMacEncryptCb not using (D)TLS\n");
01515         return -1;
01516     }
01517 
01518     /* hmac, not needed if aead mode */
01519     wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
01520 
01521     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
01522                wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
01523     if (ret != 0)
01524         return ret;
01525     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
01526     if (ret != 0)
01527         return ret;
01528     ret = wc_HmacUpdate(&hmac, macIn, macInSz);
01529     if (ret != 0)
01530         return ret;
01531     ret = wc_HmacFinal(&hmac, macOut);
01532     if (ret != 0)
01533         return ret;
01534 
01535 
01536     /* encrypt setup on first time */
01537     if (encCtx->keySetup == 0) {
01538         int   keyLen = wolfSSL_GetKeySize(ssl);
01539         const byte* key;
01540         const byte* iv;
01541 
01542         if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
01543             key = wolfSSL_GetClientWriteKey(ssl);
01544             iv  = wolfSSL_GetClientWriteIV(ssl);
01545         }
01546         else {
01547             key = wolfSSL_GetServerWriteKey(ssl);
01548             iv  = wolfSSL_GetServerWriteIV(ssl);
01549         }
01550 
01551         ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
01552         if (ret != 0) {
01553             printf("AesSetKey failed in myMacEncryptCb\n");
01554             return ret;
01555         }
01556         encCtx->keySetup = 1;
01557     }
01558 
01559     /* encrypt */
01560     return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
01561 }
01562 
01563 
01564 static INLINE int myDecryptVerifyCb(WOLFSSL* ssl,
01565        unsigned char* decOut, const unsigned char* decIn,
01566        unsigned int decSz, int macContent, int macVerify,
01567        unsigned int* padSz, void* ctx)
01568 {
01569     AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
01570     int ret      = 0;
01571     int macInSz  = 0;
01572     int ivExtra  = 0;
01573     int digestSz = wolfSSL_GetHmacSize(ssl);
01574     unsigned int pad     = 0;
01575     unsigned int padByte = 0;
01576     Hmac hmac;
01577     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
01578     byte verify[MAX_DIGEST_SIZE];
01579     const char* tlsStr = "TLS";
01580 
01581     /* example supports (d)tls aes */
01582     if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
01583         printf("myMacEncryptCb not using AES\n");
01584         return -1;
01585     }
01586 
01587     if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
01588         printf("myMacEncryptCb not using (D)TLS\n");
01589         return -1;
01590     }
01591 
01592     /*decrypt */
01593     if (decCtx->keySetup == 0) {
01594         int   keyLen = wolfSSL_GetKeySize(ssl);
01595         const byte* key;
01596         const byte* iv;
01597 
01598         /* decrypt is from other side (peer) */
01599         if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
01600             key = wolfSSL_GetClientWriteKey(ssl);
01601             iv  = wolfSSL_GetClientWriteIV(ssl);
01602         }
01603         else {
01604             key = wolfSSL_GetServerWriteKey(ssl);
01605             iv  = wolfSSL_GetServerWriteIV(ssl);
01606         }
01607 
01608         ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
01609         if (ret != 0) {
01610             printf("AesSetKey failed in myDecryptVerifyCb\n");
01611             return ret;
01612         }
01613         decCtx->keySetup = 1;
01614     }
01615 
01616     /* decrypt */
01617     ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
01618     if (ret != 0)
01619         return ret;
01620 
01621     if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
01622         *padSz = wolfSSL_GetAeadMacSize(ssl);
01623         return 0; /* hmac, not needed if aead mode */
01624     }
01625 
01626     if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
01627         pad     = *(decOut + decSz - 1);
01628         padByte = 1;
01629         if (wolfSSL_IsTLSv1_1(ssl))
01630             ivExtra = wolfSSL_GetCipherBlockSize(ssl);
01631     }
01632 
01633     *padSz  = wolfSSL_GetHmacSize(ssl) + pad + padByte;
01634     macInSz = decSz - ivExtra - digestSz - pad - padByte;
01635 
01636     wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
01637 
01638     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
01639                wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
01640     if (ret != 0)
01641         return ret;
01642     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
01643     if (ret != 0)
01644         return ret;
01645     ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
01646     if (ret != 0)
01647         return ret;
01648     ret = wc_HmacFinal(&hmac, verify);
01649     if (ret != 0)
01650         return ret;
01651 
01652     if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte,
01653                digestSz) != 0) {
01654         printf("myDecryptVerify verify failed\n");
01655         return -1;
01656     }
01657 
01658     return ret;
01659 }
01660 
01661 
01662 static INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
01663 {
01664     AtomicEncCtx* encCtx;
01665     AtomicDecCtx* decCtx;
01666 
01667     encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
01668     if (encCtx == NULL)
01669         err_sys("AtomicEncCtx malloc failed");
01670     memset(encCtx, 0, sizeof(AtomicEncCtx));
01671 
01672     decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
01673     if (decCtx == NULL) {
01674         free(encCtx);
01675         err_sys("AtomicDecCtx malloc failed");
01676     }
01677     memset(decCtx, 0, sizeof(AtomicDecCtx));
01678 
01679     wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
01680     wolfSSL_SetMacEncryptCtx(ssl, encCtx);
01681 
01682     wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
01683     wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
01684 }
01685 
01686 
01687 static INLINE void FreeAtomicUser(WOLFSSL* ssl)
01688 {
01689     AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
01690     AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
01691 
01692     free(decCtx);
01693     free(encCtx);
01694 }
01695 
01696 #endif /* ATOMIC_USER */
01697 
01698 #ifdef WOLFSSL_STATIC_MEMORY
01699 static INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats)
01700 {
01701     word16 i;
01702 
01703     if (stats == NULL) {
01704         return 0;
01705     }
01706 
01707     /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */
01708     fprintf(stderr, "Total mallocs   = %d\n", stats->totalAlloc);
01709     fprintf(stderr, "Total frees     = %d\n", stats->totalFr);
01710     fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc);
01711     fprintf(stderr, "Available IO    = %d\n", stats->avaIO);
01712     fprintf(stderr, "Max con. handshakes  = %d\n", stats->maxHa);
01713     fprintf(stderr, "Max con. IO          = %d\n", stats->maxIO);
01714     fprintf(stderr, "State of memory blocks: size   : available \n");
01715     for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
01716        fprintf(stderr, "                      : %d\t : %d\n", stats->blockSz[i],
01717                                                             stats->avaBlock[i]);
01718     }
01719 
01720     return 1;
01721 }
01722 #endif /* WOLFSSL_STATIC_MEMORY */
01723 
01724 #ifdef HAVE_PK_CALLBACKS
01725 
01726 #ifdef HAVE_ECC
01727 
01728 static INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
01729         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
01730 {
01731     WC_RNG  rng;
01732     int     ret;
01733     word32  idx = 0;
01734     ecc_key myKey;
01735 
01736     (void)ssl;
01737     (void)ctx;
01738 
01739     ret = wc_InitRng(&rng);
01740     if (ret != 0)
01741         return ret;
01742 
01743     ret = wc_ecc_init(&myKey);
01744     if (ret == 0) {
01745         ret = wc_EccPrivateKeyDecode(key, &idx, &myKey, keySz);
01746         if (ret == 0)
01747             ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
01748         wc_ecc_free(&myKey);
01749     }
01750     wc_FreeRng(&rng);
01751 
01752     return ret;
01753 }
01754 
01755 
01756 static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
01757         const byte* hash, word32 hashSz, const byte* key, word32 keySz,
01758         int* result, void* ctx)
01759 {
01760     int     ret;
01761     ecc_key myKey;
01762 
01763     (void)ssl;
01764     (void)ctx;
01765 
01766     ret = wc_ecc_init(&myKey);
01767     if (ret == 0) {
01768         ret = wc_ecc_import_x963(key, keySz, &myKey);
01769         if (ret == 0)
01770             ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
01771         wc_ecc_free(&myKey);
01772     }
01773 
01774     return ret;
01775 }
01776 
01777 static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
01778         unsigned char* pubKeyDer, unsigned int* pubKeySz,
01779         unsigned char* out, unsigned int* outlen,
01780         int side, void* ctx)
01781 {
01782     int      ret;
01783     ecc_key* privKey = NULL;
01784     ecc_key* pubKey = NULL;
01785     ecc_key  tmpKey;
01786 
01787     (void)ssl;
01788     (void)ctx;
01789 
01790     ret = wc_ecc_init(&tmpKey);
01791     if (ret != 0) {
01792         return ret;
01793     }
01794 
01795     /* for client: create and export public key */
01796     if (side == WOLFSSL_CLIENT_END) {
01797         WC_RNG rng;
01798 
01799         privKey = &tmpKey;
01800         pubKey = otherKey;
01801 
01802         ret = wc_InitRng(&rng);
01803         if (ret == 0) {
01804             ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id);
01805             if (ret == 0)
01806                 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
01807             wc_FreeRng(&rng);
01808         }
01809     }
01810 
01811     /* for server: import public key */
01812     else if (side == WOLFSSL_SERVER_END) {
01813         privKey = otherKey;
01814         pubKey = &tmpKey;
01815 
01816         ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey,
01817             otherKey->dp->id);
01818     }
01819     else {
01820         ret = BAD_FUNC_ARG;
01821     }
01822 
01823     /* generate shared secret and return it */
01824     if (ret == 0) {
01825         ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
01826     }
01827 
01828     wc_ecc_free(&tmpKey);
01829 
01830     return ret;
01831 }
01832 
01833 #endif /* HAVE_ECC */
01834 
01835 #ifndef NO_RSA
01836 
01837 static INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
01838         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
01839 {
01840     WC_RNG  rng;
01841     int     ret;
01842     word32  idx = 0;
01843     RsaKey  myKey;
01844 
01845     (void)ssl;
01846     (void)ctx;
01847 
01848     ret = wc_InitRng(&rng);
01849     if (ret != 0)
01850         return ret;
01851 
01852     ret = wc_InitRsaKey(&myKey, NULL);
01853     if (ret == 0) {
01854         ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
01855         if (ret == 0)
01856             ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
01857         if (ret > 0) {  /* save and convert to 0 success */
01858             *outSz = ret;
01859             ret = 0;
01860         }
01861         wc_FreeRsaKey(&myKey);
01862     }
01863     wc_FreeRng(&rng);
01864 
01865     return ret;
01866 }
01867 
01868 
01869 static INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
01870         byte** out,
01871         const byte* key, word32 keySz,
01872         void* ctx)
01873 {
01874     int     ret;
01875     word32  idx = 0;
01876     RsaKey  myKey;
01877 
01878     (void)ssl;
01879     (void)ctx;
01880 
01881     ret = wc_InitRsaKey(&myKey, NULL);
01882     if (ret == 0) {
01883         ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
01884         if (ret == 0)
01885             ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
01886         wc_FreeRsaKey(&myKey);
01887     }
01888 
01889     return ret;
01890 }
01891 
01892 
01893 static INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
01894                            byte* out, word32* outSz, const byte* key,
01895                            word32 keySz, void* ctx)
01896 {
01897     int     ret;
01898     word32  idx = 0;
01899     RsaKey  myKey;
01900     WC_RNG  rng;
01901 
01902     (void)ssl;
01903     (void)ctx;
01904 
01905     ret = wc_InitRng(&rng);
01906     if (ret != 0)
01907         return ret;
01908 
01909     ret = wc_InitRsaKey(&myKey, NULL);
01910     if (ret == 0) {
01911         ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
01912         if (ret == 0) {
01913             ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
01914             if (ret > 0) {
01915                 *outSz = ret;
01916                 ret = 0;  /* reset to success */
01917             }
01918         }
01919         wc_FreeRsaKey(&myKey);
01920     }
01921     wc_FreeRng(&rng);
01922 
01923     return ret;
01924 }
01925 
01926 static INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
01927                            byte** out,
01928                            const byte* key, word32 keySz, void* ctx)
01929 {
01930     int     ret;
01931     word32  idx = 0;
01932     RsaKey  myKey;
01933 
01934     (void)ssl;
01935     (void)ctx;
01936 
01937     ret = wc_InitRsaKey(&myKey, NULL);
01938     if (ret == 0) {
01939         ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
01940         if (ret == 0) {
01941             #ifdef WC_RSA_BLINDING
01942                 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl));
01943                 if (ret != 0) {
01944                     wc_FreeRsaKey(&myKey);
01945                     return ret;
01946                 }
01947             #endif
01948             ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
01949         }
01950         wc_FreeRsaKey(&myKey);
01951     }
01952 
01953     return ret;
01954 }
01955 
01956 #endif /* NO_RSA */
01957 
01958 static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
01959 {
01960     (void)ctx;
01961     (void)ssl;
01962 
01963     #ifdef HAVE_ECC
01964         wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
01965         wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
01966         wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
01967     #endif /* HAVE_ECC */
01968     #ifndef NO_RSA
01969         wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
01970         wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
01971         wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
01972         wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
01973     #endif /* NO_RSA */
01974 }
01975 
01976 #endif /* HAVE_PK_CALLBACKS */
01977 
01978 
01979 
01980 
01981 
01982 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
01983                       || defined(_MSC_VER)
01984 
01985 /* HP/UX doesn't have strsep, needed by test/suites.c */
01986 static INLINE char* strsep(char **stringp, const char *delim)
01987 {
01988     char* start;
01989     char* end;
01990 
01991     start = *stringp;
01992     if (start == NULL)
01993         return NULL;
01994 
01995     if ((end = strpbrk(start, delim))) {
01996         *end++ = '\0';
01997         *stringp = end;
01998     } else {
01999         *stringp = NULL;
02000     }
02001 
02002     return start;
02003 }
02004 
02005 #endif /* __hpux__ and others */
02006 
02007 /* Create unique filename, len is length of tempfn name, assuming
02008    len does not include null terminating character,
02009    num is number of characters in tempfn name to randomize */
02010 static INLINE const char* mymktemp(char *tempfn, int len, int num)
02011 {
02012     int x, size;
02013     static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
02014                                    "abcdefghijklmnopqrstuvwxyz";
02015     WC_RNG rng;
02016     byte   out;
02017 
02018     if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
02019         printf("Bad input\n");
02020         return NULL;
02021     }
02022 
02023     size = len - 1;
02024 
02025     if (wc_InitRng(&rng) != 0) {
02026         printf("InitRng failed\n");
02027         return NULL;
02028     }
02029 
02030     for (x = size; x > size - num; x--) {
02031         if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
02032             printf("RNG_GenerateBlock failed\n");
02033             return NULL;
02034         }
02035         tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
02036     }
02037     tempfn[len] = '\0';
02038 
02039     wc_FreeRng(&rng);
02040 
02041     return tempfn;
02042 }
02043 
02044 
02045 
02046 #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
02047                                     defined(HAVE_POLY1305)
02048 
02049     #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
02050 
02051     typedef struct key_ctx {
02052         byte name[WOLFSSL_TICKET_NAME_SZ];        /* name for this context */
02053         byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */
02054     } key_ctx;
02055 
02056     static key_ctx myKey_ctx;
02057     static WC_RNG myKey_rng;
02058 
02059     static INLINE int TicketInit(void)
02060     {
02061         int ret = wc_InitRng(&myKey_rng);
02062         if (ret != 0) return ret;
02063 
02064         ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key));
02065         if (ret != 0) return ret;
02066 
02067         ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name));
02068         if (ret != 0) return ret;
02069 
02070         return 0;
02071     }
02072 
02073     static INLINE void TicketCleanup(void)
02074     {
02075         wc_FreeRng(&myKey_rng);
02076     }
02077 
02078     static INLINE int myTicketEncCb(WOLFSSL* ssl,
02079                              byte key_name[WOLFSSL_TICKET_NAME_SZ],
02080                              byte iv[WOLFSSL_TICKET_IV_SZ],
02081                              byte mac[WOLFSSL_TICKET_MAC_SZ],
02082                              int enc, byte* ticket, int inLen, int* outLen,
02083                              void* userCtx)
02084     {
02085         (void)ssl;
02086         (void)userCtx;
02087 
02088         int ret;
02089         word16 sLen = XHTONS(inLen);
02090         byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
02091         int  aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
02092         byte* tmp = aad;
02093 
02094         if (enc) {
02095             XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
02096 
02097             ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ);
02098             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
02099 
02100             /* build aad from key name, iv, and length */
02101             XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
02102             tmp += WOLFSSL_TICKET_NAME_SZ;
02103             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
02104             tmp += WOLFSSL_TICKET_IV_SZ;
02105             XMEMCPY(tmp, &sLen, 2);
02106 
02107             ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
02108                                               aad, aadSz,
02109                                               ticket, inLen,
02110                                               ticket,
02111                                               mac);
02112             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
02113             *outLen = inLen;  /* no padding in this mode */
02114         } else {
02115             /* decrypt */
02116 
02117             /* see if we know this key */
02118             if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
02119                 printf("client presented unknown ticket key name ");
02120                 return WOLFSSL_TICKET_RET_FATAL;
02121             }
02122 
02123             /* build aad from key name, iv, and length */
02124             XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
02125             tmp += WOLFSSL_TICKET_NAME_SZ;
02126             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
02127             tmp += WOLFSSL_TICKET_IV_SZ;
02128             XMEMCPY(tmp, &sLen, 2);
02129 
02130             ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
02131                                               aad, aadSz,
02132                                               ticket, inLen,
02133                                               mac,
02134                                               ticket);
02135             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
02136             *outLen = inLen;  /* no padding in this mode */
02137         }
02138 
02139         return WOLFSSL_TICKET_RET_OK;
02140     }
02141 
02142 #endif  /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */
02143 
02144 static INLINE word16 GetRandomPort(void)
02145 {
02146     word16 port = 0;
02147 
02148     /* Generate random port for testing */
02149     WC_RNG rng;
02150     if (wc_InitRng(&rng) == 0) {
02151         wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port));
02152         port |= 0xC000; /* Make sure its in the 49152 - 65535 range */
02153         wc_FreeRng(&rng);
02154     }
02155     return port;
02156 }
02157 
02158 #endif /* wolfSSL_TEST_H */
02159