wolfSSL SSL/TLS library, support up to TLS1.3
Embed:
(wiki syntax)
Show/hide line numbers
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 #include <wolfssl/wolfcrypt/mem_track.h> 00014 #if defined(OPENSSL_EXTRA) && defined(SHOW_CERTS) 00015 #include <wolfssl/openssl/ssl.h> /* for domain component NID value */ 00016 #endif 00017 00018 #ifdef ATOMIC_USER 00019 #include <wolfssl/wolfcrypt/aes.h> 00020 #include <wolfssl/wolfcrypt/arc4.h> 00021 #include <wolfssl/wolfcrypt/hmac.h> 00022 #endif 00023 #ifdef HAVE_PK_CALLBACKS 00024 #include <wolfssl/wolfcrypt/asn.h> 00025 #ifndef NO_RSA 00026 #include <wolfssl/wolfcrypt/rsa.h> 00027 #endif 00028 #ifdef HAVE_ECC 00029 #include <wolfssl/wolfcrypt/ecc.h> 00030 #endif /* HAVE_ECC */ 00031 #ifndef NO_DH 00032 #include <wolfssl/wolfcrypt/dh.h> 00033 #endif /* !NO_DH */ 00034 #ifdef HAVE_ED25519 00035 #include <wolfssl/wolfcrypt/ed25519.h> 00036 #endif /* HAVE_ED25519 */ 00037 #ifdef HAVE_CURVE25519 00038 #include <wolfssl/wolfcrypt/curve25519.h> 00039 #endif /* HAVE_ECC */ 00040 #endif /*HAVE_PK_CALLBACKS */ 00041 00042 #ifdef USE_WINDOWS_API 00043 #include <winsock2.h> 00044 #include <process.h> 00045 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ 00046 #include <ws2tcpip.h> 00047 #include <wspiapi.h> 00048 #endif 00049 #define SOCKET_T SOCKET 00050 #define SNPRINTF _snprintf 00051 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00052 #include <string.h> 00053 #include "rl_net.h" 00054 #define SOCKET_T int 00055 typedef int socklen_t ; 00056 static unsigned long inet_addr(const char *cp) 00057 { 00058 unsigned int a[4] ; unsigned long ret ; 00059 sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ; 00060 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ; 00061 return(ret) ; 00062 } 00063 #if defined(HAVE_KEIL_RTX) 00064 #define sleep(t) os_dly_wait(t/1000+1) ; 00065 #elif defined (WOLFSSL_CMSIS_RTOS) 00066 #define sleep(t) osDelay(t/1000+1) ; 00067 #endif 00068 #elif defined(WOLFSSL_TIRTOS) 00069 #include <string.h> 00070 #include <netdb.h> 00071 #include <sys/types.h> 00072 #include <arpa/inet.h> 00073 #include <sys/socket.h> 00074 #include <ti/sysbios/knl/Task.h> 00075 struct hostent { 00076 char *h_name; /* official name of host */ 00077 char **h_aliases; /* alias list */ 00078 int h_addrtype; /* host address type */ 00079 int h_length; /* length of address */ 00080 char **h_addr_list; /* list of addresses from name server */ 00081 }; 00082 #define SOCKET_T int 00083 #elif defined(WOLFSSL_VXWORKS) 00084 #include <hostLib.h> 00085 #include <sockLib.h> 00086 #include <arpa/inet.h> 00087 #include <string.h> 00088 #include <selectLib.h> 00089 #include <sys/types.h> 00090 #include <netinet/in.h> 00091 #include <fcntl.h> 00092 #include <sys/time.h> 00093 #include <netdb.h> 00094 #include <pthread.h> 00095 #define SOCKET_T int 00096 #else 00097 #include <string.h> 00098 #include <sys/types.h> 00099 #ifndef WOLFSSL_LEANPSK 00100 #include <unistd.h> 00101 #include <netdb.h> 00102 #include <netinet/in.h> 00103 #include <netinet/tcp.h> 00104 #include <arpa/inet.h> 00105 #include <sys/ioctl.h> 00106 #include <sys/time.h> 00107 #include <sys/socket.h> 00108 #include <pthread.h> 00109 #include <fcntl.h> 00110 #ifdef TEST_IPV6 00111 #include <netdb.h> 00112 #endif 00113 #endif 00114 #define SOCKET_T int 00115 #ifndef SO_NOSIGPIPE 00116 #include <signal.h> /* ignore SIGPIPE */ 00117 #endif 00118 #define SNPRINTF snprintf 00119 #endif /* USE_WINDOWS_API */ 00120 00121 #ifdef WOLFSSL_ASYNC_CRYPT 00122 #include <wolfssl/wolfcrypt/async.h> 00123 #endif 00124 #ifdef HAVE_CAVIUM 00125 #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h> 00126 #endif 00127 #ifdef _MSC_VER 00128 /* disable conversion warning */ 00129 /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ 00130 #pragma warning(disable:4244 4996) 00131 #endif 00132 00133 /* Buffer for benchmark tests */ 00134 #ifndef TEST_BUFFER_SIZE 00135 #define TEST_BUFFER_SIZE 16384 00136 #endif 00137 00138 #ifndef WOLFSSL_HAVE_MIN 00139 #define WOLFSSL_HAVE_MIN 00140 static WC_INLINE word32 min(word32 a, word32 b) 00141 { 00142 return a > b ? b : a; 00143 } 00144 #endif /* WOLFSSL_HAVE_MIN */ 00145 00146 /* Socket Handling */ 00147 #ifndef WOLFSSL_SOCKET_INVALID 00148 #ifdef USE_WINDOWS_API 00149 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET) 00150 #elif defined(WOLFSSL_TIRTOS) 00151 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1) 00152 #else 00153 #define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0) 00154 #endif 00155 #endif /* WOLFSSL_SOCKET_INVALID */ 00156 00157 #ifndef WOLFSSL_SOCKET_IS_INVALID 00158 #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) 00159 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID) 00160 #else 00161 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID) 00162 #endif 00163 #endif /* WOLFSSL_SOCKET_IS_INVALID */ 00164 00165 #if defined(__MACH__) || defined(USE_WINDOWS_API) 00166 #ifndef _SOCKLEN_T 00167 typedef int socklen_t; 00168 #endif 00169 #endif 00170 00171 00172 /* HPUX doesn't use socklent_t for third parameter to accept, unless 00173 _XOPEN_SOURCE_EXTENDED is defined */ 00174 #if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\ 00175 && !defined(WOLFSSL_ROWLEY_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) 00176 typedef socklen_t* ACCEPT_THIRD_T; 00177 #else 00178 #if defined _XOPEN_SOURCE_EXTENDED 00179 typedef socklen_t* ACCEPT_THIRD_T; 00180 #else 00181 typedef int* ACCEPT_THIRD_T; 00182 #endif 00183 #endif 00184 00185 00186 00187 #ifdef SINGLE_THREADED 00188 typedef unsigned int THREAD_RETURN; 00189 typedef void* THREAD_TYPE; 00190 #define WOLFSSL_THREAD 00191 #else 00192 #if defined(_POSIX_THREADS) && !defined(__MINGW32__) 00193 typedef void* THREAD_RETURN; 00194 typedef pthread_t THREAD_TYPE; 00195 #define WOLFSSL_THREAD 00196 #define INFINITE -1 00197 #define WAIT_OBJECT_0 0L 00198 #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) 00199 typedef unsigned int THREAD_RETURN; 00200 typedef int THREAD_TYPE; 00201 #define WOLFSSL_THREAD 00202 #elif defined(WOLFSSL_TIRTOS) 00203 typedef void THREAD_RETURN; 00204 typedef Task_Handle THREAD_TYPE; 00205 #define WOLFSSL_THREAD 00206 #else 00207 typedef unsigned int THREAD_RETURN; 00208 typedef intptr_t THREAD_TYPE; 00209 #define WOLFSSL_THREAD __stdcall 00210 #endif 00211 #endif 00212 00213 00214 #ifdef TEST_IPV6 00215 typedef struct sockaddr_in6 SOCKADDR_IN_T; 00216 #define AF_INET_V AF_INET6 00217 #else 00218 typedef struct sockaddr_in SOCKADDR_IN_T; 00219 #define AF_INET_V AF_INET 00220 #endif 00221 00222 00223 #ifndef WOLFSSL_NO_TLS12 00224 #define SERVER_DEFAULT_VERSION 3 00225 #else 00226 #define SERVER_DEFAULT_VERSION 4 00227 #endif 00228 #define SERVER_DTLS_DEFAULT_VERSION (-2) 00229 #define SERVER_INVALID_VERSION (-99) 00230 #define SERVER_DOWNGRADE_VERSION (-98) 00231 #ifndef WOLFSSL_NO_TLS12 00232 #define CLIENT_DEFAULT_VERSION 3 00233 #else 00234 #define CLIENT_DEFAULT_VERSION 4 00235 #endif 00236 #define CLIENT_DTLS_DEFAULT_VERSION (-2) 00237 #define CLIENT_INVALID_VERSION (-99) 00238 #define CLIENT_DOWNGRADE_VERSION (-98) 00239 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) 00240 #define DEFAULT_MIN_DHKEY_BITS 2048 00241 #define DEFAULT_MAX_DHKEY_BITS 3072 00242 #else 00243 #define DEFAULT_MIN_DHKEY_BITS 1024 00244 #define DEFAULT_MAX_DHKEY_BITS 2048 00245 #endif 00246 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) 00247 #define DEFAULT_MIN_RSAKEY_BITS 2048 00248 #else 00249 #define DEFAULT_MIN_RSAKEY_BITS 1024 00250 #endif 00251 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) 00252 #define DEFAULT_MIN_ECCKEY_BITS 256 00253 #else 00254 #define DEFAULT_MIN_ECCKEY_BITS 224 00255 #endif 00256 00257 /* all certs relative to wolfSSL home directory now */ 00258 #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL) 00259 #define caCertFile "certs/ca-cert.pem" 00260 #define eccCertFile "certs/server-ecc.pem" 00261 #define eccKeyFile "certs/ecc-key.pem" 00262 #define eccRsaCertFile "certs/server-ecc-rsa.pem" 00263 #define svrCertFile "certs/server-cert.pem" 00264 #define svrKeyFile "certs/server-key.pem" 00265 #define cliCertFile "certs/client-cert.pem" 00266 #define cliCertDerFile "certs/client-cert.der" 00267 #define cliKeyFile "certs/client-key.pem" 00268 #define ntruCertFile "certs/ntru-cert.pem" 00269 #define ntruKeyFile "certs/ntru-key.raw" 00270 #define dhParamFile "certs/dh2048.pem" 00271 #define cliEccKeyFile "certs/ecc-client-key.pem" 00272 #define cliEccCertFile "certs/client-ecc-cert.pem" 00273 #define caEccCertFile "certs/ca-ecc-cert/pem" 00274 #define crlPemDir "certs/crl" 00275 #define edCertFile "certs/ed25519/server-ed25519-cert.pem" 00276 #define edKeyFile "certs/ed25519/server-ed25519-priv.pem" 00277 #define cliEdCertFile "certs/ed25519/client-ed25519.pem" 00278 #define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem" 00279 #define caEdCertFile "certs/ed25519/ca-ed25519.pem" 00280 #ifdef HAVE_WNR 00281 /* Whitewood netRandom default config file */ 00282 #define wnrConfig "wnr-example.conf" 00283 #endif 00284 #else 00285 #define caCertFile "./certs/ca-cert.pem" 00286 #define eccCertFile "./certs/server-ecc.pem" 00287 #define eccKeyFile "./certs/ecc-key.pem" 00288 #define eccRsaCertFile "./certs/server-ecc-rsa.pem" 00289 #define svrCertFile "./certs/server-cert.pem" 00290 #define svrKeyFile "./certs/server-key.pem" 00291 #define cliCertFile "./certs/client-cert.pem" 00292 #define cliCertDerFile "./certs/client-cert.der" 00293 #define cliKeyFile "./certs/client-key.pem" 00294 #define ntruCertFile "./certs/ntru-cert.pem" 00295 #define ntruKeyFile "./certs/ntru-key.raw" 00296 #define dhParamFile "./certs/dh2048.pem" 00297 #define cliEccKeyFile "./certs/ecc-client-key.pem" 00298 #define cliEccCertFile "./certs/client-ecc-cert.pem" 00299 #define caEccCertFile "./certs/ca-ecc-cert.pem" 00300 #define crlPemDir "./certs/crl" 00301 #define edCertFile "./certs/ed25519/server-ed25519.pem" 00302 #define edKeyFile "./certs/ed25519/server-ed25519-priv.pem" 00303 #define cliEdCertFile "./certs/ed25519/client-ed25519.pem" 00304 #define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem" 00305 #define caEdCertFile "./certs/ed25519/root-ed25519.pem" 00306 #ifdef HAVE_WNR 00307 /* Whitewood netRandom default config file */ 00308 #define wnrConfig "./wnr-example.conf" 00309 #endif 00310 #endif 00311 00312 typedef struct tcp_ready { 00313 word16 ready; /* predicate */ 00314 word16 port; 00315 char* srfName; /* server ready file name */ 00316 #if defined(_POSIX_THREADS) && !defined(__MINGW32__) 00317 pthread_mutex_t mutex; 00318 pthread_cond_t cond; 00319 #endif 00320 } tcp_ready; 00321 00322 00323 static WC_INLINE void InitTcpReady(tcp_ready* ready) 00324 { 00325 ready->ready = 0; 00326 ready->port = 0; 00327 ready->srfName = NULL; 00328 #ifdef SINGLE_THREADED 00329 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) 00330 pthread_mutex_init(&ready->mutex, 0); 00331 pthread_cond_init(&ready->cond, 0); 00332 #endif 00333 } 00334 00335 00336 static WC_INLINE void FreeTcpReady(tcp_ready* ready) 00337 { 00338 #ifdef SINGLE_THREADED 00339 (void)ready; 00340 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) 00341 pthread_mutex_destroy(&ready->mutex); 00342 pthread_cond_destroy(&ready->cond); 00343 #else 00344 (void)ready; 00345 #endif 00346 } 00347 00348 typedef WOLFSSL_METHOD* (*method_provider)(void); 00349 typedef void (*ctx_callback)(WOLFSSL_CTX* ctx); 00350 typedef void (*ssl_callback)(WOLFSSL* ssl); 00351 00352 typedef struct callback_functions { 00353 method_provider method; 00354 ctx_callback ctx_ready; 00355 ssl_callback ssl_ready; 00356 ssl_callback on_result; 00357 } callback_functions; 00358 00359 typedef struct func_args { 00360 int argc; 00361 char** argv; 00362 int return_code; 00363 tcp_ready* signal; 00364 callback_functions *callbacks; 00365 } func_args; 00366 00367 00368 00369 00370 void wait_tcp_ready(func_args*); 00371 00372 typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*); 00373 00374 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*); 00375 void join_thread(THREAD_TYPE); 00376 00377 /* wolfSSL */ 00378 #ifndef TEST_IPV6 00379 static const char* const wolfSSLIP = "127.0.0.1"; 00380 #else 00381 static const char* const wolfSSLIP = "::1"; 00382 #endif 00383 static const word16 wolfSSLPort = 11111; 00384 00385 00386 static WC_INLINE WC_NORETURN void err_sys(const char* msg) 00387 { 00388 printf("wolfSSL error: %s\n", msg); 00389 00390 #if !defined(__GNUC__) 00391 /* scan-build (which pretends to be gnuc) can get confused and think the 00392 * msg pointer can be null even when hardcoded and then it won't exit, 00393 * making null pointer checks above the err_sys() call useless. 00394 * We could just always exit() but some compilers will complain about no 00395 * possible return, with gcc we know the attribute to handle that with 00396 * WC_NORETURN. */ 00397 if (msg) 00398 #endif 00399 { 00400 exit(EXIT_FAILURE); 00401 } 00402 } 00403 00404 00405 #define MY_EX_USAGE 2 00406 00407 extern int myoptind; 00408 extern char* myoptarg; 00409 00410 static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring) 00411 { 00412 static char* next = NULL; 00413 00414 char c; 00415 char* cp; 00416 00417 if (myoptind == 0) 00418 next = NULL; /* we're starting new/over */ 00419 00420 if (next == NULL || *next == '\0') { 00421 if (myoptind == 0) 00422 myoptind++; 00423 00424 if (myoptind >= argc || argv[myoptind][0] != '-' || 00425 argv[myoptind][1] == '\0') { 00426 myoptarg = NULL; 00427 if (myoptind < argc) 00428 myoptarg = argv[myoptind]; 00429 00430 return -1; 00431 } 00432 00433 if (strcmp(argv[myoptind], "--") == 0) { 00434 myoptind++; 00435 myoptarg = NULL; 00436 00437 if (myoptind < argc) 00438 myoptarg = argv[myoptind]; 00439 00440 return -1; 00441 } 00442 00443 next = argv[myoptind]; 00444 next++; /* skip - */ 00445 myoptind++; 00446 } 00447 00448 c = *next++; 00449 /* The C++ strchr can return a different value */ 00450 cp = (char*)strchr(optstring, c); 00451 00452 if (cp == NULL || c == ':') 00453 return '?'; 00454 00455 cp++; 00456 00457 if (*cp == ':') { 00458 if (*next != '\0') { 00459 myoptarg = next; 00460 next = NULL; 00461 } 00462 else if (myoptind < argc) { 00463 myoptarg = argv[myoptind]; 00464 myoptind++; 00465 } 00466 else 00467 return '?'; 00468 } 00469 00470 return c; 00471 } 00472 00473 00474 #ifdef WOLFSSL_ENCRYPTED_KEYS 00475 00476 static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) 00477 { 00478 (void)rw; 00479 (void)userdata; 00480 if (userdata != NULL) { 00481 strncpy(passwd, (char*)userdata, sz); 00482 return (int)XSTRLEN((char*)userdata); 00483 } 00484 else { 00485 strncpy(passwd, "yassl123", sz); 00486 return 8; 00487 } 00488 } 00489 00490 #endif 00491 00492 00493 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) 00494 00495 static WC_INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr) 00496 { 00497 char* altName; 00498 char* issuer; 00499 char* subject; 00500 byte serial[32]; 00501 int ret; 00502 int sz = sizeof(serial); 00503 00504 if (x509 == NULL) { 00505 printf("%s No Cert\n", hdr); 00506 return; 00507 } 00508 00509 issuer = wolfSSL_X509_NAME_oneline( 00510 wolfSSL_X509_get_issuer_name(x509), 0, 0); 00511 subject = wolfSSL_X509_NAME_oneline( 00512 wolfSSL_X509_get_subject_name(x509), 0, 0); 00513 00514 printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject); 00515 00516 while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL) 00517 printf(" altname = %s\n", altName); 00518 00519 ret = wolfSSL_X509_get_serial_number(x509, serial, &sz); 00520 if (ret == WOLFSSL_SUCCESS) { 00521 int i; 00522 int strLen; 00523 char serialMsg[80]; 00524 00525 /* testsuite has multiple threads writing to stdout, get output 00526 message ready to write once */ 00527 strLen = sprintf(serialMsg, " serial number"); 00528 for (i = 0; i < sz; i++) 00529 sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]); 00530 printf("%s\n", serialMsg); 00531 } 00532 00533 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); 00534 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); 00535 00536 #if defined(OPENSSL_EXTRA) && defined(SHOW_CERTS) 00537 { 00538 WOLFSSL_BIO* bio; 00539 char buf[256]; /* should be size of ASN_NAME_MAX */ 00540 int textSz; 00541 00542 00543 /* print out domain component if certificate has it */ 00544 textSz = wolfSSL_X509_NAME_get_text_by_NID( 00545 wolfSSL_X509_get_subject_name(x509), NID_domainComponent, 00546 buf, sizeof(buf)); 00547 if (textSz > 0) { 00548 printf("Domain Component = %s\n", buf); 00549 } 00550 00551 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); 00552 if (bio != NULL) { 00553 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); 00554 wolfSSL_X509_print(bio, x509); 00555 wolfSSL_BIO_free(bio); 00556 } 00557 } 00558 #endif 00559 } 00560 00561 #endif /* KEEP_PEER_CERT || SESSION_CERTS */ 00562 00563 #if defined(SESSION_CERTS) && defined(SHOW_CERTS) 00564 static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count, 00565 const char* hdr) 00566 { 00567 int i; 00568 int length; 00569 unsigned char buffer[3072]; 00570 WOLFSSL_X509* chainX509; 00571 00572 for (i = 0; i < count; i++) { 00573 wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length); 00574 buffer[length] = 0; 00575 printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer); 00576 00577 chainX509 = wolfSSL_get_chain_X509(chain, i); 00578 if (chainX509) 00579 ShowX509(chainX509, hdr); 00580 else 00581 printf("get_chain_X509 failed\n"); 00582 wolfSSL_FreeX509(chainX509); 00583 } 00584 } 00585 #endif 00586 00587 static WC_INLINE void showPeer(WOLFSSL* ssl) 00588 { 00589 WOLFSSL_CIPHER* cipher; 00590 #ifdef HAVE_ECC 00591 const char *name; 00592 #endif 00593 #ifndef NO_DH 00594 int bits; 00595 #endif 00596 #ifdef KEEP_PEER_CERT 00597 WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); 00598 if (peer) 00599 ShowX509(peer, "peer's cert info:"); 00600 else 00601 printf("peer has no cert!\n"); 00602 wolfSSL_FreeX509(peer); 00603 #endif 00604 #if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT) 00605 ShowX509(wolfSSL_get_certificate(ssl), "our cert info:"); 00606 printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl)); 00607 #endif /* SHOW_CERTS */ 00608 printf("SSL version is %s\n", wolfSSL_get_version(ssl)); 00609 00610 cipher = wolfSSL_get_current_cipher(ssl); 00611 #ifdef HAVE_QSH 00612 printf("SSL cipher suite is %s%s\n", (wolfSSL_isQSH(ssl))? "QSH:": "", 00613 wolfSSL_CIPHER_get_name(cipher)); 00614 #else 00615 printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); 00616 #endif 00617 #ifdef HAVE_ECC 00618 if ((name = wolfSSL_get_curve_name(ssl)) != NULL) 00619 printf("SSL curve name is %s\n", name); 00620 #endif 00621 #ifndef NO_DH 00622 if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0) 00623 printf("SSL DH size is %d bits\n", bits); 00624 #endif 00625 if (wolfSSL_session_reused(ssl)) 00626 printf("SSL reused session\n"); 00627 #ifdef WOLFSSL_ALT_CERT_CHAINS 00628 if (wolfSSL_is_peer_alt_cert_chain(ssl)) 00629 printf("Alternate cert chain used\n"); 00630 #endif 00631 00632 #if defined(SESSION_CERTS) && defined(SHOW_CERTS) 00633 { 00634 WOLFSSL_X509_CHAIN* chain; 00635 00636 chain = wolfSSL_get_peer_chain(ssl); 00637 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert"); 00638 00639 #ifdef WOLFSSL_ALT_CERT_CHAINS 00640 if (wolfSSL_is_peer_alt_cert_chain(ssl)) { 00641 chain = wolfSSL_get_peer_alt_chain(ssl); 00642 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert"); 00643 } 00644 #endif 00645 } 00646 #endif /* SESSION_CERTS && SHOW_CERTS */ 00647 (void)ssl; 00648 } 00649 00650 00651 static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, 00652 word16 port, int udp, int sctp) 00653 { 00654 int useLookup = 0; 00655 (void)useLookup; 00656 (void)udp; 00657 (void)sctp; 00658 00659 if (addr == NULL) 00660 err_sys("invalid argument to build_addr, addr is NULL"); 00661 00662 XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T)); 00663 00664 #ifndef TEST_IPV6 00665 /* peer could be in human readable form */ 00666 if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) { 00667 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00668 int err; 00669 struct hostent* entry = gethostbyname(peer, &err); 00670 #elif defined(WOLFSSL_TIRTOS) 00671 struct hostent* entry = DNSGetHostByName(peer); 00672 #elif defined(WOLFSSL_VXWORKS) 00673 struct hostent* entry = (struct hostent*)hostGetByName((char*)peer); 00674 #else 00675 struct hostent* entry = gethostbyname(peer); 00676 #endif 00677 00678 if (entry) { 00679 XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0], 00680 entry->h_length); 00681 useLookup = 1; 00682 } 00683 else 00684 err_sys("no entry for host"); 00685 } 00686 #endif 00687 00688 00689 #ifndef TEST_IPV6 00690 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) 00691 addr->sin_family = PF_INET; 00692 #else 00693 addr->sin_family = AF_INET_V; 00694 #endif 00695 addr->sin_port = XHTONS(port); 00696 if ((size_t)peer == INADDR_ANY) 00697 addr->sin_addr.s_addr = INADDR_ANY; 00698 else { 00699 if (!useLookup) 00700 addr->sin_addr.s_addr = inet_addr(peer); 00701 } 00702 #else 00703 addr->sin6_family = AF_INET_V; 00704 addr->sin6_port = XHTONS(port); 00705 if ((size_t)peer == INADDR_ANY) { 00706 addr->sin6_addr = in6addr_any; 00707 } 00708 else { 00709 #ifdef HAVE_GETADDRINFO 00710 struct addrinfo hints; 00711 struct addrinfo* answer = NULL; 00712 int ret; 00713 char strPort[80]; 00714 00715 XMEMSET(&hints, 0, sizeof(hints)); 00716 00717 hints.ai_family = AF_INET_V; 00718 if (udp) { 00719 hints.ai_socktype = SOCK_DGRAM; 00720 hints.ai_protocol = IPPROTO_UDP; 00721 } 00722 #ifdef WOLFSSL_SCTP 00723 else if (sctp) { 00724 hints.ai_socktype = SOCK_STREAM; 00725 hints.ai_protocol = IPPROTO_SCTP; 00726 } 00727 #endif 00728 else { 00729 hints.ai_socktype = SOCK_STREAM; 00730 hints.ai_protocol = IPPROTO_TCP; 00731 } 00732 00733 SNPRINTF(strPort, sizeof(strPort), "%d", port); 00734 strPort[79] = '\0'; 00735 00736 ret = getaddrinfo(peer, strPort, &hints, &answer); 00737 if (ret < 0 || answer == NULL) 00738 err_sys("getaddrinfo failed"); 00739 00740 XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen); 00741 freeaddrinfo(answer); 00742 #else 00743 printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); 00744 addr->sin6_addr = in6addr_loopback; 00745 #endif 00746 } 00747 #endif 00748 } 00749 00750 00751 static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) 00752 { 00753 (void)sctp; 00754 00755 if (udp) 00756 *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP); 00757 #ifdef WOLFSSL_SCTP 00758 else if (sctp) 00759 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP); 00760 #endif 00761 else 00762 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP); 00763 00764 if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) { 00765 err_sys("socket failed\n"); 00766 } 00767 00768 #ifndef USE_WINDOWS_API 00769 #ifdef SO_NOSIGPIPE 00770 { 00771 int on = 1; 00772 socklen_t len = sizeof(on); 00773 int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); 00774 if (res < 0) 00775 err_sys("setsockopt SO_NOSIGPIPE failed\n"); 00776 } 00777 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\ 00778 defined(WOLFSSL_KEIL_TCP_NET) 00779 /* nothing to define */ 00780 #else /* no S_NOSIGPIPE */ 00781 signal(SIGPIPE, SIG_IGN); 00782 #endif /* S_NOSIGPIPE */ 00783 00784 #if defined(TCP_NODELAY) 00785 if (!udp && !sctp) 00786 { 00787 int on = 1; 00788 socklen_t len = sizeof(on); 00789 int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len); 00790 if (res < 0) 00791 err_sys("setsockopt TCP_NODELAY failed\n"); 00792 } 00793 #endif 00794 #endif /* USE_WINDOWS_API */ 00795 } 00796 00797 static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, 00798 int udp, int sctp, WOLFSSL* ssl) 00799 { 00800 SOCKADDR_IN_T addr; 00801 build_addr(&addr, ip, port, udp, sctp); 00802 if (udp) { 00803 wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); 00804 } 00805 tcp_socket(sockfd, udp, sctp); 00806 00807 if (!udp) { 00808 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00809 err_sys("tcp connect failed"); 00810 } 00811 } 00812 00813 00814 static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz) 00815 { 00816 if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0) 00817 err_sys("tcp connect failed"); 00818 } 00819 00820 00821 enum { 00822 TEST_SELECT_FAIL, 00823 TEST_TIMEOUT, 00824 TEST_RECV_READY, 00825 TEST_ERROR_READY 00826 }; 00827 00828 00829 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \ 00830 !defined(WOLFSSL_TIRTOS) 00831 static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) 00832 { 00833 fd_set recvfds, errfds; 00834 SOCKET_T nfds = socketfd + 1; 00835 #if !defined(__INTEGRITY) 00836 struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0}; 00837 #else 00838 struct timeval timeout; 00839 #endif 00840 int result; 00841 00842 FD_ZERO(&recvfds); 00843 FD_SET(socketfd, &recvfds); 00844 FD_ZERO(&errfds); 00845 FD_SET(socketfd, &errfds); 00846 00847 #if defined(__INTEGRITY) 00848 timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0; 00849 #endif 00850 result = select(nfds, &recvfds, NULL, &errfds, &timeout); 00851 00852 if (result == 0) 00853 return TEST_TIMEOUT; 00854 else if (result > 0) { 00855 if (FD_ISSET(socketfd, &recvfds)) 00856 return TEST_RECV_READY; 00857 else if(FD_ISSET(socketfd, &errfds)) 00858 return TEST_ERROR_READY; 00859 } 00860 00861 return TEST_SELECT_FAIL; 00862 } 00863 #elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET) 00864 static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) 00865 { 00866 return TEST_RECV_READY; 00867 } 00868 #endif /* !WOLFSSL_MDK_ARM */ 00869 00870 00871 static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, 00872 int udp, int sctp) 00873 { 00874 SOCKADDR_IN_T addr; 00875 00876 /* don't use INADDR_ANY by default, firewall may block, make user switch 00877 on */ 00878 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp); 00879 tcp_socket(sockfd, udp, sctp); 00880 00881 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ 00882 && !defined(WOLFSSL_KEIL_TCP_NET) 00883 { 00884 int res, on = 1; 00885 socklen_t len = sizeof(on); 00886 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); 00887 if (res < 0) 00888 err_sys("setsockopt SO_REUSEADDR failed\n"); 00889 } 00890 #endif 00891 00892 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00893 err_sys("tcp bind failed"); 00894 if (!udp) { 00895 #ifdef WOLFSSL_KEIL_TCP_NET 00896 #define SOCK_LISTEN_MAX_QUEUE 1 00897 #else 00898 #define SOCK_LISTEN_MAX_QUEUE 5 00899 #endif 00900 if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0) 00901 err_sys("tcp listen failed"); 00902 } 00903 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) 00904 if (*port == 0) { 00905 socklen_t len = sizeof(addr); 00906 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { 00907 #ifndef TEST_IPV6 00908 *port = XNTOHS(addr.sin_port); 00909 #else 00910 *port = XNTOHS(addr.sin6_port); 00911 #endif 00912 } 00913 } 00914 #endif 00915 } 00916 00917 00918 #if 0 00919 static WC_INLINE int udp_read_connect(SOCKET_T sockfd) 00920 { 00921 SOCKADDR_IN_T cliaddr; 00922 byte b[1500]; 00923 int n; 00924 socklen_t len = sizeof(cliaddr); 00925 00926 n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK, 00927 (struct sockaddr*)&cliaddr, &len); 00928 if (n > 0) { 00929 if (connect(sockfd, (const struct sockaddr*)&cliaddr, 00930 sizeof(cliaddr)) != 0) 00931 err_sys("udp connect failed"); 00932 } 00933 else 00934 err_sys("recvfrom failed"); 00935 00936 return sockfd; 00937 } 00938 #endif 00939 00940 static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, 00941 int useAnyAddr, word16 port, func_args* args) 00942 { 00943 SOCKADDR_IN_T addr; 00944 00945 (void)args; 00946 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0); 00947 tcp_socket(sockfd, 1, 0); 00948 00949 00950 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \ 00951 && !defined(WOLFSSL_KEIL_TCP_NET) 00952 { 00953 int res, on = 1; 00954 socklen_t len = sizeof(on); 00955 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); 00956 if (res < 0) 00957 err_sys("setsockopt SO_REUSEADDR failed\n"); 00958 } 00959 #endif 00960 00961 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00962 err_sys("tcp bind failed"); 00963 00964 #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS) 00965 if (port == 0) { 00966 socklen_t len = sizeof(addr); 00967 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { 00968 #ifndef TEST_IPV6 00969 port = XNTOHS(addr.sin_port); 00970 #else 00971 port = XNTOHS(addr.sin6_port); 00972 #endif 00973 } 00974 } 00975 #endif 00976 00977 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) 00978 /* signal ready to accept data */ 00979 { 00980 tcp_ready* ready = args->signal; 00981 pthread_mutex_lock(&ready->mutex); 00982 ready->ready = 1; 00983 ready->port = port; 00984 pthread_cond_signal(&ready->cond); 00985 pthread_mutex_unlock(&ready->mutex); 00986 } 00987 #elif defined (WOLFSSL_TIRTOS) 00988 /* Need mutex? */ 00989 tcp_ready* ready = args->signal; 00990 ready->ready = 1; 00991 ready->port = port; 00992 #endif 00993 00994 *clientfd = *sockfd; 00995 } 00996 00997 static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, 00998 func_args* args, word16 port, int useAnyAddr, 00999 int udp, int sctp, int ready_file, int do_listen) 01000 { 01001 SOCKADDR_IN_T client; 01002 socklen_t client_len = sizeof(client); 01003 tcp_ready* ready = NULL; 01004 01005 (void) ready; /* Account for case when "ready" is not used */ 01006 01007 if (udp) { 01008 udp_accept(sockfd, clientfd, useAnyAddr, port, args); 01009 return; 01010 } 01011 01012 if(do_listen) { 01013 tcp_listen(sockfd, &port, useAnyAddr, udp, sctp); 01014 01015 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) 01016 /* signal ready to tcp_accept */ 01017 if (args) 01018 ready = args->signal; 01019 if (ready) { 01020 pthread_mutex_lock(&ready->mutex); 01021 ready->ready = 1; 01022 ready->port = port; 01023 pthread_cond_signal(&ready->cond); 01024 pthread_mutex_unlock(&ready->mutex); 01025 } 01026 #elif defined (WOLFSSL_TIRTOS) 01027 /* Need mutex? */ 01028 if (args) 01029 ready = args->signal; 01030 if (ready) { 01031 ready->ready = 1; 01032 ready->port = port; 01033 } 01034 #endif 01035 01036 if (ready_file) { 01037 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) 01038 FILE* srf = NULL; 01039 if (args) 01040 ready = args->signal; 01041 01042 if (ready) { 01043 srf = fopen(ready->srfName, "w"); 01044 01045 if (srf) { 01046 /* let's write port sever is listening on to ready file 01047 external monitor can then do ephemeral ports by passing 01048 -p 0 to server on supported platforms with -R ready_file 01049 client can then wait for existence of ready_file and see 01050 which port the server is listening on. */ 01051 fprintf(srf, "%d\n", (int)port); 01052 fclose(srf); 01053 } 01054 } 01055 #endif 01056 } 01057 } 01058 01059 *clientfd = accept(*sockfd, (struct sockaddr*)&client, 01060 (ACCEPT_THIRD_T)&client_len); 01061 if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) { 01062 err_sys("tcp accept failed"); 01063 } 01064 } 01065 01066 01067 static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd) 01068 { 01069 #ifdef USE_WINDOWS_API 01070 unsigned long blocking = 1; 01071 int ret = ioctlsocket(*sockfd, FIONBIO, &blocking); 01072 if (ret == SOCKET_ERROR) 01073 err_sys("ioctlsocket failed"); 01074 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \ 01075 || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) 01076 /* non blocking not supported, for now */ 01077 #else 01078 int flags = fcntl(*sockfd, F_GETFL, 0); 01079 if (flags < 0) 01080 err_sys("fcntl get failed"); 01081 flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK); 01082 if (flags < 0) 01083 err_sys("fcntl set failed"); 01084 #endif 01085 } 01086 01087 01088 #ifndef NO_PSK 01089 01090 /* identity is OpenSSL testing default for openssl s_client, keep same */ 01091 static const char* kIdentityStr = "Client_identity"; 01092 01093 static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint, 01094 char* identity, unsigned int id_max_len, unsigned char* key, 01095 unsigned int key_max_len) 01096 { 01097 (void)ssl; 01098 (void)hint; 01099 (void)key_max_len; 01100 01101 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ 01102 strncpy(identity, kIdentityStr, id_max_len); 01103 01104 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { 01105 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 01106 unsigned binary */ 01107 key[0] = 0x1a; 01108 key[1] = 0x2b; 01109 key[2] = 0x3c; 01110 key[3] = 0x4d; 01111 01112 01113 return 4; /* length of key in octets or 0 for error */ 01114 } 01115 else { 01116 int i; 01117 int b = 0x01; 01118 01119 for (i = 0; i < 32; i++, b += 0x22) { 01120 if (b >= 0x100) 01121 b = 0x01; 01122 key[i] = b; 01123 } 01124 01125 return 32; /* length of key in octets or 0 for error */ 01126 } 01127 } 01128 01129 01130 static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, 01131 unsigned char* key, unsigned int key_max_len) 01132 { 01133 (void)ssl; 01134 (void)key_max_len; 01135 01136 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ 01137 if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0) 01138 return 0; 01139 01140 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { 01141 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 01142 unsigned binary */ 01143 key[0] = 0x1a; 01144 key[1] = 0x2b; 01145 key[2] = 0x3c; 01146 key[3] = 0x4d; 01147 01148 01149 return 4; /* length of key in octets or 0 for error */ 01150 } 01151 else { 01152 int i; 01153 int b = 0x01; 01154 01155 for (i = 0; i < 32; i++, b += 0x22) { 01156 if (b >= 0x100) 01157 b = 0x01; 01158 key[i] = b; 01159 } 01160 01161 return 32; /* length of key in octets or 0 for error */ 01162 } 01163 } 01164 01165 #endif /* NO_PSK */ 01166 01167 01168 #if defined(WOLFSSL_USER_CURRTIME) 01169 extern double current_time(int reset); 01170 01171 #elif defined(USE_WINDOWS_API) 01172 01173 #define WIN32_LEAN_AND_MEAN 01174 #include <windows.h> 01175 01176 static WC_INLINE double current_time(int reset) 01177 { 01178 static int init = 0; 01179 static LARGE_INTEGER freq; 01180 01181 LARGE_INTEGER count; 01182 01183 if (!init) { 01184 QueryPerformanceFrequency(&freq); 01185 init = 1; 01186 } 01187 01188 QueryPerformanceCounter(&count); 01189 01190 (void)reset; 01191 return (double)count.QuadPart / freq.QuadPart; 01192 } 01193 01194 #elif defined(WOLFSSL_TIRTOS) 01195 extern double current_time(); 01196 #else 01197 01198 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS) 01199 #include <sys/time.h> 01200 01201 static WC_INLINE double current_time(int reset) 01202 { 01203 struct timeval tv; 01204 gettimeofday(&tv, 0); 01205 (void)reset; 01206 01207 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; 01208 } 01209 #else 01210 extern double current_time(int reset); 01211 #endif 01212 #endif /* USE_WINDOWS_API */ 01213 01214 01215 #if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP) 01216 static WC_INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz, 01217 unsigned char* request, int requestSz, unsigned char** response) 01218 { 01219 #ifdef TEST_NONBLOCK_CERTS 01220 static int ioCbCnt = 0; 01221 #endif 01222 01223 (void)ioCtx; 01224 (void)url; 01225 (void)urlSz; 01226 (void)request; 01227 (void)requestSz; 01228 (void)response; 01229 01230 #ifdef TEST_NONBLOCK_CERTS 01231 if (ioCbCnt) { 01232 ioCbCnt = 0; 01233 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response); 01234 } 01235 else { 01236 ioCbCnt = 1; 01237 return WOLFSSL_CBIO_ERR_WANT_READ; 01238 } 01239 #else 01240 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response); 01241 #endif 01242 } 01243 01244 static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response) 01245 { 01246 (void)ioCtx; 01247 (void)response; 01248 } 01249 #endif 01250 01251 #if !defined(NO_CERTS) 01252 #if !defined(NO_FILESYSTEM) || \ 01253 (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST)) 01254 01255 /* reads file size, allocates buffer, reads into buffer, returns buffer */ 01256 static WC_INLINE int load_file(const char* fname, byte** buf, size_t* bufLen) 01257 { 01258 int ret; 01259 long int fileSz; 01260 FILE* file; 01261 01262 if (fname == NULL || buf == NULL || bufLen == NULL) 01263 return BAD_FUNC_ARG; 01264 01265 /* set defaults */ 01266 *buf = NULL; 01267 *bufLen = 0; 01268 01269 /* open file (read-only binary) */ 01270 file = fopen(fname, "rb"); 01271 if (!file) { 01272 printf("Error loading %s\n", fname); 01273 return BAD_PATH_ERROR; 01274 } 01275 01276 fseek(file, 0, SEEK_END); 01277 fileSz = (int)ftell(file); 01278 rewind(file); 01279 if (fileSz > 0) { 01280 *bufLen = (size_t)fileSz; 01281 *buf = (byte*)malloc(*bufLen); 01282 if (*buf == NULL) { 01283 ret = MEMORY_E; 01284 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen); 01285 } 01286 else { 01287 size_t readLen = fread(*buf, *bufLen, 1, file); 01288 01289 /* check response code */ 01290 ret = (readLen > 0) ? 0 : -1; 01291 } 01292 } 01293 else { 01294 ret = BUFFER_E; 01295 } 01296 fclose(file); 01297 01298 return ret; 01299 } 01300 01301 enum { 01302 WOLFSSL_CA = 1, 01303 WOLFSSL_CERT = 2, 01304 WOLFSSL_KEY = 3, 01305 WOLFSSL_CERT_CHAIN = 4, 01306 }; 01307 01308 static WC_INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type) 01309 { 01310 int format = WOLFSSL_FILETYPE_PEM; 01311 byte* buff = NULL; 01312 size_t sz = 0; 01313 01314 if (load_file(fname, &buff, &sz) != 0) { 01315 err_sys("can't open file for buffer load " 01316 "Please run from wolfSSL home directory if not"); 01317 } 01318 01319 /* determine format */ 01320 if (strstr(fname, ".der")) 01321 format = WOLFSSL_FILETYPE_ASN1; 01322 01323 if (type == WOLFSSL_CA) { 01324 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format) 01325 != WOLFSSL_SUCCESS) 01326 err_sys("can't load buffer ca file"); 01327 } 01328 else if (type == WOLFSSL_CERT) { 01329 if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz, 01330 format) != WOLFSSL_SUCCESS) 01331 err_sys("can't load buffer cert file"); 01332 } 01333 else if (type == WOLFSSL_KEY) { 01334 if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz, 01335 format) != WOLFSSL_SUCCESS) 01336 err_sys("can't load buffer key file"); 01337 } 01338 else if (type == WOLFSSL_CERT_CHAIN) { 01339 if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff, 01340 (long)sz, format) != WOLFSSL_SUCCESS) 01341 err_sys("can't load cert chain buffer"); 01342 } 01343 01344 if (buff) 01345 free(buff); 01346 } 01347 01348 #ifdef TEST_PK_PRIVKEY 01349 static WC_INLINE int load_key_file(const char* fname, byte** derBuf, word32* derLen) 01350 { 01351 int ret; 01352 byte* buf = NULL; 01353 size_t bufLen; 01354 01355 ret = load_file(fname, &buf, &bufLen); 01356 if (ret != 0) 01357 return ret; 01358 01359 *derBuf = (byte*)malloc(bufLen); 01360 if (*derBuf == NULL) { 01361 free(buf); 01362 return MEMORY_E; 01363 } 01364 01365 ret = wc_KeyPemToDer(buf, (word32)bufLen, *derBuf, (word32)bufLen, NULL); 01366 if (ret < 0) { 01367 free(buf); 01368 free(*derBuf); 01369 return ret; 01370 } 01371 *derLen = ret; 01372 free(buf); 01373 01374 return 0; 01375 } 01376 #endif /* TEST_PK_PRIVKEY */ 01377 01378 #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */ 01379 #endif /* !NO_CERTS */ 01380 01381 static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) 01382 { 01383 char buffer[WOLFSSL_MAX_ERROR_SZ]; 01384 #ifdef OPENSSL_EXTRA 01385 WOLFSSL_X509* peer; 01386 #endif 01387 (void)preverify; 01388 01389 printf("In verification callback, error = %d, %s\n", store->error, 01390 wolfSSL_ERR_error_string(store->error, buffer)); 01391 #ifdef OPENSSL_EXTRA 01392 peer = store->current_cert; 01393 if (peer) { 01394 char* issuer = wolfSSL_X509_NAME_oneline( 01395 wolfSSL_X509_get_issuer_name(peer), 0, 0); 01396 char* subject = wolfSSL_X509_NAME_oneline( 01397 wolfSSL_X509_get_subject_name(peer), 0, 0); 01398 printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer, 01399 subject); 01400 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); 01401 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); 01402 } 01403 else 01404 printf("\tPeer has no cert!\n"); 01405 #else 01406 printf("\tPeer certs: %d\n", store->totalCerts); 01407 #ifdef SHOW_CERTS 01408 { int i; 01409 for (i=0; i<store->totalCerts; i++) { 01410 WOLFSSL_BUFFER_INFO* cert = &store->certs[i]; 01411 printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length); 01412 } 01413 } 01414 #endif 01415 #endif 01416 01417 printf("\tSubject's domain name is %s\n", store->domain); 01418 01419 printf("\tAllowing to continue anyway (shouldn't do this, EVER!!!)\n"); 01420 return 1; 01421 } 01422 01423 01424 static WC_INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store) 01425 { 01426 char buffer[WOLFSSL_MAX_ERROR_SZ]; 01427 (void)preverify; 01428 01429 printf("In verification callback, error = %d, %s\n", store->error, 01430 wolfSSL_ERR_error_string(store->error, buffer)); 01431 printf("Subject's domain name is %s\n", store->domain); 01432 01433 if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) { 01434 printf("Overriding cert date error as example for bad clock testing\n"); 01435 return 1; 01436 } 01437 printf("Cert error is not date error, not overriding\n"); 01438 01439 return 0; 01440 } 01441 01442 01443 #ifdef HAVE_EXT_CACHE 01444 01445 static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, unsigned char* id, 01446 int id_len, int* copy) 01447 { 01448 (void)ssl; 01449 (void)id; 01450 (void)id_len; 01451 (void)copy; 01452 01453 /* using internal cache, this is for testing only */ 01454 return NULL; 01455 } 01456 01457 static WC_INLINE int mySessNewCb(WOLFSSL* ssl, WOLFSSL_SESSION* session) 01458 { 01459 (void)ssl; 01460 (void)session; 01461 01462 /* using internal cache, this is for testing only */ 01463 return 0; 01464 } 01465 01466 static WC_INLINE void mySessRemCb(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) 01467 { 01468 (void)ctx; 01469 (void)session; 01470 01471 /* using internal cache, this is for testing only */ 01472 } 01473 01474 #endif /* HAVE_EXT_CACHE */ 01475 01476 01477 #ifdef HAVE_CRL 01478 01479 static WC_INLINE void CRL_CallBack(const char* url) 01480 { 01481 printf("CRL callback url = %s\n", url); 01482 } 01483 01484 #endif 01485 01486 #ifndef NO_DH 01487 static WC_INLINE void SetDH(WOLFSSL* ssl) 01488 { 01489 /* dh1024 p */ 01490 static const unsigned char p[] = 01491 { 01492 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, 01493 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, 01494 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, 01495 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, 01496 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, 01497 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, 01498 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, 01499 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, 01500 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, 01501 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, 01502 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, 01503 }; 01504 01505 /* dh1024 g */ 01506 static const unsigned char g[] = 01507 { 01508 0x02, 01509 }; 01510 01511 wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g)); 01512 } 01513 01514 static WC_INLINE void SetDHCtx(WOLFSSL_CTX* ctx) 01515 { 01516 /* dh1024 p */ 01517 static const unsigned char p[] = 01518 { 01519 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, 01520 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, 01521 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, 01522 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, 01523 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, 01524 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, 01525 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, 01526 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, 01527 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, 01528 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, 01529 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, 01530 }; 01531 01532 /* dh1024 g */ 01533 static const unsigned char g[] = 01534 { 01535 0x02, 01536 }; 01537 01538 wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g)); 01539 } 01540 #endif /* NO_DH */ 01541 01542 #ifndef NO_CERTS 01543 01544 static WC_INLINE void CaCb(unsigned char* der, int sz, int type) 01545 { 01546 (void)der; 01547 printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type); 01548 } 01549 01550 #endif /* !NO_CERTS */ 01551 01552 01553 /* Wolf Root Directory Helper */ 01554 /* KEIL-RL File System does not support relative directory */ 01555 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) 01556 /* Maximum depth to search for WolfSSL root */ 01557 #define MAX_WOLF_ROOT_DEPTH 5 01558 01559 static WC_INLINE int ChangeToWolfRoot(void) 01560 { 01561 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) 01562 int depth, res; 01563 FILE* file; 01564 for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { 01565 file = fopen(ntruKeyFile, "rb"); 01566 if (file != NULL) { 01567 fclose(file); 01568 return depth; 01569 } 01570 #ifdef USE_WINDOWS_API 01571 res = SetCurrentDirectoryA("..\\"); 01572 #else 01573 res = chdir("../"); 01574 #endif 01575 if (res < 0) { 01576 printf("chdir to ../ failed!\n"); 01577 break; 01578 } 01579 } 01580 01581 err_sys("wolf root not found"); 01582 return -1; 01583 #else 01584 return 0; 01585 #endif 01586 } 01587 #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */ 01588 01589 #ifdef HAVE_STACK_SIZE 01590 01591 typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args); 01592 #define STACK_CHECK_VAL 0x01 01593 01594 static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf) 01595 { 01596 int ret, i, used; 01597 void* status; 01598 unsigned char* myStack = NULL; 01599 int stackSize = 1024*128; 01600 pthread_attr_t myAttr; 01601 pthread_t threadId; 01602 01603 #ifdef PTHREAD_STACK_MIN 01604 if (stackSize < PTHREAD_STACK_MIN) 01605 stackSize = PTHREAD_STACK_MIN; 01606 #endif 01607 01608 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); 01609 if (ret != 0 || myStack == NULL) 01610 err_sys("posix_memalign failed\n"); 01611 01612 XMEMSET(myStack, STACK_CHECK_VAL, stackSize); 01613 01614 ret = pthread_attr_init(&myAttr); 01615 if (ret != 0) 01616 err_sys("attr_init failed"); 01617 01618 ret = pthread_attr_setstack(&myAttr, myStack, stackSize); 01619 if (ret != 0) 01620 err_sys("attr_setstackaddr failed"); 01621 01622 ret = pthread_create(&threadId, &myAttr, tf, args); 01623 if (ret != 0) { 01624 perror("pthread_create failed"); 01625 exit(EXIT_FAILURE); 01626 } 01627 01628 ret = pthread_join(threadId, &status); 01629 if (ret != 0) 01630 err_sys("pthread_join failed"); 01631 01632 for (i = 0; i < stackSize; i++) { 01633 if (myStack[i] != STACK_CHECK_VAL) { 01634 break; 01635 } 01636 } 01637 01638 free(myStack); 01639 01640 used = stackSize - i; 01641 printf("stack used = %d\n", used); 01642 01643 return (int)((size_t)status); 01644 } 01645 01646 01647 #endif /* HAVE_STACK_SIZE */ 01648 01649 01650 #ifdef STACK_TRAP 01651 01652 /* good settings 01653 --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP" 01654 01655 */ 01656 01657 #ifdef HAVE_STACK_SIZE 01658 /* client only for now, setrlimit will fail if pthread_create() called */ 01659 /* STACK_SIZE does pthread_create() on client */ 01660 #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail" 01661 #endif /* HAVE_STACK_SIZE */ 01662 01663 static WC_INLINE void StackTrap(void) 01664 { 01665 struct rlimit rl; 01666 if (getrlimit(RLIMIT_STACK, &rl) != 0) 01667 err_sys("getrlimit failed"); 01668 printf("rlim_cur = %llu\n", rl.rlim_cur); 01669 rl.rlim_cur = 1024*21; /* adjust trap size here */ 01670 if (setrlimit(RLIMIT_STACK, &rl) != 0) { 01671 perror("setrlimit"); 01672 err_sys("setrlimit failed"); 01673 } 01674 } 01675 01676 #else /* STACK_TRAP */ 01677 01678 static WC_INLINE void StackTrap(void) 01679 { 01680 } 01681 01682 #endif /* STACK_TRAP */ 01683 01684 01685 #ifdef ATOMIC_USER 01686 01687 /* Atomic Encrypt Context example */ 01688 typedef struct AtomicEncCtx { 01689 int keySetup; /* have we done key setup yet */ 01690 Aes aes; /* for aes example */ 01691 } AtomicEncCtx; 01692 01693 01694 /* Atomic Decrypt Context example */ 01695 typedef struct AtomicDecCtx { 01696 int keySetup; /* have we done key setup yet */ 01697 Aes aes; /* for aes example */ 01698 } AtomicDecCtx; 01699 01700 01701 static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut, 01702 const unsigned char* macIn, unsigned int macInSz, int macContent, 01703 int macVerify, unsigned char* encOut, const unsigned char* encIn, 01704 unsigned int encSz, void* ctx) 01705 { 01706 int ret; 01707 Hmac hmac; 01708 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; 01709 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx; 01710 const char* tlsStr = "TLS"; 01711 01712 /* example supports (d)tls aes */ 01713 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { 01714 printf("myMacEncryptCb not using AES\n"); 01715 return -1; 01716 } 01717 01718 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { 01719 printf("myMacEncryptCb not using (D)TLS\n"); 01720 return -1; 01721 } 01722 01723 /* hmac, not needed if aead mode */ 01724 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); 01725 01726 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), 01727 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl)); 01728 if (ret != 0) 01729 return ret; 01730 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); 01731 if (ret != 0) 01732 return ret; 01733 ret = wc_HmacUpdate(&hmac, macIn, macInSz); 01734 if (ret != 0) 01735 return ret; 01736 ret = wc_HmacFinal(&hmac, macOut); 01737 if (ret != 0) 01738 return ret; 01739 01740 01741 /* encrypt setup on first time */ 01742 if (encCtx->keySetup == 0) { 01743 int keyLen = wolfSSL_GetKeySize(ssl); 01744 const byte* key; 01745 const byte* iv; 01746 01747 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) { 01748 key = wolfSSL_GetClientWriteKey(ssl); 01749 iv = wolfSSL_GetClientWriteIV(ssl); 01750 } 01751 else { 01752 key = wolfSSL_GetServerWriteKey(ssl); 01753 iv = wolfSSL_GetServerWriteIV(ssl); 01754 } 01755 01756 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION); 01757 if (ret != 0) { 01758 printf("AesSetKey failed in myMacEncryptCb\n"); 01759 return ret; 01760 } 01761 encCtx->keySetup = 1; 01762 } 01763 01764 /* encrypt */ 01765 return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz); 01766 } 01767 01768 01769 static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl, 01770 unsigned char* decOut, const unsigned char* decIn, 01771 unsigned int decSz, int macContent, int macVerify, 01772 unsigned int* padSz, void* ctx) 01773 { 01774 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx; 01775 int ret = 0; 01776 int macInSz = 0; 01777 int ivExtra = 0; 01778 int digestSz = wolfSSL_GetHmacSize(ssl); 01779 unsigned int pad = 0; 01780 unsigned int padByte = 0; 01781 Hmac hmac; 01782 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; 01783 byte verify[WC_MAX_DIGEST_SIZE]; 01784 const char* tlsStr = "TLS"; 01785 01786 /* example supports (d)tls aes */ 01787 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { 01788 printf("myMacEncryptCb not using AES\n"); 01789 return -1; 01790 } 01791 01792 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { 01793 printf("myMacEncryptCb not using (D)TLS\n"); 01794 return -1; 01795 } 01796 01797 /*decrypt */ 01798 if (decCtx->keySetup == 0) { 01799 int keyLen = wolfSSL_GetKeySize(ssl); 01800 const byte* key; 01801 const byte* iv; 01802 01803 /* decrypt is from other side (peer) */ 01804 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { 01805 key = wolfSSL_GetClientWriteKey(ssl); 01806 iv = wolfSSL_GetClientWriteIV(ssl); 01807 } 01808 else { 01809 key = wolfSSL_GetServerWriteKey(ssl); 01810 iv = wolfSSL_GetServerWriteIV(ssl); 01811 } 01812 01813 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); 01814 if (ret != 0) { 01815 printf("AesSetKey failed in myDecryptVerifyCb\n"); 01816 return ret; 01817 } 01818 decCtx->keySetup = 1; 01819 } 01820 01821 /* decrypt */ 01822 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz); 01823 if (ret != 0) 01824 return ret; 01825 01826 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) { 01827 *padSz = wolfSSL_GetAeadMacSize(ssl); 01828 return 0; /* hmac, not needed if aead mode */ 01829 } 01830 01831 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) { 01832 pad = *(decOut + decSz - 1); 01833 padByte = 1; 01834 if (wolfSSL_IsTLSv1_1(ssl)) 01835 ivExtra = wolfSSL_GetCipherBlockSize(ssl); 01836 } 01837 01838 *padSz = wolfSSL_GetHmacSize(ssl) + pad + padByte; 01839 macInSz = decSz - ivExtra - digestSz - pad - padByte; 01840 01841 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); 01842 01843 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), 01844 wolfSSL_GetMacSecret(ssl, macVerify), digestSz); 01845 if (ret != 0) 01846 return ret; 01847 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); 01848 if (ret != 0) 01849 return ret; 01850 ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz); 01851 if (ret != 0) 01852 return ret; 01853 ret = wc_HmacFinal(&hmac, verify); 01854 if (ret != 0) 01855 return ret; 01856 01857 if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte, 01858 digestSz) != 0) { 01859 printf("myDecryptVerify verify failed\n"); 01860 return -1; 01861 } 01862 01863 return ret; 01864 } 01865 01866 01867 static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl) 01868 { 01869 AtomicEncCtx* encCtx; 01870 AtomicDecCtx* decCtx; 01871 01872 encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx)); 01873 if (encCtx == NULL) 01874 err_sys("AtomicEncCtx malloc failed"); 01875 XMEMSET(encCtx, 0, sizeof(AtomicEncCtx)); 01876 01877 decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx)); 01878 if (decCtx == NULL) { 01879 free(encCtx); 01880 err_sys("AtomicDecCtx malloc failed"); 01881 } 01882 XMEMSET(decCtx, 0, sizeof(AtomicDecCtx)); 01883 01884 wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb); 01885 wolfSSL_SetMacEncryptCtx(ssl, encCtx); 01886 01887 wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb); 01888 wolfSSL_SetDecryptVerifyCtx(ssl, decCtx); 01889 } 01890 01891 01892 static WC_INLINE void FreeAtomicUser(WOLFSSL* ssl) 01893 { 01894 AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl); 01895 AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl); 01896 01897 free(decCtx); 01898 free(encCtx); 01899 } 01900 01901 #endif /* ATOMIC_USER */ 01902 01903 #ifdef WOLFSSL_STATIC_MEMORY 01904 static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats) 01905 { 01906 word16 i; 01907 01908 if (stats == NULL) { 01909 return 0; 01910 } 01911 01912 /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */ 01913 fprintf(stderr, "Total mallocs = %d\n", stats->totalAlloc); 01914 fprintf(stderr, "Total frees = %d\n", stats->totalFr); 01915 fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc); 01916 fprintf(stderr, "Available IO = %d\n", stats->avaIO); 01917 fprintf(stderr, "Max con. handshakes = %d\n", stats->maxHa); 01918 fprintf(stderr, "Max con. IO = %d\n", stats->maxIO); 01919 fprintf(stderr, "State of memory blocks: size : available \n"); 01920 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 01921 fprintf(stderr, " : %d\t : %d\n", stats->blockSz[i], 01922 stats->avaBlock[i]); 01923 } 01924 01925 return 1; 01926 } 01927 #endif /* WOLFSSL_STATIC_MEMORY */ 01928 01929 #ifdef HAVE_PK_CALLBACKS 01930 01931 typedef struct PkCbInfo { 01932 const char* ourKey; 01933 #ifdef TEST_PK_PRIVKEY 01934 union { 01935 #ifdef HAVE_ECC 01936 ecc_key ecc; 01937 #endif 01938 #ifdef HAVE_CURVE25519 01939 curve25519_key curve; 01940 #endif 01941 } keyGen; 01942 #endif 01943 } PkCbInfo; 01944 01945 #ifdef HAVE_ECC 01946 01947 static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, 01948 int ecc_curve, void* ctx) 01949 { 01950 int ret; 01951 WC_RNG rng; 01952 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 01953 ecc_key* new_key = key; 01954 #ifdef TEST_PK_PRIVKEY 01955 byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES]; 01956 word32 qxLen = sizeof(qx), qyLen = sizeof(qy); 01957 new_key = &cbInfo->keyGen.ecc; 01958 #endif 01959 01960 (void)ssl; 01961 (void)cbInfo; 01962 01963 ret = wc_InitRng(&rng); 01964 if (ret != 0) 01965 return ret; 01966 01967 ret = wc_ecc_init(new_key); 01968 if (ret == 0) { 01969 /* create new key */ 01970 ret = wc_ecc_make_key_ex(&rng, keySz, new_key, ecc_curve); 01971 01972 #ifdef TEST_PK_PRIVKEY 01973 if (ret == 0) { 01974 /* extract public portion from new key into `key` arg */ 01975 ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen); 01976 if (ret == 0) { 01977 /* load public portion only into key */ 01978 ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ecc_curve); 01979 } 01980 (void)qxLen; 01981 (void)qyLen; 01982 } 01983 #endif 01984 } 01985 01986 wc_FreeRng(&rng); 01987 01988 return ret; 01989 } 01990 01991 static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz, 01992 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) 01993 { 01994 int ret; 01995 WC_RNG rng; 01996 word32 idx = 0; 01997 ecc_key myKey; 01998 byte* keyBuf = (byte*)key; 01999 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02000 02001 (void)ssl; 02002 (void)cbInfo; 02003 02004 #ifdef TEST_PK_PRIVKEY 02005 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02006 if (ret != 0) 02007 return ret; 02008 #endif 02009 02010 ret = wc_InitRng(&rng); 02011 if (ret != 0) 02012 return ret; 02013 02014 ret = wc_ecc_init(&myKey); 02015 if (ret == 0) { 02016 ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02017 if (ret == 0) 02018 ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey); 02019 wc_ecc_free(&myKey); 02020 } 02021 wc_FreeRng(&rng); 02022 02023 #ifdef TEST_PK_PRIVKEY 02024 free(keyBuf); 02025 #endif 02026 02027 return ret; 02028 } 02029 02030 02031 static WC_INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz, 02032 const byte* hash, word32 hashSz, const byte* key, word32 keySz, 02033 int* result, void* ctx) 02034 { 02035 int ret; 02036 word32 idx = 0; 02037 ecc_key myKey; 02038 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02039 02040 (void)ssl; 02041 (void)cbInfo; 02042 02043 ret = wc_ecc_init(&myKey); 02044 if (ret == 0) { 02045 ret = wc_EccPublicKeyDecode(key, &idx, &myKey, keySz); 02046 if (ret == 0) 02047 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey); 02048 wc_ecc_free(&myKey); 02049 } 02050 02051 return ret; 02052 } 02053 02054 static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, 02055 unsigned char* pubKeyDer, unsigned int* pubKeySz, 02056 unsigned char* out, unsigned int* outlen, 02057 int side, void* ctx) 02058 { 02059 int ret; 02060 ecc_key* privKey = NULL; 02061 ecc_key* pubKey = NULL; 02062 ecc_key tmpKey; 02063 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02064 02065 (void)ssl; 02066 (void)cbInfo; 02067 02068 ret = wc_ecc_init(&tmpKey); 02069 if (ret != 0) { 02070 return ret; 02071 } 02072 02073 /* for client: create and export public key */ 02074 if (side == WOLFSSL_CLIENT_END) { 02075 WC_RNG rng; 02076 02077 privKey = &tmpKey; 02078 pubKey = otherKey; 02079 02080 ret = wc_InitRng(&rng); 02081 if (ret == 0) { 02082 ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id); 02083 #ifdef WOLFSSL_ASYNC_CRYPT 02084 if (ret == WC_PENDING_E) { 02085 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_NONE); 02086 } 02087 #endif 02088 if (ret == 0) 02089 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); 02090 wc_FreeRng(&rng); 02091 } 02092 } 02093 02094 /* for server: import public key */ 02095 else if (side == WOLFSSL_SERVER_END) { 02096 #ifdef TEST_PK_PRIVKEY 02097 privKey = &cbInfo->keyGen.ecc; 02098 #else 02099 privKey = otherKey; 02100 #endif 02101 pubKey = &tmpKey; 02102 02103 ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, 02104 otherKey->dp->id); 02105 } 02106 else { 02107 ret = BAD_FUNC_ARG; 02108 } 02109 02110 /* generate shared secret and return it */ 02111 if (ret == 0) { 02112 ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); 02113 02114 #ifdef WOLFSSL_ASYNC_CRYPT 02115 if (ret == WC_PENDING_E) { 02116 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); 02117 } 02118 #endif 02119 } 02120 02121 #ifdef TEST_PK_PRIVKEY 02122 if (side == WOLFSSL_SERVER_END) { 02123 wc_ecc_free(&cbInfo->keyGen.ecc); 02124 } 02125 #endif 02126 02127 wc_ecc_free(&tmpKey); 02128 02129 return ret; 02130 } 02131 02132 #ifdef HAVE_ED25519 02133 static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, 02134 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) 02135 { 02136 int ret; 02137 word32 idx = 0; 02138 ed25519_key myKey; 02139 byte* keyBuf = (byte*)key; 02140 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02141 02142 (void)ssl; 02143 (void)cbInfo; 02144 02145 #ifdef TEST_PK_PRIVKEY 02146 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02147 if (ret != 0) 02148 return ret; 02149 #endif 02150 02151 ret = wc_ed25519_init(&myKey); 02152 if (ret == 0) { 02153 ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02154 if (ret == 0) 02155 ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey); 02156 wc_ed25519_free(&myKey); 02157 } 02158 02159 #ifdef TEST_PK_PRIVKEY 02160 free(keyBuf); 02161 #endif 02162 02163 return ret; 02164 } 02165 02166 02167 static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz, 02168 const byte* msg, word32 msgSz, const byte* key, word32 keySz, 02169 int* result, void* ctx) 02170 { 02171 int ret; 02172 ed25519_key myKey; 02173 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02174 02175 (void)ssl; 02176 (void)cbInfo; 02177 02178 ret = wc_ed25519_init(&myKey); 02179 if (ret == 0) { 02180 ret = wc_ed25519_import_public(key, keySz, &myKey); 02181 if (ret == 0) { 02182 ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey); 02183 } 02184 wc_ed25519_free(&myKey); 02185 } 02186 02187 return ret; 02188 } 02189 #endif /* HAVE_ED25519 */ 02190 02191 #ifdef HAVE_CURVE25519 02192 static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key, 02193 unsigned int keySz, void* ctx) 02194 { 02195 int ret; 02196 WC_RNG rng; 02197 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02198 02199 (void)ssl; 02200 (void)cbInfo; 02201 02202 ret = wc_InitRng(&rng); 02203 if (ret != 0) 02204 return ret; 02205 02206 ret = wc_curve25519_make_key(&rng, keySz, key); 02207 02208 wc_FreeRng(&rng); 02209 02210 return ret; 02211 } 02212 02213 static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey, 02214 unsigned char* pubKeyDer, unsigned int* pubKeySz, 02215 unsigned char* out, unsigned int* outlen, 02216 int side, void* ctx) 02217 { 02218 int ret; 02219 curve25519_key* privKey = NULL; 02220 curve25519_key* pubKey = NULL; 02221 curve25519_key tmpKey; 02222 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02223 02224 (void)ssl; 02225 (void)cbInfo; 02226 02227 ret = wc_curve25519_init(&tmpKey); 02228 if (ret != 0) { 02229 return ret; 02230 } 02231 02232 /* for client: create and export public key */ 02233 if (side == WOLFSSL_CLIENT_END) { 02234 WC_RNG rng; 02235 02236 privKey = &tmpKey; 02237 pubKey = otherKey; 02238 02239 ret = wc_InitRng(&rng); 02240 if (ret == 0) { 02241 ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, privKey); 02242 if (ret == 0) { 02243 ret = wc_curve25519_export_public_ex(privKey, pubKeyDer, 02244 pubKeySz, EC25519_LITTLE_ENDIAN); 02245 } 02246 wc_FreeRng(&rng); 02247 } 02248 } 02249 02250 /* for server: import public key */ 02251 else if (side == WOLFSSL_SERVER_END) { 02252 privKey = otherKey; 02253 pubKey = &tmpKey; 02254 02255 ret = wc_curve25519_import_public_ex(pubKeyDer, *pubKeySz, pubKey, 02256 EC25519_LITTLE_ENDIAN); 02257 } 02258 else { 02259 ret = BAD_FUNC_ARG; 02260 } 02261 02262 /* generate shared secret and return it */ 02263 if (ret == 0) { 02264 ret = wc_curve25519_shared_secret_ex(privKey, pubKey, out, outlen, 02265 EC25519_LITTLE_ENDIAN); 02266 } 02267 02268 wc_curve25519_free(&tmpKey); 02269 02270 return ret; 02271 } 02272 #endif /* HAVE_CURVE25519 */ 02273 02274 #endif /* HAVE_ECC */ 02275 02276 #ifndef NO_DH 02277 static WC_INLINE int myDhCallback(WOLFSSL* ssl, struct DhKey* key, 02278 const unsigned char* priv, unsigned int privSz, 02279 const unsigned char* pubKeyDer, unsigned int pubKeySz, 02280 unsigned char* out, unsigned int* outlen, 02281 void* ctx) 02282 { 02283 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02284 02285 (void)ssl; 02286 (void)cbInfo; 02287 02288 /* return 0 on success */ 02289 return wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz); 02290 }; 02291 02292 #endif /* !NO_DH */ 02293 02294 #ifndef NO_RSA 02295 02296 static WC_INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, 02297 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) 02298 { 02299 WC_RNG rng; 02300 int ret; 02301 word32 idx = 0; 02302 RsaKey myKey; 02303 byte* keyBuf = (byte*)key; 02304 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02305 02306 (void)ssl; 02307 (void)cbInfo; 02308 02309 #ifdef TEST_PK_PRIVKEY 02310 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02311 if (ret != 0) 02312 return ret; 02313 #endif 02314 02315 ret = wc_InitRng(&rng); 02316 if (ret != 0) 02317 return ret; 02318 02319 ret = wc_InitRsaKey(&myKey, NULL); 02320 if (ret == 0) { 02321 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02322 if (ret == 0) 02323 ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng); 02324 if (ret > 0) { /* save and convert to 0 success */ 02325 *outSz = ret; 02326 ret = 0; 02327 } 02328 wc_FreeRsaKey(&myKey); 02329 } 02330 wc_FreeRng(&rng); 02331 02332 #ifdef TEST_PK_PRIVKEY 02333 free(keyBuf); 02334 #endif 02335 02336 return ret; 02337 } 02338 02339 02340 static WC_INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz, 02341 byte** out, const byte* key, word32 keySz, void* ctx) 02342 { 02343 int ret; 02344 word32 idx = 0; 02345 RsaKey myKey; 02346 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02347 02348 (void)ssl; 02349 (void)cbInfo; 02350 02351 ret = wc_InitRsaKey(&myKey, NULL); 02352 if (ret == 0) { 02353 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); 02354 if (ret == 0) 02355 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey); 02356 wc_FreeRsaKey(&myKey); 02357 } 02358 02359 return ret; 02360 } 02361 02362 static WC_INLINE int myRsaSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz, 02363 byte** out, const byte* key, word32 keySz, void* ctx) 02364 { 02365 int ret; 02366 word32 idx = 0; 02367 RsaKey myKey; 02368 byte* keyBuf = (byte*)key; 02369 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02370 02371 (void)ssl; 02372 (void)cbInfo; 02373 02374 #ifdef TEST_PK_PRIVKEY 02375 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02376 if (ret != 0) 02377 return ret; 02378 #endif 02379 02380 ret = wc_InitRsaKey(&myKey, NULL); 02381 if (ret == 0) { 02382 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02383 if (ret == 0) 02384 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey); 02385 wc_FreeRsaKey(&myKey); 02386 } 02387 #ifdef TEST_PK_PRIVKEY 02388 free(keyBuf); 02389 #endif 02390 02391 return ret; 02392 } 02393 02394 #ifdef WC_RSA_PSS 02395 static WC_INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz, 02396 byte* out, word32* outSz, int hash, int mgf, const byte* key, 02397 word32 keySz, void* ctx) 02398 { 02399 enum wc_HashType hashType = WC_HASH_TYPE_NONE; 02400 WC_RNG rng; 02401 int ret; 02402 word32 idx = 0; 02403 RsaKey myKey; 02404 byte* keyBuf = (byte*)key; 02405 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02406 02407 (void)ssl; 02408 (void)cbInfo; 02409 02410 #ifdef TEST_PK_PRIVKEY 02411 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02412 if (ret != 0) 02413 return ret; 02414 #endif 02415 02416 switch (hash) { 02417 #ifndef NO_SHA256 02418 case SHA256h: 02419 hashType = WC_HASH_TYPE_SHA256; 02420 break; 02421 #endif 02422 #ifdef WOLFSSL_SHA384 02423 case SHA384h: 02424 hashType = WC_HASH_TYPE_SHA384; 02425 break; 02426 #endif 02427 #ifdef WOLFSSL_SHA512 02428 case SHA512h: 02429 hashType = WC_HASH_TYPE_SHA512; 02430 break; 02431 #endif 02432 } 02433 02434 ret = wc_InitRng(&rng); 02435 if (ret != 0) 02436 return ret; 02437 02438 ret = wc_InitRsaKey(&myKey, NULL); 02439 if (ret == 0) { 02440 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02441 if (ret == 0) { 02442 ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey, 02443 &rng); 02444 } 02445 if (ret > 0) { /* save and convert to 0 success */ 02446 *outSz = ret; 02447 ret = 0; 02448 } 02449 wc_FreeRsaKey(&myKey); 02450 } 02451 wc_FreeRng(&rng); 02452 02453 #ifdef TEST_PK_PRIVKEY 02454 free(keyBuf); 02455 #endif 02456 02457 return ret; 02458 } 02459 02460 02461 static WC_INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz, 02462 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx) 02463 { 02464 int ret; 02465 word32 idx = 0; 02466 RsaKey myKey; 02467 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02468 enum wc_HashType hashType = WC_HASH_TYPE_NONE; 02469 02470 (void)ssl; 02471 (void)cbInfo; 02472 02473 switch (hash) { 02474 #ifndef NO_SHA256 02475 case SHA256h: 02476 hashType = WC_HASH_TYPE_SHA256; 02477 break; 02478 #endif 02479 #ifdef WOLFSSL_SHA384 02480 case SHA384h: 02481 hashType = WC_HASH_TYPE_SHA384; 02482 break; 02483 #endif 02484 #ifdef WOLFSSL_SHA512 02485 case SHA512h: 02486 hashType = WC_HASH_TYPE_SHA512; 02487 break; 02488 #endif 02489 } 02490 02491 ret = wc_InitRsaKey(&myKey, NULL); 02492 if (ret == 0) { 02493 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); 02494 if (ret == 0) { 02495 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf, 02496 &myKey); 02497 } 02498 wc_FreeRsaKey(&myKey); 02499 } 02500 02501 return ret; 02502 } 02503 02504 static WC_INLINE int myRsaPssSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz, 02505 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx) 02506 { 02507 int ret; 02508 word32 idx = 0; 02509 RsaKey myKey; 02510 byte* keyBuf = (byte*)key; 02511 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02512 enum wc_HashType hashType = WC_HASH_TYPE_NONE; 02513 02514 (void)ssl; 02515 (void)cbInfo; 02516 02517 #ifdef TEST_PK_PRIVKEY 02518 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02519 if (ret != 0) 02520 return ret; 02521 #endif 02522 02523 switch (hash) { 02524 #ifndef NO_SHA256 02525 case SHA256h: 02526 hashType = WC_HASH_TYPE_SHA256; 02527 break; 02528 #endif 02529 #ifdef WOLFSSL_SHA384 02530 case SHA384h: 02531 hashType = WC_HASH_TYPE_SHA384; 02532 break; 02533 #endif 02534 #ifdef WOLFSSL_SHA512 02535 case SHA512h: 02536 hashType = WC_HASH_TYPE_SHA512; 02537 break; 02538 #endif 02539 } 02540 02541 ret = wc_InitRsaKey(&myKey, NULL); 02542 if (ret == 0) { 02543 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02544 if (ret == 0) { 02545 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf, 02546 &myKey); 02547 } 02548 wc_FreeRsaKey(&myKey); 02549 } 02550 02551 #ifdef TEST_PK_PRIVKEY 02552 free(keyBuf); 02553 #endif 02554 02555 return ret; 02556 } 02557 #endif 02558 02559 02560 static WC_INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, 02561 byte* out, word32* outSz, const byte* key, 02562 word32 keySz, void* ctx) 02563 { 02564 int ret; 02565 word32 idx = 0; 02566 RsaKey myKey; 02567 WC_RNG rng; 02568 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02569 02570 (void)ssl; 02571 (void)cbInfo; 02572 02573 ret = wc_InitRng(&rng); 02574 if (ret != 0) 02575 return ret; 02576 02577 ret = wc_InitRsaKey(&myKey, NULL); 02578 if (ret == 0) { 02579 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); 02580 if (ret == 0) { 02581 ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng); 02582 if (ret > 0) { 02583 *outSz = ret; 02584 ret = 0; /* reset to success */ 02585 } 02586 } 02587 wc_FreeRsaKey(&myKey); 02588 } 02589 wc_FreeRng(&rng); 02590 02591 return ret; 02592 } 02593 02594 static WC_INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz, 02595 byte** out, 02596 const byte* key, word32 keySz, void* ctx) 02597 { 02598 int ret; 02599 word32 idx = 0; 02600 RsaKey myKey; 02601 byte* keyBuf = (byte*)key; 02602 PkCbInfo* cbInfo = (PkCbInfo*)ctx; 02603 02604 (void)ssl; 02605 (void)cbInfo; 02606 02607 #ifdef TEST_PK_PRIVKEY 02608 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); 02609 if (ret != 0) 02610 return ret; 02611 #endif 02612 02613 ret = wc_InitRsaKey(&myKey, NULL); 02614 if (ret == 0) { 02615 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); 02616 if (ret == 0) { 02617 #ifdef WC_RSA_BLINDING 02618 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl)); 02619 if (ret != 0) { 02620 wc_FreeRsaKey(&myKey); 02621 return ret; 02622 } 02623 #endif 02624 ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey); 02625 } 02626 wc_FreeRsaKey(&myKey); 02627 } 02628 02629 #ifdef TEST_PK_PRIVKEY 02630 free(keyBuf); 02631 #endif 02632 02633 return ret; 02634 } 02635 02636 #endif /* NO_RSA */ 02637 02638 static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) 02639 { 02640 (void)ctx; 02641 02642 #ifdef HAVE_ECC 02643 wolfSSL_CTX_SetEccKeyGenCb(ctx, myEccKeyGen); 02644 wolfSSL_CTX_SetEccSignCb(ctx, myEccSign); 02645 wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify); 02646 wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret); 02647 #endif /* HAVE_ECC */ 02648 #ifndef NO_DH 02649 wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback); 02650 #endif 02651 #ifdef HAVE_ED25519 02652 wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign); 02653 wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify); 02654 #endif 02655 #ifdef HAVE_CURVE25519 02656 wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen); 02657 wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret); 02658 #endif 02659 #ifndef NO_RSA 02660 wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign); 02661 wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify); 02662 wolfSSL_CTX_SetRsaSignCheckCb(ctx, myRsaSignCheck); 02663 #ifdef WC_RSA_PSS 02664 wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign); 02665 wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify); 02666 wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, myRsaPssSignCheck); 02667 #endif 02668 wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc); 02669 wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec); 02670 #endif /* NO_RSA */ 02671 } 02672 02673 static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx) 02674 { 02675 #ifdef HAVE_ECC 02676 wolfSSL_SetEccKeyGenCtx(ssl, myCtx); 02677 wolfSSL_SetEccSignCtx(ssl, myCtx); 02678 wolfSSL_SetEccVerifyCtx(ssl, myCtx); 02679 wolfSSL_SetEccSharedSecretCtx(ssl, myCtx); 02680 #endif /* HAVE_ECC */ 02681 #ifndef NO_DH 02682 wolfSSL_SetDhAgreeCtx(ssl, myCtx); 02683 #endif 02684 #ifdef HAVE_ED25519 02685 wolfSSL_SetEd25519SignCtx(ssl, myCtx); 02686 wolfSSL_SetEd25519VerifyCtx(ssl, myCtx); 02687 #endif 02688 #ifdef HAVE_CURVE25519 02689 wolfSSL_SetX25519KeyGenCtx(ssl, myCtx); 02690 wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx); 02691 #endif 02692 #ifndef NO_RSA 02693 wolfSSL_SetRsaSignCtx(ssl, myCtx); 02694 wolfSSL_SetRsaVerifyCtx(ssl, myCtx); 02695 #ifdef WC_RSA_PSS 02696 wolfSSL_SetRsaPssSignCtx(ssl, myCtx); 02697 wolfSSL_SetRsaPssVerifyCtx(ssl, myCtx); 02698 #endif 02699 wolfSSL_SetRsaEncCtx(ssl, myCtx); 02700 wolfSSL_SetRsaDecCtx(ssl, myCtx); 02701 #endif /* NO_RSA */ 02702 } 02703 02704 #endif /* HAVE_PK_CALLBACKS */ 02705 02706 02707 02708 02709 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \ 02710 || defined(_MSC_VER) 02711 02712 /* HP/UX doesn't have strsep, needed by test/suites.c */ 02713 static WC_INLINE char* strsep(char **stringp, const char *delim) 02714 { 02715 char* start; 02716 char* end; 02717 02718 start = *stringp; 02719 if (start == NULL) 02720 return NULL; 02721 02722 if ((end = strpbrk(start, delim))) { 02723 *end++ = '\0'; 02724 *stringp = end; 02725 } else { 02726 *stringp = NULL; 02727 } 02728 02729 return start; 02730 } 02731 02732 #endif /* __hpux__ and others */ 02733 02734 /* Create unique filename, len is length of tempfn name, assuming 02735 len does not include null terminating character, 02736 num is number of characters in tempfn name to randomize */ 02737 static WC_INLINE const char* mymktemp(char *tempfn, int len, int num) 02738 { 02739 int x, size; 02740 static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 02741 "abcdefghijklmnopqrstuvwxyz"; 02742 WC_RNG rng; 02743 byte out; 02744 02745 if (tempfn == NULL || len < 1 || num < 1 || len <= num) { 02746 printf("Bad input\n"); 02747 return NULL; 02748 } 02749 02750 size = len - 1; 02751 02752 if (wc_InitRng(&rng) != 0) { 02753 printf("InitRng failed\n"); 02754 return NULL; 02755 } 02756 02757 for (x = size; x > size - num; x--) { 02758 if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) { 02759 printf("RNG_GenerateBlock failed\n"); 02760 return NULL; 02761 } 02762 tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)]; 02763 } 02764 tempfn[len] = '\0'; 02765 02766 wc_FreeRng(&rng); 02767 02768 return tempfn; 02769 } 02770 02771 02772 02773 #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ 02774 defined(HAVE_POLY1305) 02775 02776 #include <wolfssl/wolfcrypt/chacha20_poly1305.h> 02777 02778 typedef struct key_ctx { 02779 byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */ 02780 byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */ 02781 } key_ctx; 02782 02783 static key_ctx myKey_ctx; 02784 static WC_RNG myKey_rng; 02785 02786 static WC_INLINE int TicketInit(void) 02787 { 02788 int ret = wc_InitRng(&myKey_rng); 02789 if (ret != 0) return ret; 02790 02791 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key)); 02792 if (ret != 0) return ret; 02793 02794 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name)); 02795 if (ret != 0) return ret; 02796 02797 return 0; 02798 } 02799 02800 static WC_INLINE void TicketCleanup(void) 02801 { 02802 wc_FreeRng(&myKey_rng); 02803 } 02804 02805 static WC_INLINE int myTicketEncCb(WOLFSSL* ssl, 02806 byte key_name[WOLFSSL_TICKET_NAME_SZ], 02807 byte iv[WOLFSSL_TICKET_IV_SZ], 02808 byte mac[WOLFSSL_TICKET_MAC_SZ], 02809 int enc, byte* ticket, int inLen, int* outLen, 02810 void* userCtx) 02811 { 02812 (void)ssl; 02813 (void)userCtx; 02814 02815 int ret; 02816 word16 sLen = XHTONS(inLen); 02817 byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2]; 02818 int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2; 02819 byte* tmp = aad; 02820 02821 if (enc) { 02822 XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ); 02823 02824 ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ); 02825 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; 02826 02827 /* build aad from key name, iv, and length */ 02828 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ); 02829 tmp += WOLFSSL_TICKET_NAME_SZ; 02830 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ); 02831 tmp += WOLFSSL_TICKET_IV_SZ; 02832 XMEMCPY(tmp, &sLen, 2); 02833 02834 ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv, 02835 aad, aadSz, 02836 ticket, inLen, 02837 ticket, 02838 mac); 02839 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; 02840 *outLen = inLen; /* no padding in this mode */ 02841 } else { 02842 /* decrypt */ 02843 02844 /* see if we know this key */ 02845 if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){ 02846 printf("client presented unknown ticket key name "); 02847 return WOLFSSL_TICKET_RET_FATAL; 02848 } 02849 02850 /* build aad from key name, iv, and length */ 02851 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ); 02852 tmp += WOLFSSL_TICKET_NAME_SZ; 02853 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ); 02854 tmp += WOLFSSL_TICKET_IV_SZ; 02855 XMEMCPY(tmp, &sLen, 2); 02856 02857 ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv, 02858 aad, aadSz, 02859 ticket, inLen, 02860 mac, 02861 ticket); 02862 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; 02863 *outLen = inLen; /* no padding in this mode */ 02864 } 02865 02866 return WOLFSSL_TICKET_RET_OK; 02867 } 02868 02869 #endif /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */ 02870 02871 static WC_INLINE word16 GetRandomPort(void) 02872 { 02873 word16 port = 0; 02874 02875 /* Generate random port for testing */ 02876 WC_RNG rng; 02877 if (wc_InitRng(&rng) == 0) { 02878 wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port)); 02879 port |= 0xC000; /* Make sure its in the 49152 - 65535 range */ 02880 wc_FreeRng(&rng); 02881 } 02882 return port; 02883 } 02884 02885 #endif /* wolfSSL_TEST_H */ 02886
Generated on Wed Jul 13 2022 01:38:47 by 1.7.2