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