wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   OS

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 #include <wolfssl/wolfcrypt/mem_track.h>
00014 #if defined(OPENSSL_EXTRA) && defined(SHOW_CERTS)
00015     #include <wolfssl/openssl/ssl.h> /* for domain component NID value */
00016 #endif
00017 
00018 #ifdef ATOMIC_USER
00019     #include <wolfssl/wolfcrypt/aes.h>
00020     #include <wolfssl/wolfcrypt/arc4.h>
00021     #include <wolfssl/wolfcrypt/hmac.h>
00022 #endif
00023 #ifdef HAVE_PK_CALLBACKS
00024     #include <wolfssl/wolfcrypt/asn.h>
00025     #ifndef NO_RSA
00026         #include <wolfssl/wolfcrypt/rsa.h>
00027     #endif
00028     #ifdef HAVE_ECC
00029         #include <wolfssl/wolfcrypt/ecc.h>
00030     #endif /* HAVE_ECC */
00031     #ifndef NO_DH
00032         #include <wolfssl/wolfcrypt/dh.h>
00033     #endif /* !NO_DH */
00034     #ifdef HAVE_ED25519
00035         #include <wolfssl/wolfcrypt/ed25519.h>
00036     #endif /* HAVE_ED25519 */
00037     #ifdef HAVE_CURVE25519
00038         #include <wolfssl/wolfcrypt/curve25519.h>
00039     #endif /* HAVE_ECC */
00040 #endif /*HAVE_PK_CALLBACKS */
00041 
00042 #ifdef USE_WINDOWS_API
00043     #include <winsock2.h>
00044     #include <process.h>
00045     #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
00046         #include <ws2tcpip.h>
00047         #include <wspiapi.h>
00048     #endif
00049     #define SOCKET_T SOCKET
00050     #define SNPRINTF _snprintf
00051 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00052     #include <string.h>
00053     #include "rl_net.h"
00054     #define SOCKET_T int
00055         typedef int socklen_t ;
00056         static unsigned long inet_addr(const char *cp)
00057     {
00058         unsigned int a[4] ; unsigned long ret ;
00059         sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
00060         ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
00061         return(ret) ;
00062     }
00063         #if defined(HAVE_KEIL_RTX)
00064         #define sleep(t) os_dly_wait(t/1000+1) ;
00065     #elif defined (WOLFSSL_CMSIS_RTOS)
00066         #define sleep(t)  osDelay(t/1000+1) ;
00067     #endif
00068 #elif defined(WOLFSSL_TIRTOS)
00069     #include <string.h>
00070     #include <netdb.h>
00071     #include <sys/types.h>
00072     #include <arpa/inet.h>
00073     #include <sys/socket.h>
00074     #include <ti/sysbios/knl/Task.h>
00075     struct hostent {
00076         char *h_name; /* official name of host */
00077         char **h_aliases; /* alias list */
00078         int h_addrtype; /* host address type */
00079         int h_length; /* length of address */
00080         char **h_addr_list; /* list of addresses from name server */
00081     };
00082     #define SOCKET_T int
00083 #elif defined(WOLFSSL_VXWORKS)
00084     #include <hostLib.h>
00085     #include <sockLib.h>
00086     #include <arpa/inet.h>
00087     #include <string.h>
00088     #include <selectLib.h>
00089     #include <sys/types.h>
00090     #include <netinet/in.h>
00091     #include <fcntl.h>
00092     #include <sys/time.h>
00093     #include <netdb.h>
00094     #include <pthread.h>
00095     #define SOCKET_T int
00096 #else
00097     #include <string.h>
00098     #include <sys/types.h>
00099 #ifndef WOLFSSL_LEANPSK
00100     #include <unistd.h>
00101     #include <netdb.h>
00102     #include <netinet/in.h>
00103     #include <netinet/tcp.h>
00104     #include <arpa/inet.h>
00105     #include <sys/ioctl.h>
00106     #include <sys/time.h>
00107     #include <sys/socket.h>
00108     #include <pthread.h>
00109     #include <fcntl.h>
00110     #ifdef TEST_IPV6
00111         #include <netdb.h>
00112     #endif
00113 #endif
00114     #define SOCKET_T int
00115     #ifndef SO_NOSIGPIPE
00116         #include <signal.h>  /* ignore SIGPIPE */
00117     #endif
00118     #define SNPRINTF snprintf
00119 #endif /* USE_WINDOWS_API */
00120 
00121 #ifdef WOLFSSL_ASYNC_CRYPT
00122     #include <wolfssl/wolfcrypt/async.h>
00123 #endif
00124 #ifdef HAVE_CAVIUM
00125     #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h>
00126 #endif
00127 #ifdef _MSC_VER
00128     /* disable conversion warning */
00129     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
00130     #pragma warning(disable:4244 4996)
00131 #endif
00132 
00133 /* Buffer for benchmark tests */
00134 #ifndef TEST_BUFFER_SIZE
00135 #define TEST_BUFFER_SIZE 16384
00136 #endif
00137 
00138 #ifndef WOLFSSL_HAVE_MIN
00139     #define WOLFSSL_HAVE_MIN
00140     static WC_INLINE word32 min(word32 a, word32 b)
00141     {
00142         return a > b ? b : a;
00143     }
00144 #endif /* WOLFSSL_HAVE_MIN */
00145 
00146 /* Socket Handling */
00147 #ifndef WOLFSSL_SOCKET_INVALID
00148 #ifdef USE_WINDOWS_API
00149     #define WOLFSSL_SOCKET_INVALID  ((SOCKET_T)INVALID_SOCKET)
00150 #elif defined(WOLFSSL_TIRTOS)
00151     #define WOLFSSL_SOCKET_INVALID  ((SOCKET_T)-1)
00152 #else
00153     #define WOLFSSL_SOCKET_INVALID  (SOCKET_T)(0)
00154 #endif
00155 #endif /* WOLFSSL_SOCKET_INVALID */
00156 
00157 #ifndef WOLFSSL_SOCKET_IS_INVALID
00158 #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS)
00159     #define WOLFSSL_SOCKET_IS_INVALID(s)  ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
00160 #else
00161     #define WOLFSSL_SOCKET_IS_INVALID(s)  ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID)
00162 #endif
00163 #endif /* WOLFSSL_SOCKET_IS_INVALID */
00164 
00165 #if defined(__MACH__) || defined(USE_WINDOWS_API)
00166     #ifndef _SOCKLEN_T
00167         typedef int socklen_t;
00168     #endif
00169 #endif
00170 
00171 
00172 /* HPUX doesn't use socklent_t for third parameter to accept, unless
00173    _XOPEN_SOURCE_EXTENDED is defined */
00174 #if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\
00175  && !defined(WOLFSSL_ROWLEY_ARM)  && !defined(WOLFSSL_KEIL_TCP_NET)
00176     typedef socklen_t* ACCEPT_THIRD_T;
00177 #else
00178     #if defined _XOPEN_SOURCE_EXTENDED
00179         typedef socklen_t* ACCEPT_THIRD_T;
00180     #else
00181         typedef int*       ACCEPT_THIRD_T;
00182     #endif
00183 #endif
00184 
00185 
00186 
00187 #ifdef SINGLE_THREADED
00188     typedef unsigned int  THREAD_RETURN;
00189     typedef void*         THREAD_TYPE;
00190     #define WOLFSSL_THREAD
00191 #else
00192     #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00193         typedef void*         THREAD_RETURN;
00194         typedef pthread_t     THREAD_TYPE;
00195         #define WOLFSSL_THREAD
00196         #define INFINITE -1
00197         #define WAIT_OBJECT_0 0L
00198     #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
00199         typedef unsigned int  THREAD_RETURN;
00200         typedef int           THREAD_TYPE;
00201         #define WOLFSSL_THREAD
00202     #elif defined(WOLFSSL_TIRTOS)
00203         typedef void          THREAD_RETURN;
00204         typedef Task_Handle   THREAD_TYPE;
00205         #define WOLFSSL_THREAD
00206     #else
00207         typedef unsigned int  THREAD_RETURN;
00208         typedef intptr_t      THREAD_TYPE;
00209         #define WOLFSSL_THREAD __stdcall
00210     #endif
00211 #endif
00212 
00213 
00214 #ifdef TEST_IPV6
00215     typedef struct sockaddr_in6 SOCKADDR_IN_T;
00216     #define AF_INET_V    AF_INET6
00217 #else
00218     typedef struct sockaddr_in  SOCKADDR_IN_T;
00219     #define AF_INET_V    AF_INET
00220 #endif
00221 
00222 
00223 #ifndef WOLFSSL_NO_TLS12
00224 #define SERVER_DEFAULT_VERSION 3
00225 #else
00226 #define SERVER_DEFAULT_VERSION 4
00227 #endif
00228 #define SERVER_DTLS_DEFAULT_VERSION (-2)
00229 #define SERVER_INVALID_VERSION (-99)
00230 #define SERVER_DOWNGRADE_VERSION (-98)
00231 #ifndef WOLFSSL_NO_TLS12
00232 #define CLIENT_DEFAULT_VERSION 3
00233 #else
00234 #define CLIENT_DEFAULT_VERSION 4
00235 #endif
00236 #define CLIENT_DTLS_DEFAULT_VERSION (-2)
00237 #define CLIENT_INVALID_VERSION (-99)
00238 #define CLIENT_DOWNGRADE_VERSION (-98)
00239 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
00240     #define DEFAULT_MIN_DHKEY_BITS 2048
00241     #define DEFAULT_MAX_DHKEY_BITS 3072
00242 #else
00243     #define DEFAULT_MIN_DHKEY_BITS 1024
00244     #define DEFAULT_MAX_DHKEY_BITS 2048
00245 #endif
00246 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
00247     #define DEFAULT_MIN_RSAKEY_BITS 2048
00248 #else
00249     #define DEFAULT_MIN_RSAKEY_BITS 1024
00250 #endif
00251 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
00252     #define DEFAULT_MIN_ECCKEY_BITS 256
00253 #else
00254     #define DEFAULT_MIN_ECCKEY_BITS 224
00255 #endif
00256 
00257 /* all certs relative to wolfSSL home directory now */
00258 #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
00259 #define caCertFile     "certs/ca-cert.pem"
00260 #define eccCertFile    "certs/server-ecc.pem"
00261 #define eccKeyFile     "certs/ecc-key.pem"
00262 #define eccRsaCertFile "certs/server-ecc-rsa.pem"
00263 #define svrCertFile    "certs/server-cert.pem"
00264 #define svrKeyFile     "certs/server-key.pem"
00265 #define cliCertFile    "certs/client-cert.pem"
00266 #define cliCertDerFile "certs/client-cert.der"
00267 #define cliKeyFile     "certs/client-key.pem"
00268 #define ntruCertFile   "certs/ntru-cert.pem"
00269 #define ntruKeyFile    "certs/ntru-key.raw"
00270 #define dhParamFile    "certs/dh2048.pem"
00271 #define cliEccKeyFile  "certs/ecc-client-key.pem"
00272 #define cliEccCertFile "certs/client-ecc-cert.pem"
00273 #define caEccCertFile  "certs/ca-ecc-cert/pem"
00274 #define crlPemDir      "certs/crl"
00275 #define edCertFile     "certs/ed25519/server-ed25519-cert.pem"
00276 #define edKeyFile      "certs/ed25519/server-ed25519-priv.pem"
00277 #define cliEdCertFile  "certs/ed25519/client-ed25519.pem"
00278 #define cliEdKeyFile   "certs/ed25519/client-ed25519-priv.pem"
00279 #define caEdCertFile   "certs/ed25519/ca-ed25519.pem"
00280 #ifdef HAVE_WNR
00281     /* Whitewood netRandom default config file */
00282     #define wnrConfig  "wnr-example.conf"
00283 #endif
00284 #else
00285 #define caCertFile     "./certs/ca-cert.pem"
00286 #define eccCertFile    "./certs/server-ecc.pem"
00287 #define eccKeyFile     "./certs/ecc-key.pem"
00288 #define eccRsaCertFile "./certs/server-ecc-rsa.pem"
00289 #define svrCertFile    "./certs/server-cert.pem"
00290 #define svrKeyFile     "./certs/server-key.pem"
00291 #define cliCertFile    "./certs/client-cert.pem"
00292 #define cliCertDerFile "./certs/client-cert.der"
00293 #define cliKeyFile     "./certs/client-key.pem"
00294 #define ntruCertFile   "./certs/ntru-cert.pem"
00295 #define ntruKeyFile    "./certs/ntru-key.raw"
00296 #define dhParamFile    "./certs/dh2048.pem"
00297 #define cliEccKeyFile  "./certs/ecc-client-key.pem"
00298 #define cliEccCertFile "./certs/client-ecc-cert.pem"
00299 #define caEccCertFile  "./certs/ca-ecc-cert.pem"
00300 #define crlPemDir      "./certs/crl"
00301 #define edCertFile     "./certs/ed25519/server-ed25519.pem"
00302 #define edKeyFile      "./certs/ed25519/server-ed25519-priv.pem"
00303 #define cliEdCertFile  "./certs/ed25519/client-ed25519.pem"
00304 #define cliEdKeyFile   "./certs/ed25519/client-ed25519-priv.pem"
00305 #define caEdCertFile   "./certs/ed25519/root-ed25519.pem"
00306 #ifdef HAVE_WNR
00307     /* Whitewood netRandom default config file */
00308     #define wnrConfig  "./wnr-example.conf"
00309 #endif
00310 #endif
00311 
00312 typedef struct tcp_ready {
00313     word16 ready;              /* predicate */
00314     word16 port;
00315     char*  srfName;     /* server ready file name */
00316 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00317     pthread_mutex_t mutex;
00318     pthread_cond_t  cond;
00319 #endif
00320 } tcp_ready;
00321 
00322 
00323 static WC_INLINE void InitTcpReady(tcp_ready* ready)
00324 {
00325     ready->ready = 0;
00326     ready->port = 0;
00327     ready->srfName = NULL;
00328 #ifdef SINGLE_THREADED
00329 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
00330     pthread_mutex_init(&ready->mutex, 0);
00331     pthread_cond_init(&ready->cond, 0);
00332 #endif
00333 }
00334 
00335 
00336 static WC_INLINE void FreeTcpReady(tcp_ready* ready)
00337 {
00338 #ifdef SINGLE_THREADED
00339     (void)ready;
00340 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
00341     pthread_mutex_destroy(&ready->mutex);
00342     pthread_cond_destroy(&ready->cond);
00343 #else
00344     (void)ready;
00345 #endif
00346 }
00347 
00348 typedef WOLFSSL_METHOD* (*method_provider)(void);
00349 typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
00350 typedef void (*ssl_callback)(WOLFSSL* ssl);
00351 
00352 typedef struct callback_functions {
00353     method_provider method;
00354     ctx_callback ctx_ready;
00355     ssl_callback ssl_ready;
00356     ssl_callback on_result;
00357 } callback_functions;
00358 
00359 typedef struct func_args {
00360     int    argc;
00361     char** argv;
00362     int    return_code;
00363     tcp_ready* signal;
00364     callback_functions *callbacks;
00365 } func_args;
00366 
00367 
00368 
00369 
00370 void wait_tcp_ready(func_args*);
00371 
00372 typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
00373 
00374 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
00375 void join_thread(THREAD_TYPE);
00376 
00377 /* wolfSSL */
00378 #ifndef TEST_IPV6
00379     static const char* const wolfSSLIP   = "127.0.0.1";
00380 #else
00381     static const char* const wolfSSLIP   = "::1";
00382 #endif
00383 static const word16      wolfSSLPort = 11111;
00384 
00385 
00386 static WC_INLINE WC_NORETURN void err_sys(const char* msg)
00387 {
00388     printf("wolfSSL error: %s\n", msg);
00389 
00390 #if !defined(__GNUC__)
00391     /* scan-build (which pretends to be gnuc) can get confused and think the
00392      * msg pointer can be null even when hardcoded and then it won't exit,
00393      * making null pointer checks above the err_sys() call useless.
00394      * We could just always exit() but some compilers will complain about no
00395      * possible return, with gcc we know the attribute to handle that with
00396      * WC_NORETURN. */
00397     if (msg)
00398 #endif
00399     {
00400         exit(EXIT_FAILURE);
00401     }
00402 }
00403 
00404 
00405 #define MY_EX_USAGE 2
00406 
00407 extern int   myoptind;
00408 extern char* myoptarg;
00409 
00410 static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
00411 {
00412     static char* next = NULL;
00413 
00414     char  c;
00415     char* cp;
00416 
00417     if (myoptind == 0)
00418         next = NULL;   /* we're starting new/over */
00419 
00420     if (next == NULL || *next == '\0') {
00421         if (myoptind == 0)
00422             myoptind++;
00423 
00424         if (myoptind >= argc || argv[myoptind][0] != '-' ||
00425                                 argv[myoptind][1] == '\0') {
00426             myoptarg = NULL;
00427             if (myoptind < argc)
00428                 myoptarg = argv[myoptind];
00429 
00430             return -1;
00431         }
00432 
00433         if (strcmp(argv[myoptind], "--") == 0) {
00434             myoptind++;
00435             myoptarg = NULL;
00436 
00437             if (myoptind < argc)
00438                 myoptarg = argv[myoptind];
00439 
00440             return -1;
00441         }
00442 
00443         next = argv[myoptind];
00444         next++;                  /* skip - */
00445         myoptind++;
00446     }
00447 
00448     c  = *next++;
00449     /* The C++ strchr can return a different value */
00450     cp = (char*)strchr(optstring, c);
00451 
00452     if (cp == NULL || c == ':')
00453         return '?';
00454 
00455     cp++;
00456 
00457     if (*cp == ':') {
00458         if (*next != '\0') {
00459             myoptarg = next;
00460             next     = NULL;
00461         }
00462         else if (myoptind < argc) {
00463             myoptarg = argv[myoptind];
00464             myoptind++;
00465         }
00466         else
00467             return '?';
00468     }
00469 
00470     return c;
00471 }
00472 
00473 
00474 #ifdef WOLFSSL_ENCRYPTED_KEYS
00475 
00476 static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
00477 {
00478     (void)rw;
00479     (void)userdata;
00480     if (userdata != NULL) {
00481         strncpy(passwd, (char*)userdata, sz);
00482         return (int)XSTRLEN((char*)userdata);
00483     }
00484     else {
00485         strncpy(passwd, "yassl123", sz);
00486         return 8;
00487     }
00488 }
00489 
00490 #endif
00491 
00492 
00493 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
00494 
00495 static WC_INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
00496 {
00497     char* altName;
00498     char* issuer;
00499     char* subject;
00500     byte  serial[32];
00501     int   ret;
00502     int   sz = sizeof(serial);
00503 
00504     if (x509 == NULL) {
00505         printf("%s No Cert\n", hdr);
00506         return;
00507     }
00508 
00509     issuer  = wolfSSL_X509_NAME_oneline(
00510                                       wolfSSL_X509_get_issuer_name(x509), 0, 0);
00511     subject = wolfSSL_X509_NAME_oneline(
00512                                      wolfSSL_X509_get_subject_name(x509), 0, 0);
00513 
00514     printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject);
00515 
00516     while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
00517         printf(" altname = %s\n", altName);
00518 
00519     ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
00520     if (ret == WOLFSSL_SUCCESS) {
00521         int  i;
00522         int  strLen;
00523         char serialMsg[80];
00524 
00525         /* testsuite has multiple threads writing to stdout, get output
00526            message ready to write once */
00527         strLen = sprintf(serialMsg, " serial number");
00528         for (i = 0; i < sz; i++)
00529             sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
00530         printf("%s\n", serialMsg);
00531     }
00532 
00533     XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
00534     XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
00535 
00536 #if defined(OPENSSL_EXTRA) && defined(SHOW_CERTS)
00537     {
00538         WOLFSSL_BIO* bio;
00539         char buf[256]; /* should be size of ASN_NAME_MAX */
00540         int  textSz;
00541 
00542 
00543         /* print out domain component if certificate has it */
00544         textSz = wolfSSL_X509_NAME_get_text_by_NID(
00545                 wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
00546                 buf, sizeof(buf));
00547         if (textSz > 0) {
00548             printf("Domain Component = %s\n", buf);
00549         }
00550 
00551         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
00552         if (bio != NULL) {
00553             wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
00554             wolfSSL_X509_print(bio, x509);
00555             wolfSSL_BIO_free(bio);
00556         }
00557     }
00558 #endif
00559 }
00560 
00561 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
00562 
00563 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
00564 static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count,
00565     const char* hdr)
00566 {
00567     int i;
00568     int length;
00569     unsigned char buffer[3072];
00570     WOLFSSL_X509* chainX509;
00571 
00572     for (i = 0; i < count; i++) {
00573         wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length);
00574         buffer[length] = 0;
00575         printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer);
00576 
00577         chainX509 = wolfSSL_get_chain_X509(chain, i);
00578         if (chainX509)
00579             ShowX509(chainX509, hdr);
00580         else
00581             printf("get_chain_X509 failed\n");
00582         wolfSSL_FreeX509(chainX509);
00583     }
00584 }
00585 #endif
00586 
00587 static WC_INLINE void showPeer(WOLFSSL* ssl)
00588 {
00589     WOLFSSL_CIPHER* cipher;
00590 #ifdef HAVE_ECC
00591     const char *name;
00592 #endif
00593 #ifndef NO_DH
00594     int bits;
00595 #endif
00596 #ifdef KEEP_PEER_CERT
00597     WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
00598     if (peer)
00599         ShowX509(peer, "peer's cert info:");
00600     else
00601         printf("peer has no cert!\n");
00602     wolfSSL_FreeX509(peer);
00603 #endif
00604 #if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT)
00605     ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
00606     printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
00607 #endif /* SHOW_CERTS */
00608     printf("SSL version is %s\n", wolfSSL_get_version(ssl));
00609 
00610     cipher = wolfSSL_get_current_cipher(ssl);
00611 #ifdef HAVE_QSH
00612     printf("SSL cipher suite is %s%s\n", (wolfSSL_isQSH(ssl))? "QSH:": "",
00613             wolfSSL_CIPHER_get_name(cipher));
00614 #else
00615     printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher));
00616 #endif
00617 #ifdef HAVE_ECC
00618     if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
00619         printf("SSL curve name is %s\n", name);
00620 #endif
00621 #ifndef NO_DH
00622     if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
00623         printf("SSL DH size is %d bits\n", bits);
00624 #endif
00625     if (wolfSSL_session_reused(ssl))
00626         printf("SSL reused session\n");
00627 #ifdef WOLFSSL_ALT_CERT_CHAINS
00628     if (wolfSSL_is_peer_alt_cert_chain(ssl))
00629         printf("Alternate cert chain used\n");
00630 #endif
00631 
00632 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
00633     {
00634         WOLFSSL_X509_CHAIN* chain;
00635 
00636         chain = wolfSSL_get_peer_chain(ssl);
00637         ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert");
00638 
00639     #ifdef WOLFSSL_ALT_CERT_CHAINS
00640         if (wolfSSL_is_peer_alt_cert_chain(ssl)) {
00641             chain = wolfSSL_get_peer_alt_chain(ssl);
00642             ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert");
00643         }
00644     #endif
00645     }
00646 #endif /* SESSION_CERTS && SHOW_CERTS */
00647   (void)ssl;
00648 }
00649 
00650 
00651 static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
00652                               word16 port, int udp, int sctp)
00653 {
00654     int useLookup = 0;
00655     (void)useLookup;
00656     (void)udp;
00657     (void)sctp;
00658 
00659     if (addr == NULL)
00660         err_sys("invalid argument to build_addr, addr is NULL");
00661 
00662     XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T));
00663 
00664 #ifndef TEST_IPV6
00665     /* peer could be in human readable form */
00666     if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) {
00667         #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00668             int err;
00669             struct hostent* entry = gethostbyname(peer, &err);
00670         #elif defined(WOLFSSL_TIRTOS)
00671             struct hostent* entry = DNSGetHostByName(peer);
00672         #elif defined(WOLFSSL_VXWORKS)
00673             struct hostent* entry = (struct hostent*)hostGetByName((char*)peer);
00674         #else
00675             struct hostent* entry = gethostbyname(peer);
00676         #endif
00677 
00678         if (entry) {
00679             XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0],
00680                    entry->h_length);
00681             useLookup = 1;
00682         }
00683         else
00684             err_sys("no entry for host");
00685     }
00686 #endif
00687 
00688 
00689 #ifndef TEST_IPV6
00690     #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
00691         addr->sin_family = PF_INET;
00692     #else
00693         addr->sin_family = AF_INET_V;
00694     #endif
00695     addr->sin_port = XHTONS(port);
00696     if ((size_t)peer == INADDR_ANY)
00697         addr->sin_addr.s_addr = INADDR_ANY;
00698     else {
00699         if (!useLookup)
00700             addr->sin_addr.s_addr = inet_addr(peer);
00701     }
00702 #else
00703     addr->sin6_family = AF_INET_V;
00704     addr->sin6_port = XHTONS(port);
00705     if ((size_t)peer == INADDR_ANY) {
00706         addr->sin6_addr = in6addr_any;
00707     }
00708     else {
00709         #ifdef HAVE_GETADDRINFO
00710             struct addrinfo  hints;
00711             struct addrinfo* answer = NULL;
00712             int    ret;
00713             char   strPort[80];
00714 
00715             XMEMSET(&hints, 0, sizeof(hints));
00716 
00717             hints.ai_family   = AF_INET_V;
00718             if (udp) {
00719                 hints.ai_socktype = SOCK_DGRAM;
00720                 hints.ai_protocol = IPPROTO_UDP;
00721             }
00722         #ifdef WOLFSSL_SCTP
00723             else if (sctp) {
00724                 hints.ai_socktype = SOCK_STREAM;
00725                 hints.ai_protocol = IPPROTO_SCTP;
00726             }
00727         #endif
00728             else {
00729                 hints.ai_socktype = SOCK_STREAM;
00730                 hints.ai_protocol = IPPROTO_TCP;
00731             }
00732 
00733             SNPRINTF(strPort, sizeof(strPort), "%d", port);
00734             strPort[79] = '\0';
00735 
00736             ret = getaddrinfo(peer, strPort, &hints, &answer);
00737             if (ret < 0 || answer == NULL)
00738                 err_sys("getaddrinfo failed");
00739 
00740             XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen);
00741             freeaddrinfo(answer);
00742         #else
00743             printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
00744             addr->sin6_addr = in6addr_loopback;
00745         #endif
00746     }
00747 #endif
00748 }
00749 
00750 
00751 static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
00752 {
00753     (void)sctp;
00754 
00755     if (udp)
00756         *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
00757 #ifdef WOLFSSL_SCTP
00758     else if (sctp)
00759         *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
00760 #endif
00761     else
00762         *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
00763 
00764     if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
00765         err_sys("socket failed\n");
00766     }
00767 
00768 #ifndef USE_WINDOWS_API
00769 #ifdef SO_NOSIGPIPE
00770     {
00771         int       on = 1;
00772         socklen_t len = sizeof(on);
00773         int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
00774         if (res < 0)
00775             err_sys("setsockopt SO_NOSIGPIPE failed\n");
00776     }
00777 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
00778                                           defined(WOLFSSL_KEIL_TCP_NET)
00779     /* nothing to define */
00780 #else  /* no S_NOSIGPIPE */
00781     signal(SIGPIPE, SIG_IGN);
00782 #endif /* S_NOSIGPIPE */
00783 
00784 #if defined(TCP_NODELAY)
00785     if (!udp && !sctp)
00786     {
00787         int       on = 1;
00788         socklen_t len = sizeof(on);
00789         int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
00790         if (res < 0)
00791             err_sys("setsockopt TCP_NODELAY failed\n");
00792     }
00793 #endif
00794 #endif  /* USE_WINDOWS_API */
00795 }
00796 
00797 static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
00798                                int udp, int sctp, WOLFSSL* ssl)
00799 {
00800     SOCKADDR_IN_T addr;
00801     build_addr(&addr, ip, port, udp, sctp);
00802     if (udp) {
00803         wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
00804     }
00805     tcp_socket(sockfd, udp, sctp);
00806 
00807     if (!udp) {
00808         if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00809             err_sys("tcp connect failed");
00810     }
00811 }
00812 
00813 
00814 static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
00815 {
00816     if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
00817         err_sys("tcp connect failed");
00818 }
00819 
00820 
00821 enum {
00822     TEST_SELECT_FAIL,
00823     TEST_TIMEOUT,
00824     TEST_RECV_READY,
00825     TEST_ERROR_READY
00826 };
00827 
00828 
00829 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
00830                                  !defined(WOLFSSL_TIRTOS)
00831 static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
00832 {
00833     fd_set recvfds, errfds;
00834     SOCKET_T nfds = socketfd + 1;
00835 #if !defined(__INTEGRITY)
00836     struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0};
00837 #else
00838     struct timeval timeout;
00839 #endif
00840     int result;
00841 
00842     FD_ZERO(&recvfds);
00843     FD_SET(socketfd, &recvfds);
00844     FD_ZERO(&errfds);
00845     FD_SET(socketfd, &errfds);
00846 
00847 #if defined(__INTEGRITY)
00848     timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0;
00849 #endif
00850     result = select(nfds, &recvfds, NULL, &errfds, &timeout);
00851 
00852     if (result == 0)
00853         return TEST_TIMEOUT;
00854     else if (result > 0) {
00855         if (FD_ISSET(socketfd, &recvfds))
00856             return TEST_RECV_READY;
00857         else if(FD_ISSET(socketfd, &errfds))
00858             return TEST_ERROR_READY;
00859     }
00860 
00861     return TEST_SELECT_FAIL;
00862 }
00863 #elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET)
00864 static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
00865 {
00866     return TEST_RECV_READY;
00867 }
00868 #endif /* !WOLFSSL_MDK_ARM */
00869 
00870 
00871 static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
00872                               int udp, int sctp)
00873 {
00874     SOCKADDR_IN_T addr;
00875 
00876     /* don't use INADDR_ANY by default, firewall may block, make user switch
00877        on */
00878     build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp);
00879     tcp_socket(sockfd, udp, sctp);
00880 
00881 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
00882                               && !defined(WOLFSSL_KEIL_TCP_NET)
00883     {
00884         int       res, on  = 1;
00885         socklen_t len = sizeof(on);
00886         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00887         if (res < 0)
00888             err_sys("setsockopt SO_REUSEADDR failed\n");
00889     }
00890 #endif
00891 
00892     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00893         err_sys("tcp bind failed");
00894     if (!udp) {
00895         #ifdef WOLFSSL_KEIL_TCP_NET
00896             #define SOCK_LISTEN_MAX_QUEUE 1
00897         #else
00898             #define SOCK_LISTEN_MAX_QUEUE 5
00899         #endif
00900         if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0)
00901                 err_sys("tcp listen failed");
00902     }
00903     #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS)
00904         if (*port == 0) {
00905             socklen_t len = sizeof(addr);
00906             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00907                 #ifndef TEST_IPV6
00908                     *port = XNTOHS(addr.sin_port);
00909                 #else
00910                     *port = XNTOHS(addr.sin6_port);
00911                 #endif
00912             }
00913         }
00914     #endif
00915 }
00916 
00917 
00918 #if 0
00919 static WC_INLINE int udp_read_connect(SOCKET_T sockfd)
00920 {
00921     SOCKADDR_IN_T cliaddr;
00922     byte          b[1500];
00923     int           n;
00924     socklen_t     len = sizeof(cliaddr);
00925 
00926     n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
00927                       (struct sockaddr*)&cliaddr, &len);
00928     if (n > 0) {
00929         if (connect(sockfd, (const struct sockaddr*)&cliaddr,
00930                     sizeof(cliaddr)) != 0)
00931             err_sys("udp connect failed");
00932     }
00933     else
00934         err_sys("recvfrom failed");
00935 
00936     return sockfd;
00937 }
00938 #endif
00939 
00940 static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00941                               int useAnyAddr, word16 port, func_args* args)
00942 {
00943     SOCKADDR_IN_T addr;
00944 
00945     (void)args;
00946     build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0);
00947     tcp_socket(sockfd, 1, 0);
00948 
00949 
00950 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
00951                               && !defined(WOLFSSL_KEIL_TCP_NET)
00952     {
00953         int       res, on  = 1;
00954         socklen_t len = sizeof(on);
00955         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00956         if (res < 0)
00957             err_sys("setsockopt SO_REUSEADDR failed\n");
00958     }
00959 #endif
00960 
00961     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00962         err_sys("tcp bind failed");
00963 
00964     #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
00965         if (port == 0) {
00966             socklen_t len = sizeof(addr);
00967             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00968                 #ifndef TEST_IPV6
00969                     port = XNTOHS(addr.sin_port);
00970                 #else
00971                     port = XNTOHS(addr.sin6_port);
00972                 #endif
00973             }
00974         }
00975     #endif
00976 
00977 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00978     /* signal ready to accept data */
00979     {
00980     tcp_ready* ready = args->signal;
00981     pthread_mutex_lock(&ready->mutex);
00982     ready->ready = 1;
00983     ready->port = port;
00984     pthread_cond_signal(&ready->cond);
00985     pthread_mutex_unlock(&ready->mutex);
00986     }
00987 #elif defined (WOLFSSL_TIRTOS)
00988     /* Need mutex? */
00989     tcp_ready* ready = args->signal;
00990     ready->ready = 1;
00991     ready->port = port;
00992 #endif
00993 
00994     *clientfd = *sockfd;
00995 }
00996 
00997 static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00998                               func_args* args, word16 port, int useAnyAddr,
00999                               int udp, int sctp, int ready_file, int do_listen)
01000 {
01001     SOCKADDR_IN_T client;
01002     socklen_t client_len = sizeof(client);
01003     tcp_ready* ready = NULL;
01004 
01005     (void) ready; /* Account for case when "ready" is not used */
01006 
01007     if (udp) {
01008         udp_accept(sockfd, clientfd, useAnyAddr, port, args);
01009         return;
01010     }
01011 
01012     if(do_listen) {
01013         tcp_listen(sockfd, &port, useAnyAddr, udp, sctp);
01014 
01015     #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
01016         /* signal ready to tcp_accept */
01017         if (args)
01018             ready = args->signal;
01019         if (ready) {
01020             pthread_mutex_lock(&ready->mutex);
01021             ready->ready = 1;
01022             ready->port = port;
01023             pthread_cond_signal(&ready->cond);
01024             pthread_mutex_unlock(&ready->mutex);
01025         }
01026     #elif defined (WOLFSSL_TIRTOS)
01027         /* Need mutex? */
01028         if (args)
01029             ready = args->signal;
01030         if (ready) {
01031             ready->ready = 1;
01032             ready->port = port;
01033         }
01034     #endif
01035 
01036         if (ready_file) {
01037         #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
01038             FILE* srf = NULL;
01039             if (args)
01040                 ready = args->signal;
01041 
01042             if (ready) {
01043                 srf = fopen(ready->srfName, "w");
01044 
01045                 if (srf) {
01046                     /* let's write port sever is listening on to ready file
01047                        external monitor can then do ephemeral ports by passing
01048                        -p 0 to server on supported platforms with -R ready_file
01049                        client can then wait for existence of ready_file and see
01050                        which port the server is listening on. */
01051                     fprintf(srf, "%d\n", (int)port);
01052                     fclose(srf);
01053                 }
01054             }
01055         #endif
01056         }
01057     }
01058 
01059     *clientfd = accept(*sockfd, (struct sockaddr*)&client,
01060                       (ACCEPT_THIRD_T)&client_len);
01061     if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
01062         err_sys("tcp accept failed");
01063     }
01064 }
01065 
01066 
01067 static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
01068 {
01069     #ifdef USE_WINDOWS_API
01070         unsigned long blocking = 1;
01071         int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
01072         if (ret == SOCKET_ERROR)
01073             err_sys("ioctlsocket failed");
01074     #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
01075         || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS)
01076          /* non blocking not supported, for now */
01077     #else
01078         int flags = fcntl(*sockfd, F_GETFL, 0);
01079         if (flags < 0)
01080             err_sys("fcntl get failed");
01081         flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
01082         if (flags < 0)
01083             err_sys("fcntl set failed");
01084     #endif
01085 }
01086 
01087 
01088 #ifndef NO_PSK
01089 
01090 /* identity is OpenSSL testing default for openssl s_client, keep same */
01091 static const char* kIdentityStr = "Client_identity";
01092 
01093 static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
01094         char* identity, unsigned int id_max_len, unsigned char* key,
01095         unsigned int key_max_len)
01096 {
01097     (void)ssl;
01098     (void)hint;
01099     (void)key_max_len;
01100 
01101     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
01102     strncpy(identity, kIdentityStr, id_max_len);
01103 
01104     if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
01105         /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
01106            unsigned binary */
01107         key[0] = 0x1a;
01108         key[1] = 0x2b;
01109         key[2] = 0x3c;
01110         key[3] = 0x4d;
01111 
01112 
01113         return 4;   /* length of key in octets or 0 for error */
01114     }
01115     else {
01116         int i;
01117         int b = 0x01;
01118 
01119         for (i = 0; i < 32; i++, b += 0x22) {
01120             if (b >= 0x100)
01121                 b = 0x01;
01122             key[i] = b;
01123         }
01124 
01125         return 32;   /* length of key in octets or 0 for error */
01126     }
01127 }
01128 
01129 
01130 static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
01131         unsigned char* key, unsigned int key_max_len)
01132 {
01133     (void)ssl;
01134     (void)key_max_len;
01135 
01136     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
01137     if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0)
01138         return 0;
01139 
01140     if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
01141         /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
01142            unsigned binary */
01143         key[0] = 0x1a;
01144         key[1] = 0x2b;
01145         key[2] = 0x3c;
01146         key[3] = 0x4d;
01147 
01148 
01149         return 4;   /* length of key in octets or 0 for error */
01150     }
01151     else {
01152         int i;
01153         int b = 0x01;
01154 
01155         for (i = 0; i < 32; i++, b += 0x22) {
01156             if (b >= 0x100)
01157                 b = 0x01;
01158             key[i] = b;
01159         }
01160 
01161         return 32;   /* length of key in octets or 0 for error */
01162     }
01163 }
01164 
01165 #endif /* NO_PSK */
01166 
01167 
01168 #if defined(WOLFSSL_USER_CURRTIME)
01169     extern   double current_time(int reset);
01170 
01171 #elif defined(USE_WINDOWS_API)
01172 
01173     #define WIN32_LEAN_AND_MEAN
01174     #include <windows.h>
01175 
01176     static WC_INLINE double current_time(int reset)
01177     {
01178         static int init = 0;
01179         static LARGE_INTEGER freq;
01180 
01181         LARGE_INTEGER count;
01182 
01183         if (!init) {
01184             QueryPerformanceFrequency(&freq);
01185             init = 1;
01186         }
01187 
01188         QueryPerformanceCounter(&count);
01189 
01190         (void)reset;
01191         return (double)count.QuadPart / freq.QuadPart;
01192     }
01193 
01194 #elif defined(WOLFSSL_TIRTOS)
01195     extern double current_time();
01196 #else
01197 
01198 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS)
01199     #include <sys/time.h>
01200 
01201     static WC_INLINE double current_time(int reset)
01202     {
01203         struct timeval tv;
01204         gettimeofday(&tv, 0);
01205         (void)reset;
01206 
01207         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
01208     }
01209 #else
01210     extern double current_time(int reset);
01211 #endif
01212 #endif /* USE_WINDOWS_API */
01213 
01214 
01215 #if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP)
01216 static WC_INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz,
01217     unsigned char* request, int requestSz, unsigned char** response)
01218 {
01219 #ifdef TEST_NONBLOCK_CERTS
01220     static int ioCbCnt = 0;
01221 #endif
01222 
01223     (void)ioCtx;
01224     (void)url;
01225     (void)urlSz;
01226     (void)request;
01227     (void)requestSz;
01228     (void)response;
01229 
01230 #ifdef TEST_NONBLOCK_CERTS
01231     if (ioCbCnt) {
01232         ioCbCnt = 0;
01233         return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
01234     }
01235     else {
01236         ioCbCnt = 1;
01237         return WOLFSSL_CBIO_ERR_WANT_READ;
01238     }
01239 #else
01240     return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
01241 #endif
01242 }
01243 
01244 static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response)
01245 {
01246     (void)ioCtx;
01247     (void)response;
01248 }
01249 #endif
01250 
01251 #if !defined(NO_CERTS)
01252     #if !defined(NO_FILESYSTEM) || \
01253         (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST))
01254 
01255     /* reads file size, allocates buffer, reads into buffer, returns buffer */
01256     static WC_INLINE int load_file(const char* fname, byte** buf, size_t* bufLen)
01257     {
01258         int ret;
01259         long int fileSz;
01260         FILE* file;
01261 
01262         if (fname == NULL || buf == NULL || bufLen == NULL)
01263             return BAD_FUNC_ARG;
01264 
01265         /* set defaults */
01266         *buf = NULL;
01267         *bufLen = 0;
01268 
01269         /* open file (read-only binary) */
01270         file = fopen(fname, "rb");
01271         if (!file) {
01272             printf("Error loading %s\n", fname);
01273             return BAD_PATH_ERROR;
01274         }
01275 
01276         fseek(file, 0, SEEK_END);
01277         fileSz = (int)ftell(file);
01278         rewind(file);
01279         if (fileSz  > 0) {
01280             *bufLen = (size_t)fileSz;
01281             *buf = (byte*)malloc(*bufLen);
01282             if (*buf == NULL) {
01283                 ret = MEMORY_E;
01284                 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen);
01285             }
01286             else {
01287                 size_t readLen = fread(*buf, *bufLen, 1, file);
01288 
01289                 /* check response code */
01290                 ret = (readLen > 0) ? 0 : -1;
01291             }
01292         }
01293         else {
01294             ret = BUFFER_E;
01295         }
01296         fclose(file);
01297 
01298         return ret;
01299     }
01300 
01301     enum {
01302         WOLFSSL_CA   = 1,
01303         WOLFSSL_CERT = 2,
01304         WOLFSSL_KEY  = 3,
01305         WOLFSSL_CERT_CHAIN = 4,
01306     };
01307 
01308     static WC_INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
01309     {
01310         int format = WOLFSSL_FILETYPE_PEM;
01311         byte* buff = NULL;
01312         size_t sz = 0;
01313 
01314         if (load_file(fname, &buff, &sz) != 0) {
01315             err_sys("can't open file for buffer load "
01316                     "Please run from wolfSSL home directory if not");
01317         }
01318 
01319         /* determine format */
01320         if (strstr(fname, ".der"))
01321             format = WOLFSSL_FILETYPE_ASN1;
01322 
01323         if (type == WOLFSSL_CA) {
01324             if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
01325                                               != WOLFSSL_SUCCESS)
01326                 err_sys("can't load buffer ca file");
01327         }
01328         else if (type == WOLFSSL_CERT) {
01329             if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz,
01330                         format) != WOLFSSL_SUCCESS)
01331                 err_sys("can't load buffer cert file");
01332         }
01333         else if (type == WOLFSSL_KEY) {
01334             if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz,
01335                         format) != WOLFSSL_SUCCESS)
01336                 err_sys("can't load buffer key file");
01337         }
01338         else if (type == WOLFSSL_CERT_CHAIN) {
01339             if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff,
01340                     (long)sz, format) != WOLFSSL_SUCCESS)
01341                 err_sys("can't load cert chain buffer");
01342         }
01343 
01344         if (buff)
01345             free(buff);
01346     }
01347 
01348     #ifdef TEST_PK_PRIVKEY
01349     static WC_INLINE int load_key_file(const char* fname, byte** derBuf, word32* derLen)
01350     {
01351         int ret;
01352         byte* buf = NULL;
01353         size_t bufLen;
01354 
01355         ret = load_file(fname, &buf, &bufLen);
01356         if (ret != 0)
01357             return ret;
01358 
01359         *derBuf = (byte*)malloc(bufLen);
01360         if (*derBuf == NULL) {
01361             free(buf);
01362             return MEMORY_E;
01363         }
01364 
01365         ret = wc_KeyPemToDer(buf, (word32)bufLen, *derBuf, (word32)bufLen, NULL);
01366         if (ret < 0) {
01367             free(buf);
01368             free(*derBuf);
01369             return ret;
01370         }
01371         *derLen = ret;
01372         free(buf);
01373 
01374         return 0;
01375     }
01376     #endif /* TEST_PK_PRIVKEY */
01377 
01378     #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */
01379 #endif /* !NO_CERTS */
01380 
01381 static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
01382 {
01383     char buffer[WOLFSSL_MAX_ERROR_SZ];
01384 #ifdef OPENSSL_EXTRA
01385     WOLFSSL_X509* peer;
01386 #endif
01387     (void)preverify;
01388 
01389     printf("In verification callback, error = %d, %s\n", store->error,
01390                                  wolfSSL_ERR_error_string(store->error, buffer));
01391 #ifdef OPENSSL_EXTRA
01392     peer = store->current_cert;
01393     if (peer) {
01394         char* issuer  = wolfSSL_X509_NAME_oneline(
01395                                        wolfSSL_X509_get_issuer_name(peer), 0, 0);
01396         char* subject = wolfSSL_X509_NAME_oneline(
01397                                       wolfSSL_X509_get_subject_name(peer), 0, 0);
01398         printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer,
01399                                                                   subject);
01400         XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
01401         XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
01402     }
01403     else
01404         printf("\tPeer has no cert!\n");
01405 #else
01406     printf("\tPeer certs: %d\n", store->totalCerts);
01407     #ifdef SHOW_CERTS
01408     {   int i;
01409         for (i=0; i<store->totalCerts; i++) {
01410             WOLFSSL_BUFFER_INFO* cert = &store->certs[i];
01411             printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length);
01412         }
01413     }
01414     #endif
01415 #endif
01416 
01417     printf("\tSubject's domain name is %s\n", store->domain);
01418 
01419     printf("\tAllowing to continue anyway (shouldn't do this, EVER!!!)\n");
01420     return 1;
01421 }
01422 
01423 
01424 static WC_INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store)
01425 {
01426     char buffer[WOLFSSL_MAX_ERROR_SZ];
01427     (void)preverify;
01428 
01429     printf("In verification callback, error = %d, %s\n", store->error,
01430                                  wolfSSL_ERR_error_string(store->error, buffer));
01431     printf("Subject's domain name is %s\n", store->domain);
01432 
01433     if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
01434         printf("Overriding cert date error as example for bad clock testing\n");
01435         return 1;
01436     }
01437     printf("Cert error is not date error, not overriding\n");
01438 
01439     return 0;
01440 }
01441 
01442 
01443 #ifdef HAVE_EXT_CACHE
01444 
01445 static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, unsigned char* id,
01446     int id_len, int* copy)
01447 {
01448     (void)ssl;
01449     (void)id;
01450     (void)id_len;
01451     (void)copy;
01452 
01453     /* using internal cache, this is for testing only */
01454     return NULL;
01455 }
01456 
01457 static WC_INLINE int mySessNewCb(WOLFSSL* ssl, WOLFSSL_SESSION* session)
01458 {
01459     (void)ssl;
01460     (void)session;
01461 
01462     /* using internal cache, this is for testing only */
01463     return 0;
01464 }
01465 
01466 static WC_INLINE void mySessRemCb(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
01467 {
01468     (void)ctx;
01469     (void)session;
01470 
01471     /* using internal cache, this is for testing only */
01472 }
01473 
01474 #endif /* HAVE_EXT_CACHE */
01475 
01476 
01477 #ifdef HAVE_CRL
01478 
01479 static WC_INLINE void CRL_CallBack(const char* url)
01480 {
01481     printf("CRL callback url = %s\n", url);
01482 }
01483 
01484 #endif
01485 
01486 #ifndef NO_DH
01487 static WC_INLINE void SetDH(WOLFSSL* ssl)
01488 {
01489     /* dh1024 p */
01490     static const unsigned char p[] =
01491     {
01492         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
01493         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
01494         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
01495         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
01496         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
01497         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
01498         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
01499         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
01500         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
01501         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
01502         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
01503     };
01504 
01505     /* dh1024 g */
01506     static const unsigned char g[] =
01507     {
01508       0x02,
01509     };
01510 
01511     wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
01512 }
01513 
01514 static WC_INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
01515 {
01516     /* dh1024 p */
01517     static const unsigned char p[] =
01518     {
01519         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
01520         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
01521         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
01522         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
01523         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
01524         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
01525         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
01526         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
01527         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
01528         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
01529         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
01530     };
01531 
01532     /* dh1024 g */
01533     static const unsigned char g[] =
01534     {
01535       0x02,
01536     };
01537 
01538     wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
01539 }
01540 #endif /* NO_DH */
01541 
01542 #ifndef NO_CERTS
01543 
01544 static WC_INLINE void CaCb(unsigned char* der, int sz, int type)
01545 {
01546     (void)der;
01547     printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
01548 }
01549 
01550 #endif /* !NO_CERTS */
01551 
01552 
01553 /* Wolf Root Directory Helper */
01554 /* KEIL-RL File System does not support relative directory */
01555 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS)
01556     /* Maximum depth to search for WolfSSL root */
01557     #define MAX_WOLF_ROOT_DEPTH 5
01558 
01559     static WC_INLINE int ChangeToWolfRoot(void)
01560     {
01561         #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
01562             int depth, res;
01563             FILE* file;
01564             for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
01565                 file = fopen(ntruKeyFile, "rb");
01566                 if (file != NULL) {
01567                     fclose(file);
01568                     return depth;
01569                 }
01570             #ifdef USE_WINDOWS_API
01571                 res = SetCurrentDirectoryA("..\\");
01572             #else
01573                 res = chdir("../");
01574             #endif
01575                 if (res < 0) {
01576                     printf("chdir to ../ failed!\n");
01577                     break;
01578                 }
01579             }
01580 
01581             err_sys("wolf root not found");
01582             return -1;
01583         #else
01584             return 0;
01585         #endif
01586     }
01587 #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */
01588 
01589 #ifdef HAVE_STACK_SIZE
01590 
01591 typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
01592 #define STACK_CHECK_VAL 0x01
01593 
01594 static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
01595 {
01596     int            ret, i, used;
01597     void*          status;
01598     unsigned char* myStack = NULL;
01599     int            stackSize = 1024*128;
01600     pthread_attr_t myAttr;
01601     pthread_t      threadId;
01602 
01603 #ifdef PTHREAD_STACK_MIN
01604     if (stackSize < PTHREAD_STACK_MIN)
01605         stackSize = PTHREAD_STACK_MIN;
01606 #endif
01607 
01608     ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
01609     if (ret != 0 || myStack == NULL)
01610         err_sys("posix_memalign failed\n");
01611 
01612     XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
01613 
01614     ret = pthread_attr_init(&myAttr);
01615     if (ret != 0)
01616         err_sys("attr_init failed");
01617 
01618     ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
01619     if (ret != 0)
01620         err_sys("attr_setstackaddr failed");
01621 
01622     ret = pthread_create(&threadId, &myAttr, tf, args);
01623     if (ret != 0) {
01624         perror("pthread_create failed");
01625         exit(EXIT_FAILURE);
01626     }
01627 
01628     ret = pthread_join(threadId, &status);
01629     if (ret != 0)
01630         err_sys("pthread_join failed");
01631 
01632     for (i = 0; i < stackSize; i++) {
01633         if (myStack[i] != STACK_CHECK_VAL) {
01634             break;
01635         }
01636     }
01637 
01638     free(myStack);
01639 
01640     used = stackSize - i;
01641     printf("stack used = %d\n", used);
01642 
01643     return (int)((size_t)status);
01644 }
01645 
01646 
01647 #endif /* HAVE_STACK_SIZE */
01648 
01649 
01650 #ifdef STACK_TRAP
01651 
01652 /* good settings
01653    --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
01654 
01655 */
01656 
01657 #ifdef HAVE_STACK_SIZE
01658     /* client only for now, setrlimit will fail if pthread_create() called */
01659     /* STACK_SIZE does pthread_create() on client */
01660     #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
01661 #endif /* HAVE_STACK_SIZE */
01662 
01663 static WC_INLINE void StackTrap(void)
01664 {
01665     struct rlimit  rl;
01666     if (getrlimit(RLIMIT_STACK, &rl) != 0)
01667         err_sys("getrlimit failed");
01668     printf("rlim_cur = %llu\n", rl.rlim_cur);
01669     rl.rlim_cur = 1024*21;  /* adjust trap size here */
01670     if (setrlimit(RLIMIT_STACK, &rl) != 0) {
01671         perror("setrlimit");
01672         err_sys("setrlimit failed");
01673     }
01674 }
01675 
01676 #else /* STACK_TRAP */
01677 
01678 static WC_INLINE void StackTrap(void)
01679 {
01680 }
01681 
01682 #endif /* STACK_TRAP */
01683 
01684 
01685 #ifdef ATOMIC_USER
01686 
01687 /* Atomic Encrypt Context example */
01688 typedef struct AtomicEncCtx {
01689     int  keySetup;           /* have we done key setup yet */
01690     Aes  aes;                /* for aes example */
01691 } AtomicEncCtx;
01692 
01693 
01694 /* Atomic Decrypt Context example */
01695 typedef struct AtomicDecCtx {
01696     int  keySetup;           /* have we done key setup yet */
01697     Aes  aes;                /* for aes example */
01698 } AtomicDecCtx;
01699 
01700 
01701 static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut,
01702        const unsigned char* macIn, unsigned int macInSz, int macContent,
01703        int macVerify, unsigned char* encOut, const unsigned char* encIn,
01704        unsigned int encSz, void* ctx)
01705 {
01706     int  ret;
01707     Hmac hmac;
01708     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
01709     AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
01710     const char* tlsStr = "TLS";
01711 
01712     /* example supports (d)tls aes */
01713     if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
01714         printf("myMacEncryptCb not using AES\n");
01715         return -1;
01716     }
01717 
01718     if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
01719         printf("myMacEncryptCb not using (D)TLS\n");
01720         return -1;
01721     }
01722 
01723     /* hmac, not needed if aead mode */
01724     wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
01725 
01726     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
01727                wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
01728     if (ret != 0)
01729         return ret;
01730     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
01731     if (ret != 0)
01732         return ret;
01733     ret = wc_HmacUpdate(&hmac, macIn, macInSz);
01734     if (ret != 0)
01735         return ret;
01736     ret = wc_HmacFinal(&hmac, macOut);
01737     if (ret != 0)
01738         return ret;
01739 
01740 
01741     /* encrypt setup on first time */
01742     if (encCtx->keySetup == 0) {
01743         int   keyLen = wolfSSL_GetKeySize(ssl);
01744         const byte* key;
01745         const byte* iv;
01746 
01747         if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
01748             key = wolfSSL_GetClientWriteKey(ssl);
01749             iv  = wolfSSL_GetClientWriteIV(ssl);
01750         }
01751         else {
01752             key = wolfSSL_GetServerWriteKey(ssl);
01753             iv  = wolfSSL_GetServerWriteIV(ssl);
01754         }
01755 
01756         ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
01757         if (ret != 0) {
01758             printf("AesSetKey failed in myMacEncryptCb\n");
01759             return ret;
01760         }
01761         encCtx->keySetup = 1;
01762     }
01763 
01764     /* encrypt */
01765     return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
01766 }
01767 
01768 
01769 static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl,
01770        unsigned char* decOut, const unsigned char* decIn,
01771        unsigned int decSz, int macContent, int macVerify,
01772        unsigned int* padSz, void* ctx)
01773 {
01774     AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
01775     int ret      = 0;
01776     int macInSz  = 0;
01777     int ivExtra  = 0;
01778     int digestSz = wolfSSL_GetHmacSize(ssl);
01779     unsigned int pad     = 0;
01780     unsigned int padByte = 0;
01781     Hmac hmac;
01782     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
01783     byte verify[WC_MAX_DIGEST_SIZE];
01784     const char* tlsStr = "TLS";
01785 
01786     /* example supports (d)tls aes */
01787     if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
01788         printf("myMacEncryptCb not using AES\n");
01789         return -1;
01790     }
01791 
01792     if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
01793         printf("myMacEncryptCb not using (D)TLS\n");
01794         return -1;
01795     }
01796 
01797     /*decrypt */
01798     if (decCtx->keySetup == 0) {
01799         int   keyLen = wolfSSL_GetKeySize(ssl);
01800         const byte* key;
01801         const byte* iv;
01802 
01803         /* decrypt is from other side (peer) */
01804         if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
01805             key = wolfSSL_GetClientWriteKey(ssl);
01806             iv  = wolfSSL_GetClientWriteIV(ssl);
01807         }
01808         else {
01809             key = wolfSSL_GetServerWriteKey(ssl);
01810             iv  = wolfSSL_GetServerWriteIV(ssl);
01811         }
01812 
01813         ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
01814         if (ret != 0) {
01815             printf("AesSetKey failed in myDecryptVerifyCb\n");
01816             return ret;
01817         }
01818         decCtx->keySetup = 1;
01819     }
01820 
01821     /* decrypt */
01822     ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
01823     if (ret != 0)
01824         return ret;
01825 
01826     if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
01827         *padSz = wolfSSL_GetAeadMacSize(ssl);
01828         return 0; /* hmac, not needed if aead mode */
01829     }
01830 
01831     if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
01832         pad     = *(decOut + decSz - 1);
01833         padByte = 1;
01834         if (wolfSSL_IsTLSv1_1(ssl))
01835             ivExtra = wolfSSL_GetCipherBlockSize(ssl);
01836     }
01837 
01838     *padSz  = wolfSSL_GetHmacSize(ssl) + pad + padByte;
01839     macInSz = decSz - ivExtra - digestSz - pad - padByte;
01840 
01841     wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
01842 
01843     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
01844                wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
01845     if (ret != 0)
01846         return ret;
01847     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
01848     if (ret != 0)
01849         return ret;
01850     ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
01851     if (ret != 0)
01852         return ret;
01853     ret = wc_HmacFinal(&hmac, verify);
01854     if (ret != 0)
01855         return ret;
01856 
01857     if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte,
01858                digestSz) != 0) {
01859         printf("myDecryptVerify verify failed\n");
01860         return -1;
01861     }
01862 
01863     return ret;
01864 }
01865 
01866 
01867 static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
01868 {
01869     AtomicEncCtx* encCtx;
01870     AtomicDecCtx* decCtx;
01871 
01872     encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
01873     if (encCtx == NULL)
01874         err_sys("AtomicEncCtx malloc failed");
01875     XMEMSET(encCtx, 0, sizeof(AtomicEncCtx));
01876 
01877     decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
01878     if (decCtx == NULL) {
01879         free(encCtx);
01880         err_sys("AtomicDecCtx malloc failed");
01881     }
01882     XMEMSET(decCtx, 0, sizeof(AtomicDecCtx));
01883 
01884     wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
01885     wolfSSL_SetMacEncryptCtx(ssl, encCtx);
01886 
01887     wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
01888     wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
01889 }
01890 
01891 
01892 static WC_INLINE void FreeAtomicUser(WOLFSSL* ssl)
01893 {
01894     AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
01895     AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
01896 
01897     free(decCtx);
01898     free(encCtx);
01899 }
01900 
01901 #endif /* ATOMIC_USER */
01902 
01903 #ifdef WOLFSSL_STATIC_MEMORY
01904 static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats)
01905 {
01906     word16 i;
01907 
01908     if (stats == NULL) {
01909         return 0;
01910     }
01911 
01912     /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */
01913     fprintf(stderr, "Total mallocs   = %d\n", stats->totalAlloc);
01914     fprintf(stderr, "Total frees     = %d\n", stats->totalFr);
01915     fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc);
01916     fprintf(stderr, "Available IO    = %d\n", stats->avaIO);
01917     fprintf(stderr, "Max con. handshakes  = %d\n", stats->maxHa);
01918     fprintf(stderr, "Max con. IO          = %d\n", stats->maxIO);
01919     fprintf(stderr, "State of memory blocks: size   : available \n");
01920     for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
01921        fprintf(stderr, "                      : %d\t : %d\n", stats->blockSz[i],
01922                                                             stats->avaBlock[i]);
01923     }
01924 
01925     return 1;
01926 }
01927 #endif /* WOLFSSL_STATIC_MEMORY */
01928 
01929 #ifdef HAVE_PK_CALLBACKS
01930 
01931 typedef struct PkCbInfo {
01932     const char* ourKey;
01933 #ifdef TEST_PK_PRIVKEY
01934     union {
01935     #ifdef HAVE_ECC
01936         ecc_key ecc;
01937     #endif
01938     #ifdef HAVE_CURVE25519
01939         curve25519_key curve;
01940     #endif
01941     } keyGen;
01942 #endif
01943 } PkCbInfo;
01944 
01945 #ifdef HAVE_ECC
01946 
01947 static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, 
01948     int ecc_curve, void* ctx)
01949 {
01950     int       ret;
01951     WC_RNG    rng;
01952     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
01953     ecc_key*  new_key = key;
01954 #ifdef TEST_PK_PRIVKEY
01955     byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES];
01956     word32 qxLen = sizeof(qx), qyLen = sizeof(qy);
01957     new_key = &cbInfo->keyGen.ecc;
01958 #endif
01959 
01960     (void)ssl;
01961     (void)cbInfo;
01962 
01963     ret = wc_InitRng(&rng);
01964     if (ret != 0)
01965         return ret;
01966 
01967     ret = wc_ecc_init(new_key);
01968     if (ret == 0) {
01969         /* create new key */
01970         ret = wc_ecc_make_key_ex(&rng, keySz, new_key, ecc_curve);
01971 
01972     #ifdef TEST_PK_PRIVKEY
01973         if (ret == 0) {
01974             /* extract public portion from new key into `key` arg */
01975             ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen);
01976             if (ret == 0) {
01977                 /* load public portion only into key */
01978                 ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ecc_curve);
01979             }
01980             (void)qxLen;
01981             (void)qyLen;
01982         }
01983     #endif
01984     }
01985 
01986     wc_FreeRng(&rng);
01987 
01988     return ret;
01989 }
01990 
01991 static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
01992         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
01993 {
01994     int       ret;
01995     WC_RNG    rng;
01996     word32    idx = 0;
01997     ecc_key   myKey;
01998     byte*     keyBuf = (byte*)key;
01999     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02000 
02001     (void)ssl;
02002     (void)cbInfo;
02003 
02004 #ifdef TEST_PK_PRIVKEY
02005     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02006     if (ret != 0)
02007         return ret;
02008 #endif
02009 
02010     ret = wc_InitRng(&rng);
02011     if (ret != 0)
02012         return ret;
02013 
02014     ret = wc_ecc_init(&myKey);
02015     if (ret == 0) {
02016         ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02017         if (ret == 0)
02018             ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
02019         wc_ecc_free(&myKey);
02020     }
02021     wc_FreeRng(&rng);
02022 
02023 #ifdef TEST_PK_PRIVKEY
02024     free(keyBuf);
02025 #endif
02026 
02027     return ret;
02028 }
02029 
02030 
02031 static WC_INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
02032         const byte* hash, word32 hashSz, const byte* key, word32 keySz,
02033         int* result, void* ctx)
02034 {
02035     int       ret;
02036     word32    idx = 0;
02037     ecc_key   myKey;
02038     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02039 
02040     (void)ssl;
02041     (void)cbInfo;
02042 
02043     ret = wc_ecc_init(&myKey);
02044     if (ret == 0) {
02045         ret = wc_EccPublicKeyDecode(key, &idx, &myKey, keySz);
02046         if (ret == 0)
02047             ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
02048         wc_ecc_free(&myKey);
02049     }
02050 
02051     return ret;
02052 }
02053 
02054 static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
02055         unsigned char* pubKeyDer, unsigned int* pubKeySz,
02056         unsigned char* out, unsigned int* outlen,
02057         int side, void* ctx)
02058 {
02059     int       ret;
02060     ecc_key*  privKey = NULL;
02061     ecc_key*  pubKey = NULL;
02062     ecc_key   tmpKey;
02063     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02064 
02065     (void)ssl;
02066     (void)cbInfo;
02067 
02068     ret = wc_ecc_init(&tmpKey);
02069     if (ret != 0) {
02070         return ret;
02071     }
02072 
02073     /* for client: create and export public key */
02074     if (side == WOLFSSL_CLIENT_END) {
02075         WC_RNG rng;
02076 
02077         privKey = &tmpKey;
02078         pubKey = otherKey;
02079 
02080         ret = wc_InitRng(&rng);
02081         if (ret == 0) {
02082             ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id);
02083         #ifdef WOLFSSL_ASYNC_CRYPT
02084             if (ret == WC_PENDING_E) {
02085                 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_NONE);
02086             }
02087         #endif
02088             if (ret == 0)
02089                 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
02090             wc_FreeRng(&rng);
02091         }
02092     }
02093 
02094     /* for server: import public key */
02095     else if (side == WOLFSSL_SERVER_END) {
02096     #ifdef TEST_PK_PRIVKEY
02097         privKey = &cbInfo->keyGen.ecc;
02098     #else
02099         privKey = otherKey;
02100     #endif
02101         pubKey = &tmpKey;
02102 
02103         ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey,
02104             otherKey->dp->id);
02105     }
02106     else {
02107         ret = BAD_FUNC_ARG;
02108     }
02109 
02110     /* generate shared secret and return it */
02111     if (ret == 0) {
02112         ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
02113 
02114     #ifdef WOLFSSL_ASYNC_CRYPT
02115         if (ret == WC_PENDING_E) {
02116             ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
02117         }
02118     #endif
02119     }
02120 
02121 #ifdef TEST_PK_PRIVKEY
02122     if (side == WOLFSSL_SERVER_END) {
02123         wc_ecc_free(&cbInfo->keyGen.ecc);
02124     }
02125 #endif
02126 
02127     wc_ecc_free(&tmpKey);
02128 
02129     return ret;
02130 }
02131 
02132 #ifdef HAVE_ED25519
02133 static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
02134         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
02135 {
02136     int         ret;
02137     word32      idx = 0;
02138     ed25519_key myKey;
02139     byte*       keyBuf = (byte*)key;
02140     PkCbInfo*   cbInfo = (PkCbInfo*)ctx;
02141 
02142     (void)ssl;
02143     (void)cbInfo;
02144 
02145 #ifdef TEST_PK_PRIVKEY
02146     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02147     if (ret != 0)
02148         return ret;
02149 #endif
02150 
02151     ret = wc_ed25519_init(&myKey);
02152     if (ret == 0) {
02153         ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02154         if (ret == 0)
02155             ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey);
02156         wc_ed25519_free(&myKey);
02157     }
02158 
02159 #ifdef TEST_PK_PRIVKEY
02160     free(keyBuf);
02161 #endif
02162 
02163     return ret;
02164 }
02165 
02166 
02167 static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
02168         const byte* msg, word32 msgSz, const byte* key, word32 keySz,
02169         int* result, void* ctx)
02170 {
02171     int         ret;
02172     ed25519_key myKey;
02173     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02174 
02175     (void)ssl;
02176     (void)cbInfo;
02177 
02178     ret = wc_ed25519_init(&myKey);
02179     if (ret == 0) {
02180         ret = wc_ed25519_import_public(key, keySz, &myKey);
02181         if (ret == 0) {
02182             ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
02183         }
02184         wc_ed25519_free(&myKey);
02185     }
02186 
02187     return ret;
02188 }
02189 #endif /* HAVE_ED25519 */
02190 
02191 #ifdef HAVE_CURVE25519
02192 static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key, 
02193     unsigned int keySz, void* ctx)
02194 {
02195     int       ret;
02196     WC_RNG    rng;
02197     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02198 
02199     (void)ssl;
02200     (void)cbInfo;
02201 
02202     ret = wc_InitRng(&rng);
02203     if (ret != 0)
02204         return ret;
02205 
02206     ret = wc_curve25519_make_key(&rng, keySz, key);
02207 
02208     wc_FreeRng(&rng);
02209 
02210     return ret;
02211 }
02212 
02213 static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey,
02214         unsigned char* pubKeyDer, unsigned int* pubKeySz,
02215         unsigned char* out, unsigned int* outlen,
02216         int side, void* ctx)
02217 {
02218     int      ret;
02219     curve25519_key* privKey = NULL;
02220     curve25519_key* pubKey = NULL;
02221     curve25519_key  tmpKey;
02222     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02223 
02224     (void)ssl;
02225     (void)cbInfo;
02226 
02227     ret = wc_curve25519_init(&tmpKey);
02228     if (ret != 0) {
02229         return ret;
02230     }
02231 
02232     /* for client: create and export public key */
02233     if (side == WOLFSSL_CLIENT_END) {
02234         WC_RNG rng;
02235 
02236         privKey = &tmpKey;
02237         pubKey = otherKey;
02238 
02239         ret = wc_InitRng(&rng);
02240         if (ret == 0) {
02241             ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, privKey);
02242             if (ret == 0) {
02243                 ret = wc_curve25519_export_public_ex(privKey, pubKeyDer,
02244                     pubKeySz, EC25519_LITTLE_ENDIAN);
02245             }
02246             wc_FreeRng(&rng);
02247         }
02248     }
02249 
02250     /* for server: import public key */
02251     else if (side == WOLFSSL_SERVER_END) {
02252         privKey = otherKey;
02253         pubKey = &tmpKey;
02254 
02255         ret = wc_curve25519_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
02256             EC25519_LITTLE_ENDIAN);
02257     }
02258     else {
02259         ret = BAD_FUNC_ARG;
02260     }
02261 
02262     /* generate shared secret and return it */
02263     if (ret == 0) {
02264         ret = wc_curve25519_shared_secret_ex(privKey, pubKey, out, outlen,
02265             EC25519_LITTLE_ENDIAN);
02266     }
02267 
02268     wc_curve25519_free(&tmpKey);
02269 
02270     return ret;
02271 }
02272 #endif /* HAVE_CURVE25519 */
02273 
02274 #endif /* HAVE_ECC */
02275 
02276 #ifndef NO_DH
02277 static WC_INLINE int myDhCallback(WOLFSSL* ssl, struct DhKey* key,
02278         const unsigned char* priv, unsigned int privSz,
02279         const unsigned char* pubKeyDer, unsigned int pubKeySz,
02280         unsigned char* out, unsigned int* outlen,
02281         void* ctx)
02282 {
02283     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02284 
02285     (void)ssl;
02286     (void)cbInfo;
02287 
02288     /* return 0 on success */
02289     return wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz);
02290 };
02291 
02292 #endif /* !NO_DH */
02293 
02294 #ifndef NO_RSA
02295 
02296 static WC_INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
02297         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
02298 {
02299     WC_RNG  rng;
02300     int     ret;
02301     word32  idx = 0;
02302     RsaKey  myKey;
02303     byte*   keyBuf = (byte*)key;
02304     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02305 
02306     (void)ssl;
02307     (void)cbInfo;
02308 
02309 #ifdef TEST_PK_PRIVKEY
02310     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02311     if (ret != 0)
02312         return ret;
02313 #endif
02314 
02315     ret = wc_InitRng(&rng);
02316     if (ret != 0)
02317         return ret;
02318 
02319     ret = wc_InitRsaKey(&myKey, NULL);
02320     if (ret == 0) {
02321         ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02322         if (ret == 0)
02323             ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
02324         if (ret > 0) {  /* save and convert to 0 success */
02325             *outSz = ret;
02326             ret = 0;
02327         }
02328         wc_FreeRsaKey(&myKey);
02329     }
02330     wc_FreeRng(&rng);
02331 
02332 #ifdef TEST_PK_PRIVKEY
02333     free(keyBuf);
02334 #endif
02335 
02336     return ret;
02337 }
02338 
02339 
02340 static WC_INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
02341         byte** out, const byte* key, word32 keySz, void* ctx)
02342 {
02343     int     ret;
02344     word32  idx = 0;
02345     RsaKey  myKey;
02346     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02347 
02348     (void)ssl;
02349     (void)cbInfo;
02350 
02351     ret = wc_InitRsaKey(&myKey, NULL);
02352     if (ret == 0) {
02353         ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
02354         if (ret == 0)
02355             ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
02356         wc_FreeRsaKey(&myKey);
02357     }
02358 
02359     return ret;
02360 }
02361 
02362 static WC_INLINE int myRsaSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
02363         byte** out, const byte* key, word32 keySz, void* ctx)
02364 {
02365     int     ret;
02366     word32  idx = 0;
02367     RsaKey  myKey;
02368     byte*   keyBuf = (byte*)key;
02369     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02370 
02371     (void)ssl;
02372     (void)cbInfo;
02373 
02374 #ifdef TEST_PK_PRIVKEY
02375     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02376     if (ret != 0)
02377         return ret;
02378 #endif
02379 
02380     ret = wc_InitRsaKey(&myKey, NULL);
02381     if (ret == 0) {
02382         ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02383         if (ret == 0)
02384             ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
02385         wc_FreeRsaKey(&myKey);
02386     }
02387 #ifdef TEST_PK_PRIVKEY
02388     free(keyBuf);
02389 #endif
02390 
02391     return ret;
02392 }
02393 
02394 #ifdef WC_RSA_PSS
02395 static WC_INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
02396         byte* out, word32* outSz, int hash, int mgf, const byte* key,
02397         word32 keySz, void* ctx)
02398 {
02399     enum wc_HashType hashType = WC_HASH_TYPE_NONE;
02400     WC_RNG           rng;
02401     int              ret;
02402     word32           idx = 0;
02403     RsaKey           myKey;
02404     byte*            keyBuf = (byte*)key;
02405     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02406 
02407     (void)ssl;
02408     (void)cbInfo;
02409 
02410 #ifdef TEST_PK_PRIVKEY
02411     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02412     if (ret != 0)
02413         return ret;
02414 #endif
02415 
02416     switch (hash) {
02417 #ifndef NO_SHA256
02418         case SHA256h:
02419             hashType = WC_HASH_TYPE_SHA256;
02420             break;
02421 #endif
02422 #ifdef WOLFSSL_SHA384
02423         case SHA384h:
02424             hashType = WC_HASH_TYPE_SHA384;
02425             break;
02426 #endif
02427 #ifdef WOLFSSL_SHA512
02428         case SHA512h:
02429             hashType = WC_HASH_TYPE_SHA512;
02430             break;
02431 #endif
02432     }
02433 
02434     ret = wc_InitRng(&rng);
02435     if (ret != 0)
02436         return ret;
02437 
02438     ret = wc_InitRsaKey(&myKey, NULL);
02439     if (ret == 0) {
02440         ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02441         if (ret == 0) {
02442             ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey,
02443                                  &rng);
02444         }
02445         if (ret > 0) {  /* save and convert to 0 success */
02446             *outSz = ret;
02447             ret = 0;
02448         }
02449         wc_FreeRsaKey(&myKey);
02450     }
02451     wc_FreeRng(&rng);
02452 
02453 #ifdef TEST_PK_PRIVKEY
02454     free(keyBuf);
02455 #endif
02456 
02457     return ret;
02458 }
02459 
02460 
02461 static WC_INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
02462         byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
02463 {
02464     int       ret;
02465     word32    idx = 0;
02466     RsaKey    myKey;
02467     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02468     enum wc_HashType hashType = WC_HASH_TYPE_NONE;
02469 
02470     (void)ssl;
02471     (void)cbInfo;
02472 
02473     switch (hash) {
02474 #ifndef NO_SHA256
02475         case SHA256h:
02476             hashType = WC_HASH_TYPE_SHA256;
02477             break;
02478 #endif
02479 #ifdef WOLFSSL_SHA384
02480         case SHA384h:
02481             hashType = WC_HASH_TYPE_SHA384;
02482             break;
02483 #endif
02484 #ifdef WOLFSSL_SHA512
02485         case SHA512h:
02486             hashType = WC_HASH_TYPE_SHA512;
02487             break;
02488 #endif
02489     }
02490 
02491     ret = wc_InitRsaKey(&myKey, NULL);
02492     if (ret == 0) {
02493         ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
02494         if (ret == 0) {
02495             ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
02496                                          &myKey);
02497             }
02498         wc_FreeRsaKey(&myKey);
02499     }
02500 
02501     return ret;
02502 }
02503 
02504 static WC_INLINE int myRsaPssSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
02505         byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
02506 {
02507     int       ret;
02508     word32    idx = 0;
02509     RsaKey    myKey;
02510     byte*     keyBuf = (byte*)key;
02511     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02512     enum wc_HashType hashType = WC_HASH_TYPE_NONE;
02513 
02514     (void)ssl;
02515     (void)cbInfo;
02516 
02517 #ifdef TEST_PK_PRIVKEY
02518     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02519     if (ret != 0)
02520         return ret;
02521 #endif
02522 
02523     switch (hash) {
02524 #ifndef NO_SHA256
02525         case SHA256h:
02526             hashType = WC_HASH_TYPE_SHA256;
02527             break;
02528 #endif
02529 #ifdef WOLFSSL_SHA384
02530         case SHA384h:
02531             hashType = WC_HASH_TYPE_SHA384;
02532             break;
02533 #endif
02534 #ifdef WOLFSSL_SHA512
02535         case SHA512h:
02536             hashType = WC_HASH_TYPE_SHA512;
02537             break;
02538 #endif
02539     }
02540 
02541     ret = wc_InitRsaKey(&myKey, NULL);
02542     if (ret == 0) {
02543         ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02544         if (ret == 0) {
02545             ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
02546                                          &myKey);
02547             }
02548         wc_FreeRsaKey(&myKey);
02549     }
02550 
02551 #ifdef TEST_PK_PRIVKEY
02552     free(keyBuf);
02553 #endif
02554 
02555     return ret;
02556 }
02557 #endif
02558 
02559 
02560 static WC_INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
02561                            byte* out, word32* outSz, const byte* key,
02562                            word32 keySz, void* ctx)
02563 {
02564     int       ret;
02565     word32    idx = 0;
02566     RsaKey    myKey;
02567     WC_RNG    rng;
02568     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02569 
02570     (void)ssl;
02571     (void)cbInfo;
02572 
02573     ret = wc_InitRng(&rng);
02574     if (ret != 0)
02575         return ret;
02576 
02577     ret = wc_InitRsaKey(&myKey, NULL);
02578     if (ret == 0) {
02579         ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
02580         if (ret == 0) {
02581             ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
02582             if (ret > 0) {
02583                 *outSz = ret;
02584                 ret = 0;  /* reset to success */
02585             }
02586         }
02587         wc_FreeRsaKey(&myKey);
02588     }
02589     wc_FreeRng(&rng);
02590 
02591     return ret;
02592 }
02593 
02594 static WC_INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
02595                            byte** out,
02596                            const byte* key, word32 keySz, void* ctx)
02597 {
02598     int       ret;
02599     word32    idx = 0;
02600     RsaKey    myKey;
02601     byte*     keyBuf = (byte*)key;
02602     PkCbInfo* cbInfo = (PkCbInfo*)ctx;
02603 
02604     (void)ssl;
02605     (void)cbInfo;
02606 
02607 #ifdef TEST_PK_PRIVKEY
02608     ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
02609     if (ret != 0)
02610         return ret;
02611 #endif
02612 
02613     ret = wc_InitRsaKey(&myKey, NULL);
02614     if (ret == 0) {
02615         ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
02616         if (ret == 0) {
02617             #ifdef WC_RSA_BLINDING
02618                 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl));
02619                 if (ret != 0) {
02620                     wc_FreeRsaKey(&myKey);
02621                     return ret;
02622                 }
02623             #endif
02624             ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
02625         }
02626         wc_FreeRsaKey(&myKey);
02627     }
02628 
02629 #ifdef TEST_PK_PRIVKEY
02630     free(keyBuf);
02631 #endif
02632 
02633     return ret;
02634 }
02635 
02636 #endif /* NO_RSA */
02637 
02638 static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx)
02639 {
02640     (void)ctx;
02641 
02642     #ifdef HAVE_ECC
02643         wolfSSL_CTX_SetEccKeyGenCb(ctx, myEccKeyGen);
02644         wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
02645         wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
02646         wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
02647     #endif /* HAVE_ECC */
02648     #ifndef NO_DH
02649         wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback);
02650     #endif
02651     #ifdef HAVE_ED25519
02652         wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign);
02653         wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify);
02654     #endif
02655     #ifdef HAVE_CURVE25519
02656         wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen);
02657         wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
02658     #endif
02659     #ifndef NO_RSA
02660         wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
02661         wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
02662         wolfSSL_CTX_SetRsaSignCheckCb(ctx, myRsaSignCheck);
02663         #ifdef WC_RSA_PSS
02664             wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
02665             wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify);
02666             wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, myRsaPssSignCheck);
02667         #endif
02668         wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
02669         wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
02670     #endif /* NO_RSA */
02671 }
02672 
02673 static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx)
02674 {
02675     #ifdef HAVE_ECC
02676         wolfSSL_SetEccKeyGenCtx(ssl, myCtx);
02677         wolfSSL_SetEccSignCtx(ssl, myCtx);
02678         wolfSSL_SetEccVerifyCtx(ssl, myCtx);
02679         wolfSSL_SetEccSharedSecretCtx(ssl, myCtx);
02680     #endif /* HAVE_ECC */
02681     #ifndef NO_DH
02682         wolfSSL_SetDhAgreeCtx(ssl, myCtx);
02683     #endif
02684     #ifdef HAVE_ED25519
02685         wolfSSL_SetEd25519SignCtx(ssl, myCtx);
02686         wolfSSL_SetEd25519VerifyCtx(ssl, myCtx);
02687     #endif
02688     #ifdef HAVE_CURVE25519
02689         wolfSSL_SetX25519KeyGenCtx(ssl, myCtx);
02690         wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx);
02691     #endif
02692     #ifndef NO_RSA
02693         wolfSSL_SetRsaSignCtx(ssl, myCtx);
02694         wolfSSL_SetRsaVerifyCtx(ssl, myCtx);
02695         #ifdef WC_RSA_PSS
02696             wolfSSL_SetRsaPssSignCtx(ssl, myCtx);
02697             wolfSSL_SetRsaPssVerifyCtx(ssl, myCtx);
02698         #endif
02699         wolfSSL_SetRsaEncCtx(ssl, myCtx);
02700         wolfSSL_SetRsaDecCtx(ssl, myCtx);
02701     #endif /* NO_RSA */
02702 }
02703 
02704 #endif /* HAVE_PK_CALLBACKS */
02705 
02706 
02707 
02708 
02709 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
02710                       || defined(_MSC_VER)
02711 
02712 /* HP/UX doesn't have strsep, needed by test/suites.c */
02713 static WC_INLINE char* strsep(char **stringp, const char *delim)
02714 {
02715     char* start;
02716     char* end;
02717 
02718     start = *stringp;
02719     if (start == NULL)
02720         return NULL;
02721 
02722     if ((end = strpbrk(start, delim))) {
02723         *end++ = '\0';
02724         *stringp = end;
02725     } else {
02726         *stringp = NULL;
02727     }
02728 
02729     return start;
02730 }
02731 
02732 #endif /* __hpux__ and others */
02733 
02734 /* Create unique filename, len is length of tempfn name, assuming
02735    len does not include null terminating character,
02736    num is number of characters in tempfn name to randomize */
02737 static WC_INLINE const char* mymktemp(char *tempfn, int len, int num)
02738 {
02739     int x, size;
02740     static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
02741                                    "abcdefghijklmnopqrstuvwxyz";
02742     WC_RNG rng;
02743     byte   out;
02744 
02745     if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
02746         printf("Bad input\n");
02747         return NULL;
02748     }
02749 
02750     size = len - 1;
02751 
02752     if (wc_InitRng(&rng) != 0) {
02753         printf("InitRng failed\n");
02754         return NULL;
02755     }
02756 
02757     for (x = size; x > size - num; x--) {
02758         if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
02759             printf("RNG_GenerateBlock failed\n");
02760             return NULL;
02761         }
02762         tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
02763     }
02764     tempfn[len] = '\0';
02765 
02766     wc_FreeRng(&rng);
02767 
02768     return tempfn;
02769 }
02770 
02771 
02772 
02773 #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
02774                                     defined(HAVE_POLY1305)
02775 
02776     #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
02777 
02778     typedef struct key_ctx {
02779         byte name[WOLFSSL_TICKET_NAME_SZ];        /* name for this context */
02780         byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */
02781     } key_ctx;
02782 
02783     static key_ctx myKey_ctx;
02784     static WC_RNG myKey_rng;
02785 
02786     static WC_INLINE int TicketInit(void)
02787     {
02788         int ret = wc_InitRng(&myKey_rng);
02789         if (ret != 0) return ret;
02790 
02791         ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key));
02792         if (ret != 0) return ret;
02793 
02794         ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name));
02795         if (ret != 0) return ret;
02796 
02797         return 0;
02798     }
02799 
02800     static WC_INLINE void TicketCleanup(void)
02801     {
02802         wc_FreeRng(&myKey_rng);
02803     }
02804 
02805     static WC_INLINE int myTicketEncCb(WOLFSSL* ssl,
02806                              byte key_name[WOLFSSL_TICKET_NAME_SZ],
02807                              byte iv[WOLFSSL_TICKET_IV_SZ],
02808                              byte mac[WOLFSSL_TICKET_MAC_SZ],
02809                              int enc, byte* ticket, int inLen, int* outLen,
02810                              void* userCtx)
02811     {
02812         (void)ssl;
02813         (void)userCtx;
02814 
02815         int ret;
02816         word16 sLen = XHTONS(inLen);
02817         byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
02818         int  aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
02819         byte* tmp = aad;
02820 
02821         if (enc) {
02822             XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
02823 
02824             ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ);
02825             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
02826 
02827             /* build aad from key name, iv, and length */
02828             XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
02829             tmp += WOLFSSL_TICKET_NAME_SZ;
02830             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
02831             tmp += WOLFSSL_TICKET_IV_SZ;
02832             XMEMCPY(tmp, &sLen, 2);
02833 
02834             ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
02835                                               aad, aadSz,
02836                                               ticket, inLen,
02837                                               ticket,
02838                                               mac);
02839             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
02840             *outLen = inLen;  /* no padding in this mode */
02841         } else {
02842             /* decrypt */
02843 
02844             /* see if we know this key */
02845             if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
02846                 printf("client presented unknown ticket key name ");
02847                 return WOLFSSL_TICKET_RET_FATAL;
02848             }
02849 
02850             /* build aad from key name, iv, and length */
02851             XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
02852             tmp += WOLFSSL_TICKET_NAME_SZ;
02853             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
02854             tmp += WOLFSSL_TICKET_IV_SZ;
02855             XMEMCPY(tmp, &sLen, 2);
02856 
02857             ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
02858                                               aad, aadSz,
02859                                               ticket, inLen,
02860                                               mac,
02861                                               ticket);
02862             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
02863             *outLen = inLen;  /* no padding in this mode */
02864         }
02865 
02866         return WOLFSSL_TICKET_RET_OK;
02867     }
02868 
02869 #endif  /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */
02870 
02871 static WC_INLINE word16 GetRandomPort(void)
02872 {
02873     word16 port = 0;
02874 
02875     /* Generate random port for testing */
02876     WC_RNG rng;
02877     if (wc_InitRng(&rng) == 0) {
02878         wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port));
02879         port |= 0xC000; /* Make sure its in the 49152 - 65535 range */
02880         wc_FreeRng(&rng);
02881     }
02882     return port;
02883 }
02884 
02885 #endif /* wolfSSL_TEST_H */
02886