This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test.h Source File

test.h

00001 /* test.h */
00002 
00003 #ifndef CyaSSL_TEST_H
00004 #define CyaSSL_TEST_H
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <assert.h>
00009 #include <ctype.h>
00010 #include <cyassl/ssl.h>
00011 #include <cyassl/ctaocrypt/types.h>
00012 
00013 #ifdef USE_WINDOWS_API 
00014     #include <winsock2.h>
00015     #include <process.h>
00016     #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
00017         #include <ws2tcpip.h>
00018         #include <wspiapi.h>
00019     #endif
00020     #define SOCKET_T SOCKET
00021     #define SNPRINTF _snprintf
00022 #elif defined(CYASSL_MDK_ARM)
00023     #include <string.h>
00024 #else
00025     #include <string.h>
00026     #include <sys/types.h>
00027 #ifndef CYASSL_LEANPSK
00028     #include <unistd.h>
00029     #include <netdb.h>
00030     #include <netinet/in.h>
00031     #include <netinet/tcp.h>
00032     #include <arpa/inet.h>
00033     #include <sys/ioctl.h>
00034     #include <sys/time.h>
00035     #include <sys/socket.h>
00036     #include <pthread.h>
00037     #include <fcntl.h>
00038     #ifdef TEST_IPV6
00039         #include <netdb.h>
00040     #endif
00041 #endif
00042     #define SOCKET_T int
00043     #ifndef SO_NOSIGPIPE
00044         #include <signal.h>  /* ignore SIGPIPE */
00045     #endif
00046     #define SNPRINTF snprintf
00047 #endif /* USE_WINDOWS_API */
00048 
00049 #ifdef HAVE_CAVIUM
00050     #include "cavium_sysdep.h"
00051     #include "cavium_common.h"
00052     #include "cavium_ioctl.h"
00053 #endif
00054 
00055 #ifdef _MSC_VER
00056     /* disable conversion warning */
00057     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
00058     #pragma warning(disable:4244 4996)
00059 #endif
00060 
00061 
00062 #if defined(__MACH__) || defined(USE_WINDOWS_API)
00063     #ifndef _SOCKLEN_T
00064         typedef int socklen_t;
00065     #endif
00066 #endif
00067 
00068 
00069 /* HPUX doesn't use socklent_t for third parameter to accept, unless
00070    _XOPEN_SOURCE_EXTENDED is defined */
00071 #if !defined(__hpux__) && !defined(CYASSL_MDK_ARM)
00072     typedef socklen_t* ACCEPT_THIRD_T;
00073 #else
00074     #if defined _XOPEN_SOURCE_EXTENDED
00075         typedef socklen_t* ACCEPT_THIRD_T;
00076     #else
00077         typedef int*       ACCEPT_THIRD_T;
00078     #endif
00079 #endif
00080 
00081 
00082 #ifdef USE_WINDOWS_API 
00083     #define CloseSocket(s) closesocket(s)
00084     #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
00085 #elif defined(CYASSL_MDK_ARM)
00086     #define CloseSocket(s) closesocket(s)
00087     #define StartTCP() 
00088 #else
00089     #define CloseSocket(s) close(s)
00090     #define StartTCP() 
00091 #endif
00092 
00093 
00094 #ifdef SINGLE_THREADED
00095     typedef unsigned int  THREAD_RETURN;
00096     typedef void*         THREAD_TYPE;
00097     #define CYASSL_THREAD
00098 #else
00099     #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00100         typedef void*         THREAD_RETURN;
00101         typedef pthread_t     THREAD_TYPE;
00102         #define CYASSL_THREAD
00103         #define INFINITE -1
00104         #define WAIT_OBJECT_0 0L
00105     #elif defined(CYASSL_MDK_ARM)
00106         typedef unsigned int  THREAD_RETURN;
00107         typedef int           THREAD_TYPE;
00108         #define CYASSL_THREAD
00109     #else
00110         typedef unsigned int  THREAD_RETURN;
00111         typedef intptr_t      THREAD_TYPE;
00112         #define CYASSL_THREAD __stdcall
00113     #endif
00114 #endif
00115 
00116 
00117 #ifdef TEST_IPV6
00118     typedef struct sockaddr_in6 SOCKADDR_IN_T;
00119     #define AF_INET_V    AF_INET6
00120 #else
00121     typedef struct sockaddr_in  SOCKADDR_IN_T;
00122     #define AF_INET_V    AF_INET
00123 #endif
00124    
00125 
00126 #define SERVER_DEFAULT_VERSION 3
00127 #define SERVER_DTLS_DEFAULT_VERSION (-2)
00128 #define SERVER_INVALID_VERSION (-99)
00129 #define CLIENT_DEFAULT_VERSION 3
00130 #define CLIENT_DTLS_DEFAULT_VERSION (-2)
00131 #define CLIENT_INVALID_VERSION (-99)
00132 
00133 /* all certs relative to CyaSSL home directory now */
00134 #define caCert     "./certs/ca-cert.pem"
00135 #define eccCert    "./certs/server-ecc.pem"
00136 #define eccKey     "./certs/ecc-key.pem"
00137 #define svrCert    "./certs/server-cert.pem"
00138 #define svrKey     "./certs/server-key.pem"
00139 #define cliCert    "./certs/client-cert.pem"
00140 #define cliKey     "./certs/client-key.pem"
00141 #define ntruCert   "./certs/ntru-cert.pem"
00142 #define ntruKey    "./certs/ntru-key.raw"
00143 #define dhParam    "./certs/dh2048.pem"
00144 #define cliEccKey  "./certs/ecc-client-key.pem"
00145 #define cliEccCert "./certs/client-ecc-cert.pem"
00146 #define crlPemDir  "./certs/crl"
00147 
00148 typedef struct tcp_ready {
00149     int ready;              /* predicate */
00150     int port;
00151 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00152     pthread_mutex_t mutex;
00153     pthread_cond_t  cond;
00154 #endif
00155 } tcp_ready;    
00156 
00157 
00158 void InitTcpReady(tcp_ready*);
00159 void FreeTcpReady(tcp_ready*);
00160 
00161 
00162 typedef struct func_args {
00163     int    argc;
00164     char** argv;
00165     int    return_code;
00166     tcp_ready* signal;
00167 } func_args;
00168 
00169 void wait_tcp_ready(func_args*);
00170 
00171 typedef THREAD_RETURN CYASSL_THREAD THREAD_FUNC(void*);
00172 
00173 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
00174 void join_thread(THREAD_TYPE);
00175 
00176 /* yaSSL */
00177 #ifndef TEST_IPV6
00178     static const char* const yasslIP   = "127.0.0.1";
00179 #else
00180     static const char* const yasslIP   = "::1";
00181 #endif
00182 static const word16      yasslPort = 11111;
00183 
00184 static INLINE void err_sys(const char* msg)
00185 {
00186     printf("yassl error: %s\n", msg);
00187     #ifndef CYASSL_MDK_SHELL
00188     if (msg)
00189         exit(EXIT_FAILURE);
00190     #endif
00191 }
00192 
00193 
00194 #define MY_EX_USAGE 2
00195 
00196 extern int   myoptind;
00197 extern char* myoptarg;
00198 
00199 static INLINE int mygetopt(int argc, char** argv, const char* optstring)
00200 {
00201     static char* next = NULL;
00202 
00203     char  c;
00204     char* cp;
00205 
00206     if (myoptind == 0)
00207         next = NULL;   /* we're starting new/over */
00208 
00209     if (next == NULL || *next == '\0') {
00210         if (myoptind == 0)
00211             myoptind++;
00212 
00213         if (myoptind >= argc || argv[myoptind][0] != '-' ||
00214                                 argv[myoptind][1] == '\0') {
00215             myoptarg = NULL;
00216             if (myoptind < argc)
00217                 myoptarg = argv[myoptind];
00218 
00219             return -1;
00220         }
00221 
00222         if (strcmp(argv[myoptind], "--") == 0) {
00223             myoptind++;
00224             myoptarg = NULL;
00225 
00226             if (myoptind < argc)
00227                 myoptarg = argv[myoptind];
00228 
00229             return -1;
00230         }
00231 
00232         next = argv[myoptind];
00233         next++;                  /* skip - */
00234         myoptind++;
00235     }
00236 
00237     c  = *next++;
00238     /* The C++ strchr can return a different value */
00239     cp = (char*)strchr(optstring, c);
00240 
00241     if (cp == NULL || c == ':') 
00242         return '?';
00243 
00244     cp++;
00245 
00246     if (*cp == ':') {
00247         if (*next != '\0') {
00248             myoptarg = next;
00249             next     = NULL;
00250         }
00251         else if (myoptind < argc) {
00252             myoptarg = argv[myoptind];
00253             myoptind++;
00254         }
00255         else 
00256             return '?';
00257     }
00258 
00259     return c;
00260 }
00261 
00262 
00263 #ifdef OPENSSL_EXTRA
00264 
00265 static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
00266 {
00267     (void)rw;
00268     (void)userdata;
00269     strncpy(passwd, "yassl123", sz);
00270     return 8;
00271 }
00272 
00273 #endif
00274 
00275 
00276 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
00277 
00278 static INLINE void ShowX509(CYASSL_X509* x509, const char* hdr)
00279 {
00280     char* altName;
00281     char* issuer  = CyaSSL_X509_NAME_oneline(
00282                                        CyaSSL_X509_get_issuer_name(x509), 0, 0);
00283     char* subject = CyaSSL_X509_NAME_oneline(
00284                                       CyaSSL_X509_get_subject_name(x509), 0, 0);
00285     byte  serial[32];
00286     int   ret;
00287     int   sz = sizeof(serial);
00288         
00289     printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject);
00290 
00291     while ( (altName = CyaSSL_X509_get_next_altname(x509)) != NULL)
00292         printf(" altname = %s\n", altName);
00293 
00294     ret = CyaSSL_X509_get_serial_number(x509, serial, &sz);
00295     if (ret == SSL_SUCCESS) {
00296         int  i;
00297         int  strLen;
00298         char serialMsg[80];
00299 
00300         /* testsuite has multiple threads writing to stdout, get output
00301            message ready to write once */
00302         strLen = sprintf(serialMsg, " serial number");
00303         for (i = 0; i < sz; i++)
00304             sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
00305         printf("%s\n", serialMsg);
00306     }
00307 
00308     XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
00309     XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
00310 }
00311 
00312 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
00313 
00314 
00315 static INLINE void showPeer(CYASSL* ssl)
00316 {
00317 
00318     CYASSL_CIPHER* cipher;
00319 #ifdef KEEP_PEER_CERT
00320     CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl);
00321     if (peer)
00322         ShowX509(peer, "peer's cert info:");
00323     else
00324         printf("peer has no cert!\n");
00325 #endif
00326     printf("SSL version is %s\n", CyaSSL_get_version(ssl));
00327 
00328     cipher = CyaSSL_get_current_cipher(ssl);
00329     printf("SSL cipher suite is %s\n", CyaSSL_CIPHER_get_name(cipher));
00330 
00331 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
00332     {
00333         CYASSL_X509_CHAIN* chain = CyaSSL_get_peer_chain(ssl);
00334         int                count = CyaSSL_get_chain_count(chain);
00335         int i;
00336 
00337         for (i = 0; i < count; i++) {
00338             int length;
00339             unsigned char buffer[3072];
00340             CYASSL_X509* chainX509;
00341 
00342             CyaSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length);
00343             buffer[length] = 0;
00344             printf("cert %d has length %d data = \n%s\n", i, length, buffer);
00345 
00346             chainX509 = CyaSSL_get_chain_X509(chain, i);
00347             if (chainX509)
00348                 ShowX509(chainX509, "session cert info:");
00349             else
00350                 printf("get_chain_X509 failed\n");
00351             CyaSSL_FreeX509(chainX509);
00352         }
00353     }
00354 #endif
00355   (void)ssl;
00356 }
00357 
00358 
00359 static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
00360                               word16 port, int udp)
00361 {
00362     int useLookup = 0;
00363     (void)useLookup;
00364     (void)udp;
00365 
00366     memset(addr, 0, sizeof(SOCKADDR_IN_T));
00367 
00368 #ifndef TEST_IPV6
00369     /* peer could be in human readable form */
00370     if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) {
00371         #ifdef CYASSL_MDK_ARM
00372             int err;
00373             struct hostent* entry = gethostbyname(peer, &err);
00374         #else
00375             struct hostent* entry = gethostbyname(peer);
00376         #endif
00377 
00378         if (entry) {
00379             memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0],
00380                    entry->h_length);
00381             useLookup = 1;
00382         }
00383         else
00384             err_sys("no entry for host");
00385     }
00386 #endif
00387 
00388 
00389 #ifndef TEST_IPV6
00390     #if defined(CYASSL_MDK_ARM)
00391         addr->sin_family = PF_INET;
00392     #else
00393         addr->sin_family = AF_INET_V;
00394     #endif
00395     addr->sin_port = htons(port);
00396     if (peer == INADDR_ANY)
00397         addr->sin_addr.s_addr = INADDR_ANY;
00398     else {
00399         if (!useLookup)
00400             addr->sin_addr.s_addr = inet_addr(peer);
00401     }
00402 #else
00403     addr->sin6_family = AF_INET_V;
00404     addr->sin6_port = htons(port);
00405     if (peer == INADDR_ANY)
00406         addr->sin6_addr = in6addr_any;
00407     else {
00408         #ifdef HAVE_GETADDRINFO
00409             struct addrinfo  hints;
00410             struct addrinfo* answer = NULL;
00411             int    ret;
00412             char   strPort[80];
00413 
00414             memset(&hints, 0, sizeof(hints));
00415 
00416             hints.ai_family   = AF_INET_V;
00417             hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
00418             hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
00419 
00420             SNPRINTF(strPort, sizeof(strPort), "%d", port);
00421             strPort[79] = '\0';
00422 
00423             ret = getaddrinfo(peer, strPort, &hints, &answer);
00424             if (ret < 0 || answer == NULL)
00425                 err_sys("getaddrinfo failed");
00426 
00427             memcpy(addr, answer->ai_addr, answer->ai_addrlen);
00428             freeaddrinfo(answer);
00429         #else
00430             printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
00431             addr->sin6_addr = in6addr_loopback;
00432         #endif
00433     }
00434 #endif
00435 }
00436 
00437 
00438 static INLINE void tcp_socket(SOCKET_T* sockfd, int udp)
00439 {
00440     if (udp)
00441         *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0);
00442     else
00443         *sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
00444 
00445 #ifdef USE_WINDOWS_API
00446     if (*sockfd == INVALID_SOCKET)
00447         err_sys("socket failed\n");
00448 #else
00449     if (*sockfd < 0)
00450         err_sys("socket failed\n");
00451 #endif
00452 
00453 #ifndef USE_WINDOWS_API 
00454 #ifdef SO_NOSIGPIPE
00455     {
00456         int       on = 1;
00457         socklen_t len = sizeof(on);
00458         int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
00459         if (res < 0)
00460             err_sys("setsockopt SO_NOSIGPIPE failed\n");
00461     }
00462 #elif defined(CYASSL_MDK_ARM)
00463     /* nothing to define */
00464 #else  /* no S_NOSIGPIPE */
00465     signal(SIGPIPE, SIG_IGN);
00466 #endif /* S_NOSIGPIPE */
00467 
00468 #if defined(TCP_NODELAY)
00469     if (!udp)
00470     {
00471         int       on = 1;
00472         socklen_t len = sizeof(on);
00473         int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
00474         if (res < 0)
00475             err_sys("setsockopt TCP_NODELAY failed\n");
00476     }
00477 #endif
00478 #endif  /* USE_WINDOWS_API */
00479 }
00480 
00481 static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
00482                                int udp)
00483 {
00484     SOCKADDR_IN_T addr;
00485     build_addr(&addr, ip, port, udp);
00486     tcp_socket(sockfd, udp);
00487 
00488     if (!udp) {
00489         if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00490             err_sys("tcp connect failed");
00491     }
00492 }
00493 
00494 
00495 static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
00496 {
00497     if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
00498         err_sys("tcp connect failed");
00499 }
00500 
00501 
00502 enum {
00503     TEST_SELECT_FAIL,
00504     TEST_TIMEOUT,
00505     TEST_RECV_READY,
00506     TEST_ERROR_READY
00507 };
00508 
00509 
00510 #if !defined(CYASSL_MDK_ARM)
00511 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
00512 {
00513     fd_set recvfds, errfds;
00514     SOCKET_T nfds = socketfd + 1;
00515     struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
00516     int result;
00517 
00518     FD_ZERO(&recvfds);
00519     FD_SET(socketfd, &recvfds);
00520     FD_ZERO(&errfds);
00521     FD_SET(socketfd, &errfds);
00522 
00523     result = select(nfds, &recvfds, NULL, &errfds, &timeout);
00524 
00525     if (result == 0)
00526         return TEST_TIMEOUT;
00527     else if (result > 0) {
00528         if (FD_ISSET(socketfd, &recvfds))
00529             return TEST_RECV_READY;
00530         else if(FD_ISSET(socketfd, &errfds))
00531             return TEST_ERROR_READY;
00532     }
00533 
00534     return TEST_SELECT_FAIL;
00535 }
00536 #endif /* !CYASSL_MDK_ARM */
00537 
00538 
00539 static INLINE void tcp_listen(SOCKET_T* sockfd, int* port, int useAnyAddr,
00540                               int udp)
00541 {
00542     SOCKADDR_IN_T addr;
00543 
00544     /* don't use INADDR_ANY by default, firewall may block, make user switch
00545        on */
00546     build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), *port, udp);
00547     tcp_socket(sockfd, udp);
00548 
00549 #if !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_ARM)
00550     {
00551         int       res, on  = 1;
00552         socklen_t len = sizeof(on);
00553         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00554         if (res < 0)
00555             err_sys("setsockopt SO_REUSEADDR failed\n");
00556     }
00557 #endif
00558 
00559     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00560         err_sys("tcp bind failed");
00561     if (!udp) {
00562         if (listen(*sockfd, 5) != 0)
00563             err_sys("tcp listen failed");
00564     }
00565     #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)
00566         if (*port == 0) {
00567             socklen_t len = sizeof(addr);
00568             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00569                 #ifndef TEST_IPV6
00570                     *port = ntohs(addr.sin_port);
00571                 #else
00572                     *port = ntohs(addr.sin6_port);
00573                 #endif
00574             }
00575         }
00576     #endif
00577 }
00578 
00579 
00580 static INLINE int udp_read_connect(SOCKET_T sockfd)
00581 {
00582     SOCKADDR_IN_T cliaddr;
00583     byte          b[1500];
00584     int           n;
00585     socklen_t     len = sizeof(cliaddr);
00586 
00587     n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
00588                       (struct sockaddr*)&cliaddr, &len);
00589     if (n > 0) {
00590         if (connect(sockfd, (const struct sockaddr*)&cliaddr,
00591                     sizeof(cliaddr)) != 0)
00592             err_sys("udp connect failed");
00593     }
00594     else
00595         err_sys("recvfrom failed");
00596 
00597     return sockfd;
00598 }
00599 
00600 static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00601                               int useAnyAddr, int port, func_args* args)
00602 {
00603     SOCKADDR_IN_T addr;
00604 
00605     (void)args;
00606     build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), port, 1);
00607     tcp_socket(sockfd, 1);
00608 
00609 
00610 #if !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_ARM)
00611     {
00612         int       res, on  = 1;
00613         socklen_t len = sizeof(on);
00614         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00615         if (res < 0)
00616             err_sys("setsockopt SO_REUSEADDR failed\n");
00617     }
00618 #endif
00619 
00620     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00621         err_sys("tcp bind failed");
00622 
00623     #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)
00624         if (port == 0) {
00625             socklen_t len = sizeof(addr);
00626             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00627                 #ifndef TEST_IPV6
00628                     port = ntohs(addr.sin_port);
00629                 #else
00630                     port = ntohs(addr.sin6_port);
00631                 #endif
00632             }
00633         }
00634     #endif
00635 
00636 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00637     /* signal ready to accept data */
00638     {
00639     tcp_ready* ready = args->signal;
00640     pthread_mutex_lock(&ready->mutex);
00641     ready->ready = 1;
00642     ready->port = port;
00643     pthread_cond_signal(&ready->cond);
00644     pthread_mutex_unlock(&ready->mutex);
00645     }
00646 #endif
00647 
00648     *clientfd = udp_read_connect(*sockfd);
00649 }
00650 
00651 static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00652                               func_args* args, int port, int useAnyAddr,
00653                               int udp)
00654 {
00655     SOCKADDR_IN_T client;
00656     socklen_t client_len = sizeof(client);
00657 
00658     if (udp) {
00659         udp_accept(sockfd, clientfd, useAnyAddr, port, args);
00660         return;
00661     }
00662 
00663     tcp_listen(sockfd, &port, useAnyAddr, udp);
00664 
00665 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00666     /* signal ready to tcp_accept */
00667     {
00668     tcp_ready* ready = args->signal;
00669     pthread_mutex_lock(&ready->mutex);
00670     ready->ready = 1;
00671     ready->port = port;
00672     pthread_cond_signal(&ready->cond);
00673     pthread_mutex_unlock(&ready->mutex);
00674     }
00675 #endif
00676 
00677     *clientfd = accept(*sockfd, (struct sockaddr*)&client,
00678                       (ACCEPT_THIRD_T)&client_len);
00679 #ifdef USE_WINDOWS_API
00680     if (*clientfd == INVALID_SOCKET)
00681         err_sys("tcp accept failed");
00682 #else
00683     if (*clientfd == -1)
00684         err_sys("tcp accept failed");
00685 #endif
00686 }
00687 
00688 
00689 static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
00690 {
00691     #ifdef USE_WINDOWS_API 
00692         unsigned long blocking = 1;
00693         int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
00694         if (ret == SOCKET_ERROR)
00695             err_sys("ioctlsocket failed");
00696     #elif defined(CYASSL_MDK_ARM)
00697          /* non blocking not suppported, for now */ 
00698     #else
00699         int flags = fcntl(*sockfd, F_GETFL, 0);
00700         if (flags < 0)
00701             err_sys("fcntl get failed");
00702         flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
00703         if (flags < 0)
00704             err_sys("fcntl set failed");
00705     #endif
00706 }
00707 
00708 
00709 #ifndef NO_PSK
00710 
00711 static INLINE unsigned int my_psk_client_cb(CYASSL* ssl, const char* hint,
00712         char* identity, unsigned int id_max_len, unsigned char* key,
00713         unsigned int key_max_len)
00714 {
00715     (void)ssl;
00716     (void)hint;
00717     (void)key_max_len;
00718 
00719     /* identity is OpenSSL testing default for openssl s_client, keep same */
00720     strncpy(identity, "Client_identity", id_max_len);
00721 
00722 
00723     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
00724        unsigned binary */
00725     key[0] = 26;
00726     key[1] = 43;
00727     key[2] = 60;
00728     key[3] = 77;
00729 
00730     return 4;   /* length of key in octets or 0 for error */
00731 }
00732 
00733 
00734 static INLINE unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity,
00735         unsigned char* key, unsigned int key_max_len)
00736 {
00737     (void)ssl;
00738     (void)key_max_len;
00739 
00740     /* identity is OpenSSL testing default for openssl s_client, keep same */
00741     if (strncmp(identity, "Client_identity", 15) != 0)
00742         return 0;
00743 
00744     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
00745        unsigned binary */
00746     key[0] = 26;
00747     key[1] = 43;
00748     key[2] = 60;
00749     key[3] = 77;
00750 
00751     return 4;   /* length of key in octets or 0 for error */
00752 }
00753 
00754 #endif /* NO_PSK */
00755 
00756 
00757 #ifdef USE_WINDOWS_API 
00758 
00759     #define WIN32_LEAN_AND_MEAN
00760     #include <windows.h>
00761 
00762     static INLINE double current_time()
00763     {
00764         static int init = 0;
00765         static LARGE_INTEGER freq;
00766     
00767         LARGE_INTEGER count;
00768 
00769         if (!init) {
00770             QueryPerformanceFrequency(&freq);
00771             init = 1;
00772         }
00773 
00774         QueryPerformanceCounter(&count);
00775 
00776         return (double)count.QuadPart / freq.QuadPart;
00777     }
00778 
00779 #else
00780 
00781 #if !defined(CYASSL_MDK_ARM)
00782     #include <sys/time.h>
00783 
00784     static INLINE double current_time(void)
00785     {
00786         struct timeval tv;
00787         gettimeofday(&tv, 0);
00788 
00789         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
00790     }
00791         
00792 #endif
00793 #endif /* USE_WINDOWS_API */
00794 
00795 
00796 #if defined(NO_FILESYSTEM) && !defined(NO_CERTS)
00797 
00798     enum {
00799         CYASSL_CA   = 1,
00800         CYASSL_CERT = 2,
00801         CYASSL_KEY  = 3
00802     };
00803 
00804     static INLINE void load_buffer(CYASSL_CTX* ctx, const char* fname, int type)
00805     {
00806         /* test buffer load */
00807         long  sz = 0;
00808         byte  buff[10000];
00809         FILE* file = fopen(fname, "rb");
00810 
00811         if (!file)
00812             err_sys("can't open file for buffer load "
00813                     "Please run from CyaSSL home directory if not");
00814         fseek(file, 0, SEEK_END);
00815         sz = ftell(file);
00816         rewind(file);
00817         fread(buff, sizeof(buff), 1, file);
00818   
00819         if (type == CYASSL_CA) {
00820             if (CyaSSL_CTX_load_verify_buffer(ctx, buff, sz, SSL_FILETYPE_PEM)
00821                                               != SSL_SUCCESS)
00822                 err_sys("can't load buffer ca file");
00823         }
00824         else if (type == CYASSL_CERT) {
00825             if (CyaSSL_CTX_use_certificate_buffer(ctx, buff, sz,
00826                         SSL_FILETYPE_PEM) != SSL_SUCCESS)
00827                 err_sys("can't load buffer cert file");
00828         }
00829         else if (type == CYASSL_KEY) {
00830             if (CyaSSL_CTX_use_PrivateKey_buffer(ctx, buff, sz,
00831                         SSL_FILETYPE_PEM) != SSL_SUCCESS)
00832                 err_sys("can't load buffer key file");
00833         }
00834     }
00835 
00836 #endif /* NO_FILESYSTEM */
00837 
00838 #ifdef VERIFY_CALLBACK
00839 
00840 static INLINE int myVerify(int preverify, CYASSL_X509_STORE_CTX* store)
00841 {
00842     char buffer[80];
00843 
00844 #ifdef OPENSSL_EXTRA
00845     CYASSL_X509* peer;
00846 #endif
00847 
00848     printf("In verification callback, error = %d, %s\n", store->error,
00849                                  CyaSSL_ERR_error_string(store->error, buffer));
00850 #ifdef OPENSSL_EXTRA
00851     peer = store->current_cert;
00852     if (peer) {
00853         char* issuer  = CyaSSL_X509_NAME_oneline(
00854                                        CyaSSL_X509_get_issuer_name(peer), 0, 0);
00855         char* subject = CyaSSL_X509_NAME_oneline(
00856                                       CyaSSL_X509_get_subject_name(peer), 0, 0);
00857         printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
00858                                                                   subject);
00859         XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
00860         XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
00861     }
00862     else
00863         printf("peer has no cert!\n");
00864 #endif
00865     printf("Subject's domain name is %s\n", store->domain);
00866 
00867     printf("Allowing to continue anyway (shouldn't do this, EVER!!!)\n");
00868     return 1;
00869 }
00870 
00871 #endif /* VERIFY_CALLBACK */
00872 
00873 
00874 #ifdef HAVE_CRL
00875 
00876 static INLINE void CRL_CallBack(const char* url)
00877 {
00878     printf("CRL callback url = %s\n", url);
00879 }
00880 
00881 #endif
00882 
00883 #ifndef NO_CERTS
00884 
00885 static INLINE void CaCb(unsigned char* der, int sz, int type)
00886 {
00887     (void)der;
00888     printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
00889 }
00890 
00891 
00892 static INLINE void SetDH(CYASSL* ssl)
00893 {
00894     /* dh1024 p */
00895     static unsigned char p[] =
00896     {
00897         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
00898         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
00899         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
00900         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
00901         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
00902         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
00903         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
00904         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
00905         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
00906         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
00907         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
00908     };
00909 
00910     /* dh1024 g */
00911     static unsigned char g[] =
00912     {
00913       0x02,
00914     };
00915 
00916     CyaSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
00917 }
00918 
00919 static INLINE void SetDHCtx(CYASSL_CTX* ctx)
00920 {
00921     /* dh1024 p */
00922     static unsigned char p[] =
00923     {
00924         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
00925         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
00926         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
00927         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
00928         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
00929         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
00930         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
00931         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
00932         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
00933         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
00934         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
00935     };
00936 
00937     /* dh1024 g */
00938     static unsigned char g[] =
00939     {
00940       0x02,
00941     };
00942 
00943     CyaSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
00944 }
00945 
00946 #endif /* !NO_CERTS */
00947 
00948 #ifdef HAVE_CAVIUM
00949 
00950 static INLINE int OpenNitroxDevice(int dma_mode,int dev_id)
00951 {
00952    Csp1CoreAssignment core_assign;
00953    Uint32             device;
00954 
00955    if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID))
00956       return -1;
00957    if (Csp1GetDevType(&device))
00958       return -1;
00959    if (device != NPX_DEVICE) {
00960       if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT,
00961                 (Uint32 *)&core_assign)!= 0)
00962          return -1;
00963    }
00964    CspShutdown(CAVIUM_DEV_ID);
00965 
00966    return CspInitialize(dma_mode, dev_id);
00967 }
00968 
00969 #endif /* HAVE_CAVIUM */
00970 
00971 
00972 #ifdef USE_WINDOWS_API 
00973 
00974 /* do back x number of directories */
00975 static INLINE void ChangeDirBack(int x)
00976 {
00977     char path[MAX_PATH];
00978 
00979     if (x == 1)
00980         strncpy(path, "..\\", MAX_PATH);
00981     else if (x == 2)
00982         strncpy(path, "..\\..\\", MAX_PATH);
00983     else if (x == 3)
00984         strncpy(path, "..\\..\\..\\", MAX_PATH);
00985     else if (x == 4)
00986         strncpy(path, "..\\..\\..\\..\\", MAX_PATH);
00987     else
00988         strncpy(path, ".\\", MAX_PATH);
00989     
00990     SetCurrentDirectoryA(path);
00991 }
00992 
00993 /* does current dir contain str */
00994 static INLINE int CurrentDir(const char* str)
00995 {
00996     char  path[MAX_PATH];
00997     char* baseName;
00998 
00999     GetCurrentDirectoryA(sizeof(path), path);
01000 
01001     baseName = strrchr(path, '\\');
01002     if (baseName)
01003         baseName++;
01004     else
01005         baseName = path;
01006 
01007     if (strstr(baseName, str))
01008         return 1;
01009 
01010     return 0;
01011 }
01012 
01013 #elif defined(CYASSL_MDK_ARM)
01014     /* KEIL-RL File System does not support relative directry */
01015 #else
01016 
01017 #ifndef MAX_PATH
01018     #define MAX_PATH 256
01019 #endif
01020 
01021 /* do back x number of directories */
01022 static INLINE void ChangeDirBack(int x)
01023 {
01024     char path[MAX_PATH];
01025 
01026     if (x == 1)
01027         strncpy(path, "../", MAX_PATH);
01028     else if (x == 2)
01029         strncpy(path, "../../", MAX_PATH);
01030     else if (x == 3)
01031         strncpy(path, "../../../", MAX_PATH);
01032     else if (x == 4)
01033         strncpy(path, "../../../../", MAX_PATH);
01034     else
01035         strncpy(path, "./", MAX_PATH);
01036     
01037     if (chdir(path) < 0)
01038         printf("chdir to %s failed\n", path);
01039 }
01040 
01041 /* does current dir contain str */
01042 static INLINE int CurrentDir(const char* str)
01043 {
01044     char  path[MAX_PATH];
01045     char* baseName;
01046 
01047     if (getcwd(path, sizeof(path)) == NULL) {
01048         printf("no current dir?\n");
01049         return 0;
01050     }
01051 
01052     baseName = strrchr(path, '/');
01053     if (baseName)
01054         baseName++;
01055     else
01056         baseName = path;
01057 
01058     if (strstr(baseName, str))
01059         return 1;
01060 
01061     return 0;
01062 }
01063 
01064 #endif /* USE_WINDOWS_API */
01065 
01066 
01067 #ifdef USE_CYASSL_MEMORY
01068 
01069     typedef struct memoryStats {
01070         size_t totalAllocs;     /* number of allocations */
01071         size_t totalBytes;      /* total number of bytes allocated */
01072         size_t peakBytes;       /* concurrent max bytes */
01073         size_t currentBytes;    /* total current bytes in use */
01074     } memoryStats;
01075 
01076     typedef struct memHint {
01077         size_t thisSize;      /* size of this memory */
01078         void*  thisMemory;    /* actual memory for user */
01079     } memHint;
01080 
01081     typedef struct memoryTrack {
01082         union {
01083             memHint hint;
01084             byte    alignit[16];   /* make sure we have strong alignment */
01085         } u;
01086     } memoryTrack;
01087 
01088     #if defined(CYASSL_TRACK_MEMORY)
01089         #define DO_MEM_STATS
01090         static memoryStats ourMemStats;
01091     #endif
01092 
01093     static INLINE void* TrackMalloc(size_t sz)
01094     {
01095         memoryTrack* mt;
01096 
01097         if (sz == 0)
01098             return NULL;
01099 
01100         mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);
01101         if (mt == NULL)
01102             return NULL;
01103 
01104         mt->u.hint.thisSize   = sz;
01105         mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack);
01106 
01107 #ifdef DO_MEM_STATS
01108         ourMemStats.totalAllocs++;
01109         ourMemStats.totalBytes   += sz;
01110         ourMemStats.currentBytes += sz;
01111         if (ourMemStats.currentBytes > ourMemStats.peakBytes)
01112             ourMemStats.peakBytes = ourMemStats.currentBytes;
01113 #endif
01114 
01115         return mt->u.hint.thisMemory;
01116     }
01117 
01118 
01119     static INLINE void TrackFree(void* ptr)
01120     {
01121         memoryTrack* mt;
01122 
01123         if (ptr == NULL)
01124             return;
01125 
01126         mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack));
01127 
01128 #ifdef DO_MEM_STATS 
01129         ourMemStats.currentBytes -= mt->u.hint.thisSize; 
01130 #endif
01131 
01132         free(mt);
01133     }
01134 
01135 
01136     static INLINE void* TrackRealloc(void* ptr, size_t sz)
01137     {
01138         void* ret = TrackMalloc(sz);
01139 
01140         if (ptr) {
01141             /* if realloc is bigger, don't overread old ptr */
01142             memoryTrack* mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack));
01143 
01144             if (mt->u.hint.thisSize < sz)
01145                 sz = mt->u.hint.thisSize;
01146         }
01147 
01148         if (ret && ptr)
01149             memcpy(ret, ptr, sz);
01150 
01151         if (ret)
01152             TrackFree(ptr);
01153 
01154         return ret;
01155     }
01156 
01157     static INLINE void InitMemoryTracker(void) 
01158     {
01159         if (CyaSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc) != 0)
01160             err_sys("CyaSSL SetAllocators failed for track memory");
01161 
01162     #ifdef DO_MEM_STATS
01163         ourMemStats.totalAllocs  = 0;
01164         ourMemStats.totalBytes   = 0;
01165         ourMemStats.peakBytes    = 0;
01166         ourMemStats.currentBytes = 0;
01167     #endif
01168     }
01169 
01170     static INLINE void ShowMemoryTracker(void) 
01171     {
01172     #ifdef DO_MEM_STATS 
01173         printf("total   Allocs = %9lu\n",
01174                                        (unsigned long)ourMemStats.totalAllocs);
01175         printf("total   Bytes  = %9lu\n",
01176                                        (unsigned long)ourMemStats.totalBytes);
01177         printf("peak    Bytes  = %9lu\n",
01178                                        (unsigned long)ourMemStats.peakBytes);
01179         printf("current Bytes  = %9lu\n",
01180                                        (unsigned long)ourMemStats.currentBytes);
01181     #endif
01182     }
01183 
01184 #endif /* USE_CYASSL_MEMORY */
01185 
01186 
01187 #ifdef HAVE_STACK_SIZE
01188 
01189 typedef THREAD_RETURN CYASSL_THREAD (*thread_func)(void* args);
01190 
01191 
01192 static INLINE void StackSizeCheck(func_args* args, thread_func tf)
01193 {
01194     int            ret, i, used;
01195     unsigned char* myStack;
01196     int            stackSize = 1024*128;
01197     pthread_attr_t myAttr;
01198     pthread_t      threadId;
01199 
01200 #ifdef PTHREAD_STACK_MIN
01201     if (stackSize < PTHREAD_STACK_MIN)
01202         stackSize = PTHREAD_STACK_MIN;
01203 #endif
01204 
01205     ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
01206     if (ret != 0) 
01207         err_sys("posix_memalign failed\n");        
01208 
01209     memset(myStack, 0xee, stackSize);
01210 
01211     ret = pthread_attr_init(&myAttr);
01212     if (ret != 0)
01213         err_sys("attr_init failed");
01214 
01215     ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
01216     if (ret != 0)
01217         err_sys("attr_setstackaddr failed");
01218 
01219     ret = pthread_create(&threadId, &myAttr, tf, args);
01220     if (ret != 0) {
01221         perror("pthread_create failed");
01222         exit(EXIT_FAILURE);
01223     }
01224 
01225     ret = pthread_join(threadId, NULL);
01226     if (ret != 0)
01227         err_sys("pthread_join failed");
01228 
01229     for (i = 0; i < stackSize; i++) {
01230         if (myStack[i] != 0xee) {
01231             break;
01232         }
01233     }
01234 
01235     used = stackSize - i;
01236     printf("stack used = %d\n", used);
01237 }
01238 
01239 
01240 #endif /* HAVE_STACK_SIZE */
01241 
01242 
01243 #ifdef STACK_TRAP
01244 
01245 /* good settings
01246    --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
01247 
01248 */
01249 
01250 #ifdef HAVE_STACK_SIZE
01251     /* client only for now, setrlimit will fail if pthread_create() called */
01252     /* STACK_SIZE does pthread_create() on client */
01253     #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
01254 #endif /* HAVE_STACK_SIZE */
01255 
01256 static INLINE void StackTrap(void)
01257 {
01258     struct rlimit  rl;
01259     if (getrlimit(RLIMIT_STACK, &rl) != 0)
01260         err_sys("getrlimit failed");
01261     printf("rlim_cur = %llu\n", rl.rlim_cur);
01262     rl.rlim_cur = 1024*21;  /* adjust trap size here */
01263     if (setrlimit(RLIMIT_STACK, &rl) != 0) {
01264         perror("setrlimit");
01265         err_sys("setrlimit failed");
01266     }
01267 }
01268 
01269 #else /* STACK_TRAP */
01270 
01271 static INLINE void StackTrap(void)
01272 {
01273 }
01274 
01275 #endif /* STACK_TRAP */
01276 
01277 
01278 #if defined(__hpux__) || defined(__MINGW32__)
01279 
01280 /* HP/UX doesn't have strsep, needed by test/suites.c */
01281 static INLINE char* strsep(char **stringp, const char *delim)
01282 {
01283     char* start;
01284     char* end;
01285 
01286     start = *stringp;
01287     if (start == NULL)
01288         return NULL;
01289 
01290     if ((end = strpbrk(start, delim))) {
01291         *end++ = '\0';
01292         *stringp = end;
01293     } else {
01294         *stringp = NULL;
01295     }
01296 
01297     return start;
01298 }
01299 
01300 #endif /* __hpux__ */
01301 
01302 #endif /* CyaSSL_TEST_H */
01303