Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
test.h
00001 /* test.h */ 00002 00003 #ifndef wolfSSL_TEST_H 00004 #define wolfSSL_TEST_H 00005 00006 #include <stdio.h> 00007 #include <stdlib.h> 00008 #include <assert.h> 00009 #include <ctype.h> 00010 #include <wolfssl/wolfcrypt/types.h> 00011 #include <wolfssl/wolfcrypt/error-crypt.h> 00012 #include <wolfssl/wolfcrypt/random.h> 00013 00014 #ifdef ATOMIC_USER 00015 #include <wolfssl/wolfcrypt/aes.h> 00016 #include <wolfssl/wolfcrypt/arc4.h> 00017 #include <wolfssl/wolfcrypt/hmac.h> 00018 #endif 00019 #ifdef HAVE_PK_CALLBACKS 00020 #include <wolfssl/wolfcrypt/asn.h> 00021 #ifndef NO_RSA 00022 #include <wolfssl/wolfcrypt/rsa.h> 00023 #endif 00024 #ifdef HAVE_ECC 00025 #include <wolfssl/wolfcrypt/ecc.h> 00026 #endif /* HAVE_ECC */ 00027 #endif /*HAVE_PK_CALLBACKS */ 00028 00029 #ifdef USE_WINDOWS_API 00030 #include <winsock2.h> 00031 #include <process.h> 00032 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ 00033 #include <ws2tcpip.h> 00034 #include <wspiapi.h> 00035 #endif 00036 #define SOCKET_T SOCKET 00037 #define SNPRINTF _snprintf 00038 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00039 #include <string.h> 00040 #include "rl_net.h" 00041 #define SOCKET_T int 00042 typedef int socklen_t ; 00043 static unsigned long inet_addr(const char *cp) 00044 { 00045 unsigned int a[4] ; unsigned long ret ; 00046 sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ; 00047 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ; 00048 return(ret) ; 00049 } 00050 #if defined(HAVE_KEIL_RTX) 00051 #define sleep(t) os_dly_wait(t/1000+1) ; 00052 #elif defined (WOLFSSL_CMSIS_RTOS) 00053 #define sleep(t) osDelay(t/1000+1) ; 00054 #endif 00055 00056 static int wolfssl_tcp_select(int sd, int timeout) 00057 { return 0 ; } 00058 #define tcp_select(sd,t) wolfssl_tcp_select(sd, t) /* avoid conflicting Keil TCP tcp_select */ 00059 #elif defined(WOLFSSL_TIRTOS) 00060 #include <string.h> 00061 #include <netdb.h> 00062 #include <sys/types.h> 00063 #include <arpa/inet.h> 00064 #include <sys/socket.h> 00065 #include <ti/sysbios/knl/Task.h> 00066 struct hostent { 00067 char *h_name; /* official name of host */ 00068 char **h_aliases; /* alias list */ 00069 int h_addrtype; /* host address type */ 00070 int h_length; /* length of address */ 00071 char **h_addr_list; /* list of addresses from name server */ 00072 }; 00073 #define SOCKET_T int 00074 #elif defined(WOLFSSL_VXWORKS) 00075 #include <hostLib.h> 00076 #include <sockLib.h> 00077 #include <arpa/inet.h> 00078 #include <string.h> 00079 #include <selectLib.h> 00080 #include <sys/types.h> 00081 #include <netinet/in.h> 00082 #include <fcntl.h> 00083 #include <sys/time.h> 00084 #include <netdb.h> 00085 #include <pthread.h> 00086 #define SOCKET_T int 00087 #else 00088 #include <string.h> 00089 #include <sys/types.h> 00090 #ifndef WOLFSSL_LEANPSK 00091 #include <unistd.h> 00092 #include <netdb.h> 00093 #include <netinet/in.h> 00094 #include <netinet/tcp.h> 00095 #include <arpa/inet.h> 00096 #include <sys/ioctl.h> 00097 #include <sys/time.h> 00098 #include <sys/socket.h> 00099 #include <pthread.h> 00100 #include <fcntl.h> 00101 #ifdef TEST_IPV6 00102 #include <netdb.h> 00103 #endif 00104 #endif 00105 #define SOCKET_T int 00106 #ifndef SO_NOSIGPIPE 00107 #include <signal.h> /* ignore SIGPIPE */ 00108 #endif 00109 #define SNPRINTF snprintf 00110 #endif /* USE_WINDOWS_API */ 00111 00112 #ifdef WOLFSSL_ASYNC_CRYPT 00113 #include <wolfssl/wolfcrypt/async.h> 00114 #endif 00115 #ifdef HAVE_CAVIUM 00116 #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h> 00117 #endif 00118 00119 #ifdef _MSC_VER 00120 /* disable conversion warning */ 00121 /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ 00122 #pragma warning(disable:4244 4996) 00123 #endif 00124 00125 /* Buffer for benchmark tests */ 00126 #ifndef TEST_BUFFER_SIZE 00127 #define TEST_BUFFER_SIZE 16384 00128 #endif 00129 00130 #ifndef WOLFSSL_HAVE_MIN 00131 #define WOLFSSL_HAVE_MIN 00132 static INLINE word32 min(word32 a, word32 b) 00133 { 00134 return a > b ? b : a; 00135 } 00136 #endif /* WOLFSSL_HAVE_MIN */ 00137 00138 /* Socket Handling */ 00139 #ifndef WOLFSSL_SOCKET_INVALID 00140 #ifdef USE_WINDOWS_API 00141 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET) 00142 #elif defined(WOLFSSL_TIRTOS) 00143 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1) 00144 #else 00145 #define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0) 00146 #endif 00147 #endif /* WOLFSSL_SOCKET_INVALID */ 00148 00149 #ifndef WOLFSSL_SOCKET_IS_INVALID 00150 #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) 00151 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID) 00152 #else 00153 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID) 00154 #endif 00155 #endif /* WOLFSSL_SOCKET_IS_INVALID */ 00156 00157 #if defined(__MACH__) || defined(USE_WINDOWS_API) 00158 #ifndef _SOCKLEN_T 00159 typedef int socklen_t; 00160 #endif 00161 #endif 00162 00163 00164 /* HPUX doesn't use socklent_t for third parameter to accept, unless 00165 _XOPEN_SOURCE_EXTENDED is defined */ 00166 #if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\ 00167 && !defined(WOLFSSL_ROWLEY_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) 00168 typedef socklen_t* ACCEPT_THIRD_T; 00169 #else 00170 #if defined _XOPEN_SOURCE_EXTENDED 00171 typedef socklen_t* ACCEPT_THIRD_T; 00172 #else 00173 typedef int* ACCEPT_THIRD_T; 00174 #endif 00175 #endif 00176 00177 00178 #ifdef USE_WINDOWS_API 00179 #define CloseSocket(s) closesocket(s) 00180 #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); } 00181 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00182 #define CloseSocket(s) closesocket(s) 00183 #define StartTCP() 00184 #else 00185 #define CloseSocket(s) close(s) 00186 #define StartTCP() 00187 #endif 00188 00189 00190 #ifdef SINGLE_THREADED 00191 typedef unsigned int THREAD_RETURN; 00192 typedef void* THREAD_TYPE; 00193 #define WOLFSSL_THREAD 00194 #else 00195 #if defined(_POSIX_THREADS) && !defined(__MINGW32__) 00196 typedef void* THREAD_RETURN; 00197 typedef pthread_t THREAD_TYPE; 00198 #define WOLFSSL_THREAD 00199 #define INFINITE -1 00200 #define WAIT_OBJECT_0 0L 00201 #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) 00202 typedef unsigned int THREAD_RETURN; 00203 typedef int THREAD_TYPE; 00204 #define WOLFSSL_THREAD 00205 #elif defined(WOLFSSL_TIRTOS) 00206 typedef void THREAD_RETURN; 00207 typedef Task_Handle THREAD_TYPE; 00208 #define WOLFSSL_THREAD 00209 #else 00210 typedef unsigned int THREAD_RETURN; 00211 typedef intptr_t THREAD_TYPE; 00212 #define WOLFSSL_THREAD __stdcall 00213 #endif 00214 #endif 00215 00216 00217 #ifdef TEST_IPV6 00218 typedef struct sockaddr_in6 SOCKADDR_IN_T; 00219 #define AF_INET_V AF_INET6 00220 #else 00221 typedef struct sockaddr_in SOCKADDR_IN_T; 00222 #define AF_INET_V AF_INET 00223 #endif 00224 00225 00226 #define SERVER_DEFAULT_VERSION 3 00227 #define SERVER_DTLS_DEFAULT_VERSION (-2) 00228 #define SERVER_INVALID_VERSION (-99) 00229 #define CLIENT_DEFAULT_VERSION 3 00230 #define CLIENT_DTLS_DEFAULT_VERSION (-2) 00231 #define CLIENT_INVALID_VERSION (-99) 00232 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) 00233 #define DEFAULT_MIN_DHKEY_BITS 2048 00234 #else 00235 #define DEFAULT_MIN_DHKEY_BITS 1024 00236 #endif 00237 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) 00238 #define DEFAULT_MIN_RSAKEY_BITS 2048 00239 #else 00240 #define DEFAULT_MIN_RSAKEY_BITS 1024 00241 #endif 00242 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) 00243 #define DEFAULT_MIN_ECCKEY_BITS 256 00244 #else 00245 #define DEFAULT_MIN_ECCKEY_BITS 224 00246 #endif 00247 00248 /* all certs relative to wolfSSL home directory now */ 00249 #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL) 00250 #define caCertFile "certs/ca-cert.pem" 00251 #define eccCertFile "certs/server-ecc.pem" 00252 #define eccKeyFile "certs/ecc-key.pem" 00253 #define svrCertFile "certs/server-cert.pem" 00254 #define svrKeyFile "certs/server-key.pem" 00255 #define cliCertFile "certs/client-cert.pem" 00256 #define cliKeyFile "certs/client-key.pem" 00257 #define ntruCertFile "certs/ntru-cert.pem" 00258 #define ntruKeyFile "certs/ntru-key.raw" 00259 #define dhParamFile "certs/dh2048.pem" 00260 #define cliEccKeyFile "certs/ecc-client-key.pem" 00261 #define cliEccCertFile "certs/client-ecc-cert.pem" 00262 #define crlPemDir "certs/crl" 00263 #ifdef HAVE_WNR 00264 /* Whitewood netRandom default config file */ 00265 #define wnrConfig "wnr-example.conf" 00266 #endif 00267 #else 00268 #define caCertFile "./certs/ca-cert.pem" 00269 #define eccCertFile "./certs/server-ecc.pem" 00270 #define eccKeyFile "./certs/ecc-key.pem" 00271 #define svrCertFile "./certs/server-cert.pem" 00272 #define svrKeyFile "./certs/server-key.pem" 00273 #define cliCertFile "./certs/client-cert.pem" 00274 #define cliKeyFile "./certs/client-key.pem" 00275 #define ntruCertFile "./certs/ntru-cert.pem" 00276 #define ntruKeyFile "./certs/ntru-key.raw" 00277 #define dhParamFile "./certs/dh2048.pem" 00278 #define cliEccKeyFile "./certs/ecc-client-key.pem" 00279 #define cliEccCertFile "./certs/client-ecc-cert.pem" 00280 #define crlPemDir "./certs/crl" 00281 #ifdef HAVE_WNR 00282 /* Whitewood netRandom default config file */ 00283 #define wnrConfig "./wnr-example.conf" 00284 #endif 00285 #endif 00286 00287 typedef struct tcp_ready { 00288 word16 ready; /* predicate */ 00289 word16 port; 00290 char* srfName; /* server ready file name */ 00291 #if defined(_POSIX_THREADS) && !defined(__MINGW32__) 00292 pthread_mutex_t mutex; 00293 pthread_cond_t cond; 00294 #endif 00295 } tcp_ready; 00296 00297 00298 static INLINE void InitTcpReady(tcp_ready* ready) 00299 { 00300 ready->ready = 0; 00301 ready->port = 0; 00302 ready->srfName = NULL; 00303 #ifdef SINGLE_THREADED 00304 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) 00305 pthread_mutex_init(&ready->mutex, 0); 00306 pthread_cond_init(&ready->cond, 0); 00307 #endif 00308 } 00309 00310 00311 static INLINE void FreeTcpReady(tcp_ready* ready) 00312 { 00313 #ifdef SINGLE_THREADED 00314 (void)ready; 00315 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) 00316 pthread_mutex_destroy(&ready->mutex); 00317 pthread_cond_destroy(&ready->cond); 00318 #else 00319 (void)ready; 00320 #endif 00321 } 00322 00323 typedef WOLFSSL_METHOD* (*method_provider)(void); 00324 typedef void (*ctx_callback)(WOLFSSL_CTX* ctx); 00325 typedef void (*ssl_callback)(WOLFSSL* ssl); 00326 00327 typedef struct callback_functions { 00328 method_provider method; 00329 ctx_callback ctx_ready; 00330 ssl_callback ssl_ready; 00331 ssl_callback on_result; 00332 } callback_functions; 00333 00334 typedef struct func_args { 00335 int argc; 00336 char** argv; 00337 int return_code; 00338 tcp_ready* signal; 00339 callback_functions *callbacks; 00340 } func_args; 00341 00342 00343 00344 00345 void wait_tcp_ready(func_args*); 00346 00347 typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*); 00348 00349 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*); 00350 void join_thread(THREAD_TYPE); 00351 00352 /* wolfSSL */ 00353 #ifndef TEST_IPV6 00354 static const char* const wolfSSLIP = "127.0.0.1"; 00355 #else 00356 static const char* const wolfSSLIP = "::1"; 00357 #endif 00358 static const word16 wolfSSLPort = 11111; 00359 00360 00361 #if defined(__GNUC__) 00362 #define WC_NORETURN __attribute__((noreturn)) 00363 #else 00364 #define WC_NORETURN 00365 #endif 00366 00367 static INLINE WC_NORETURN void err_sys(const char* msg) 00368 { 00369 printf("wolfSSL error: %s\n", msg); 00370 00371 #if !defined(__GNUC__) 00372 /* scan-build (which pretends to be gnuc) can get confused and think the 00373 * msg pointer can be null even when hardcoded and then it won't exit, 00374 * making null pointer checks above the err_sys() call useless. 00375 * We could just always exit() but some compilers will complain about no 00376 * possible return, with gcc we know the attribute to handle that with 00377 * WC_NORETURN. */ 00378 if (msg) 00379 #endif 00380 { 00381 exit(EXIT_FAILURE); 00382 } 00383 } 00384 00385 00386 #define MY_EX_USAGE 2 00387 00388 extern int myoptind; 00389 extern char* myoptarg; 00390 00391 static INLINE int mygetopt(int argc, char** argv, const char* optstring) 00392 { 00393 static char* next = NULL; 00394 00395 char c; 00396 char* cp; 00397 00398 if (myoptind == 0) 00399 next = NULL; /* we're starting new/over */ 00400 00401 if (next == NULL || *next == '\0') { 00402 if (myoptind == 0) 00403 myoptind++; 00404 00405 if (myoptind >= argc || argv[myoptind][0] != '-' || 00406 argv[myoptind][1] == '\0') { 00407 myoptarg = NULL; 00408 if (myoptind < argc) 00409 myoptarg = argv[myoptind]; 00410 00411 return -1; 00412 } 00413 00414 if (strcmp(argv[myoptind], "--") == 0) { 00415 myoptind++; 00416 myoptarg = NULL; 00417 00418 if (myoptind < argc) 00419 myoptarg = argv[myoptind]; 00420 00421 return -1; 00422 } 00423 00424 next = argv[myoptind]; 00425 next++; /* skip - */ 00426 myoptind++; 00427 } 00428 00429 c = *next++; 00430 /* The C++ strchr can return a different value */ 00431 cp = (char*)strchr(optstring, c); 00432 00433 if (cp == NULL || c == ':') 00434 return '?'; 00435 00436 cp++; 00437 00438 if (*cp == ':') { 00439 if (*next != '\0') { 00440 myoptarg = next; 00441 next = NULL; 00442 } 00443 else if (myoptind < argc) { 00444 myoptarg = argv[myoptind]; 00445 myoptind++; 00446 } 00447 else 00448 return '?'; 00449 } 00450 00451 return c; 00452 } 00453 00454 00455 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) 00456 00457 static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) 00458 { 00459 (void)rw; 00460 (void)userdata; 00461 strncpy(passwd, "yassl123", sz); 00462 return 8; 00463 } 00464 00465 #endif 00466 00467 00468 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) 00469 00470 static INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr) 00471 { 00472 char* altName; 00473 char* issuer; 00474 char* subject; 00475 byte serial[32]; 00476 int ret; 00477 int sz = sizeof(serial); 00478 00479 if (x509 == NULL) { 00480 printf("%s No Cert\n", hdr); 00481 return; 00482 } 00483 00484 issuer = wolfSSL_X509_NAME_oneline( 00485 wolfSSL_X509_get_issuer_name(x509), 0, 0); 00486 subject = wolfSSL_X509_NAME_oneline( 00487 wolfSSL_X509_get_subject_name(x509), 0, 0); 00488 00489 printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject); 00490 00491 while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL) 00492 printf(" altname = %s\n", altName); 00493 00494 ret = wolfSSL_X509_get_serial_number(x509, serial, &sz); 00495 if (ret == SSL_SUCCESS) { 00496 int i; 00497 int strLen; 00498 char serialMsg[80]; 00499 00500 /* testsuite has multiple threads writing to stdout, get output 00501 message ready to write once */ 00502 strLen = sprintf(serialMsg, " serial number"); 00503 for (i = 0; i < sz; i++) 00504 sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]); 00505 printf("%s\n", serialMsg); 00506 } 00507 00508 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); 00509 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); 00510 } 00511 00512 #endif /* KEEP_PEER_CERT || SESSION_CERTS */ 00513 00514 00515 static INLINE void showPeer(WOLFSSL* ssl) 00516 { 00517 00518 WOLFSSL_CIPHER* cipher; 00519 #ifdef HAVE_ECC 00520 const char *name; 00521 #endif 00522 #ifndef NO_DH 00523 int bits; 00524 #endif 00525 #ifdef KEEP_PEER_CERT 00526 WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); 00527 if (peer) 00528 ShowX509(peer, "peer's cert info:"); 00529 else 00530 printf("peer has no cert!\n"); 00531 wolfSSL_FreeX509(peer); 00532 #endif 00533 #if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT) 00534 ShowX509(wolfSSL_get_certificate(ssl), "our cert info:"); 00535 printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl)); 00536 #endif /* SHOW_CERTS */ 00537 printf("SSL version is %s\n", wolfSSL_get_version(ssl)); 00538 00539 cipher = wolfSSL_get_current_cipher(ssl); 00540 #ifdef HAVE_QSH 00541 printf("SSL cipher suite is %s%s\n", (wolfSSL_isQSH(ssl))? "QSH:": "", 00542 wolfSSL_CIPHER_get_name(cipher)); 00543 #else 00544 printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); 00545 #endif 00546 #ifdef HAVE_ECC 00547 if ((name = wolfSSL_get_curve_name(ssl)) != NULL) 00548 printf("SSL curve name is %s\n", name); 00549 #endif 00550 #ifndef NO_DH 00551 if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0) 00552 printf("SSL DH size is %d bits\n", bits); 00553 #endif 00554 if (wolfSSL_session_reused(ssl)) 00555 printf("SSL reused session\n"); 00556 00557 #if defined(SESSION_CERTS) && defined(SHOW_CERTS) 00558 { 00559 WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl); 00560 int count = wolfSSL_get_chain_count(chain); 00561 int i; 00562 00563 for (i = 0; i < count; i++) { 00564 int length; 00565 unsigned char buffer[3072]; 00566 WOLFSSL_X509* chainX509; 00567 00568 wolfSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length); 00569 buffer[length] = 0; 00570 printf("cert %d has length %d data = \n%s\n", i, length, buffer); 00571 00572 chainX509 = wolfSSL_get_chain_X509(chain, i); 00573 if (chainX509) 00574 ShowX509(chainX509, "session cert info:"); 00575 else 00576 printf("get_chain_X509 failed\n"); 00577 wolfSSL_FreeX509(chainX509); 00578 } 00579 } 00580 #endif 00581 (void)ssl; 00582 } 00583 00584 00585 static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, 00586 word16 port, int udp, int sctp) 00587 { 00588 int useLookup = 0; 00589 (void)useLookup; 00590 (void)udp; 00591 (void)sctp; 00592 00593 if (addr == NULL) 00594 err_sys("invalid argument to build_addr, addr is NULL"); 00595 00596 memset(addr, 0, sizeof(SOCKADDR_IN_T)); 00597 00598 #ifndef TEST_IPV6 00599 /* peer could be in human readable form */ 00600 if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) { 00601 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00602 int err; 00603 struct hostent* entry = gethostbyname(peer, &err); 00604 #elif defined(WOLFSSL_TIRTOS) 00605 struct hostent* entry = DNSGetHostByName(peer); 00606 #elif defined(WOLFSSL_VXWORKS) 00607 struct hostent* entry = (struct hostent*)hostGetByName((char*)peer); 00608 #else 00609 struct hostent* entry = gethostbyname(peer); 00610 #endif 00611 00612 if (entry) { 00613 XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0], 00614 entry->h_length); 00615 useLookup = 1; 00616 } 00617 else 00618 err_sys("no entry for host"); 00619 } 00620 #endif 00621 00622 00623 #ifndef TEST_IPV6 00624 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00625 addr->sin_family = PF_INET; 00626 #else 00627 addr->sin_family = AF_INET_V; 00628 #endif 00629 addr->sin_port = XHTONS(port); 00630 if (peer == INADDR_ANY) 00631 addr->sin_addr.s_addr = INADDR_ANY; 00632 else { 00633 if (!useLookup) 00634 addr->sin_addr.s_addr = inet_addr(peer); 00635 } 00636 #else 00637 addr->sin6_family = AF_INET_V; 00638 addr->sin6_port = XHTONS(port); 00639 if (peer == INADDR_ANY) 00640 addr->sin6_addr = in6addr_any; 00641 else { 00642 #ifdef HAVE_GETADDRINFO 00643 struct addrinfo hints; 00644 struct addrinfo* answer = NULL; 00645 int ret; 00646 char strPort[80]; 00647 00648 memset(&hints, 0, sizeof(hints)); 00649 00650 hints.ai_family = AF_INET_V; 00651 if (udp) { 00652 hints.ai_socktype = SOCK_DGRAM; 00653 hints.ai_protocol = IPPROTO_UDP; 00654 } 00655 #ifdef WOLFSSL_SCTP 00656 else if (sctp) { 00657 hints.ai_socktype = SOCK_STREAM; 00658 hints.ai_protocol = IPPROTO_SCTP; 00659 } 00660 #endif 00661 else { 00662 hints.ai_socktype = SOCK_STREAM; 00663 hints.ai_protocol = IPPROTO_TCP; 00664 } 00665 00666 SNPRINTF(strPort, sizeof(strPort), "%d", port); 00667 strPort[79] = '\0'; 00668 00669 ret = getaddrinfo(peer, strPort, &hints, &answer); 00670 if (ret < 0 || answer == NULL) 00671 err_sys("getaddrinfo failed"); 00672 00673 XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen); 00674 freeaddrinfo(answer); 00675 #else 00676 printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); 00677 addr->sin6_addr = in6addr_loopback; 00678 #endif 00679 } 00680 #endif 00681 } 00682 00683 00684 static INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) 00685 { 00686 (void)sctp; 00687 00688 if (udp) 00689 *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP); 00690 #ifdef WOLFSSL_SCTP 00691 else if (sctp) 00692 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP); 00693 #endif 00694 else 00695 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP); 00696 00697 if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) { 00698 err_sys("socket failed\n"); 00699 } 00700 00701 #ifndef USE_WINDOWS_API 00702 #ifdef SO_NOSIGPIPE 00703 { 00704 int on = 1; 00705 socklen_t len = sizeof(on); 00706 int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); 00707 if (res < 0) 00708 err_sys("setsockopt SO_NOSIGPIPE failed\n"); 00709 } 00710 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\ 00711 defined(WOLFSSL_KEIL_TCP_NET) 00712 /* nothing to define */ 00713 #else /* no S_NOSIGPIPE */ 00714 signal(SIGPIPE, SIG_IGN); 00715 #endif /* S_NOSIGPIPE */ 00716 00717 #if defined(TCP_NODELAY) 00718 if (!udp && !sctp) 00719 { 00720 int on = 1; 00721 socklen_t len = sizeof(on); 00722 int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len); 00723 if (res < 0) 00724 err_sys("setsockopt TCP_NODELAY failed\n"); 00725 } 00726 #endif 00727 #endif /* USE_WINDOWS_API */ 00728 } 00729 00730 static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, 00731 int udp, int sctp, WOLFSSL* ssl) 00732 { 00733 SOCKADDR_IN_T addr; 00734 build_addr(&addr, ip, port, udp, sctp); 00735 if (udp) { 00736 wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); 00737 } 00738 tcp_socket(sockfd, udp, sctp); 00739 00740 if (!udp) { 00741 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00742 err_sys("tcp connect failed"); 00743 } 00744 } 00745 00746 00747 static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz) 00748 { 00749 if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0) 00750 err_sys("tcp connect failed"); 00751 } 00752 00753 00754 enum { 00755 TEST_SELECT_FAIL, 00756 TEST_TIMEOUT, 00757 TEST_RECV_READY, 00758 TEST_ERROR_READY 00759 }; 00760 00761 00762 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \ 00763 !defined(WOLFSSL_TIRTOS) 00764 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec) 00765 { 00766 fd_set recvfds, errfds; 00767 SOCKET_T nfds = socketfd + 1; 00768 struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0}; 00769 int result; 00770 00771 FD_ZERO(&recvfds); 00772 FD_SET(socketfd, &recvfds); 00773 FD_ZERO(&errfds); 00774 FD_SET(socketfd, &errfds); 00775 00776 result = select(nfds, &recvfds, NULL, &errfds, &timeout); 00777 00778 if (result == 0) 00779 return TEST_TIMEOUT; 00780 else if (result > 0) { 00781 if (FD_ISSET(socketfd, &recvfds)) 00782 return TEST_RECV_READY; 00783 else if(FD_ISSET(socketfd, &errfds)) 00784 return TEST_ERROR_READY; 00785 } 00786 00787 return TEST_SELECT_FAIL; 00788 } 00789 #elif defined(WOLFSSL_TIRTOS) 00790 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec) 00791 { 00792 return TEST_RECV_READY; 00793 } 00794 #endif /* !WOLFSSL_MDK_ARM */ 00795 00796 00797 static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, 00798 int udp, int sctp) 00799 { 00800 SOCKADDR_IN_T addr; 00801 00802 /* don't use INADDR_ANY by default, firewall may block, make user switch 00803 on */ 00804 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp); 00805 tcp_socket(sockfd, udp, sctp); 00806 00807 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ 00808 && !defined(WOLFSSL_KEIL_TCP_NET) 00809 { 00810 int res, on = 1; 00811 socklen_t len = sizeof(on); 00812 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); 00813 if (res < 0) 00814 err_sys("setsockopt SO_REUSEADDR failed\n"); 00815 } 00816 #endif 00817 00818 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00819 err_sys("tcp bind failed"); 00820 if (!udp) { 00821 if (listen(*sockfd, 5) != 0) 00822 err_sys("tcp listen failed"); 00823 } 00824 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) 00825 if (*port == 0) { 00826 socklen_t len = sizeof(addr); 00827 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { 00828 #ifndef TEST_IPV6 00829 *port = XNTOHS(addr.sin_port); 00830 #else 00831 *port = XNTOHS(addr.sin6_port); 00832 #endif 00833 } 00834 } 00835 #endif 00836 } 00837 00838 00839 #if 0 00840 static INLINE int udp_read_connect(SOCKET_T sockfd) 00841 { 00842 SOCKADDR_IN_T cliaddr; 00843 byte b[1500]; 00844 int n; 00845 socklen_t len = sizeof(cliaddr); 00846 00847 n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK, 00848 (struct sockaddr*)&cliaddr, &len); 00849 if (n > 0) { 00850 if (connect(sockfd, (const struct sockaddr*)&cliaddr, 00851 sizeof(cliaddr)) != 0) 00852 err_sys("udp connect failed"); 00853 } 00854 else 00855 err_sys("recvfrom failed"); 00856 00857 return sockfd; 00858 } 00859 #endif 00860 00861 static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, 00862 int useAnyAddr, word16 port, func_args* args) 00863 { 00864 SOCKADDR_IN_T addr; 00865 00866 (void)args; 00867 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0); 00868 tcp_socket(sockfd, 1, 0); 00869 00870 00871 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \ 00872 && !defined(WOLFSSL_KEIL_TCP_NET) 00873 { 00874 int res, on = 1; 00875 socklen_t len = sizeof(on); 00876 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); 00877 if (res < 0) 00878 err_sys("setsockopt SO_REUSEADDR failed\n"); 00879 } 00880 #endif 00881 00882 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00883 err_sys("tcp bind failed"); 00884 00885 #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS) 00886 if (port == 0) { 00887 socklen_t len = sizeof(addr); 00888 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { 00889 #ifndef TEST_IPV6 00890 port = XNTOHS(addr.sin_port); 00891 #else 00892 port = XNTOHS(addr.sin6_port); 00893 #endif 00894 } 00895 } 00896 #endif 00897 00898 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) 00899 /* signal ready to accept data */ 00900 { 00901 tcp_ready* ready = args->signal; 00902 pthread_mutex_lock(&ready->mutex); 00903 ready->ready = 1; 00904 ready->port = port; 00905 pthread_cond_signal(&ready->cond); 00906 pthread_mutex_unlock(&ready->mutex); 00907 } 00908 #elif defined (WOLFSSL_TIRTOS) 00909 /* Need mutex? */ 00910 tcp_ready* ready = args->signal; 00911 ready->ready = 1; 00912 ready->port = port; 00913 #endif 00914 00915 *clientfd = *sockfd; 00916 } 00917 00918 static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, 00919 func_args* args, word16 port, int useAnyAddr, 00920 int udp, int sctp, int ready_file, int do_listen) 00921 { 00922 SOCKADDR_IN_T client; 00923 socklen_t client_len = sizeof(client); 00924 tcp_ready* ready = NULL; 00925 00926 (void) ready; /* Account for case when "ready" is not used */ 00927 00928 if (udp) { 00929 udp_accept(sockfd, clientfd, useAnyAddr, port, args); 00930 return; 00931 } 00932 00933 if(do_listen) { 00934 tcp_listen(sockfd, &port, useAnyAddr, udp, sctp); 00935 00936 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) 00937 /* signal ready to tcp_accept */ 00938 if (args) 00939 ready = args->signal; 00940 if (ready) { 00941 pthread_mutex_lock(&ready->mutex); 00942 ready->ready = 1; 00943 ready->port = port; 00944 pthread_cond_signal(&ready->cond); 00945 pthread_mutex_unlock(&ready->mutex); 00946 } 00947 #elif defined (WOLFSSL_TIRTOS) 00948 /* Need mutex? */ 00949 if (args) 00950 ready = args->signal; 00951 if (ready) { 00952 ready->ready = 1; 00953 ready->port = port; 00954 } 00955 #endif 00956 00957 if (ready_file) { 00958 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) 00959 FILE* srf = NULL; 00960 if (args) 00961 ready = args->signal; 00962 00963 if (ready) { 00964 srf = fopen(ready->srfName, "w"); 00965 00966 if (srf) { 00967 /* let's write port sever is listening on to ready file 00968 external monitor can then do ephemeral ports by passing 00969 -p 0 to server on supported platforms with -R ready_file 00970 client can then wait for existence of ready_file and see 00971 which port the server is listening on. */ 00972 fprintf(srf, "%d\n", (int)port); 00973 fclose(srf); 00974 } 00975 } 00976 #endif 00977 } 00978 } 00979 00980 *clientfd = accept(*sockfd, (struct sockaddr*)&client, 00981 (ACCEPT_THIRD_T)&client_len); 00982 if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) { 00983 err_sys("tcp accept failed"); 00984 } 00985 } 00986 00987 00988 static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd) 00989 { 00990 #ifdef USE_WINDOWS_API 00991 unsigned long blocking = 1; 00992 int ret = ioctlsocket(*sockfd, FIONBIO, &blocking); 00993 if (ret == SOCKET_ERROR) 00994 err_sys("ioctlsocket failed"); 00995 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \ 00996 || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) 00997 /* non blocking not supported, for now */ 00998 #else 00999 int flags = fcntl(*sockfd, F_GETFL, 0); 01000 if (flags < 0) 01001 err_sys("fcntl get failed"); 01002 flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK); 01003 if (flags < 0) 01004 err_sys("fcntl set failed"); 01005 #endif 01006 } 01007 01008 01009 #ifndef NO_PSK 01010 01011 /* identity is OpenSSL testing default for openssl s_client, keep same */ 01012 static const char* kIdentityStr = "Client_identity"; 01013 01014 static INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint, 01015 char* identity, unsigned int id_max_len, unsigned char* key, 01016 unsigned int key_max_len) 01017 { 01018 (void)ssl; 01019 (void)hint; 01020 (void)key_max_len; 01021 01022 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ 01023 strncpy(identity, kIdentityStr, id_max_len); 01024 01025 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 01026 unsigned binary */ 01027 key[0] = 26; 01028 key[1] = 43; 01029 key[2] = 60; 01030 key[3] = 77; 01031 01032 return 4; /* length of key in octets or 0 for error */ 01033 } 01034 01035 01036 static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, 01037 unsigned char* key, unsigned int key_max_len) 01038 { 01039 (void)ssl; 01040 (void)key_max_len; 01041 01042 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ 01043 if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0) 01044 return 0; 01045 01046 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 01047 unsigned binary */ 01048 key[0] = 26; 01049 key[1] = 43; 01050 key[2] = 60; 01051 key[3] = 77; 01052 01053 return 4; /* length of key in octets or 0 for error */ 01054 } 01055 01056 #endif /* NO_PSK */ 01057 01058 01059 #if defined(WOLFSSL_USER_CURRTIME) 01060 extern double current_time(int reset); 01061 01062 #elif defined(USE_WINDOWS_API) 01063 01064 #define WIN32_LEAN_AND_MEAN 01065 #include <windows.h> 01066 01067 static INLINE double current_time(int reset) 01068 { 01069 static int init = 0; 01070 static LARGE_INTEGER freq; 01071 01072 LARGE_INTEGER count; 01073 01074 if (!init) { 01075 QueryPerformanceFrequency(&freq); 01076 init = 1; 01077 } 01078 01079 QueryPerformanceCounter(&count); 01080 01081 (void)reset; 01082 return (double)count.QuadPart / freq.QuadPart; 01083 } 01084 01085 #elif defined(WOLFSSL_TIRTOS) 01086 extern double current_time(); 01087 #else 01088 01089 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) 01090 #include <sys/time.h> 01091 01092 static INLINE double current_time(int reset) 01093 { 01094 struct timeval tv; 01095 gettimeofday(&tv, 0); 01096 (void)reset; 01097 01098 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; 01099 } 01100 #else 01101 extern double current_time(int reset); 01102 #endif 01103 #endif /* USE_WINDOWS_API */ 01104 01105 01106 #if !defined(NO_CERTS) 01107 #if !defined(NO_FILESYSTEM) || \ 01108 (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST)) 01109 01110 /* reads file size, allocates buffer, reads into buffer, returns buffer */ 01111 static INLINE int load_file(const char* fname, byte** buf, size_t* bufLen) 01112 { 01113 int ret; 01114 long int fileSz; 01115 FILE* file; 01116 01117 if (fname == NULL || buf == NULL || bufLen == NULL) 01118 return BAD_FUNC_ARG; 01119 01120 /* set defaults */ 01121 *buf = NULL; 01122 *bufLen = 0; 01123 01124 /* open file (read-only binary) */ 01125 file = fopen(fname, "rb"); 01126 if (!file) { 01127 printf("Error loading %s\n", fname); 01128 return BAD_PATH_ERROR; 01129 } 01130 01131 fseek(file, 0, SEEK_END); 01132 fileSz = (int)ftell(file); 01133 rewind(file); 01134 if (fileSz > 0) { 01135 *bufLen = (size_t)fileSz; 01136 *buf = (byte*)malloc(*bufLen); 01137 if (*buf == NULL) { 01138 ret = MEMORY_E; 01139 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen); 01140 } 01141 else { 01142 size_t readLen = fread(*buf, *bufLen, 1, file); 01143 01144 /* check response code */ 01145 ret = (readLen > 0) ? 0 : -1; 01146 } 01147 } 01148 else { 01149 ret = BUFFER_E; 01150 } 01151 fclose(file); 01152 01153 return ret; 01154 } 01155 01156 enum { 01157 WOLFSSL_CA = 1, 01158 WOLFSSL_CERT = 2, 01159 WOLFSSL_KEY = 3, 01160 WOLFSSL_CERT_CHAIN = 4, 01161 }; 01162 01163 static INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type) 01164 { 01165 int format = SSL_FILETYPE_PEM; 01166 byte* buff = NULL; 01167 size_t sz = 0; 01168 01169 if (load_file(fname, &buff, &sz) != 0) { 01170 err_sys("can't open file for buffer load " 01171 "Please run from wolfSSL home directory if not"); 01172 } 01173 01174 /* determine format */ 01175 if (strstr(fname, ".der")) 01176 format = SSL_FILETYPE_ASN1; 01177 01178 if (type == WOLFSSL_CA) { 01179 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format) 01180 != SSL_SUCCESS) 01181 err_sys("can't load buffer ca file"); 01182 } 01183 else if (type == WOLFSSL_CERT) { 01184 if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz, 01185 format) != SSL_SUCCESS) 01186 err_sys("can't load buffer cert file"); 01187 } 01188 else if (type == WOLFSSL_KEY) { 01189 if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz, 01190 format) != SSL_SUCCESS) 01191 err_sys("can't load buffer key file"); 01192 } 01193 else if (type == WOLFSSL_CERT_CHAIN) { 01194 if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff, 01195 (long)sz, format) != SSL_SUCCESS) 01196 err_sys("can't load cert chain buffer"); 01197 } 01198 01199 if (buff) 01200 free(buff); 01201 } 01202 #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */ 01203 #endif /* !NO_CERTS */ 01204 01205 #ifdef VERIFY_CALLBACK 01206 01207 static INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) 01208 { 01209 (void)preverify; 01210 char buffer[WOLFSSL_MAX_ERROR_SZ]; 01211 01212 #ifdef OPENSSL_EXTRA 01213 WOLFSSL_X509* peer; 01214 #endif 01215 01216 printf("In verification callback, error = %d, %s\n", store->error, 01217 wolfSSL_ERR_error_string(store->error, buffer)); 01218 #ifdef OPENSSL_EXTRA 01219 peer = store->current_cert; 01220 if (peer) { 01221 char* issuer = wolfSSL_X509_NAME_oneline( 01222 wolfSSL_X509_get_issuer_name(peer), 0, 0); 01223 char* subject = wolfSSL_X509_NAME_oneline( 01224 wolfSSL_X509_get_subject_name(peer), 0, 0); 01225 printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer, 01226 subject); 01227 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); 01228 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); 01229 } 01230 else 01231 printf("\tPeer has no cert!\n"); 01232 #else 01233 printf("\tPeer certs: %d\n", store->totalCerts); 01234 #ifdef VERIFY_CALLBACK_SHOW_PEER_CERTS 01235 { int i; 01236 for (i=0; i<store->totalCerts; i++) { 01237 WOLFSSL_BUFFER_INFO* cert = &store->certs[i]; 01238 printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length); 01239 } 01240 } 01241 #endif 01242 #endif 01243 01244 printf("\tSubject's domain name is %s\n", store->domain); 01245 01246 printf("\tAllowing to continue anyway (shouldn't do this, EVER!!!)\n"); 01247 return 1; 01248 } 01249 01250 #endif /* VERIFY_CALLBACK */ 01251 01252 01253 static INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store) 01254 { 01255 char buffer[WOLFSSL_MAX_ERROR_SZ]; 01256 (void)preverify; 01257 01258 printf("In verification callback, error = %d, %s\n", store->error, 01259 wolfSSL_ERR_error_string(store->error, buffer)); 01260 printf("Subject's domain name is %s\n", store->domain); 01261 01262 if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) { 01263 printf("Overriding cert date error as example for bad clock testing\n"); 01264 return 1; 01265 } 01266 printf("Cert error is not date error, not overriding\n"); 01267 01268 return 0; 01269 } 01270 01271 01272 #ifdef HAVE_CRL 01273 01274 static INLINE void CRL_CallBack(const char* url) 01275 { 01276 printf("CRL callback url = %s\n", url); 01277 } 01278 01279 #endif 01280 01281 #ifndef NO_DH 01282 static INLINE void SetDH(WOLFSSL* ssl) 01283 { 01284 /* dh1024 p */ 01285 static unsigned char p[] = 01286 { 01287 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, 01288 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, 01289 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, 01290 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, 01291 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, 01292 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, 01293 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, 01294 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, 01295 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, 01296 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, 01297 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, 01298 }; 01299 01300 /* dh1024 g */ 01301 static unsigned char g[] = 01302 { 01303 0x02, 01304 }; 01305 01306 wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g)); 01307 } 01308 01309 static INLINE void SetDHCtx(WOLFSSL_CTX* ctx) 01310 { 01311 /* dh1024 p */ 01312 static unsigned char p[] = 01313 { 01314 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, 01315 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, 01316 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, 01317 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, 01318 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, 01319 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, 01320 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, 01321 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, 01322 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, 01323 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, 01324 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, 01325 }; 01326 01327 /* dh1024 g */ 01328 static unsigned char g[] = 01329 { 01330 0x02, 01331 }; 01332 01333 wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g)); 01334 } 01335 #endif /* NO_DH */ 01336 01337 #ifndef NO_CERTS 01338 01339 static INLINE void CaCb(unsigned char* der, int sz, int type) 01340 { 01341 (void)der; 01342 printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type); 01343 } 01344 01345 #endif /* !NO_CERTS */ 01346 01347 01348 /* Wolf Root Directory Helper */ 01349 /* KEIL-RL File System does not support relative directory */ 01350 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) 01351 /* Maximum depth to search for WolfSSL root */ 01352 #define MAX_WOLF_ROOT_DEPTH 5 01353 01354 static INLINE int ChangeToWolfRoot(void) 01355 { 01356 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) 01357 int depth, res; 01358 FILE* file; 01359 for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { 01360 file = fopen(ntruKeyFile, "rb"); 01361 if (file != NULL) { 01362 fclose(file); 01363 return depth; 01364 } 01365 #ifdef USE_WINDOWS_API 01366 res = SetCurrentDirectoryA("..\\"); 01367 #else 01368 res = chdir("../"); 01369 #endif 01370 if (res < 0) { 01371 printf("chdir to ../ failed!\n"); 01372 break; 01373 } 01374 } 01375 01376 err_sys("wolf root not found"); 01377 return -1; 01378 #else 01379 return 0; 01380 #endif 01381 } 01382 #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */ 01383 01384 #ifdef HAVE_STACK_SIZE 01385 01386 typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args); 01387 01388 01389 static INLINE int StackSizeCheck(func_args* args, thread_func tf) 01390 { 01391 int ret, i, used; 01392 void* status; 01393 unsigned char* myStack = NULL; 01394 int stackSize = 1024*128; 01395 pthread_attr_t myAttr; 01396 pthread_t threadId; 01397 01398 #ifdef PTHREAD_STACK_MIN 01399 if (stackSize < PTHREAD_STACK_MIN) 01400 stackSize = PTHREAD_STACK_MIN; 01401 #endif 01402 01403 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); 01404 if (ret != 0 || myStack == NULL) 01405 err_sys("posix_memalign failed\n"); 01406 01407 XMEMSET(myStack, 0x01, stackSize); 01408 01409 ret = pthread_attr_init(&myAttr); 01410 if (ret != 0) 01411 err_sys("attr_init failed"); 01412 01413 ret = pthread_attr_setstack(&myAttr, myStack, stackSize); 01414 if (ret != 0) 01415 err_sys("attr_setstackaddr failed"); 01416 01417 ret = pthread_create(&threadId, &myAttr, tf, args); 01418 if (ret != 0) { 01419 perror("pthread_create failed"); 01420 exit(EXIT_FAILURE); 01421 } 01422 01423 ret = pthread_join(threadId, &status); 01424 if (ret != 0) 01425 err_sys("pthread_join failed"); 01426 01427 for (i = 0; i < stackSize; i++) { 01428 if (myStack[i] != 0x01) { 01429 break; 01430 } 01431 } 01432 01433 free(myStack); 01434 01435 used = stackSize - i; 01436 printf("stack used = %d\n", used); 01437 01438 return (int)((size_t)status); 01439 } 01440 01441 01442 #endif /* HAVE_STACK_SIZE */ 01443 01444 01445 #ifdef STACK_TRAP 01446 01447 /* good settings 01448 --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP" 01449 01450 */ 01451 01452 #ifdef HAVE_STACK_SIZE 01453 /* client only for now, setrlimit will fail if pthread_create() called */ 01454 /* STACK_SIZE does pthread_create() on client */ 01455 #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail" 01456 #endif /* HAVE_STACK_SIZE */ 01457 01458 static INLINE void StackTrap(void) 01459 { 01460 struct rlimit rl; 01461 if (getrlimit(RLIMIT_STACK, &rl) != 0) 01462 err_sys("getrlimit failed"); 01463 printf("rlim_cur = %llu\n", rl.rlim_cur); 01464 rl.rlim_cur = 1024*21; /* adjust trap size here */ 01465 if (setrlimit(RLIMIT_STACK, &rl) != 0) { 01466 perror("setrlimit"); 01467 err_sys("setrlimit failed"); 01468 } 01469 } 01470 01471 #else /* STACK_TRAP */ 01472 01473 static INLINE void StackTrap(void) 01474 { 01475 } 01476 01477 #endif /* STACK_TRAP */ 01478 01479 01480 #ifdef ATOMIC_USER 01481 01482 /* Atomic Encrypt Context example */ 01483 typedef struct AtomicEncCtx { 01484 int keySetup; /* have we done key setup yet */ 01485 Aes aes; /* for aes example */ 01486 } AtomicEncCtx; 01487 01488 01489 /* Atomic Decrypt Context example */ 01490 typedef struct AtomicDecCtx { 01491 int keySetup; /* have we done key setup yet */ 01492 Aes aes; /* for aes example */ 01493 } AtomicDecCtx; 01494 01495 01496 static INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut, 01497 const unsigned char* macIn, unsigned int macInSz, int macContent, 01498 int macVerify, unsigned char* encOut, const unsigned char* encIn, 01499 unsigned int encSz, void* ctx) 01500 { 01501 int ret; 01502 Hmac hmac; 01503 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; 01504 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx; 01505 const char* tlsStr = "TLS"; 01506 01507 /* example supports (d)tls aes */ 01508 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { 01509 printf("myMacEncryptCb not using AES\n"); 01510 return -1; 01511 } 01512 01513 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { 01514 printf("myMacEncryptCb not using (D)TLS\n"); 01515 return -1; 01516 } 01517 01518 /* hmac, not needed if aead mode */ 01519 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); 01520 01521 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), 01522 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl)); 01523 if (ret != 0) 01524 return ret; 01525 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); 01526 if (ret != 0) 01527 return ret; 01528 ret = wc_HmacUpdate(&hmac, macIn, macInSz); 01529 if (ret != 0) 01530 return ret; 01531 ret = wc_HmacFinal(&hmac, macOut); 01532 if (ret != 0) 01533 return ret; 01534 01535 01536 /* encrypt setup on first time */ 01537 if (encCtx->keySetup == 0) { 01538 int keyLen = wolfSSL_GetKeySize(ssl); 01539 const byte* key; 01540 const byte* iv; 01541 01542 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) { 01543 key = wolfSSL_GetClientWriteKey(ssl); 01544 iv = wolfSSL_GetClientWriteIV(ssl); 01545 } 01546 else { 01547 key = wolfSSL_GetServerWriteKey(ssl); 01548 iv = wolfSSL_GetServerWriteIV(ssl); 01549 } 01550 01551 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION); 01552 if (ret != 0) { 01553 printf("AesSetKey failed in myMacEncryptCb\n"); 01554 return ret; 01555 } 01556 encCtx->keySetup = 1; 01557 } 01558 01559 /* encrypt */ 01560 return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz); 01561 } 01562 01563 01564 static INLINE int myDecryptVerifyCb(WOLFSSL* ssl, 01565 unsigned char* decOut, const unsigned char* decIn, 01566 unsigned int decSz, int macContent, int macVerify, 01567 unsigned int* padSz, void* ctx) 01568 { 01569 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx; 01570 int ret = 0; 01571 int macInSz = 0; 01572 int ivExtra = 0; 01573 int digestSz = wolfSSL_GetHmacSize(ssl); 01574 unsigned int pad = 0; 01575 unsigned int padByte = 0; 01576 Hmac hmac; 01577 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; 01578 byte verify[MAX_DIGEST_SIZE]; 01579 const char* tlsStr = "TLS"; 01580 01581 /* example supports (d)tls aes */ 01582 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { 01583 printf("myMacEncryptCb not using AES\n"); 01584 return -1; 01585 } 01586 01587 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { 01588 printf("myMacEncryptCb not using (D)TLS\n"); 01589 return -1; 01590 } 01591 01592 /*decrypt */ 01593 if (decCtx->keySetup == 0) { 01594 int keyLen = wolfSSL_GetKeySize(ssl); 01595 const byte* key; 01596 const byte* iv; 01597 01598 /* decrypt is from other side (peer) */ 01599 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { 01600 key = wolfSSL_GetClientWriteKey(ssl); 01601 iv = wolfSSL_GetClientWriteIV(ssl); 01602 } 01603 else { 01604 key = wolfSSL_GetServerWriteKey(ssl); 01605 iv = wolfSSL_GetServerWriteIV(ssl); 01606 } 01607 01608 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); 01609 if (ret != 0) { 01610 printf("AesSetKey failed in myDecryptVerifyCb\n"); 01611 return ret; 01612 } 01613 decCtx->keySetup = 1; 01614 } 01615 01616 /* decrypt */ 01617 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz); 01618 if (ret != 0) 01619 return ret; 01620 01621 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) { 01622 *padSz = wolfSSL_GetAeadMacSize(ssl); 01623 return 0; /* hmac, not needed if aead mode */ 01624 } 01625 01626 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) { 01627 pad = *(decOut + decSz - 1); 01628 padByte = 1; 01629 if (wolfSSL_IsTLSv1_1(ssl)) 01630 ivExtra = wolfSSL_GetCipherBlockSize(ssl); 01631 } 01632 01633 *padSz = wolfSSL_GetHmacSize(ssl) + pad + padByte; 01634 macInSz = decSz - ivExtra - digestSz - pad - padByte; 01635 01636 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); 01637 01638 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), 01639 wolfSSL_GetMacSecret(ssl, macVerify), digestSz); 01640 if (ret != 0) 01641 return ret; 01642 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); 01643 if (ret != 0) 01644 return ret; 01645 ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz); 01646 if (ret != 0) 01647 return ret; 01648 ret = wc_HmacFinal(&hmac, verify); 01649 if (ret != 0) 01650 return ret; 01651 01652 if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte, 01653 digestSz) != 0) { 01654 printf("myDecryptVerify verify failed\n"); 01655 return -1; 01656 } 01657 01658 return ret; 01659 } 01660 01661 01662 static INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl) 01663 { 01664 AtomicEncCtx* encCtx; 01665 AtomicDecCtx* decCtx; 01666 01667 encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx)); 01668 if (encCtx == NULL) 01669 err_sys("AtomicEncCtx malloc failed"); 01670 memset(encCtx, 0, sizeof(AtomicEncCtx)); 01671 01672 decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx)); 01673 if (decCtx == NULL) { 01674 free(encCtx); 01675 err_sys("AtomicDecCtx malloc failed"); 01676 } 01677 memset(decCtx, 0, sizeof(AtomicDecCtx)); 01678 01679 wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb); 01680 wolfSSL_SetMacEncryptCtx(ssl, encCtx); 01681 01682 wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb); 01683 wolfSSL_SetDecryptVerifyCtx(ssl, decCtx); 01684 } 01685 01686 01687 static INLINE void FreeAtomicUser(WOLFSSL* ssl) 01688 { 01689 AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl); 01690 AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl); 01691 01692 free(decCtx); 01693 free(encCtx); 01694 } 01695 01696 #endif /* ATOMIC_USER */ 01697 01698 #ifdef WOLFSSL_STATIC_MEMORY 01699 static INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats) 01700 { 01701 word16 i; 01702 01703 if (stats == NULL) { 01704 return 0; 01705 } 01706 01707 /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */ 01708 fprintf(stderr, "Total mallocs = %d\n", stats->totalAlloc); 01709 fprintf(stderr, "Total frees = %d\n", stats->totalFr); 01710 fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc); 01711 fprintf(stderr, "Available IO = %d\n", stats->avaIO); 01712 fprintf(stderr, "Max con. handshakes = %d\n", stats->maxHa); 01713 fprintf(stderr, "Max con. IO = %d\n", stats->maxIO); 01714 fprintf(stderr, "State of memory blocks: size : available \n"); 01715 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 01716 fprintf(stderr, " : %d\t : %d\n", stats->blockSz[i], 01717 stats->avaBlock[i]); 01718 } 01719 01720 return 1; 01721 } 01722 #endif /* WOLFSSL_STATIC_MEMORY */ 01723 01724 #ifdef HAVE_PK_CALLBACKS 01725 01726 #ifdef HAVE_ECC 01727 01728 static INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz, 01729 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) 01730 { 01731 WC_RNG rng; 01732 int ret; 01733 word32 idx = 0; 01734 ecc_key myKey; 01735 01736 (void)ssl; 01737 (void)ctx; 01738 01739 ret = wc_InitRng(&rng); 01740 if (ret != 0) 01741 return ret; 01742 01743 ret = wc_ecc_init(&myKey); 01744 if (ret == 0) { 01745 ret = wc_EccPrivateKeyDecode(key, &idx, &myKey, keySz); 01746 if (ret == 0) 01747 ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey); 01748 wc_ecc_free(&myKey); 01749 } 01750 wc_FreeRng(&rng); 01751 01752 return ret; 01753 } 01754 01755 01756 static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz, 01757 const byte* hash, word32 hashSz, const byte* key, word32 keySz, 01758 int* result, void* ctx) 01759 { 01760 int ret; 01761 ecc_key myKey; 01762 01763 (void)ssl; 01764 (void)ctx; 01765 01766 ret = wc_ecc_init(&myKey); 01767 if (ret == 0) { 01768 ret = wc_ecc_import_x963(key, keySz, &myKey); 01769 if (ret == 0) 01770 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey); 01771 wc_ecc_free(&myKey); 01772 } 01773 01774 return ret; 01775 } 01776 01777 static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, 01778 unsigned char* pubKeyDer, unsigned int* pubKeySz, 01779 unsigned char* out, unsigned int* outlen, 01780 int side, void* ctx) 01781 { 01782 int ret; 01783 ecc_key* privKey = NULL; 01784 ecc_key* pubKey = NULL; 01785 ecc_key tmpKey; 01786 01787 (void)ssl; 01788 (void)ctx; 01789 01790 ret = wc_ecc_init(&tmpKey); 01791 if (ret != 0) { 01792 return ret; 01793 } 01794 01795 /* for client: create and export public key */ 01796 if (side == WOLFSSL_CLIENT_END) { 01797 WC_RNG rng; 01798 01799 privKey = &tmpKey; 01800 pubKey = otherKey; 01801 01802 ret = wc_InitRng(&rng); 01803 if (ret == 0) { 01804 ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id); 01805 if (ret == 0) 01806 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); 01807 wc_FreeRng(&rng); 01808 } 01809 } 01810 01811 /* for server: import public key */ 01812 else if (side == WOLFSSL_SERVER_END) { 01813 privKey = otherKey; 01814 pubKey = &tmpKey; 01815 01816 ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, 01817 otherKey->dp->id); 01818 } 01819 else { 01820 ret = BAD_FUNC_ARG; 01821 } 01822 01823 /* generate shared secret and return it */ 01824 if (ret == 0) { 01825 ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); 01826 } 01827 01828 wc_ecc_free(&tmpKey); 01829 01830 return ret; 01831 } 01832 01833 #endif /* HAVE_ECC */ 01834 01835 #ifndef NO_RSA 01836 01837 static INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, 01838 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) 01839 { 01840 WC_RNG rng; 01841 int ret; 01842 word32 idx = 0; 01843 RsaKey myKey; 01844 01845 (void)ssl; 01846 (void)ctx; 01847 01848 ret = wc_InitRng(&rng); 01849 if (ret != 0) 01850 return ret; 01851 01852 ret = wc_InitRsaKey(&myKey, NULL); 01853 if (ret == 0) { 01854 ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz); 01855 if (ret == 0) 01856 ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng); 01857 if (ret > 0) { /* save and convert to 0 success */ 01858 *outSz = ret; 01859 ret = 0; 01860 } 01861 wc_FreeRsaKey(&myKey); 01862 } 01863 wc_FreeRng(&rng); 01864 01865 return ret; 01866 } 01867 01868 01869 static INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz, 01870 byte** out, 01871 const byte* key, word32 keySz, 01872 void* ctx) 01873 { 01874 int ret; 01875 word32 idx = 0; 01876 RsaKey myKey; 01877 01878 (void)ssl; 01879 (void)ctx; 01880 01881 ret = wc_InitRsaKey(&myKey, NULL); 01882 if (ret == 0) { 01883 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); 01884 if (ret == 0) 01885 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey); 01886 wc_FreeRsaKey(&myKey); 01887 } 01888 01889 return ret; 01890 } 01891 01892 01893 static INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, 01894 byte* out, word32* outSz, const byte* key, 01895 word32 keySz, void* ctx) 01896 { 01897 int ret; 01898 word32 idx = 0; 01899 RsaKey myKey; 01900 WC_RNG rng; 01901 01902 (void)ssl; 01903 (void)ctx; 01904 01905 ret = wc_InitRng(&rng); 01906 if (ret != 0) 01907 return ret; 01908 01909 ret = wc_InitRsaKey(&myKey, NULL); 01910 if (ret == 0) { 01911 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); 01912 if (ret == 0) { 01913 ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng); 01914 if (ret > 0) { 01915 *outSz = ret; 01916 ret = 0; /* reset to success */ 01917 } 01918 } 01919 wc_FreeRsaKey(&myKey); 01920 } 01921 wc_FreeRng(&rng); 01922 01923 return ret; 01924 } 01925 01926 static INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz, 01927 byte** out, 01928 const byte* key, word32 keySz, void* ctx) 01929 { 01930 int ret; 01931 word32 idx = 0; 01932 RsaKey myKey; 01933 01934 (void)ssl; 01935 (void)ctx; 01936 01937 ret = wc_InitRsaKey(&myKey, NULL); 01938 if (ret == 0) { 01939 ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz); 01940 if (ret == 0) { 01941 #ifdef WC_RSA_BLINDING 01942 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl)); 01943 if (ret != 0) { 01944 wc_FreeRsaKey(&myKey); 01945 return ret; 01946 } 01947 #endif 01948 ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey); 01949 } 01950 wc_FreeRsaKey(&myKey); 01951 } 01952 01953 return ret; 01954 } 01955 01956 #endif /* NO_RSA */ 01957 01958 static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl) 01959 { 01960 (void)ctx; 01961 (void)ssl; 01962 01963 #ifdef HAVE_ECC 01964 wolfSSL_CTX_SetEccSignCb(ctx, myEccSign); 01965 wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify); 01966 wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret); 01967 #endif /* HAVE_ECC */ 01968 #ifndef NO_RSA 01969 wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign); 01970 wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify); 01971 wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc); 01972 wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec); 01973 #endif /* NO_RSA */ 01974 } 01975 01976 #endif /* HAVE_PK_CALLBACKS */ 01977 01978 01979 01980 01981 01982 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \ 01983 || defined(_MSC_VER) 01984 01985 /* HP/UX doesn't have strsep, needed by test/suites.c */ 01986 static INLINE char* strsep(char **stringp, const char *delim) 01987 { 01988 char* start; 01989 char* end; 01990 01991 start = *stringp; 01992 if (start == NULL) 01993 return NULL; 01994 01995 if ((end = strpbrk(start, delim))) { 01996 *end++ = '\0'; 01997 *stringp = end; 01998 } else { 01999 *stringp = NULL; 02000 } 02001 02002 return start; 02003 } 02004 02005 #endif /* __hpux__ and others */ 02006 02007 /* Create unique filename, len is length of tempfn name, assuming 02008 len does not include null terminating character, 02009 num is number of characters in tempfn name to randomize */ 02010 static INLINE const char* mymktemp(char *tempfn, int len, int num) 02011 { 02012 int x, size; 02013 static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 02014 "abcdefghijklmnopqrstuvwxyz"; 02015 WC_RNG rng; 02016 byte out; 02017 02018 if (tempfn == NULL || len < 1 || num < 1 || len <= num) { 02019 printf("Bad input\n"); 02020 return NULL; 02021 } 02022 02023 size = len - 1; 02024 02025 if (wc_InitRng(&rng) != 0) { 02026 printf("InitRng failed\n"); 02027 return NULL; 02028 } 02029 02030 for (x = size; x > size - num; x--) { 02031 if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) { 02032 printf("RNG_GenerateBlock failed\n"); 02033 return NULL; 02034 } 02035 tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)]; 02036 } 02037 tempfn[len] = '\0'; 02038 02039 wc_FreeRng(&rng); 02040 02041 return tempfn; 02042 } 02043 02044 02045 02046 #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ 02047 defined(HAVE_POLY1305) 02048 02049 #include <wolfssl/wolfcrypt/chacha20_poly1305.h> 02050 02051 typedef struct key_ctx { 02052 byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */ 02053 byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */ 02054 } key_ctx; 02055 02056 static key_ctx myKey_ctx; 02057 static WC_RNG myKey_rng; 02058 02059 static INLINE int TicketInit(void) 02060 { 02061 int ret = wc_InitRng(&myKey_rng); 02062 if (ret != 0) return ret; 02063 02064 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key)); 02065 if (ret != 0) return ret; 02066 02067 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name)); 02068 if (ret != 0) return ret; 02069 02070 return 0; 02071 } 02072 02073 static INLINE void TicketCleanup(void) 02074 { 02075 wc_FreeRng(&myKey_rng); 02076 } 02077 02078 static INLINE int myTicketEncCb(WOLFSSL* ssl, 02079 byte key_name[WOLFSSL_TICKET_NAME_SZ], 02080 byte iv[WOLFSSL_TICKET_IV_SZ], 02081 byte mac[WOLFSSL_TICKET_MAC_SZ], 02082 int enc, byte* ticket, int inLen, int* outLen, 02083 void* userCtx) 02084 { 02085 (void)ssl; 02086 (void)userCtx; 02087 02088 int ret; 02089 word16 sLen = XHTONS(inLen); 02090 byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2]; 02091 int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2; 02092 byte* tmp = aad; 02093 02094 if (enc) { 02095 XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ); 02096 02097 ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ); 02098 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; 02099 02100 /* build aad from key name, iv, and length */ 02101 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ); 02102 tmp += WOLFSSL_TICKET_NAME_SZ; 02103 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ); 02104 tmp += WOLFSSL_TICKET_IV_SZ; 02105 XMEMCPY(tmp, &sLen, 2); 02106 02107 ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv, 02108 aad, aadSz, 02109 ticket, inLen, 02110 ticket, 02111 mac); 02112 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; 02113 *outLen = inLen; /* no padding in this mode */ 02114 } else { 02115 /* decrypt */ 02116 02117 /* see if we know this key */ 02118 if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){ 02119 printf("client presented unknown ticket key name "); 02120 return WOLFSSL_TICKET_RET_FATAL; 02121 } 02122 02123 /* build aad from key name, iv, and length */ 02124 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ); 02125 tmp += WOLFSSL_TICKET_NAME_SZ; 02126 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ); 02127 tmp += WOLFSSL_TICKET_IV_SZ; 02128 XMEMCPY(tmp, &sLen, 2); 02129 02130 ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv, 02131 aad, aadSz, 02132 ticket, inLen, 02133 mac, 02134 ticket); 02135 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; 02136 *outLen = inLen; /* no padding in this mode */ 02137 } 02138 02139 return WOLFSSL_TICKET_RET_OK; 02140 } 02141 02142 #endif /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */ 02143 02144 static INLINE word16 GetRandomPort(void) 02145 { 02146 word16 port = 0; 02147 02148 /* Generate random port for testing */ 02149 WC_RNG rng; 02150 if (wc_InitRng(&rng) == 0) { 02151 wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port)); 02152 port |= 0xC000; /* Make sure its in the 49152 - 65535 range */ 02153 wc_FreeRng(&rng); 02154 } 02155 return port; 02156 } 02157 02158 #endif /* wolfSSL_TEST_H */ 02159
Generated on Tue Jul 12 2022 23:31:01 by
1.7.2
