This is a port of cyaSSL 2.7.0.
Dependents: CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet
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
Generated on Tue Jul 12 2022 20:44:52 by 1.7.2