Fork of CyaSSL for my specific settings
Fork of CyaSSL by
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 21:40:06 by 1.7.2