Fork of CyaSSL for my specific settings

Dependents:   CyaSSL_Example

Fork of CyaSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test.h Source File

test.h

00001 /* test.h */
00002 
00003 #ifndef 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 ATOMIC_USER
00014     #include <cyassl/ctaocrypt/aes.h>
00015     #include <cyassl/ctaocrypt/arc4.h>
00016     #include <cyassl/ctaocrypt/hmac.h>
00017 #endif
00018 #ifdef HAVE_PK_CALLBACKS
00019     #include <cyassl/ctaocrypt/random.h>
00020     #include <cyassl/ctaocrypt/asn.h>
00021     #ifdef HAVE_ECC
00022         #include <cyassl/ctaocrypt/ecc.h>
00023     #endif /* HAVE_ECC */
00024 #endif /*HAVE_PK_CALLBACKS */
00025 
00026 #ifdef USE_WINDOWS_API 
00027     #include <winsock2.h>
00028     #include <process.h>
00029     #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
00030         #include <ws2tcpip.h>
00031         #include <wspiapi.h>
00032     #endif
00033     #define SOCKET_T SOCKET
00034     #define SNPRINTF _snprintf
00035 #elif defined(CYASSL_MDK_ARM)
00036     #include <string.h>
00037 #else
00038     #include <string.h>
00039     #include <sys/types.h>
00040 #ifndef CYASSL_LEANPSK
00041     #include <unistd.h>
00042     #include <netdb.h>
00043     #include <netinet/in.h>
00044     #include <netinet/tcp.h>
00045     #include <arpa/inet.h>
00046     #include <sys/ioctl.h>
00047     #include <sys/time.h>
00048     #include <sys/socket.h>
00049     #include <pthread.h>
00050     #include <fcntl.h>
00051     #ifdef TEST_IPV6
00052         #include <netdb.h>
00053     #endif
00054 #endif
00055     #define SOCKET_T int
00056     #ifndef SO_NOSIGPIPE
00057         #include <signal.h>  /* ignore SIGPIPE */
00058     #endif
00059     #define SNPRINTF snprintf
00060 #endif /* USE_WINDOWS_API */
00061 
00062 #ifdef HAVE_CAVIUM
00063     #include "cavium_sysdep.h"
00064     #include "cavium_common.h"
00065     #include "cavium_ioctl.h"
00066 #endif
00067 
00068 #ifdef _MSC_VER
00069     /* disable conversion warning */
00070     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
00071     #pragma warning(disable:4244 4996)
00072 #endif
00073 
00074 
00075 #if defined(__MACH__) || defined(USE_WINDOWS_API)
00076     #ifndef _SOCKLEN_T
00077         typedef int socklen_t;
00078     #endif
00079 #endif
00080 
00081 
00082 /* HPUX doesn't use socklent_t for third parameter to accept, unless
00083    _XOPEN_SOURCE_EXTENDED is defined */
00084 #if !defined(__hpux__) && !defined(CYASSL_MDK_ARM) && !defined(CYASSL_IAR_ARM)
00085     typedef socklen_t* ACCEPT_THIRD_T;
00086 #else
00087     #if defined _XOPEN_SOURCE_EXTENDED
00088         typedef socklen_t* ACCEPT_THIRD_T;
00089     #else
00090         typedef int*       ACCEPT_THIRD_T;
00091     #endif
00092 #endif
00093 
00094 
00095 #ifdef USE_WINDOWS_API 
00096     #define CloseSocket(s) closesocket(s)
00097     #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
00098 #elif defined(CYASSL_MDK_ARM)
00099     #define CloseSocket(s) closesocket(s)
00100     #define StartTCP() 
00101 #else
00102     #define CloseSocket(s) close(s)
00103     #define StartTCP() 
00104 #endif
00105 
00106 
00107 #ifdef SINGLE_THREADED
00108     typedef unsigned int  THREAD_RETURN;
00109     typedef void*         THREAD_TYPE;
00110     #define CYASSL_THREAD
00111 #else
00112     #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00113         typedef void*         THREAD_RETURN;
00114         typedef pthread_t     THREAD_TYPE;
00115         #define CYASSL_THREAD
00116         #define INFINITE -1
00117         #define WAIT_OBJECT_0 0L
00118     #elif defined(CYASSL_MDK_ARM)
00119         typedef unsigned int  THREAD_RETURN;
00120         typedef int           THREAD_TYPE;
00121         #define CYASSL_THREAD
00122     #else
00123         typedef unsigned int  THREAD_RETURN;
00124         typedef intptr_t      THREAD_TYPE;
00125         #define CYASSL_THREAD __stdcall
00126     #endif
00127 #endif
00128 
00129 
00130 #ifdef TEST_IPV6
00131     typedef struct sockaddr_in6 SOCKADDR_IN_T;
00132     #define AF_INET_V    AF_INET6
00133 #else
00134     typedef struct sockaddr_in  SOCKADDR_IN_T;
00135     #define AF_INET_V    AF_INET
00136 #endif
00137    
00138 
00139 #define SERVER_DEFAULT_VERSION 3
00140 #define SERVER_DTLS_DEFAULT_VERSION (-2)
00141 #define SERVER_INVALID_VERSION (-99)
00142 #define CLIENT_DEFAULT_VERSION 3
00143 #define CLIENT_DTLS_DEFAULT_VERSION (-2)
00144 #define CLIENT_INVALID_VERSION (-99)
00145 
00146 /* all certs relative to CyaSSL home directory now */
00147 #define caCert     "./certs/ca-cert.pem"
00148 #define eccCert    "./certs/server-ecc.pem"
00149 #define eccKey     "./certs/ecc-key.pem"
00150 #define svrCert    "./certs/server-cert.pem"
00151 #define svrKey     "./certs/server-key.pem"
00152 #define cliCert    "./certs/client-cert.pem"
00153 #define cliKey     "./certs/client-key.pem"
00154 #define ntruCert   "./certs/ntru-cert.pem"
00155 #define ntruKey    "./certs/ntru-key.raw"
00156 #define dhParam    "./certs/dh2048.pem"
00157 #define cliEccKey  "./certs/ecc-client-key.pem"
00158 #define cliEccCert "./certs/client-ecc-cert.pem"
00159 #define crlPemDir  "./certs/crl"
00160 
00161 typedef struct tcp_ready {
00162     word16 ready;              /* predicate */
00163     word16 port;
00164 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
00165     pthread_mutex_t mutex;
00166     pthread_cond_t  cond;
00167 #endif
00168 } tcp_ready;    
00169 
00170 
00171 void InitTcpReady(tcp_ready*);
00172 void FreeTcpReady(tcp_ready*);
00173 
00174 typedef CYASSL_METHOD* (*method_provider)(void);
00175 typedef void (*ctx_callback)(CYASSL_CTX* ctx);
00176 typedef void (*ssl_callback)(CYASSL* ssl);
00177 
00178 typedef struct callback_functions {
00179     method_provider method;
00180     ctx_callback ctx_ready;
00181     ssl_callback ssl_ready;
00182     ssl_callback on_result;
00183 } callback_functions;
00184 
00185 typedef struct func_args {
00186     int    argc;
00187     char** argv;
00188     int    return_code;
00189     tcp_ready* signal;
00190     callback_functions *callbacks;
00191 } func_args;
00192 
00193 void wait_tcp_ready(func_args*);
00194 
00195 typedef THREAD_RETURN CYASSL_THREAD THREAD_FUNC(void*);
00196 
00197 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
00198 void join_thread(THREAD_TYPE);
00199 
00200 /* yaSSL */
00201 #ifndef TEST_IPV6
00202     static const char* const yasslIP   = "127.0.0.1";
00203 #else
00204     static const char* const yasslIP   = "::1";
00205 #endif
00206 static const word16      yasslPort = 11111;
00207 
00208 static INLINE void err_sys(const char* msg)
00209 {
00210     printf("yassl error: %s\n", msg);
00211     if (msg)
00212         exit(EXIT_FAILURE);
00213 }
00214 
00215 
00216 #define MY_EX_USAGE 2
00217 
00218 extern int   myoptind;
00219 extern char* myoptarg;
00220 
00221 static INLINE int mygetopt(int argc, char** argv, const char* optstring)
00222 {
00223     static char* next = NULL;
00224 
00225     char  c;
00226     char* cp;
00227 
00228     if (myoptind == 0)
00229         next = NULL;   /* we're starting new/over */
00230 
00231     if (next == NULL || *next == '\0') {
00232         if (myoptind == 0)
00233             myoptind++;
00234 
00235         if (myoptind >= argc || argv[myoptind][0] != '-' ||
00236                                 argv[myoptind][1] == '\0') {
00237             myoptarg = NULL;
00238             if (myoptind < argc)
00239                 myoptarg = argv[myoptind];
00240 
00241             return -1;
00242         }
00243 
00244         if (strcmp(argv[myoptind], "--") == 0) {
00245             myoptind++;
00246             myoptarg = NULL;
00247 
00248             if (myoptind < argc)
00249                 myoptarg = argv[myoptind];
00250 
00251             return -1;
00252         }
00253 
00254         next = argv[myoptind];
00255         next++;                  /* skip - */
00256         myoptind++;
00257     }
00258 
00259     c  = *next++;
00260     /* The C++ strchr can return a different value */
00261     cp = (char*)strchr(optstring, c);
00262 
00263     if (cp == NULL || c == ':') 
00264         return '?';
00265 
00266     cp++;
00267 
00268     if (*cp == ':') {
00269         if (*next != '\0') {
00270             myoptarg = next;
00271             next     = NULL;
00272         }
00273         else if (myoptind < argc) {
00274             myoptarg = argv[myoptind];
00275             myoptind++;
00276         }
00277         else 
00278             return '?';
00279     }
00280 
00281     return c;
00282 }
00283 
00284 
00285 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
00286 
00287 static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
00288 {
00289     (void)rw;
00290     (void)userdata;
00291     strncpy(passwd, "yassl123", sz);
00292     return 8;
00293 }
00294 
00295 #endif
00296 
00297 
00298 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
00299 
00300 static INLINE void ShowX509(CYASSL_X509* x509, const char* hdr)
00301 {
00302     char* altName;
00303     char* issuer  = CyaSSL_X509_NAME_oneline(
00304                                        CyaSSL_X509_get_issuer_name(x509), 0, 0);
00305     char* subject = CyaSSL_X509_NAME_oneline(
00306                                       CyaSSL_X509_get_subject_name(x509), 0, 0);
00307     byte  serial[32];
00308     int   ret;
00309     int   sz = sizeof(serial);
00310         
00311     printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject);
00312 
00313     while ( (altName = CyaSSL_X509_get_next_altname(x509)) != NULL)
00314         printf(" altname = %s\n", altName);
00315 
00316     ret = CyaSSL_X509_get_serial_number(x509, serial, &sz);
00317     if (ret == SSL_SUCCESS) {
00318         int  i;
00319         int  strLen;
00320         char serialMsg[80];
00321 
00322         /* testsuite has multiple threads writing to stdout, get output
00323            message ready to write once */
00324         strLen = sprintf(serialMsg, " serial number");
00325         for (i = 0; i < sz; i++)
00326             sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
00327         printf("%s\n", serialMsg);
00328     }
00329 
00330     XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
00331     XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
00332 }
00333 
00334 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
00335 
00336 
00337 static INLINE void showPeer(CYASSL* ssl)
00338 {
00339 
00340     CYASSL_CIPHER* cipher;
00341 #ifdef KEEP_PEER_CERT
00342     CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl);
00343     if (peer)
00344         ShowX509(peer, "peer's cert info:");
00345     else
00346         printf("peer has no cert!\n");
00347 #endif
00348     printf("SSL version is %s\n", CyaSSL_get_version(ssl));
00349 
00350     cipher = CyaSSL_get_current_cipher(ssl);
00351     printf("SSL cipher suite is %s\n", CyaSSL_CIPHER_get_name(cipher));
00352 
00353 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
00354     {
00355         CYASSL_X509_CHAIN* chain = CyaSSL_get_peer_chain(ssl);
00356         int                count = CyaSSL_get_chain_count(chain);
00357         int i;
00358 
00359         for (i = 0; i < count; i++) {
00360             int length;
00361             unsigned char buffer[3072];
00362             CYASSL_X509* chainX509;
00363 
00364             CyaSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length);
00365             buffer[length] = 0;
00366             printf("cert %d has length %d data = \n%s\n", i, length, buffer);
00367 
00368             chainX509 = CyaSSL_get_chain_X509(chain, i);
00369             if (chainX509)
00370                 ShowX509(chainX509, "session cert info:");
00371             else
00372                 printf("get_chain_X509 failed\n");
00373             CyaSSL_FreeX509(chainX509);
00374         }
00375     }
00376 #endif
00377   (void)ssl;
00378 }
00379 
00380 
00381 static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
00382                               word16 port, int udp)
00383 {
00384     int useLookup = 0;
00385     (void)useLookup;
00386     (void)udp;
00387 
00388     memset(addr, 0, sizeof(SOCKADDR_IN_T));
00389 
00390 #ifndef TEST_IPV6
00391     /* peer could be in human readable form */
00392     if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) {
00393         #ifdef CYASSL_MDK_ARM
00394             int err;
00395             struct hostent* entry = gethostbyname(peer, &err);
00396         #else
00397             struct hostent* entry = gethostbyname(peer);
00398         #endif
00399 
00400         if (entry) {
00401             memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0],
00402                    entry->h_length);
00403             useLookup = 1;
00404         }
00405         else
00406             err_sys("no entry for host");
00407     }
00408 #endif
00409 
00410 
00411 #ifndef TEST_IPV6
00412     #if defined(CYASSL_MDK_ARM)
00413         addr->sin_family = PF_INET;
00414     #else
00415         addr->sin_family = AF_INET_V;
00416     #endif
00417     addr->sin_port = htons(port);
00418     if (peer == INADDR_ANY)
00419         addr->sin_addr.s_addr = INADDR_ANY;
00420     else {
00421         if (!useLookup)
00422             addr->sin_addr.s_addr = inet_addr(peer);
00423     }
00424 #else
00425     addr->sin6_family = AF_INET_V;
00426     addr->sin6_port = htons(port);
00427     if (peer == INADDR_ANY)
00428         addr->sin6_addr = in6addr_any;
00429     else {
00430         #ifdef HAVE_GETADDRINFO
00431             struct addrinfo  hints;
00432             struct addrinfo* answer = NULL;
00433             int    ret;
00434             char   strPort[80];
00435 
00436             memset(&hints, 0, sizeof(hints));
00437 
00438             hints.ai_family   = AF_INET_V;
00439             hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
00440             hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
00441 
00442             SNPRINTF(strPort, sizeof(strPort), "%d", port);
00443             strPort[79] = '\0';
00444 
00445             ret = getaddrinfo(peer, strPort, &hints, &answer);
00446             if (ret < 0 || answer == NULL)
00447                 err_sys("getaddrinfo failed");
00448 
00449             memcpy(addr, answer->ai_addr, answer->ai_addrlen);
00450             freeaddrinfo(answer);
00451         #else
00452             printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
00453             addr->sin6_addr = in6addr_loopback;
00454         #endif
00455     }
00456 #endif
00457 }
00458 
00459 
00460 static INLINE void tcp_socket(SOCKET_T* sockfd, int udp)
00461 {
00462     if (udp)
00463         *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0);
00464     else
00465         *sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
00466 
00467 #ifdef USE_WINDOWS_API
00468     if (*sockfd == INVALID_SOCKET)
00469         err_sys("socket failed\n");
00470 #else
00471     if (*sockfd < 0)
00472         err_sys("socket failed\n");
00473 #endif
00474 
00475 #ifndef USE_WINDOWS_API 
00476 #ifdef SO_NOSIGPIPE
00477     {
00478         int       on = 1;
00479         socklen_t len = sizeof(on);
00480         int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
00481         if (res < 0)
00482             err_sys("setsockopt SO_NOSIGPIPE failed\n");
00483     }
00484 #elif defined(CYASSL_MDK_ARM)
00485     /* nothing to define */
00486 #else  /* no S_NOSIGPIPE */
00487     signal(SIGPIPE, SIG_IGN);
00488 #endif /* S_NOSIGPIPE */
00489 
00490 #if defined(TCP_NODELAY)
00491     if (!udp)
00492     {
00493         int       on = 1;
00494         socklen_t len = sizeof(on);
00495         int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
00496         if (res < 0)
00497             err_sys("setsockopt TCP_NODELAY failed\n");
00498     }
00499 #endif
00500 #endif  /* USE_WINDOWS_API */
00501 }
00502 
00503 static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
00504                                int udp)
00505 {
00506     SOCKADDR_IN_T addr;
00507     build_addr(&addr, ip, port, udp);
00508     tcp_socket(sockfd, udp);
00509 
00510     if (!udp) {
00511         if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00512             err_sys("tcp connect failed");
00513     }
00514 }
00515 
00516 
00517 static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
00518 {
00519     if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
00520         err_sys("tcp connect failed");
00521 }
00522 
00523 
00524 enum {
00525     TEST_SELECT_FAIL,
00526     TEST_TIMEOUT,
00527     TEST_RECV_READY,
00528     TEST_ERROR_READY
00529 };
00530 
00531 
00532 #if !defined(CYASSL_MDK_ARM)
00533 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
00534 {
00535     fd_set recvfds, errfds;
00536     SOCKET_T nfds = socketfd + 1;
00537     struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
00538     int result;
00539 
00540     FD_ZERO(&recvfds);
00541     FD_SET(socketfd, &recvfds);
00542     FD_ZERO(&errfds);
00543     FD_SET(socketfd, &errfds);
00544 
00545     result = select(nfds, &recvfds, NULL, &errfds, &timeout);
00546 
00547     if (result == 0)
00548         return TEST_TIMEOUT;
00549     else if (result > 0) {
00550         if (FD_ISSET(socketfd, &recvfds))
00551             return TEST_RECV_READY;
00552         else if(FD_ISSET(socketfd, &errfds))
00553             return TEST_ERROR_READY;
00554     }
00555 
00556     return TEST_SELECT_FAIL;
00557 }
00558 #endif /* !CYASSL_MDK_ARM */
00559 
00560 
00561 static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
00562                               int udp)
00563 {
00564     SOCKADDR_IN_T addr;
00565 
00566     /* don't use INADDR_ANY by default, firewall may block, make user switch
00567        on */
00568     build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), *port, udp);
00569     tcp_socket(sockfd, udp);
00570 
00571 #if !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_ARM)
00572     {
00573         int       res, on  = 1;
00574         socklen_t len = sizeof(on);
00575         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00576         if (res < 0)
00577             err_sys("setsockopt SO_REUSEADDR failed\n");
00578     }
00579 #endif
00580 
00581     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00582         err_sys("tcp bind failed");
00583     if (!udp) {
00584         if (listen(*sockfd, 5) != 0)
00585             err_sys("tcp listen failed");
00586     }
00587     #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)
00588         if (*port == 0) {
00589             socklen_t len = sizeof(addr);
00590             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00591                 #ifndef TEST_IPV6
00592                     *port = ntohs(addr.sin_port);
00593                 #else
00594                     *port = ntohs(addr.sin6_port);
00595                 #endif
00596             }
00597         }
00598     #endif
00599 }
00600 
00601 
00602 static INLINE int udp_read_connect(SOCKET_T sockfd)
00603 {
00604     SOCKADDR_IN_T cliaddr;
00605     byte          b[1500];
00606     int           n;
00607     socklen_t     len = sizeof(cliaddr);
00608 
00609     n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
00610                       (struct sockaddr*)&cliaddr, &len);
00611     if (n > 0) {
00612         if (connect(sockfd, (const struct sockaddr*)&cliaddr,
00613                     sizeof(cliaddr)) != 0)
00614             err_sys("udp connect failed");
00615     }
00616     else
00617         err_sys("recvfrom failed");
00618 
00619     return sockfd;
00620 }
00621 
00622 static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00623                               int useAnyAddr, word16 port, func_args* args)
00624 {
00625     SOCKADDR_IN_T addr;
00626 
00627     (void)args;
00628     build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), port, 1);
00629     tcp_socket(sockfd, 1);
00630 
00631 
00632 #if !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_ARM)
00633     {
00634         int       res, on  = 1;
00635         socklen_t len = sizeof(on);
00636         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
00637         if (res < 0)
00638             err_sys("setsockopt SO_REUSEADDR failed\n");
00639     }
00640 #endif
00641 
00642     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
00643         err_sys("tcp bind failed");
00644 
00645     #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)
00646         if (port == 0) {
00647             socklen_t len = sizeof(addr);
00648             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
00649                 #ifndef TEST_IPV6
00650                     port = ntohs(addr.sin_port);
00651                 #else
00652                     port = ntohs(addr.sin6_port);
00653                 #endif
00654             }
00655         }
00656     #endif
00657 
00658 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00659     /* signal ready to accept data */
00660     {
00661     tcp_ready* ready = args->signal;
00662     pthread_mutex_lock(&ready->mutex);
00663     ready->ready = 1;
00664     ready->port = port;
00665     pthread_cond_signal(&ready->cond);
00666     pthread_mutex_unlock(&ready->mutex);
00667     }
00668 #endif
00669 
00670     *clientfd = udp_read_connect(*sockfd);
00671 }
00672 
00673 static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
00674                               func_args* args, word16 port, int useAnyAddr,
00675                               int udp)
00676 {
00677     SOCKADDR_IN_T client;
00678     socklen_t client_len = sizeof(client);
00679 
00680     if (udp) {
00681         udp_accept(sockfd, clientfd, useAnyAddr, port, args);
00682         return;
00683     }
00684 
00685     tcp_listen(sockfd, &port, useAnyAddr, udp);
00686 
00687 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
00688     /* signal ready to tcp_accept */
00689     {
00690     tcp_ready* ready = args->signal;
00691     pthread_mutex_lock(&ready->mutex);
00692     ready->ready = 1;
00693     ready->port = port;
00694     pthread_cond_signal(&ready->cond);
00695     pthread_mutex_unlock(&ready->mutex);
00696     }
00697 #endif
00698 
00699     *clientfd = accept(*sockfd, (struct sockaddr*)&client,
00700                       (ACCEPT_THIRD_T)&client_len);
00701 #ifdef USE_WINDOWS_API
00702     if (*clientfd == INVALID_SOCKET)
00703         err_sys("tcp accept failed");
00704 #else
00705     if (*clientfd == -1)
00706         err_sys("tcp accept failed");
00707 #endif
00708 }
00709 
00710 
00711 static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
00712 {
00713     #ifdef USE_WINDOWS_API 
00714         unsigned long blocking = 1;
00715         int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
00716         if (ret == SOCKET_ERROR)
00717             err_sys("ioctlsocket failed");
00718     #elif defined(CYASSL_MDK_ARM)
00719          /* non blocking not suppported, for now */ 
00720     #else
00721         int flags = fcntl(*sockfd, F_GETFL, 0);
00722         if (flags < 0)
00723             err_sys("fcntl get failed");
00724         flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
00725         if (flags < 0)
00726             err_sys("fcntl set failed");
00727     #endif
00728 }
00729 
00730 
00731 #ifndef NO_PSK
00732 
00733 static INLINE unsigned int my_psk_client_cb(CYASSL* ssl, const char* hint,
00734         char* identity, unsigned int id_max_len, unsigned char* key,
00735         unsigned int key_max_len)
00736 {
00737     (void)ssl;
00738     (void)hint;
00739     (void)key_max_len;
00740 
00741     /* identity is OpenSSL testing default for openssl s_client, keep same */
00742     strncpy(identity, "Client_identity", id_max_len);
00743 
00744 
00745     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
00746        unsigned binary */
00747     key[0] = 26;
00748     key[1] = 43;
00749     key[2] = 60;
00750     key[3] = 77;
00751 
00752     return 4;   /* length of key in octets or 0 for error */
00753 }
00754 
00755 
00756 static INLINE unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity,
00757         unsigned char* key, unsigned int key_max_len)
00758 {
00759     (void)ssl;
00760     (void)key_max_len;
00761 
00762     /* identity is OpenSSL testing default for openssl s_client, keep same */
00763     if (strncmp(identity, "Client_identity", 15) != 0)
00764         return 0;
00765 
00766     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
00767        unsigned binary */
00768     key[0] = 26;
00769     key[1] = 43;
00770     key[2] = 60;
00771     key[3] = 77;
00772 
00773     return 4;   /* length of key in octets or 0 for error */
00774 }
00775 
00776 #endif /* NO_PSK */
00777 
00778 
00779 #ifdef USE_WINDOWS_API 
00780 
00781     #define WIN32_LEAN_AND_MEAN
00782     #include <windows.h>
00783 
00784     static INLINE double current_time()
00785     {
00786         static int init = 0;
00787         static LARGE_INTEGER freq;
00788     
00789         LARGE_INTEGER count;
00790 
00791         if (!init) {
00792             QueryPerformanceFrequency(&freq);
00793             init = 1;
00794         }
00795 
00796         QueryPerformanceCounter(&count);
00797 
00798         return (double)count.QuadPart / freq.QuadPart;
00799     }
00800 
00801 #else
00802 
00803 #if !defined(CYASSL_MDK_ARM)
00804     #include <sys/time.h>
00805 
00806     static INLINE double current_time(void)
00807     {
00808         struct timeval tv;
00809         gettimeofday(&tv, 0);
00810 
00811         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
00812     }
00813         
00814 #endif
00815 #endif /* USE_WINDOWS_API */
00816 
00817 
00818 #if defined(NO_FILESYSTEM) && !defined(NO_CERTS)
00819 
00820     enum {
00821         CYASSL_CA   = 1,
00822         CYASSL_CERT = 2,
00823         CYASSL_KEY  = 3
00824     };
00825 
00826     static INLINE void load_buffer(CYASSL_CTX* ctx, const char* fname, int type)
00827     {
00828         /* test buffer load */
00829         long  sz = 0;
00830         byte  buff[10000];
00831         FILE* file = fopen(fname, "rb");
00832 
00833         if (!file)
00834             err_sys("can't open file for buffer load "
00835                     "Please run from CyaSSL home directory if not");
00836         fseek(file, 0, SEEK_END);
00837         sz = ftell(file);
00838         rewind(file);
00839         fread(buff, sizeof(buff), 1, file);
00840   
00841         if (type == CYASSL_CA) {
00842             if (CyaSSL_CTX_load_verify_buffer(ctx, buff, sz, SSL_FILETYPE_PEM)
00843                                               != SSL_SUCCESS)
00844                 err_sys("can't load buffer ca file");
00845         }
00846         else if (type == CYASSL_CERT) {
00847             if (CyaSSL_CTX_use_certificate_buffer(ctx, buff, sz,
00848                         SSL_FILETYPE_PEM) != SSL_SUCCESS)
00849                 err_sys("can't load buffer cert file");
00850         }
00851         else if (type == CYASSL_KEY) {
00852             if (CyaSSL_CTX_use_PrivateKey_buffer(ctx, buff, sz,
00853                         SSL_FILETYPE_PEM) != SSL_SUCCESS)
00854                 err_sys("can't load buffer key file");
00855         }
00856     }
00857 
00858 #endif /* NO_FILESYSTEM */
00859 
00860 #ifdef VERIFY_CALLBACK
00861 
00862 static INLINE int myVerify(int preverify, CYASSL_X509_STORE_CTX* store)
00863 {
00864     (void)preverify;
00865     char buffer[CYASSL_MAX_ERROR_SZ];
00866 
00867 #ifdef OPENSSL_EXTRA
00868     CYASSL_X509* peer;
00869 #endif
00870 
00871     printf("In verification callback, error = %d, %s\n", store->error,
00872                                  CyaSSL_ERR_error_string(store->error, buffer));
00873 #ifdef OPENSSL_EXTRA
00874     peer = store->current_cert;
00875     if (peer) {
00876         char* issuer  = CyaSSL_X509_NAME_oneline(
00877                                        CyaSSL_X509_get_issuer_name(peer), 0, 0);
00878         char* subject = CyaSSL_X509_NAME_oneline(
00879                                       CyaSSL_X509_get_subject_name(peer), 0, 0);
00880         printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
00881                                                                   subject);
00882         XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
00883         XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
00884     }
00885     else
00886         printf("peer has no cert!\n");
00887 #endif
00888     printf("Subject's domain name is %s\n", store->domain);
00889 
00890     printf("Allowing to continue anyway (shouldn't do this, EVER!!!)\n");
00891     return 1;
00892 }
00893 
00894 #endif /* VERIFY_CALLBACK */
00895 
00896 
00897 #ifdef HAVE_CRL
00898 
00899 static INLINE void CRL_CallBack(const char* url)
00900 {
00901     printf("CRL callback url = %s\n", url);
00902 }
00903 
00904 #endif
00905 
00906 #ifndef NO_CERTS
00907 
00908 static INLINE void CaCb(unsigned char* der, int sz, int type)
00909 {
00910     (void)der;
00911     printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
00912 }
00913 
00914 
00915 static INLINE void SetDH(CYASSL* ssl)
00916 {
00917     /* dh1024 p */
00918     static unsigned char p[] =
00919     {
00920         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
00921         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
00922         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
00923         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
00924         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
00925         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
00926         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
00927         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
00928         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
00929         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
00930         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
00931     };
00932 
00933     /* dh1024 g */
00934     static unsigned char g[] =
00935     {
00936       0x02,
00937     };
00938 
00939     CyaSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
00940 }
00941 
00942 static INLINE void SetDHCtx(CYASSL_CTX* ctx)
00943 {
00944     /* dh1024 p */
00945     static unsigned char p[] =
00946     {
00947         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
00948         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
00949         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
00950         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
00951         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
00952         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
00953         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
00954         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
00955         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
00956         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
00957         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
00958     };
00959 
00960     /* dh1024 g */
00961     static unsigned char g[] =
00962     {
00963       0x02,
00964     };
00965 
00966     CyaSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
00967 }
00968 
00969 #endif /* !NO_CERTS */
00970 
00971 #ifdef HAVE_CAVIUM
00972 
00973 static INLINE int OpenNitroxDevice(int dma_mode,int dev_id)
00974 {
00975    Csp1CoreAssignment core_assign;
00976    Uint32             device;
00977 
00978    if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID))
00979       return -1;
00980    if (Csp1GetDevType(&device))
00981       return -1;
00982    if (device != NPX_DEVICE) {
00983       if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT,
00984                 (Uint32 *)&core_assign)!= 0)
00985          return -1;
00986    }
00987    CspShutdown(CAVIUM_DEV_ID);
00988 
00989    return CspInitialize(dma_mode, dev_id);
00990 }
00991 
00992 #endif /* HAVE_CAVIUM */
00993 
00994 
00995 #ifdef USE_WINDOWS_API 
00996 
00997 /* do back x number of directories */
00998 static INLINE void ChangeDirBack(int x)
00999 {
01000     char path[MAX_PATH];
01001 
01002     if (x == 1)
01003         strncpy(path, "..\\", MAX_PATH);
01004     else if (x == 2)
01005         strncpy(path, "..\\..\\", MAX_PATH);
01006     else if (x == 3)
01007         strncpy(path, "..\\..\\..\\", MAX_PATH);
01008     else if (x == 4)
01009         strncpy(path, "..\\..\\..\\..\\", MAX_PATH);
01010     else
01011         strncpy(path, ".\\", MAX_PATH);
01012     
01013     SetCurrentDirectoryA(path);
01014 }
01015 
01016 /* does current dir contain str */
01017 static INLINE int CurrentDir(const char* str)
01018 {
01019     char  path[MAX_PATH];
01020     char* baseName;
01021 
01022     GetCurrentDirectoryA(sizeof(path), path);
01023 
01024     baseName = strrchr(path, '\\');
01025     if (baseName)
01026         baseName++;
01027     else
01028         baseName = path;
01029 
01030     if (strstr(baseName, str))
01031         return 1;
01032 
01033     return 0;
01034 }
01035 
01036 #elif defined(CYASSL_MDK_ARM)
01037     /* KEIL-RL File System does not support relative directry */
01038 #else
01039 
01040 #ifndef MAX_PATH
01041     #define MAX_PATH 256
01042 #endif
01043 
01044 /* do back x number of directories */
01045 static INLINE void ChangeDirBack(int x)
01046 {
01047     char path[MAX_PATH];
01048 
01049     if (x == 1)
01050         strncpy(path, "../", MAX_PATH);
01051     else if (x == 2)
01052         strncpy(path, "../../", MAX_PATH);
01053     else if (x == 3)
01054         strncpy(path, "../../../", MAX_PATH);
01055     else if (x == 4)
01056         strncpy(path, "../../../../", MAX_PATH);
01057     else
01058         strncpy(path, "./", MAX_PATH);
01059     
01060     if (chdir(path) < 0)
01061         printf("chdir to %s failed\n", path);
01062 }
01063 
01064 /* does current dir contain str */
01065 static INLINE int CurrentDir(const char* str)
01066 {
01067     char  path[MAX_PATH];
01068     char* baseName;
01069 
01070     if (getcwd(path, sizeof(path)) == NULL) {
01071         printf("no current dir?\n");
01072         return 0;
01073     }
01074 
01075     baseName = strrchr(path, '/');
01076     if (baseName)
01077         baseName++;
01078     else
01079         baseName = path;
01080 
01081     if (strstr(baseName, str))
01082         return 1;
01083 
01084     return 0;
01085 }
01086 
01087 #endif /* USE_WINDOWS_API */
01088 
01089 
01090 #ifdef USE_CYASSL_MEMORY
01091 
01092     typedef struct memoryStats {
01093         size_t totalAllocs;     /* number of allocations */
01094         size_t totalBytes;      /* total number of bytes allocated */
01095         size_t peakBytes;       /* concurrent max bytes */
01096         size_t currentBytes;    /* total current bytes in use */
01097     } memoryStats;
01098 
01099     typedef struct memHint {
01100         size_t thisSize;      /* size of this memory */
01101         void*  thisMemory;    /* actual memory for user */
01102     } memHint;
01103 
01104     typedef struct memoryTrack {
01105         union {
01106             memHint hint;
01107             byte    alignit[16];   /* make sure we have strong alignment */
01108         } u;
01109     } memoryTrack;
01110 
01111     #if defined(CYASSL_TRACK_MEMORY)
01112         #define DO_MEM_STATS
01113         static memoryStats ourMemStats;
01114     #endif
01115 
01116     static INLINE void* TrackMalloc(size_t sz)
01117     {
01118         memoryTrack* mt;
01119 
01120         if (sz == 0)
01121             return NULL;
01122 
01123         mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);
01124         if (mt == NULL)
01125             return NULL;
01126 
01127         mt->u.hint.thisSize   = sz;
01128         mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack);
01129 
01130 #ifdef DO_MEM_STATS
01131         ourMemStats.totalAllocs++;
01132         ourMemStats.totalBytes   += sz;
01133         ourMemStats.currentBytes += sz;
01134         if (ourMemStats.currentBytes > ourMemStats.peakBytes)
01135             ourMemStats.peakBytes = ourMemStats.currentBytes;
01136 #endif
01137 
01138         return mt->u.hint.thisMemory;
01139     }
01140 
01141 
01142     static INLINE void TrackFree(void* ptr)
01143     {
01144         memoryTrack* mt;
01145 
01146         if (ptr == NULL)
01147             return;
01148 
01149         mt = (memoryTrack*)ptr;
01150         --mt;   /* same as minus sizeof(memoryTrack), removes header */
01151 
01152 #ifdef DO_MEM_STATS 
01153         ourMemStats.currentBytes -= mt->u.hint.thisSize; 
01154 #endif
01155 
01156         free(mt);
01157     }
01158 
01159 
01160     static INLINE void* TrackRealloc(void* ptr, size_t sz)
01161     {
01162         void* ret = TrackMalloc(sz);
01163 
01164         if (ptr) {
01165             /* if realloc is bigger, don't overread old ptr */
01166             memoryTrack* mt = (memoryTrack*)ptr;
01167             --mt;  /* same as minus sizeof(memoryTrack), removes header */
01168 
01169             if (mt->u.hint.thisSize < sz)
01170                 sz = mt->u.hint.thisSize;
01171         }
01172 
01173         if (ret && ptr)
01174             memcpy(ret, ptr, sz);
01175 
01176         if (ret)
01177             TrackFree(ptr);
01178 
01179         return ret;
01180     }
01181 
01182     static INLINE void InitMemoryTracker(void) 
01183     {
01184         if (CyaSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc) != 0)
01185             err_sys("CyaSSL SetAllocators failed for track memory");
01186 
01187     #ifdef DO_MEM_STATS
01188         ourMemStats.totalAllocs  = 0;
01189         ourMemStats.totalBytes   = 0;
01190         ourMemStats.peakBytes    = 0;
01191         ourMemStats.currentBytes = 0;
01192     #endif
01193     }
01194 
01195     static INLINE void ShowMemoryTracker(void) 
01196     {
01197     #ifdef DO_MEM_STATS 
01198         printf("total   Allocs = %9lu\n",
01199                                        (unsigned long)ourMemStats.totalAllocs);
01200         printf("total   Bytes  = %9lu\n",
01201                                        (unsigned long)ourMemStats.totalBytes);
01202         printf("peak    Bytes  = %9lu\n",
01203                                        (unsigned long)ourMemStats.peakBytes);
01204         printf("current Bytes  = %9lu\n",
01205                                        (unsigned long)ourMemStats.currentBytes);
01206     #endif
01207     }
01208 
01209 #endif /* USE_CYASSL_MEMORY */
01210 
01211 
01212 #ifdef HAVE_STACK_SIZE
01213 
01214 typedef THREAD_RETURN CYASSL_THREAD (*thread_func)(void* args);
01215 
01216 
01217 static INLINE void StackSizeCheck(func_args* args, thread_func tf)
01218 {
01219     int            ret, i, used;
01220     unsigned char* myStack;
01221     int            stackSize = 1024*128;
01222     pthread_attr_t myAttr;
01223     pthread_t      threadId;
01224 
01225 #ifdef PTHREAD_STACK_MIN
01226     if (stackSize < PTHREAD_STACK_MIN)
01227         stackSize = PTHREAD_STACK_MIN;
01228 #endif
01229 
01230     ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
01231     if (ret != 0) 
01232         err_sys("posix_memalign failed\n");        
01233 
01234     memset(myStack, 0x01, stackSize);
01235 
01236     ret = pthread_attr_init(&myAttr);
01237     if (ret != 0)
01238         err_sys("attr_init failed");
01239 
01240     ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
01241     if (ret != 0)
01242         err_sys("attr_setstackaddr failed");
01243 
01244     ret = pthread_create(&threadId, &myAttr, tf, args);
01245     if (ret != 0) {
01246         perror("pthread_create failed");
01247         exit(EXIT_FAILURE);
01248     }
01249 
01250     ret = pthread_join(threadId, NULL);
01251     if (ret != 0)
01252         err_sys("pthread_join failed");
01253 
01254     for (i = 0; i < stackSize; i++) {
01255         if (myStack[i] != 0x01) {
01256             break;
01257         }
01258     }
01259 
01260     used = stackSize - i;
01261     printf("stack used = %d\n", used);
01262 }
01263 
01264 
01265 #endif /* HAVE_STACK_SIZE */
01266 
01267 
01268 #ifdef STACK_TRAP
01269 
01270 /* good settings
01271    --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
01272 
01273 */
01274 
01275 #ifdef HAVE_STACK_SIZE
01276     /* client only for now, setrlimit will fail if pthread_create() called */
01277     /* STACK_SIZE does pthread_create() on client */
01278     #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
01279 #endif /* HAVE_STACK_SIZE */
01280 
01281 static INLINE void StackTrap(void)
01282 {
01283     struct rlimit  rl;
01284     if (getrlimit(RLIMIT_STACK, &rl) != 0)
01285         err_sys("getrlimit failed");
01286     printf("rlim_cur = %llu\n", rl.rlim_cur);
01287     rl.rlim_cur = 1024*21;  /* adjust trap size here */
01288     if (setrlimit(RLIMIT_STACK, &rl) != 0) {
01289         perror("setrlimit");
01290         err_sys("setrlimit failed");
01291     }
01292 }
01293 
01294 #else /* STACK_TRAP */
01295 
01296 static INLINE void StackTrap(void)
01297 {
01298 }
01299 
01300 #endif /* STACK_TRAP */
01301 
01302 
01303 #ifdef ATOMIC_USER
01304 
01305 /* Atomic Encrypt Context example */
01306 typedef struct AtomicEncCtx {
01307     int  keySetup;           /* have we done key setup yet */
01308     Aes  aes;                /* for aes example */
01309 } AtomicEncCtx;
01310 
01311 
01312 /* Atomic Decrypt Context example */
01313 typedef struct AtomicDecCtx {
01314     int  keySetup;           /* have we done key setup yet */
01315     Aes  aes;                /* for aes example */
01316 } AtomicDecCtx;
01317 
01318 
01319 static INLINE int myMacEncryptCb(CYASSL* ssl, unsigned char* macOut, 
01320        const unsigned char* macIn, unsigned int macInSz, int macContent, 
01321        int macVerify, unsigned char* encOut, const unsigned char* encIn,
01322        unsigned int encSz, void* ctx)
01323 {
01324     int  ret;
01325     Hmac hmac;
01326     byte myInner[CYASSL_TLS_HMAC_INNER_SZ];
01327     AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
01328     const char* tlsStr = "TLS";
01329 
01330     /* example supports (d)tls aes */
01331     if (CyaSSL_GetBulkCipher(ssl) != cyassl_aes) {
01332         printf("myMacEncryptCb not using AES\n");
01333         return -1;
01334     }
01335 
01336     if (strstr(CyaSSL_get_version(ssl), tlsStr) == NULL) {
01337         printf("myMacEncryptCb not using (D)TLS\n");
01338         return -1;
01339     }
01340 
01341     /* hmac, not needed if aead mode */
01342     CyaSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
01343 
01344     ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl),
01345                CyaSSL_GetMacSecret(ssl, macVerify), CyaSSL_GetHmacSize(ssl));
01346     if (ret != 0)
01347         return ret;
01348     ret = HmacUpdate(&hmac, myInner, sizeof(myInner));
01349     if (ret != 0)
01350         return ret;
01351     ret = HmacUpdate(&hmac, macIn, macInSz);
01352     if (ret != 0)
01353         return ret;
01354     ret = HmacFinal(&hmac, macOut);
01355     if (ret != 0)
01356         return ret;
01357 
01358 
01359     /* encrypt setup on first time */
01360     if (encCtx->keySetup == 0) {
01361         int   keyLen = CyaSSL_GetKeySize(ssl);
01362         const byte* key;
01363         const byte* iv;
01364 
01365         if (CyaSSL_GetSide(ssl) == CYASSL_CLIENT_END) {
01366             key = CyaSSL_GetClientWriteKey(ssl);
01367             iv  = CyaSSL_GetClientWriteIV(ssl);
01368         }
01369         else {
01370             key = CyaSSL_GetServerWriteKey(ssl);
01371             iv  = CyaSSL_GetServerWriteIV(ssl);
01372         }
01373 
01374         ret = AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
01375         if (ret != 0) {
01376             printf("AesSetKey failed in myMacEncryptCb\n");
01377             return ret;
01378         }
01379         encCtx->keySetup = 1;
01380     }
01381 
01382     /* encrypt */
01383     return AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
01384 }
01385 
01386 
01387 static INLINE int myDecryptVerifyCb(CYASSL* ssl, 
01388        unsigned char* decOut, const unsigned char* decIn,
01389        unsigned int decSz, int macContent, int macVerify,
01390        unsigned int* padSz, void* ctx)
01391 {
01392     AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
01393     int ret      = 0;
01394     int macInSz  = 0;
01395     int ivExtra  = 0;
01396     int digestSz = CyaSSL_GetHmacSize(ssl);
01397     unsigned int pad     = 0;
01398     unsigned int padByte = 0;
01399     Hmac hmac;
01400     byte myInner[CYASSL_TLS_HMAC_INNER_SZ];
01401     byte verify[MAX_DIGEST_SIZE];
01402     const char* tlsStr = "TLS";
01403 
01404     /* example supports (d)tls aes */
01405     if (CyaSSL_GetBulkCipher(ssl) != cyassl_aes) {
01406         printf("myMacEncryptCb not using AES\n");
01407         return -1;
01408     }
01409 
01410     if (strstr(CyaSSL_get_version(ssl), tlsStr) == NULL) {
01411         printf("myMacEncryptCb not using (D)TLS\n");
01412         return -1;
01413     }
01414 
01415     /*decrypt */
01416     if (decCtx->keySetup == 0) {
01417         int   keyLen = CyaSSL_GetKeySize(ssl);
01418         const byte* key;
01419         const byte* iv;
01420 
01421         /* decrypt is from other side (peer) */
01422         if (CyaSSL_GetSide(ssl) == CYASSL_SERVER_END) {
01423             key = CyaSSL_GetClientWriteKey(ssl);
01424             iv  = CyaSSL_GetClientWriteIV(ssl);
01425         }
01426         else {
01427             key = CyaSSL_GetServerWriteKey(ssl);
01428             iv  = CyaSSL_GetServerWriteIV(ssl);
01429         }
01430 
01431         ret = AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
01432         if (ret != 0) {
01433             printf("AesSetKey failed in myDecryptVerifyCb\n");
01434             return ret;
01435         }
01436         decCtx->keySetup = 1;
01437     }
01438 
01439     /* decrypt */
01440     ret = AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
01441 
01442     if (CyaSSL_GetCipherType(ssl) == CYASSL_AEAD_TYPE) {
01443         *padSz = CyaSSL_GetAeadMacSize(ssl);
01444         return 0; /* hmac, not needed if aead mode */
01445     }
01446 
01447     if (CyaSSL_GetCipherType(ssl) == CYASSL_BLOCK_TYPE) {
01448         pad     = *(decOut + decSz - 1);
01449         padByte = 1;
01450         if (CyaSSL_IsTLSv1_1(ssl))
01451             ivExtra = CyaSSL_GetCipherBlockSize(ssl);
01452     }
01453 
01454     *padSz  = CyaSSL_GetHmacSize(ssl) + pad + padByte;
01455     macInSz = decSz - ivExtra - digestSz - pad - padByte;
01456 
01457     CyaSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
01458 
01459     ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl),
01460                CyaSSL_GetMacSecret(ssl, macVerify), digestSz);
01461     if (ret != 0)
01462         return ret;
01463     ret = HmacUpdate(&hmac, myInner, sizeof(myInner));
01464     if (ret != 0)
01465         return ret;
01466     ret = HmacUpdate(&hmac, decOut + ivExtra, macInSz);
01467     if (ret != 0)
01468         return ret;
01469     ret = HmacFinal(&hmac, verify);
01470     if (ret != 0)
01471         return ret;
01472 
01473     if (memcmp(verify, decOut + decSz - digestSz - pad - padByte,
01474                digestSz) != 0) {
01475         printf("myDecryptVerify verify failed\n");
01476         return -1;
01477     }
01478 
01479     return ret;
01480 }
01481 
01482 
01483 static INLINE void SetupAtomicUser(CYASSL_CTX* ctx, CYASSL* ssl)
01484 {
01485     AtomicEncCtx* encCtx;
01486     AtomicDecCtx* decCtx;
01487 
01488     encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
01489     if (encCtx == NULL)
01490         err_sys("AtomicEncCtx malloc failed");
01491     memset(encCtx, 0, sizeof(AtomicEncCtx));
01492 
01493     decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
01494     if (decCtx == NULL) {
01495         free(encCtx);
01496         err_sys("AtomicDecCtx malloc failed");
01497     }
01498     memset(decCtx, 0, sizeof(AtomicDecCtx));
01499 
01500     CyaSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
01501     CyaSSL_SetMacEncryptCtx(ssl, encCtx);
01502 
01503     CyaSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
01504     CyaSSL_SetDecryptVerifyCtx(ssl, decCtx);
01505 }
01506 
01507 
01508 static INLINE void FreeAtomicUser(CYASSL* ssl)
01509 {
01510     AtomicEncCtx* encCtx = CyaSSL_GetMacEncryptCtx(ssl);
01511     AtomicDecCtx* decCtx = CyaSSL_GetDecryptVerifyCtx(ssl);
01512 
01513     free(decCtx);
01514     free(encCtx);
01515 }
01516 
01517 #endif /* ATOMIC_USER */
01518 
01519 
01520 #ifdef HAVE_PK_CALLBACKS
01521 
01522 #ifdef HAVE_ECC
01523 
01524 static INLINE int myEccSign(CYASSL* ssl, const byte* in, word32 inSz,
01525         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
01526 {
01527     RNG     rng;
01528     int     ret;
01529     word32  idx = 0;
01530     ecc_key myKey;
01531 
01532     (void)ssl;
01533     (void)ctx;
01534 
01535     ret = InitRng(&rng);
01536     if (ret != 0)
01537         return ret;
01538 
01539     ecc_init(&myKey);
01540     
01541     ret = EccPrivateKeyDecode(key, &idx, &myKey, keySz);    
01542     if (ret == 0)
01543         ret = ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
01544     ecc_free(&myKey);
01545 
01546     return ret;
01547 }
01548 
01549 
01550 static INLINE int myEccVerify(CYASSL* ssl, const byte* sig, word32 sigSz,
01551         const byte* hash, word32 hashSz, const byte* key, word32 keySz,
01552         int* result, void* ctx)
01553 {
01554     int     ret;
01555     ecc_key myKey;
01556 
01557     (void)ssl;
01558     (void)ctx;
01559 
01560     ecc_init(&myKey);
01561     
01562     ret = ecc_import_x963(key, keySz, &myKey);
01563     if (ret == 0)
01564         ret = ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
01565     ecc_free(&myKey);
01566 
01567     return ret;
01568 }
01569 
01570 #endif /* HAVE_ECC */
01571 
01572 #ifndef NO_RSA
01573 
01574 static INLINE int myRsaSign(CYASSL* ssl, const byte* in, word32 inSz,
01575         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
01576 {
01577     RNG     rng;
01578     int     ret;
01579     word32  idx = 0;
01580     RsaKey  myKey;
01581 
01582     (void)ssl;
01583     (void)ctx;
01584 
01585     ret = InitRng(&rng);
01586     if (ret != 0)
01587         return ret;
01588 
01589     InitRsaKey(&myKey, NULL);
01590     
01591     ret = RsaPrivateKeyDecode(key, &idx, &myKey, keySz);    
01592     if (ret == 0)
01593         ret = RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
01594     if (ret > 0) {  /* save and convert to 0 success */
01595         *outSz = ret;
01596         ret = 0;
01597     }
01598     FreeRsaKey(&myKey);
01599 
01600     return ret;
01601 }
01602 
01603 
01604 static INLINE int myRsaVerify(CYASSL* ssl, byte* sig, word32 sigSz,
01605         byte** out,
01606         const byte* key, word32 keySz,
01607         void* ctx)
01608 {
01609     int     ret;
01610     word32  idx = 0;
01611     RsaKey  myKey;
01612 
01613     (void)ssl;
01614     (void)ctx;
01615 
01616     InitRsaKey(&myKey, NULL);
01617     
01618     ret = RsaPublicKeyDecode(key, &idx, &myKey, keySz);
01619     if (ret == 0)
01620         ret = RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
01621     FreeRsaKey(&myKey);
01622 
01623     return ret;
01624 }
01625 
01626 
01627 static INLINE int myRsaEnc(CYASSL* ssl, const byte* in, word32 inSz,
01628                            byte* out, word32* outSz, const byte* key,
01629                            word32 keySz, void* ctx)
01630 {
01631     int     ret;
01632     word32  idx = 0;
01633     RsaKey  myKey;
01634     RNG     rng;
01635 
01636     (void)ssl;
01637     (void)ctx;
01638 
01639     ret = InitRng(&rng);
01640     if (ret != 0)
01641         return ret;
01642 
01643     InitRsaKey(&myKey, NULL);
01644     
01645     ret = RsaPublicKeyDecode(key, &idx, &myKey, keySz);
01646     if (ret == 0) {
01647         ret = RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
01648         if (ret > 0) {
01649             *outSz = ret;
01650             ret = 0;  /* reset to success */
01651         }
01652     }
01653     FreeRsaKey(&myKey);
01654 
01655     return ret;
01656 }
01657 
01658 static INLINE int myRsaDec(CYASSL* ssl, byte* in, word32 inSz,
01659                            byte** out,
01660                            const byte* key, word32 keySz, void* ctx)
01661 {
01662     int     ret;
01663     word32  idx = 0;
01664     RsaKey  myKey;
01665 
01666     (void)ssl;
01667     (void)ctx;
01668 
01669     InitRsaKey(&myKey, NULL);
01670     
01671     ret = RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
01672     if (ret == 0) {
01673         ret = RsaPrivateDecryptInline(in, inSz, out, &myKey);
01674     }
01675     FreeRsaKey(&myKey);
01676 
01677     return ret;
01678 }
01679 
01680 #endif /* NO_RSA */
01681 
01682 static INLINE void SetupPkCallbacks(CYASSL_CTX* ctx, CYASSL* ssl)
01683 {
01684     (void)ctx;
01685     (void)ssl;
01686 
01687     #ifdef HAVE_ECC
01688         CyaSSL_CTX_SetEccSignCb(ctx, myEccSign);
01689         CyaSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
01690     #endif /* HAVE_ECC */
01691     #ifndef NO_RSA 
01692         CyaSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
01693         CyaSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
01694         CyaSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
01695         CyaSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
01696     #endif /* NO_RSA */
01697 }
01698 
01699 #endif /* HAVE_PK_CALLBACKS */
01700 
01701 
01702 
01703 
01704 
01705 #if defined(__hpux__) || defined(__MINGW32__)
01706 
01707 /* HP/UX doesn't have strsep, needed by test/suites.c */
01708 static INLINE char* strsep(char **stringp, const char *delim)
01709 {
01710     char* start;
01711     char* end;
01712 
01713     start = *stringp;
01714     if (start == NULL)
01715         return NULL;
01716 
01717     if ((end = strpbrk(start, delim))) {
01718         *end++ = '\0';
01719         *stringp = end;
01720     } else {
01721         *stringp = NULL;
01722     }
01723 
01724     return start;
01725 }
01726 
01727 #endif /* __hpux__ */
01728 
01729 #endif /* CyaSSL_TEST_H */
01730 
01731