1 /* test.h */
2
3 #ifndef wolfSSL_TEST_H
4 #define wolfSSL_TEST_H
5
6 #ifdef FUSION_RTOS
7 #include <fclstdio.h>
8 #include <fclstdlib.h>
9 #else
10 #include <stdio.h>
11 #include <stdlib.h>
12 #endif
13 #include <assert.h>
14 #include <ctype.h>
15 #ifdef HAVE_ERRNO_H
16 #include <errno.h>
17 #endif
18 #include <wolfssl/wolfcrypt/types.h>
19 #include <wolfssl/error-ssl.h>
20 #include <wolfssl/wolfcrypt/random.h>
21 #include <wolfssl/wolfcrypt/mem_track.h>
22 #include <wolfssl/wolfio.h>
23 #if defined(SHOW_CERTS) && \
24 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
25 #include <wolfssl/wolfcrypt/asn.h> /* for domain component NID value */
26 #endif
27
28 #ifdef ATOMIC_USER
29 #include <wolfssl/wolfcrypt/aes.h>
30 #include <wolfssl/wolfcrypt/arc4.h>
31 #include <wolfssl/wolfcrypt/hmac.h>
32 #endif
33 #ifdef HAVE_PK_CALLBACKS
34 #include <wolfssl/wolfcrypt/asn.h>
35 #ifndef NO_RSA
36 #include <wolfssl/wolfcrypt/rsa.h>
37 #endif
38 #ifdef HAVE_ECC
39 #include <wolfssl/wolfcrypt/ecc.h>
40 #endif /* HAVE_ECC */
41 #ifndef NO_DH
42 #include <wolfssl/wolfcrypt/dh.h>
43 #endif /* !NO_DH */
44 #ifdef HAVE_ED25519
45 #include <wolfssl/wolfcrypt/ed25519.h>
46 #endif /* HAVE_ED25519 */
47 #ifdef HAVE_CURVE25519
48 #include <wolfssl/wolfcrypt/curve25519.h>
49 #endif /* HAVE_ECC */
50 #ifdef HAVE_ED448
51 #include <wolfssl/wolfcrypt/ed448.h>
52 #endif /* HAVE_ED448 */
53 #ifdef HAVE_CURVE448
54 #include <wolfssl/wolfcrypt/curve448.h>
55 #endif /* HAVE_ECC */
56 #endif /*HAVE_PK_CALLBACKS */
57
58 #ifdef USE_WINDOWS_API
59 #include <winsock2.h>
60 #include <process.h>
61 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */
62 #include <ws2tcpip.h>
63 #include <wspiapi.h>
64 #endif
65 #define SOCKET_T SOCKET
66 #define SNPRINTF _snprintf
67 #define XSLEEP_MS(t) Sleep(t)
68 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
69 #include <string.h>
70 #include "rl_net.h"
71 #define SOCKET_T int
72 typedef int socklen_t ;
73 #define inet_addr wolfSSL_inet_addr
wolfSSL_inet_addr(const char * cp)74 static unsigned long wolfSSL_inet_addr(const char *cp)
75 {
76 unsigned int a[4] ; unsigned long ret ;
77 sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
78 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
79 return(ret) ;
80 }
81 #if defined(HAVE_KEIL_RTX)
82 #define XSLEEP_MS(t) os_dly_wait(t)
83 #elif defined(WOLFSSL_CMSIS_RTOS) || defined(WOLFSSL_CMSIS_RTOSv2)
84 #define XSLEEP_MS(t) osDelay(t)
85 #endif
86 #elif defined(WOLFSSL_TIRTOS)
87 #include <string.h>
88 #include <netdb.h>
89 #include <sys/types.h>
90 #include <arpa/inet.h>
91 #include <sys/socket.h>
92 #include <ti/sysbios/knl/Task.h>
93 struct hostent {
94 char *h_name; /* official name of host */
95 char **h_aliases; /* alias list */
96 int h_addrtype; /* host address type */
97 int h_length; /* length of address */
98 char **h_addr_list; /* list of addresses from name server */
99 };
100 #define SOCKET_T int
101 #define XSLEEP_MS(t) Task_sleep(t/1000)
102 #elif defined(WOLFSSL_VXWORKS)
103 #include <hostLib.h>
104 #include <sockLib.h>
105 #include <arpa/inet.h>
106 #include <string.h>
107 #include <selectLib.h>
108 #include <sys/types.h>
109 #include <netinet/in.h>
110 #include <fcntl.h>
111 #include <sys/time.h>
112 #include <netdb.h>
113 #include <pthread.h>
114 #define SOCKET_T int
115 #elif defined(WOLFSSL_ZEPHYR)
116 #include <string.h>
117 #include <sys/types.h>
118 #include <net/socket.h>
119 #define SOCKET_T int
120 #define SOL_SOCKET 1
121 #define WOLFSSL_USE_GETADDRINFO
122
inet_addr(const char * cp)123 static unsigned long inet_addr(const char *cp)
124 {
125 unsigned int a[4]; unsigned long ret;
126 int i, j;
127 for (i=0, j=0; i<4; i++) {
128 a[i] = 0;
129 while (cp[j] != '.' && cp[j] != '\0') {
130 a[i] *= 10;
131 a[i] += cp[j] - '0';
132 j++;
133 }
134 }
135 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
136 return(ret) ;
137 }
138 #elif defined(NETOS)
139 #include <string.h>
140 #include <sys/types.h>
141 struct hostent {
142 char* h_name; /* official name of host */
143 char** h_aliases; /* alias list */
144 int h_addrtype; /* host address type */
145 int h_length; /* length of address */
146 char** h_addr_list; /* list of addresses from the name server */
147 };
148 #else
149 #include <string.h>
150 #include <sys/types.h>
151 #ifndef WOLFSSL_LEANPSK
152 #include <unistd.h>
153 #include <netdb.h>
154 #include <netinet/in.h>
155 #include <netinet/tcp.h>
156 #include <arpa/inet.h>
157 #include <sys/ioctl.h>
158 #include <sys/time.h>
159 #include <sys/socket.h>
160 #include <pthread.h>
161 #include <fcntl.h>
162 #ifdef TEST_IPV6
163 #include <netdb.h>
164 #endif
165 #endif
166 #ifdef FREESCALE_MQX
167 typedef int socklen_t ;
168 #endif
169 #define SOCKET_T int
170 #ifndef SO_NOSIGPIPE
171 #include <signal.h> /* ignore SIGPIPE */
172 #endif
173 #define SNPRINTF snprintf
174
175 #define XSELECT_WAIT(x,y) do { \
176 struct timeval tv = {((x) + ((y) / 1000000)),((y) % 1000000)}; \
177 select(0, NULL, NULL, NULL, &tv); \
178 } while (0)
179 #define XSLEEP_US(u) XSELECT_WAIT(0,u)
180 #define XSLEEP_MS(m) XSELECT_WAIT(0,(m)*1000)
181 #endif /* USE_WINDOWS_API */
182
183 #ifndef XSLEEP_MS
184 #define XSLEEP_MS(t) sleep(t/1000)
185 #endif
186
187 #ifdef WOLFSSL_ASYNC_CRYPT
188 #include <wolfssl/wolfcrypt/async.h>
189 #endif
190 #ifdef HAVE_CAVIUM
191 #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h>
192 #endif
193 #ifdef _MSC_VER
194 /* disable conversion warning */
195 /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
196 #pragma warning(disable:4244 4996)
197 #endif
198
199 #ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
200 #define WOLFSSL_CIPHER_LIST_MAX_SIZE 4096
201 #endif
202 /* Buffer for benchmark tests */
203 #ifndef TEST_BUFFER_SIZE
204 #define TEST_BUFFER_SIZE 16384
205 #endif
206
207 #ifndef WOLFSSL_HAVE_MIN
208 #define WOLFSSL_HAVE_MIN
min(word32 a,word32 b)209 static WC_INLINE word32 min(word32 a, word32 b)
210 {
211 return a > b ? b : a;
212 }
213 #endif /* WOLFSSL_HAVE_MIN */
214
215 /* Socket Handling */
216 #ifndef WOLFSSL_SOCKET_INVALID
217 #ifdef USE_WINDOWS_API
218 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET)
219 #elif defined(WOLFSSL_TIRTOS)
220 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1)
221 #else
222 #define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0)
223 #endif
224 #endif /* WOLFSSL_SOCKET_INVALID */
225
226 #ifndef WOLFSSL_SOCKET_IS_INVALID
227 #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS)
228 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
229 #else
230 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID)
231 #endif
232 #endif /* WOLFSSL_SOCKET_IS_INVALID */
233
234 #if defined(__MACH__) || defined(USE_WINDOWS_API)
235 #ifndef _SOCKLEN_T
236 typedef int socklen_t;
237 #endif
238 #endif
239
240
241 /* HPUX doesn't use socklent_t for third parameter to accept, unless
242 _XOPEN_SOURCE_EXTENDED is defined */
243 #if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\
244 && !defined(WOLFSSL_ROWLEY_ARM) && !defined(WOLFSSL_KEIL_TCP_NET)
245 typedef socklen_t* ACCEPT_THIRD_T;
246 #else
247 #if defined _XOPEN_SOURCE_EXTENDED
248 typedef socklen_t* ACCEPT_THIRD_T;
249 #else
250 typedef int* ACCEPT_THIRD_T;
251 #endif
252 #endif
253
254
255
256 #ifdef SINGLE_THREADED
257 typedef unsigned int THREAD_RETURN;
258 typedef void* THREAD_TYPE;
259 #define WOLFSSL_THREAD
260 #else
261 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
262 typedef void* THREAD_RETURN;
263 typedef pthread_t THREAD_TYPE;
264 #define WOLFSSL_THREAD
265 #define INFINITE -1
266 #define WAIT_OBJECT_0 0L
267 #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) || defined(FREESCALE_MQX)
268 typedef unsigned int THREAD_RETURN;
269 typedef int THREAD_TYPE;
270 #define WOLFSSL_THREAD
271 #elif defined(WOLFSSL_TIRTOS)
272 typedef void THREAD_RETURN;
273 typedef Task_Handle THREAD_TYPE;
274 #ifdef HAVE_STACK_SIZE
275 #undef EXIT_TEST
276 #define EXIT_TEST(ret)
277 #endif
278 #define WOLFSSL_THREAD
279 #elif defined(WOLFSSL_ZEPHYR)
280 typedef void THREAD_RETURN;
281 typedef struct k_thread THREAD_TYPE;
282 #ifdef HAVE_STACK_SIZE
283 #undef EXIT_TEST
284 #define EXIT_TEST(ret)
285 #endif
286 #define WOLFSSL_THREAD
287 #elif defined(NETOS)
288 typedef UINT THREAD_RETURN;
289 typedef TX_THREAD THREAD_TYPE;
290 #define WOLFSSL_THREAD
291 #define INFINITE TX_WAIT_FOREVER
292 #define WAIT_OBJECT_0 TX_NO_WAIT
293 #else
294 typedef unsigned int THREAD_RETURN;
295 typedef intptr_t THREAD_TYPE;
296 #define WOLFSSL_THREAD __stdcall
297 #endif
298 #endif
299
300
301 #ifdef TEST_IPV6
302 typedef struct sockaddr_in6 SOCKADDR_IN_T;
303 #define AF_INET_V AF_INET6
304 #else
305 typedef struct sockaddr_in SOCKADDR_IN_T;
306 #define AF_INET_V AF_INET
307 #endif
308
309
310 #ifndef WOLFSSL_NO_TLS12
311 #define SERVER_DEFAULT_VERSION 3
312 #else
313 #define SERVER_DEFAULT_VERSION 4
314 #endif
315 #define SERVER_DTLS_DEFAULT_VERSION (-2)
316 #define SERVER_INVALID_VERSION (-99)
317 #define SERVER_DOWNGRADE_VERSION (-98)
318 #ifndef WOLFSSL_NO_TLS12
319 #define CLIENT_DEFAULT_VERSION 3
320 #else
321 #define CLIENT_DEFAULT_VERSION 4
322 #endif
323 #define CLIENT_DTLS_DEFAULT_VERSION (-2)
324 #define CLIENT_INVALID_VERSION (-99)
325 #define CLIENT_DOWNGRADE_VERSION (-98)
326 #define EITHER_DOWNGRADE_VERSION (-97)
327 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
328 #define DEFAULT_MIN_DHKEY_BITS 2048
329 #define DEFAULT_MAX_DHKEY_BITS 3072
330 #else
331 #define DEFAULT_MIN_DHKEY_BITS 1024
332 #define DEFAULT_MAX_DHKEY_BITS 2048
333 #endif
334 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
335 #define DEFAULT_MIN_RSAKEY_BITS 2048
336 #else
337 #ifndef DEFAULT_MIN_RSAKEY_BITS
338 #define DEFAULT_MIN_RSAKEY_BITS 1024
339 #endif
340 #endif
341 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
342 #define DEFAULT_MIN_ECCKEY_BITS 256
343 #else
344 #ifndef DEFAULT_MIN_ECCKEY_BITS
345 #define DEFAULT_MIN_ECCKEY_BITS 224
346 #endif
347 #endif
348
349 /* all certs relative to wolfSSL home directory now */
350 #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
351 #define caCertFile "certs/ca-cert.pem"
352 #define eccCertFile "certs/server-ecc.pem"
353 #define eccKeyFile "certs/ecc-key.pem"
354 #define eccKeyPubFile "certs/ecc-keyPub.pem"
355 #define eccRsaCertFile "certs/server-ecc-rsa.pem"
356 #define svrCertFile "certs/server-cert.pem"
357 #define svrKeyFile "certs/server-key.pem"
358 #define svrKeyPubFile "certs/server-keyPub.pem"
359 #define cliCertFile "certs/client-cert.pem"
360 #define cliCertDerFile "certs/client-cert.der"
361 #define cliCertFileExt "certs/client-cert-ext.pem"
362 #define cliCertDerFileExt "certs/client-cert-ext.der"
363 #define cliKeyFile "certs/client-key.pem"
364 #define cliKeyPubFile "certs/client-keyPub.pem"
365 #define dhParamFile "certs/dh2048.pem"
366 #define cliEccKeyFile "certs/ecc-client-key.pem"
367 #define cliEccKeyPubFile "certs/ecc-client-keyPub.pem"
368 #define cliEccCertFile "certs/client-ecc-cert.pem"
369 #define caEccCertFile "certs/ca-ecc-cert.pem"
370 #define crlPemDir "certs/crl"
371 #define edCertFile "certs/ed25519/server-ed25519-cert.pem"
372 #define edKeyFile "certs/ed25519/server-ed25519-priv.pem"
373 #define edKeyPubFile "certs/ed25519/server-ed25519-key.pem"
374 #define cliEdCertFile "certs/ed25519/client-ed25519.pem"
375 #define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem"
376 #define cliEdKeyPubFile "certs/ed25519/client-ed25519-key.pem"
377 #define caEdCertFile "certs/ed25519/ca-ed25519.pem"
378 #define ed448CertFile "certs/ed448/server-ed448-cert.pem"
379 #define ed448KeyFile "certs/ed448/server-ed448-priv.pem"
380 #define cliEd448CertFile "certs/ed448/client-ed448.pem"
381 #define cliEd448KeyFile "certs/ed448/client-ed448-priv.pem"
382 #define caEd448CertFile "certs/ed448/ca-ed448.pem"
383 #define caCertFolder "certs/"
384 #ifdef HAVE_WNR
385 /* Whitewood netRandom default config file */
386 #define wnrConfig "wnr-example.conf"
387 #endif
388 #elif defined(NETOS) && defined(HAVE_FIPS)
389 /* These defines specify the file system volume and root directory used by
390 * the FTP server used in the only supported NETOS FIPS solution (at this
391 * time), these can be tailored in the event a future FIPS solution is added
392 * for an alternate NETOS use-case */
393 #define FS_VOLUME1 "FLASH0"
394 #define FS_VOLUME1_DIR FS_VOLUME1 "/"
395 #define caCertFile FS_VOLUME1_DIR "certs/ca-cert.pem"
396 #define eccCertFile FS_VOLUME1_DIR "certs/server-ecc.pem"
397 #define eccKeyFile FS_VOLUME1_DIR "certs/ecc-key.pem"
398 #define svrCertFile FS_VOLUME1_DIR "certs/server-cert.pem"
399 #define svrKeyFile FS_VOLUME1_DIR "certs/server-key.pem"
400 #define cliCertFile FS_VOLUME1_DIR "certs/client-cert.pem"
401 #define cliKeyFile FS_VOLUME1_DIR "certs/client-key.pem"
402 #define ntruCertFile FS_VOLUME1_DIR "certs/ntru-cert.pem"
403 #define ntruKeyFile FS_VOLUME1_DIR "certs/ntru-key.raw"
404 #define dhParamFile FS_VOLUME1_DIR "certs/dh2048.pem"
405 #define cliEccKeyFile FS_VOLUME1_DIR "certs/ecc-client-key.pem"
406 #define cliEccCertFile FS_VOLUME1_DIR "certs/client-ecc-cert.pem"
407 #define caEccCertFile FS_VOLUME1_DIR "certs/ca-ecc-cert/pem"
408 #define crlPemDir FS_VOLUME1_DIR "certs/crl"
409 #ifdef HAVE_WNR
410 /* Whitewood netRandom default config file */
411 #define wnrConfig "wnr-example.conf"
412 #endif
413 #else
414 #define caCertFile "./certs/ca-cert.pem"
415 #define eccCertFile "./certs/server-ecc.pem"
416 #define eccKeyFile "./certs/ecc-key.pem"
417 #define eccKeyPubFile "./certs/ecc-keyPub.pem"
418 #define eccRsaCertFile "./certs/server-ecc-rsa.pem"
419 #define svrCertFile "./certs/server-cert.pem"
420 #define svrKeyFile "./certs/server-key.pem"
421 #define svrKeyPubFile "./certs/server-keyPub.pem"
422 #define cliCertFile "./certs/client-cert.pem"
423 #define cliCertDerFile "./certs/client-cert.der"
424 #define cliCertFileExt "./certs/client-cert-ext.pem"
425 #define cliCertDerFileExt "./certs/client-cert-ext.der"
426 #define cliKeyFile "./certs/client-key.pem"
427 #define cliKeyPubFile "./certs/client-keyPub.pem"
428 #define dhParamFile "./certs/dh2048.pem"
429 #define cliEccKeyFile "./certs/ecc-client-key.pem"
430 #define cliEccKeyPubFile "./certs/ecc-client-keyPub.pem"
431 #define cliEccCertFile "./certs/client-ecc-cert.pem"
432 #define caEccCertFile "./certs/ca-ecc-cert.pem"
433 #define crlPemDir "./certs/crl"
434 #define edCertFile "./certs/ed25519/server-ed25519-cert.pem"
435 #define edKeyFile "./certs/ed25519/server-ed25519-priv.pem"
436 #define edKeyPubFile "./certs/ed25519/server-ed25519-key.pem"
437 #define cliEdCertFile "./certs/ed25519/client-ed25519.pem"
438 #define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem"
439 #define cliEdKeyPubFile "./certs/ed25519/client-ed25519-key.pem"
440 #define caEdCertFile "./certs/ed25519/ca-ed25519.pem"
441 #define ed448CertFile "./certs/ed448/server-ed448-cert.pem"
442 #define ed448KeyFile "./certs/ed448/server-ed448-priv.pem"
443 #define cliEd448CertFile "./certs/ed448/client-ed448.pem"
444 #define cliEd448KeyFile "./certs/ed448/client-ed448-priv.pem"
445 #define caEd448CertFile "./certs/ed448/ca-ed448.pem"
446 #define caCertFolder "./certs/"
447 #ifdef HAVE_WNR
448 /* Whitewood netRandom default config file */
449 #define wnrConfig "./wnr-example.conf"
450 #endif
451 #endif
452
453 typedef struct tcp_ready {
454 word16 ready; /* predicate */
455 word16 port;
456 char* srfName; /* server ready file name */
457 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
458 pthread_mutex_t mutex;
459 pthread_cond_t cond;
460 #endif
461 #ifdef NETOS
462 TX_MUTEX mutex;
463 #endif
464 } tcp_ready;
465
466
InitTcpReady(tcp_ready * ready)467 static WC_INLINE void InitTcpReady(tcp_ready* ready)
468 {
469 ready->ready = 0;
470 ready->port = 0;
471 ready->srfName = NULL;
472 #ifdef SINGLE_THREADED
473 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
474 pthread_mutex_init(&ready->mutex, 0);
475 pthread_cond_init(&ready->cond, 0);
476 #elif defined(NETOS)
477 tx_mutex_create(&ready->mutex, "wolfSSL Lock", TX_INHERIT);
478 #endif
479 }
480
481 #ifdef NETOS
482 struct hostent* gethostbyname(vonst char* name);
483 #endif
484
FreeTcpReady(tcp_ready * ready)485 static WC_INLINE void FreeTcpReady(tcp_ready* ready)
486 {
487 #ifdef SINGLE_THREADED
488 (void)ready;
489 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
490 pthread_mutex_destroy(&ready->mutex);
491 pthread_cond_destroy(&ready->cond);
492 #elif defined(NETOS)
493 tx_mutex_delete(&ready->mutex);
494 #else
495 (void)ready;
496 #endif
497 }
498
499 typedef WOLFSSL_METHOD* (*method_provider)(void);
500 typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
501 typedef void (*ssl_callback)(WOLFSSL* ssl);
502
503 typedef struct callback_functions {
504 method_provider method;
505 ctx_callback ctx_ready;
506 ssl_callback ssl_ready;
507 ssl_callback on_result;
508 WOLFSSL_CTX* ctx;
509 const char* caPemFile;
510 const char* certPemFile;
511 const char* keyPemFile;
512 #ifdef WOLFSSL_STATIC_MEMORY
513 byte* mem;
514 word32 memSz;
515 wolfSSL_method_func method_ex;
516 #endif
517 int devId;
518 int return_code;
519 unsigned char isSharedCtx:1;
520 unsigned char loadToSSL:1;
521 } callback_functions;
522
523 typedef struct func_args {
524 int argc;
525 char** argv;
526 int return_code;
527 tcp_ready* signal;
528 callback_functions *callbacks;
529 } func_args;
530
531 #ifdef NETOS
532 int dc_log_printf(char* format, ...);
533 #undef printf
534 #define printf dc_log_printf
535 #endif
536
537 void wait_tcp_ready(func_args*);
538
539 #ifdef WOLFSSL_ZEPHYR
540 typedef void THREAD_FUNC(void*, void*, void*);
541 #else
542 typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
543 #endif
544
545 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
546 void join_thread(THREAD_TYPE);
547
548 /* wolfSSL */
549 #ifndef TEST_IPV6
550 static const char* const wolfSSLIP = "127.0.0.1";
551 #else
552 static const char* const wolfSSLIP = "::1";
553 #endif
554 static const word16 wolfSSLPort = 11111;
555
556
557
558 #ifndef MY_EX_USAGE
559 #define MY_EX_USAGE 2
560 #endif
561
562 #ifndef EXIT_FAILURE
563 #define EXIT_FAILURE 1
564 #endif
565
566 #if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
567 #ifndef EXIT_SUCCESS
568 #define EXIT_SUCCESS 0
569 #endif
570 #define XEXIT(rc) return rc
571 #define XEXIT_T(rc) return (THREAD_RETURN)rc
572 #else
573 #define XEXIT(rc) exit((int)(rc))
574 #define XEXIT_T(rc) exit((int)(rc))
575 #endif
576
577
578 static WC_INLINE
579 #if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
580 THREAD_RETURN
581 #else
582 WC_NORETURN void
583 #endif
err_sys(const char * msg)584 err_sys(const char* msg)
585 {
586 #if !defined(__GNUC__)
587 /* scan-build (which pretends to be gnuc) can get confused and think the
588 * msg pointer can be null even when hardcoded and then it won't exit,
589 * making null pointer checks above the err_sys() call useless.
590 * We could just always exit() but some compilers will complain about no
591 * possible return, with gcc we know the attribute to handle that with
592 * WC_NORETURN. */
593 if (msg)
594 #endif
595 {
596 printf("wolfSSL error: %s\n", msg);
597
598 XEXIT_T(EXIT_FAILURE);
599 }
600 }
601
602 static WC_INLINE
603 #if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
604 THREAD_RETURN
605 #else
606 WC_NORETURN void
607 #endif
err_sys_with_errno(const char * msg)608 err_sys_with_errno(const char* msg)
609 {
610 #if !defined(__GNUC__)
611 /* scan-build (which pretends to be gnuc) can get confused and think the
612 * msg pointer can be null even when hardcoded and then it won't exit,
613 * making null pointer checks above the err_sys() call useless.
614 * We could just always exit() but some compilers will complain about no
615 * possible return, with gcc we know the attribute to handle that with
616 * WC_NORETURN. */
617 if (msg)
618 #endif
619 {
620 #if defined(HAVE_STRING_H) && defined(HAVE_ERRNO_H)
621 printf("wolfSSL error: %s: %s\n", msg, strerror(errno));
622 #else
623 printf("wolfSSL error: %s\n", msg);
624 #endif
625
626 XEXIT_T(EXIT_FAILURE);
627 }
628 }
629
630
631 extern int myoptind;
632 extern char* myoptarg;
633
634 /**
635 *
636 * @param argc Number of argv strings
637 * @param argv Array of string arguments
638 * @param optstring String containing the supported alphanumeric arguments.
639 * A ':' following a character means that it requires a
640 * value in myoptarg to be set. A ';' means that the
641 * myoptarg is optional. myoptarg is set to "" if not
642 * present.
643 * @return Option letter in argument
644 */
mygetopt(int argc,char ** argv,const char * optstring)645 static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
646 {
647 static char* next = NULL;
648
649 char c;
650 char* cp;
651
652 /* Added sanity check because scan-build complains argv[myoptind] access
653 * results in a null pointer dereference. */
654 if (argv == NULL) {
655 myoptarg = NULL;
656 return -1;
657 }
658
659 if (myoptind == 0)
660 next = NULL; /* we're starting new/over */
661
662 if (next == NULL || *next == '\0') {
663 if (myoptind == 0)
664 myoptind++;
665
666 if (myoptind >= argc || argv[myoptind] == NULL ||
667 argv[myoptind][0] != '-' || argv[myoptind][1] == '\0') {
668 myoptarg = NULL;
669 if (myoptind < argc)
670 myoptarg = argv[myoptind];
671
672 return -1;
673 }
674
675 if (strcmp(argv[myoptind], "--") == 0) {
676 myoptind++;
677 myoptarg = NULL;
678
679 if (myoptind < argc)
680 myoptarg = argv[myoptind];
681
682 return -1;
683 }
684
685 next = argv[myoptind];
686 next++; /* skip - */
687 myoptind++;
688 }
689
690 c = *next++;
691 /* The C++ strchr can return a different value */
692 cp = (char*)strchr(optstring, c);
693
694 if (cp == NULL || c == ':' || c == ';')
695 return '?';
696
697 cp++;
698
699 if (*cp == ':') {
700 if (*next != '\0') {
701 myoptarg = next;
702 next = NULL;
703 }
704 else if (myoptind < argc) {
705 myoptarg = argv[myoptind];
706 myoptind++;
707 }
708 else
709 return '?';
710 }
711 else if (*cp == ';') {
712 myoptarg = (char*)"";
713 if (*next != '\0') {
714 myoptarg = next;
715 next = NULL;
716 }
717 else if (myoptind < argc) {
718 /* Check if next argument is not a parameter argument */
719 if (argv[myoptind] && argv[myoptind][0] != '-') {
720 myoptarg = argv[myoptind];
721 myoptind++;
722 }
723 }
724 }
725
726 return c;
727 }
728
729 struct mygetopt_long_config {
730 const char *name;
731 int takes_arg;
732 int value;
733 };
734
735 /**
736 *
737 * @param argc Number of argv strings
738 * @param argv Array of string arguments
739 * @param optstring String containing the supported alphanumeric arguments.
740 * A ':' following a character means that it requires a
741 * value in myoptarg to be set. A ';' means that the
742 * myoptarg is optional. myoptarg is set to "" if not
743 * present.
744 * @return Option letter in argument
745 */
mygetopt_long(int argc,char ** argv,const char * optstring,const struct mygetopt_long_config * longopts,int * longindex)746 static WC_INLINE int mygetopt_long(int argc, char** argv, const char* optstring,
747 const struct mygetopt_long_config *longopts, int *longindex)
748 {
749 static char* next = NULL;
750
751 int c;
752 char* cp;
753
754 /* Added sanity check because scan-build complains argv[myoptind] access
755 * results in a null pointer dereference. */
756 if (argv == NULL) {
757 myoptarg = NULL;
758 return -1;
759 }
760
761 if (myoptind == 0)
762 next = NULL; /* we're starting new/over */
763
764 if (next == NULL || *next == '\0') {
765 if (myoptind == 0)
766 myoptind++;
767
768 if (myoptind >= argc || argv[myoptind] == NULL ||
769 argv[myoptind][0] != '-' || argv[myoptind][1] == '\0') {
770 myoptarg = NULL;
771 if (myoptind < argc)
772 myoptarg = argv[myoptind];
773
774 return -1;
775 }
776
777 if (strcmp(argv[myoptind], "--") == 0) {
778 myoptind++;
779 myoptarg = NULL;
780
781 if (myoptind < argc)
782 myoptarg = argv[myoptind];
783
784 return -1;
785 }
786
787 if (strncmp(argv[myoptind], "--", 2) == 0) {
788 const struct mygetopt_long_config *i;
789 c = -1;
790 myoptarg = NULL;
791 for (i = longopts; i->name; ++i) {
792 if (! strcmp(argv[myoptind] + 2, i->name)) {
793 c = i->value;
794 myoptind++;
795 if (longindex)
796 *longindex = (int)((i - longopts) / sizeof *i);
797 if (i->takes_arg) {
798 if (myoptind < argc) {
799 myoptarg = argv[myoptind];
800 myoptind++;
801 } else
802 return -1;
803 }
804 break;
805 }
806 }
807
808 return c;
809 }
810
811 next = argv[myoptind];
812 next++; /* skip - */
813 myoptind++;
814 }
815
816 c = *next++;
817 /* The C++ strchr can return a different value */
818 cp = (char*)strchr(optstring, c);
819
820 if (cp == NULL || c == ':' || c == ';')
821 return '?';
822
823 cp++;
824
825 if (*cp == ':') {
826 if (*next != '\0') {
827 myoptarg = next;
828 next = NULL;
829 }
830 else if (myoptind < argc) {
831 myoptarg = argv[myoptind];
832 myoptind++;
833 }
834 else
835 return '?';
836 }
837 else if (*cp == ';') {
838 myoptarg = (char*)"";
839 if (*next != '\0') {
840 myoptarg = next;
841 next = NULL;
842 }
843 else if (myoptind < argc) {
844 /* Check if next argument is not a parameter argument */
845 if (argv[myoptind] && argv[myoptind][0] != '-') {
846 myoptarg = argv[myoptind];
847 myoptind++;
848 }
849 }
850 }
851
852 return c;
853 }
854
855
856 #ifdef WOLFSSL_ENCRYPTED_KEYS
857
PasswordCallBack(char * passwd,int sz,int rw,void * userdata)858 static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
859 {
860 (void)rw;
861 (void)userdata;
862 if (userdata != NULL) {
863 strncpy(passwd, (char*)userdata, sz);
864 return (int)XSTRLEN((char*)userdata);
865 }
866 else {
867 strncpy(passwd, "yassl123", sz);
868 return 8;
869 }
870 }
871
872 #endif
873
874 static const char* client_showpeer_msg[][9] = {
875 /* English */
876 {
877 "SSL version is",
878 "SSL cipher suite is",
879 "SSL signature algorithm is",
880 "SSL curve name is",
881 "SSL DH size is",
882 "SSL reused session",
883 "Alternate cert chain used",
884 "peer's cert info:",
885 NULL
886 },
887 #ifndef NO_MULTIBYTE_PRINT
888 /* Japanese */
889 {
890 "SSL バージョンは",
891 "SSL 暗号スイートは",
892 "SSL signature algorithm is",
893 "SSL 曲線名は",
894 "SSL DH サイズは",
895 "SSL 再利用セッション",
896 "代替証明チェーンを使用",
897 "相手方証明書情報",
898 NULL
899 },
900 #endif
901 };
902
903 #if defined(KEEP_PEER_CERT) || defined(KEEP_OUR_CERT) || defined(SESSION_CERTS)
904 static const char* client_showx509_msg[][5] = {
905 /* English */
906 {
907 "issuer",
908 "subject",
909 "altname",
910 "serial number",
911 NULL
912 },
913 #ifndef NO_MULTIBYTE_PRINT
914 /* Japanese */
915 {
916 "発行者",
917 "サブジェクト",
918 "代替名",
919 "シリアル番号",
920 NULL
921 },
922 #endif
923 };
924
925 /* lng_index is to specify the language for displaying message. */
926 /* 0:English, 1:Japanese */
ShowX509Ex(WOLFSSL_X509 * x509,const char * hdr,int lng_index)927 static WC_INLINE void ShowX509Ex(WOLFSSL_X509* x509, const char* hdr,
928 int lng_index)
929 {
930 char* altName;
931 char* issuer;
932 char* subject;
933 byte serial[32];
934 int ret;
935 int sz = sizeof(serial);
936 const char** words = client_showx509_msg[lng_index];
937
938 if (x509 == NULL) {
939 printf("%s No Cert\n", hdr);
940 return;
941 }
942
943 issuer = wolfSSL_X509_NAME_oneline(
944 wolfSSL_X509_get_issuer_name(x509), 0, 0);
945 subject = wolfSSL_X509_NAME_oneline(
946 wolfSSL_X509_get_subject_name(x509), 0, 0);
947
948 printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject);
949
950 while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
951 printf(" %s = %s\n", words[2], altName);
952
953 ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
954 if (ret == WOLFSSL_SUCCESS) {
955 int i;
956 int strLen;
957 char serialMsg[80];
958
959 /* testsuite has multiple threads writing to stdout, get output
960 message ready to write once */
961 strLen = sprintf(serialMsg, " %s", words[3]);
962 for (i = 0; i < sz; i++)
963 sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
964 printf("%s\n", serialMsg);
965 }
966
967 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
968 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
969
970 #if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA)
971 {
972 WOLFSSL_BIO* bio;
973 char buf[256]; /* should be size of ASN_NAME_MAX */
974 int textSz;
975
976 /* print out domain component if certificate has it */
977 textSz = wolfSSL_X509_NAME_get_text_by_NID(
978 wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
979 buf, sizeof(buf));
980 if (textSz > 0) {
981 printf("Domain Component = %s\n", buf);
982 }
983
984 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
985 if (bio != NULL) {
986 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
987 wolfSSL_X509_print(bio, x509);
988 wolfSSL_BIO_free(bio);
989 }
990 }
991 #endif /* SHOW_CERTS && OPENSSL_EXTRA */
992 }
993 /* original ShowX509 to maintain compatibility */
ShowX509(WOLFSSL_X509 * x509,const char * hdr)994 static WC_INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
995 {
996 ShowX509Ex(x509, hdr, 0);
997 }
998
999 #endif /* KEEP_PEER_CERT || KEEP_OUR_CERT || SESSION_CERTS */
1000
1001 #if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \
1002 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
ShowX509Chain(WOLFSSL_X509_CHAIN * chain,int count,const char * hdr)1003 static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count,
1004 const char* hdr)
1005 {
1006 int i;
1007 int length;
1008 unsigned char buffer[3072];
1009 WOLFSSL_X509* chainX509;
1010
1011 for (i = 0; i < count; i++) {
1012 wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length);
1013 buffer[length] = 0;
1014 printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer);
1015
1016 chainX509 = wolfSSL_get_chain_X509(chain, i);
1017 if (chainX509)
1018 ShowX509(chainX509, hdr);
1019 else
1020 printf("get_chain_X509 failed\n");
1021 wolfSSL_FreeX509(chainX509);
1022 }
1023 }
1024 #endif /* SHOW_CERTS && SESSION_CERTS */
1025
1026 /* lng_index is to specify the language for displaying message. */
1027 /* 0:English, 1:Japanese */
showPeerEx(WOLFSSL * ssl,int lng_index)1028 static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index)
1029 {
1030 WOLFSSL_CIPHER* cipher;
1031 const char** words = client_showpeer_msg[lng_index];
1032
1033 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
1034 !defined(NO_DH)
1035 const char *name;
1036 #endif
1037 #ifndef NO_DH
1038 int bits;
1039 #endif
1040 #ifdef OPENSSL_EXTRA
1041 int nid;
1042 #endif
1043 #ifdef KEEP_PEER_CERT
1044 WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
1045 if (peer)
1046 ShowX509Ex(peer, words[6], lng_index);
1047 else
1048 printf("peer has no cert!\n");
1049 wolfSSL_FreeX509(peer);
1050 #endif
1051 #if defined(SHOW_CERTS) && defined(KEEP_OUR_CERT) && \
1052 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
1053 ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
1054 printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
1055 #endif /* SHOW_CERTS && KEEP_OUR_CERT */
1056 printf("%s %s\n", words[0], wolfSSL_get_version(ssl));
1057
1058 cipher = wolfSSL_get_current_cipher(ssl);
1059 printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
1060 #ifdef OPENSSL_EXTRA
1061 if (wolfSSL_get_signature_nid(ssl, &nid) == WOLFSSL_SUCCESS) {
1062 printf("%s %s\n", words[2], OBJ_nid2sn(nid));
1063 }
1064 #endif
1065 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
1066 !defined(NO_DH)
1067 if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
1068 printf("%s %s\n", words[3], name);
1069 #endif
1070 #ifndef NO_DH
1071 else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
1072 printf("%s %d bits\n", words[4], bits);
1073 #endif
1074 if (wolfSSL_session_reused(ssl))
1075 printf("%s\n", words[5]);
1076 #ifdef WOLFSSL_ALT_CERT_CHAINS
1077 if (wolfSSL_is_peer_alt_cert_chain(ssl))
1078 printf("%s\n", words[6]);
1079 #endif
1080
1081 #if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \
1082 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
1083 {
1084 WOLFSSL_X509_CHAIN* chain;
1085
1086 chain = wolfSSL_get_peer_chain(ssl);
1087 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert");
1088
1089 #ifdef WOLFSSL_ALT_CERT_CHAINS
1090 if (wolfSSL_is_peer_alt_cert_chain(ssl)) {
1091 chain = wolfSSL_get_peer_alt_chain(ssl);
1092 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert");
1093 }
1094 #endif
1095 }
1096 #endif /* SHOW_CERTS && SESSION_CERTS */
1097 (void)ssl;
1098 }
1099 /* original showPeer to maintain compatibility */
showPeer(WOLFSSL * ssl)1100 static WC_INLINE void showPeer(WOLFSSL* ssl)
1101 {
1102 showPeerEx(ssl, 0);
1103 }
1104
build_addr(SOCKADDR_IN_T * addr,const char * peer,word16 port,int udp,int sctp)1105 static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
1106 word16 port, int udp, int sctp)
1107 {
1108 int useLookup = 0;
1109 (void)useLookup;
1110 (void)udp;
1111 (void)sctp;
1112
1113 if (addr == NULL)
1114 err_sys("invalid argument to build_addr, addr is NULL");
1115
1116 XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T));
1117
1118 #ifndef TEST_IPV6
1119 /* peer could be in human readable form */
1120 if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) {
1121 #ifdef WOLFSSL_USE_POPEN_HOST
1122 char host_ipaddr[4] = { 127, 0, 0, 1 };
1123 int found = 1;
1124
1125 if ((XSTRNCMP(peer, "localhost", 10) != 0) &&
1126 (XSTRNCMP(peer, "127.0.0.1", 10) != 0)) {
1127 FILE* fp;
1128 char host_out[100];
1129 char cmd[100];
1130
1131 XSTRNCPY(cmd, "host ", 6);
1132 XSTRNCAT(cmd, peer, 99 - XSTRLEN(cmd));
1133 found = 0;
1134 fp = popen(cmd, "r");
1135 if (fp != NULL) {
1136 while (fgets(host_out, sizeof(host_out), fp) != NULL) {
1137 int i;
1138 int j = 0;
1139 for (j = 0; host_out[j] != '\0'; j++) {
1140 if ((host_out[j] >= '0') && (host_out[j] <= '9')) {
1141 break;
1142 }
1143 }
1144 found = (host_out[j] >= '0') && (host_out[j] <= '9');
1145 if (!found) {
1146 continue;
1147 }
1148
1149 for (i = 0; i < 4; i++) {
1150 host_ipaddr[i] = atoi(host_out + j);
1151 while ((host_out[j] >= '0') && (host_out[j] <= '9')) {
1152 j++;
1153 }
1154 if (host_out[j] == '.') {
1155 j++;
1156 found &= (i != 3);
1157 }
1158 else {
1159 found &= (i == 3);
1160 break;
1161 }
1162 }
1163 if (found) {
1164 break;
1165 }
1166 }
1167 pclose(fp);
1168 }
1169 }
1170 if (found) {
1171 XMEMCPY(&addr->sin_addr.s_addr, host_ipaddr, sizeof(host_ipaddr));
1172 useLookup = 1;
1173 }
1174 #elif !defined(WOLFSSL_USE_GETADDRINFO)
1175 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
1176 int err;
1177 struct hostent* entry = gethostbyname(peer, &err);
1178 #elif defined(WOLFSSL_TIRTOS)
1179 struct hostent* entry = DNSGetHostByName(peer);
1180 #elif defined(WOLFSSL_VXWORKS)
1181 struct hostent* entry = (struct hostent*)hostGetByName((char*)peer);
1182 #else
1183 struct hostent* entry = gethostbyname(peer);
1184 #endif
1185
1186 if (entry) {
1187 XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0],
1188 entry->h_length);
1189 useLookup = 1;
1190 }
1191 #else
1192 struct zsock_addrinfo hints, *addrInfo;
1193 char portStr[6];
1194 XSNPRINTF(portStr, sizeof(portStr), "%d", port);
1195 XMEMSET(&hints, 0, sizeof(hints));
1196 hints.ai_family = AF_UNSPEC;
1197 hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
1198 hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
1199 if (getaddrinfo((char*)peer, portStr, &hints, &addrInfo) == 0) {
1200 XMEMCPY(addr, addrInfo->ai_addr, sizeof(*addr));
1201 useLookup = 1;
1202 }
1203 #endif
1204 else
1205 err_sys("no entry for host");
1206 }
1207 #endif
1208
1209
1210 #ifndef TEST_IPV6
1211 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
1212 addr->sin_family = PF_INET;
1213 #else
1214 addr->sin_family = AF_INET_V;
1215 #endif
1216 addr->sin_port = XHTONS(port);
1217 if ((size_t)peer == INADDR_ANY)
1218 addr->sin_addr.s_addr = INADDR_ANY;
1219 else {
1220 if (!useLookup)
1221 addr->sin_addr.s_addr = inet_addr(peer);
1222 }
1223 #else
1224 addr->sin6_family = AF_INET_V;
1225 addr->sin6_port = XHTONS(port);
1226 if ((size_t)peer == INADDR_ANY) {
1227 addr->sin6_addr = in6addr_any;
1228 }
1229 else {
1230 #if defined(HAVE_GETADDRINFO) || defined(WOLF_C99)
1231 struct addrinfo hints;
1232 struct addrinfo* answer = NULL;
1233 int ret;
1234 char strPort[80];
1235
1236 XMEMSET(&hints, 0, sizeof(hints));
1237
1238 hints.ai_family = AF_INET_V;
1239 if (udp) {
1240 hints.ai_socktype = SOCK_DGRAM;
1241 hints.ai_protocol = IPPROTO_UDP;
1242 }
1243 #ifdef WOLFSSL_SCTP
1244 else if (sctp) {
1245 hints.ai_socktype = SOCK_STREAM;
1246 hints.ai_protocol = IPPROTO_SCTP;
1247 }
1248 #endif
1249 else {
1250 hints.ai_socktype = SOCK_STREAM;
1251 hints.ai_protocol = IPPROTO_TCP;
1252 }
1253
1254 SNPRINTF(strPort, sizeof(strPort), "%d", port);
1255 strPort[79] = '\0';
1256
1257 ret = getaddrinfo(peer, strPort, &hints, &answer);
1258 if (ret < 0 || answer == NULL)
1259 err_sys("getaddrinfo failed");
1260
1261 XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen);
1262 freeaddrinfo(answer);
1263 #else
1264 printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
1265 addr->sin6_addr = in6addr_loopback;
1266 #endif
1267 }
1268 #endif
1269 }
1270
1271
tcp_socket(SOCKET_T * sockfd,int udp,int sctp)1272 static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
1273 {
1274 (void)sctp;
1275
1276 if (udp)
1277 *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
1278 #ifdef WOLFSSL_SCTP
1279 else if (sctp)
1280 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
1281 #endif
1282 else
1283 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
1284
1285 if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
1286 err_sys_with_errno("socket failed\n");
1287 }
1288
1289 #ifndef USE_WINDOWS_API
1290 #ifdef SO_NOSIGPIPE
1291 {
1292 int on = 1;
1293 socklen_t len = sizeof(on);
1294 int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
1295 if (res < 0)
1296 err_sys_with_errno("setsockopt SO_NOSIGPIPE failed\n");
1297 }
1298 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
1299 defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR)
1300 /* nothing to define */
1301 #elif defined(NETOS)
1302 /* TODO: signal(SIGPIPE, SIG_IGN); */
1303 #else /* no S_NOSIGPIPE */
1304 signal(SIGPIPE, SIG_IGN);
1305 #endif /* S_NOSIGPIPE */
1306
1307 #if defined(TCP_NODELAY)
1308 if (!udp && !sctp)
1309 {
1310 int on = 1;
1311 socklen_t len = sizeof(on);
1312 int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
1313 if (res < 0)
1314 err_sys_with_errno("setsockopt TCP_NODELAY failed\n");
1315 }
1316 #endif
1317 #endif /* USE_WINDOWS_API */
1318 }
1319
1320 #if defined(WOLFSSL_WOLFSENTRY_HOOKS) && defined(WOLFSENTRY_H)
1321
1322 #include <wolfsentry/wolfsentry_util.h>
1323
1324 #if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
1325 #include <wolfsentry/wolfsentry_json.h>
1326 #endif
1327
1328 struct wolfsentry_data {
1329 WOLFSENTRY_SOCKADDR(128) remote;
1330 WOLFSENTRY_SOCKADDR(128) local;
1331 wolfsentry_route_flags_t flags;
1332 void *heap;
1333 int alloctype;
1334 };
1335
free_wolfsentry_data(struct wolfsentry_data * data)1336 static void free_wolfsentry_data(struct wolfsentry_data *data) {
1337 XFREE(data, data->heap, data->alloctype);
1338 }
1339
1340 static struct wolfsentry_context *wolfsentry = NULL;
1341
1342 static int wolfsentry_data_index = -1;
1343
wolfsentry_store_endpoints(WOLFSSL * ssl,SOCKADDR_IN_T * remote,SOCKADDR_IN_T * local,int proto,wolfsentry_route_flags_t flags,struct wolfsentry_data ** wolfsentry_data_out)1344 static WC_INLINE int wolfsentry_store_endpoints(
1345 WOLFSSL *ssl,
1346 SOCKADDR_IN_T *remote,
1347 SOCKADDR_IN_T *local,
1348 int proto,
1349 wolfsentry_route_flags_t flags,
1350 struct wolfsentry_data **wolfsentry_data_out)
1351 {
1352 struct wolfsentry_data *wolfsentry_data = (struct wolfsentry_data *)XMALLOC(
1353 sizeof *wolfsentry_data, NULL, DYNAMIC_TYPE_SOCKADDR);
1354 if (wolfsentry_data == NULL)
1355 return WOLFSSL_FAILURE;
1356
1357 wolfsentry_data->heap = NULL;
1358 wolfsentry_data->alloctype = DYNAMIC_TYPE_SOCKADDR;
1359
1360 #ifdef TEST_IPV6
1361 if ((sizeof wolfsentry_data->remote.addr < sizeof remote->sin6_addr) ||
1362 (sizeof wolfsentry_data->local.addr < sizeof local->sin6_addr))
1363 return WOLFSSL_FAILURE;
1364 wolfsentry_data->remote.sa_family = wolfsentry_data->local.sa_family = remote->sin6_family;
1365 wolfsentry_data->remote.sa_port = ntohs(remote->sin6_port);
1366 wolfsentry_data->local.sa_port = ntohs(local->sin6_port);
1367 if (WOLFSENTRY_MASKIN_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_ADDR_WILDCARD)) {
1368 wolfsentry_data->remote.addr_len = 0;
1369 XMEMSET(wolfsentry_data->remote.addr, 0, sizeof remote->sin6_addr);
1370 } else {
1371 wolfsentry_data->remote.addr_len = sizeof remote->sin6_addr * BITS_PER_BYTE;
1372 XMEMCPY(wolfsentry_data->remote.addr, &remote->sin6_addr, sizeof remote->sin6_addr);
1373 }
1374 if (WOLFSENTRY_MASKIN_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD)) {
1375 wolfsentry_data->local.addr_len = 0;
1376 XMEMSET(wolfsentry_data->local.addr, 0, sizeof local->sin6_addr);
1377 } else {
1378 wolfsentry_data->local.addr_len = sizeof local->sin6_addr * BITS_PER_BYTE;
1379 XMEMCPY(wolfsentry_data->local.addr, &local->sin6_addr, sizeof local->sin6_addr);
1380 }
1381 #else
1382 if ((sizeof wolfsentry_data->remote.addr < sizeof remote->sin_addr) ||
1383 (sizeof wolfsentry_data->local.addr < sizeof local->sin_addr))
1384 return WOLFSSL_FAILURE;
1385 wolfsentry_data->remote.sa_family = wolfsentry_data->local.sa_family = remote->sin_family;
1386 wolfsentry_data->remote.sa_port = ntohs(remote->sin_port);
1387 wolfsentry_data->local.sa_port = ntohs(local->sin_port);
1388 if (WOLFSENTRY_MASKIN_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_ADDR_WILDCARD)) {
1389 wolfsentry_data->remote.addr_len = 0;
1390 XMEMSET(wolfsentry_data->remote.addr, 0, sizeof remote->sin_addr);
1391 } else {
1392 wolfsentry_data->remote.addr_len = sizeof remote->sin_addr * BITS_PER_BYTE;
1393 XMEMCPY(wolfsentry_data->remote.addr, &remote->sin_addr, sizeof remote->sin_addr);
1394 }
1395 if (WOLFSENTRY_MASKIN_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD)) {
1396 wolfsentry_data->local.addr_len = 0;
1397 XMEMSET(wolfsentry_data->local.addr, 0, sizeof local->sin_addr);
1398 } else {
1399 wolfsentry_data->local.addr_len = sizeof local->sin_addr * BITS_PER_BYTE;
1400 XMEMCPY(wolfsentry_data->local.addr, &local->sin_addr, sizeof local->sin_addr);
1401 }
1402 #endif
1403 wolfsentry_data->remote.sa_proto = wolfsentry_data->local.sa_proto = proto;
1404 wolfsentry_data->remote.interface = wolfsentry_data->local.interface = 0;
1405 wolfsentry_data->flags = flags;
1406
1407 if (wolfSSL_set_ex_data_with_cleanup(
1408 ssl, wolfsentry_data_index, wolfsentry_data,
1409 (wolfSSL_ex_data_cleanup_routine_t)free_wolfsentry_data) !=
1410 WOLFSSL_SUCCESS) {
1411 free_wolfsentry_data(wolfsentry_data);
1412 return WOLFSSL_FAILURE;
1413 }
1414
1415 if (wolfsentry_data_out != NULL)
1416 *wolfsentry_data_out = wolfsentry_data;
1417
1418 return WOLFSSL_SUCCESS;
1419 }
1420
wolfSentry_NetworkFilterCallback(WOLFSSL * ssl,struct wolfsentry_context * _wolfsentry,wolfSSL_netfilter_decision_t * decision)1421 static int wolfSentry_NetworkFilterCallback(
1422 WOLFSSL *ssl,
1423 struct wolfsentry_context *_wolfsentry,
1424 wolfSSL_netfilter_decision_t *decision)
1425 {
1426 struct wolfsentry_data *data;
1427 char inet_ntop_buf[INET6_ADDRSTRLEN], inet_ntop_buf2[INET6_ADDRSTRLEN];
1428 wolfsentry_errcode_t ret;
1429 wolfsentry_action_res_t action_results;
1430
1431 if ((data = wolfSSL_get_ex_data(ssl, wolfsentry_data_index)) == NULL)
1432 return WOLFSSL_FAILURE;
1433
1434 ret = wolfsentry_route_event_dispatch(
1435 _wolfsentry,
1436 (const struct wolfsentry_sockaddr *)&data->remote,
1437 (const struct wolfsentry_sockaddr *)&data->local,
1438 data->flags,
1439 NULL /* event_label */,
1440 0 /* event_label_len */,
1441 NULL /* caller_context */,
1442 NULL /* id */,
1443 NULL /* inexact_matches */,
1444 &action_results);
1445
1446 if (ret >= 0) {
1447 if (WOLFSENTRY_MASKIN_BITS(action_results, WOLFSENTRY_ACTION_RES_REJECT))
1448 *decision = WOLFSSL_NETFILTER_REJECT;
1449 else if (WOLFSENTRY_MASKIN_BITS(action_results, WOLFSENTRY_ACTION_RES_ACCEPT))
1450 *decision = WOLFSSL_NETFILTER_ACCEPT;
1451 else
1452 *decision = WOLFSSL_NETFILTER_PASS;
1453 } else {
1454 printf("wolfsentry_route_event_dispatch error "
1455 WOLFSENTRY_ERROR_FMT "\n", WOLFSENTRY_ERROR_FMT_ARGS(ret));
1456 *decision = WOLFSSL_NETFILTER_PASS;
1457 }
1458
1459 printf("wolfSentry got network filter callback: family=%d proto=%d rport=%d"
1460 " lport=%d raddr=%s laddr=%s interface=%d; decision=%d (%s)\n",
1461 data->remote.sa_family,
1462 data->remote.sa_proto,
1463 data->remote.sa_port,
1464 data->local.sa_port,
1465 inet_ntop(data->remote.sa_family, data->remote.addr, inet_ntop_buf,
1466 sizeof inet_ntop_buf),
1467 inet_ntop(data->local.sa_family, data->local.addr, inet_ntop_buf2,
1468 sizeof inet_ntop_buf2),
1469 data->remote.interface,
1470 *decision,
1471 *decision == WOLFSSL_NETFILTER_REJECT ? "REJECT" :
1472 *decision == WOLFSSL_NETFILTER_ACCEPT ? "ACCEPT" :
1473 *decision == WOLFSSL_NETFILTER_PASS ? "PASS" :
1474 "???");
1475
1476 return WOLFSSL_SUCCESS;
1477 }
1478
wolfsentry_setup(struct wolfsentry_context ** _wolfsentry,const char * _wolfsentry_config_path,wolfsentry_route_flags_t route_flags)1479 static int wolfsentry_setup(
1480 struct wolfsentry_context **_wolfsentry,
1481 const char *_wolfsentry_config_path,
1482 wolfsentry_route_flags_t route_flags)
1483 {
1484 wolfsentry_errcode_t ret;
1485 ret = wolfsentry_init(NULL /* hpi */, NULL /* default config */,
1486 _wolfsentry);
1487 if (ret < 0) {
1488 fprintf(stderr, "wolfsentry_init() returned " WOLFSENTRY_ERROR_FMT "\n",
1489 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1490 err_sys("unable to initialize wolfSentry");
1491 }
1492
1493 if (wolfsentry_data_index < 0)
1494 wolfsentry_data_index = wolfSSL_get_ex_new_index(0, NULL, NULL, NULL,
1495 NULL);
1496
1497 #if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
1498 if (_wolfsentry_config_path != NULL) {
1499 char buf[512], err_buf[512];
1500 struct wolfsentry_json_process_state *jps;
1501
1502 FILE *f = fopen(_wolfsentry_config_path, "r");
1503
1504 if (f == NULL) {
1505 fprintf(stderr, "fopen(%s): %s\n",_wolfsentry_config_path,strerror(errno));
1506 err_sys("unable to open wolfSentry config file");
1507 }
1508
1509 if ((ret = wolfsentry_config_json_init(
1510 *_wolfsentry,
1511 WOLFSENTRY_CONFIG_LOAD_FLAG_NONE,
1512 &jps)) < 0) {
1513 fprintf(stderr, "wolfsentry_config_json_init() returned "
1514 WOLFSENTRY_ERROR_FMT "\n",
1515 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1516 err_sys("error while initializing wolfSentry config parser");
1517 }
1518
1519 for (;;) {
1520 size_t n = fread(buf, 1, sizeof buf, f);
1521 if ((n < sizeof buf) && ferror(f)) {
1522 fprintf(stderr,"fread(%s): %s\n",_wolfsentry_config_path, strerror(errno));
1523 err_sys("error while reading wolfSentry config file");
1524 }
1525
1526 ret = wolfsentry_config_json_feed(jps, buf, n, err_buf, sizeof err_buf);
1527 if (ret < 0) {
1528 fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf);
1529 err_sys("error while loading wolfSentry config file");
1530 }
1531 if ((n < sizeof buf) && feof(f))
1532 break;
1533 }
1534 fclose(f);
1535
1536 if ((ret = wolfsentry_config_json_fini(&jps, err_buf, sizeof err_buf)) < 0) {
1537 fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf);
1538 err_sys("error while loading wolfSentry config file");
1539 }
1540
1541 } else
1542 #endif /* !NO_FILESYSTEM && !WOLFSENTRY_NO_JSON */
1543 {
1544 struct wolfsentry_route_table *table;
1545
1546 if ((ret = wolfsentry_route_get_table_static(*_wolfsentry,
1547 &table)) < 0)
1548 fprintf(stderr, "wolfsentry_route_get_table_static() returned "
1549 WOLFSENTRY_ERROR_FMT "\n",
1550 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1551
1552 if (ret < 0)
1553 return ret;
1554
1555 if (WOLFSENTRY_MASKIN_BITS(route_flags, WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT)) {
1556 WOLFSENTRY_SOCKADDR(128) remote, local;
1557 wolfsentry_ent_id_t id;
1558 wolfsentry_action_res_t action_results;
1559
1560 if ((ret = wolfsentry_route_table_default_policy_set(
1561 *_wolfsentry, table,
1562 WOLFSENTRY_ACTION_RES_ACCEPT))
1563 < 0) {
1564 fprintf(stderr,
1565 "wolfsentry_route_table_default_policy_set() returned "
1566 WOLFSENTRY_ERROR_FMT "\n",
1567 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1568 return ret;
1569 }
1570
1571 XMEMSET(&remote, 0, sizeof remote);
1572 XMEMSET(&local, 0, sizeof local);
1573 #ifdef TEST_IPV6
1574 remote.sa_family = local.sa_family = AF_INET6;
1575 remote.addr_len = 128;
1576 XMEMCPY(remote.addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", 16);
1577 #else
1578 remote.sa_family = local.sa_family = AF_INET;
1579 remote.addr_len = 32;
1580 XMEMCPY(remote.addr, "\177\000\000\001", 4);
1581 #endif
1582
1583 if ((ret = wolfsentry_route_insert_static
1584 (*_wolfsentry, NULL /* caller_context */,
1585 (const struct wolfsentry_sockaddr *)&remote,
1586 (const struct wolfsentry_sockaddr *)&local,
1587 route_flags |
1588 WOLFSENTRY_ROUTE_FLAG_GREENLISTED |
1589 WOLFSENTRY_ROUTE_FLAG_PARENT_EVENT_WILDCARD |
1590 WOLFSENTRY_ROUTE_FLAG_REMOTE_INTERFACE_WILDCARD|
1591 WOLFSENTRY_ROUTE_FLAG_LOCAL_INTERFACE_WILDCARD |
1592 WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD |
1593 WOLFSENTRY_ROUTE_FLAG_SA_PROTO_WILDCARD |
1594 WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_PORT_WILDCARD |
1595 WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD,
1596 0 /* event_label_len */, 0 /* event_label */, &id,
1597 &action_results)) < 0) {
1598 fprintf(stderr, "wolfsentry_route_insert_static() returned "
1599 WOLFSENTRY_ERROR_FMT "\n",
1600 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1601 return ret;
1602 }
1603 } else if (WOLFSENTRY_MASKIN_BITS(route_flags, WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN)) {
1604 WOLFSENTRY_SOCKADDR(128) remote, local;
1605 wolfsentry_ent_id_t id;
1606 wolfsentry_action_res_t action_results;
1607
1608 if ((ret = wolfsentry_route_table_default_policy_set(
1609 *_wolfsentry, table,
1610 WOLFSENTRY_ACTION_RES_REJECT|WOLFSENTRY_ACTION_RES_STOP))
1611 < 0) {
1612 fprintf(stderr,
1613 "wolfsentry_route_table_default_policy_set() returned "
1614 WOLFSENTRY_ERROR_FMT "\n",
1615 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1616 return ret;
1617 }
1618
1619 XMEMSET(&remote, 0, sizeof remote);
1620 XMEMSET(&local, 0, sizeof local);
1621 #ifdef TEST_IPV6
1622 remote.sa_family = local.sa_family = AF_INET6;
1623 remote.addr_len = 128;
1624 XMEMCPY(remote.addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", 16);
1625 #else
1626 remote.sa_family = local.sa_family = AF_INET;
1627 remote.addr_len = 32;
1628 XMEMCPY(remote.addr, "\177\000\000\001", 4);
1629 #endif
1630
1631 if ((ret = wolfsentry_route_insert_static
1632 (*_wolfsentry, NULL /* caller_context */,
1633 (const struct wolfsentry_sockaddr *)&remote, (const struct wolfsentry_sockaddr *)&local,
1634 route_flags |
1635 WOLFSENTRY_ROUTE_FLAG_GREENLISTED |
1636 WOLFSENTRY_ROUTE_FLAG_PARENT_EVENT_WILDCARD |
1637 WOLFSENTRY_ROUTE_FLAG_REMOTE_INTERFACE_WILDCARD|
1638 WOLFSENTRY_ROUTE_FLAG_LOCAL_INTERFACE_WILDCARD |
1639 WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD |
1640 WOLFSENTRY_ROUTE_FLAG_SA_PROTO_WILDCARD |
1641 WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_PORT_WILDCARD |
1642 WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD,
1643 0 /* event_label_len */, 0 /* event_label */, &id,
1644 &action_results)) < 0) {
1645 fprintf(stderr, "wolfsentry_route_insert_static() returned "
1646 WOLFSENTRY_ERROR_FMT "\n",
1647 WOLFSENTRY_ERROR_FMT_ARGS(ret));
1648 return ret;
1649 }
1650 }
1651 }
1652
1653 return 0;
1654 }
1655
tcp_connect_with_wolfSentry(SOCKET_T * sockfd,const char * ip,word16 port,int udp,int sctp,WOLFSSL * ssl,struct wolfsentry_context * _wolfsentry)1656 static WC_INLINE int tcp_connect_with_wolfSentry(
1657 SOCKET_T* sockfd,
1658 const char* ip,
1659 word16 port,
1660 int udp,
1661 int sctp,
1662 WOLFSSL* ssl,
1663 struct wolfsentry_context *_wolfsentry)
1664 {
1665 SOCKADDR_IN_T remote_addr;
1666 struct wolfsentry_data *wolfsentry_data;
1667 char inet_ntop_buf[INET6_ADDRSTRLEN], inet_ntop_buf2[INET6_ADDRSTRLEN];
1668 wolfsentry_errcode_t ret;
1669 wolfsentry_action_res_t action_results;
1670 wolfSSL_netfilter_decision_t decision;
1671
1672 build_addr(&remote_addr, ip, port, udp, sctp);
1673
1674 {
1675 SOCKADDR_IN_T local_addr;
1676 #ifdef TEST_IPV6
1677 local_addr.sin6_port = 0;
1678 #else
1679 local_addr.sin_port = 0;
1680 #endif
1681 ((struct sockaddr *)&local_addr)->sa_family = ((struct sockaddr *)&remote_addr)->sa_family;
1682
1683 if (wolfsentry_store_endpoints(
1684 ssl, &remote_addr, &local_addr,
1685 udp ? IPPROTO_UDP : IPPROTO_TCP,
1686 WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT|
1687 WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD|
1688 WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD, &wolfsentry_data) != WOLFSSL_SUCCESS)
1689 return WOLFSSL_FAILURE;
1690 }
1691
1692 ret = wolfsentry_route_event_dispatch(
1693 _wolfsentry,
1694 (const struct wolfsentry_sockaddr *)&wolfsentry_data->remote,
1695 (const struct wolfsentry_sockaddr *)&wolfsentry_data->local,
1696 wolfsentry_data->flags,
1697 NULL /* event_label */,
1698 0 /* event_label_len */,
1699 NULL /* caller_context */,
1700 NULL /* id */,
1701 NULL /* inexact_matches */,
1702 &action_results);
1703
1704 if (ret < 0) {
1705 printf("wolfsentry_route_event_dispatch error "
1706 WOLFSENTRY_ERROR_FMT "\n", WOLFSENTRY_ERROR_FMT_ARGS(ret));
1707 decision = WOLFSSL_NETFILTER_PASS;
1708 } else {
1709 if (WOLFSENTRY_MASKIN_BITS(action_results, WOLFSENTRY_ACTION_RES_REJECT))
1710 decision = WOLFSSL_NETFILTER_REJECT;
1711 else if (WOLFSENTRY_MASKIN_BITS(action_results, WOLFSENTRY_ACTION_RES_ACCEPT))
1712 decision = WOLFSSL_NETFILTER_ACCEPT;
1713 else
1714 decision = WOLFSSL_NETFILTER_PASS;
1715 }
1716
1717 printf("wolfSentry callin from tcp_connect_with_wolfSentry: family=%d proto=%d rport=%d"
1718 " lport=%d raddr=%s laddr=%s interface=%d; decision=%d (%s)\n",
1719 wolfsentry_data->remote.sa_family,
1720 wolfsentry_data->remote.sa_proto,
1721 wolfsentry_data->remote.sa_port,
1722 wolfsentry_data->local.sa_port,
1723 inet_ntop(wolfsentry_data->remote.sa_family, wolfsentry_data->remote.addr, inet_ntop_buf,
1724 sizeof inet_ntop_buf),
1725 inet_ntop(wolfsentry_data->local.sa_family, wolfsentry_data->local.addr, inet_ntop_buf2,
1726 sizeof inet_ntop_buf2),
1727 wolfsentry_data->remote.interface,
1728 decision,
1729 decision == WOLFSSL_NETFILTER_REJECT ? "REJECT" :
1730 decision == WOLFSSL_NETFILTER_ACCEPT ? "ACCEPT" :
1731 decision == WOLFSSL_NETFILTER_PASS ? "PASS" :
1732 "???");
1733
1734 if (decision == WOLFSSL_NETFILTER_REJECT)
1735 return SOCKET_FILTERED_E;
1736
1737 if (udp) {
1738 wolfSSL_dtls_set_peer(ssl, &remote_addr, sizeof(remote_addr));
1739 }
1740 tcp_socket(sockfd, udp, sctp);
1741
1742 if (!udp) {
1743 if (connect(*sockfd, (const struct sockaddr*)&remote_addr, sizeof(remote_addr)) != 0)
1744 err_sys_with_errno("tcp connect failed");
1745 }
1746
1747 return WOLFSSL_SUCCESS;
1748 }
1749
1750 #define tcp_connect(sockfd, ip, port, udp, sctp, ssl) \
1751 tcp_connect_with_wolfSentry(sockfd, ip, port, udp, sctp, ssl, wolfsentry)
1752
1753 #else /* !WOLFSSL_WOLFSENTRY_HOOKS */
1754
tcp_connect(SOCKET_T * sockfd,const char * ip,word16 port,int udp,int sctp,WOLFSSL * ssl)1755 static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
1756 int udp, int sctp, WOLFSSL* ssl)
1757 {
1758 SOCKADDR_IN_T addr;
1759 build_addr(&addr, ip, port, udp, sctp);
1760 if (udp) {
1761 wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
1762 }
1763 tcp_socket(sockfd, udp, sctp);
1764
1765 if (!udp) {
1766 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1767 err_sys_with_errno("tcp connect failed");
1768 }
1769 }
1770
1771 #endif /* WOLFSSL_WOLFSENTRY_HOOKS */
1772
1773
udp_connect(SOCKET_T * sockfd,void * addr,int addrSz)1774 static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
1775 {
1776 if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
1777 err_sys_with_errno("tcp connect failed");
1778 }
1779
1780
1781 enum {
1782 TEST_SELECT_FAIL,
1783 TEST_TIMEOUT,
1784 TEST_RECV_READY,
1785 TEST_SEND_READY,
1786 TEST_ERROR_READY
1787 };
1788
1789
1790 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
1791 !defined(WOLFSSL_TIRTOS)
tcp_select_ex(SOCKET_T socketfd,int to_sec,int rx)1792 static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx)
1793 {
1794 fd_set fds, errfds;
1795 fd_set* recvfds = NULL;
1796 fd_set* sendfds = NULL;
1797 SOCKET_T nfds = socketfd + 1;
1798 #if !defined(__INTEGRITY)
1799 struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0};
1800 #else
1801 struct timeval timeout;
1802 #endif
1803 int result;
1804
1805 FD_ZERO(&fds);
1806 FD_SET(socketfd, &fds);
1807 FD_ZERO(&errfds);
1808 FD_SET(socketfd, &errfds);
1809
1810 if (rx)
1811 recvfds = &fds;
1812 else
1813 sendfds = &fds;
1814
1815 #if defined(__INTEGRITY)
1816 timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0;
1817 #endif
1818 result = select(nfds, recvfds, sendfds, &errfds, &timeout);
1819
1820 if (result == 0)
1821 return TEST_TIMEOUT;
1822 else if (result > 0) {
1823 if (FD_ISSET(socketfd, &fds)) {
1824 if (rx)
1825 return TEST_RECV_READY;
1826 else
1827 return TEST_SEND_READY;
1828 }
1829 else if(FD_ISSET(socketfd, &errfds))
1830 return TEST_ERROR_READY;
1831 }
1832
1833 return TEST_SELECT_FAIL;
1834 }
1835
tcp_select(SOCKET_T socketfd,int to_sec)1836 static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
1837 {
1838 return tcp_select_ex(socketfd, to_sec, 1);
1839 }
1840
tcp_select_tx(SOCKET_T socketfd,int to_sec)1841 static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
1842 {
1843 return tcp_select_ex(socketfd, to_sec, 0);
1844 }
1845
1846 #elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET)
tcp_select(SOCKET_T socketfd,int to_sec)1847 static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
1848 {
1849 return TEST_RECV_READY;
1850 }
tcp_select_tx(SOCKET_T socketfd,int to_sec)1851 static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
1852 {
1853 return TEST_SEND_READY;
1854 }
1855 #endif /* !WOLFSSL_MDK_ARM */
1856
1857
tcp_listen(SOCKET_T * sockfd,word16 * port,int useAnyAddr,int udp,int sctp)1858 static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
1859 int udp, int sctp)
1860 {
1861 SOCKADDR_IN_T addr;
1862
1863 /* don't use INADDR_ANY by default, firewall may block, make user switch
1864 on */
1865 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp);
1866 tcp_socket(sockfd, udp, sctp);
1867
1868 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
1869 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1870 {
1871 int res, on = 1;
1872 socklen_t len = sizeof(on);
1873 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
1874 if (res < 0)
1875 err_sys_with_errno("setsockopt SO_REUSEADDR failed\n");
1876 }
1877 #ifdef SO_REUSEPORT
1878 {
1879 int res, on = 1;
1880 socklen_t len = sizeof(on);
1881 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len);
1882 if (res < 0)
1883 err_sys_with_errno("setsockopt SO_REUSEPORT failed\n");
1884 }
1885 #endif
1886 #endif
1887
1888 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1889 err_sys_with_errno("tcp bind failed");
1890 if (!udp) {
1891 #ifdef WOLFSSL_KEIL_TCP_NET
1892 #define SOCK_LISTEN_MAX_QUEUE 1
1893 #else
1894 #define SOCK_LISTEN_MAX_QUEUE 5
1895 #endif
1896 if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0)
1897 err_sys_with_errno("tcp listen failed");
1898 }
1899 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) \
1900 && !defined(WOLFSSL_ZEPHYR)
1901 if (*port == 0) {
1902 socklen_t len = sizeof(addr);
1903 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
1904 #ifndef TEST_IPV6
1905 *port = XNTOHS(addr.sin_port);
1906 #else
1907 *port = XNTOHS(addr.sin6_port);
1908 #endif
1909 }
1910 }
1911 #endif
1912 }
1913
1914
1915 #if 0
1916 static WC_INLINE int udp_read_connect(SOCKET_T sockfd)
1917 {
1918 SOCKADDR_IN_T cliaddr;
1919 byte b[1500];
1920 int n;
1921 socklen_t len = sizeof(cliaddr);
1922
1923 n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
1924 (struct sockaddr*)&cliaddr, &len);
1925 if (n > 0) {
1926 if (connect(sockfd, (const struct sockaddr*)&cliaddr,
1927 sizeof(cliaddr)) != 0)
1928 err_sys("udp connect failed");
1929 }
1930 else
1931 err_sys("recvfrom failed");
1932
1933 return sockfd;
1934 }
1935 #endif
1936
udp_accept(SOCKET_T * sockfd,SOCKET_T * clientfd,int useAnyAddr,word16 port,func_args * args)1937 static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
1938 int useAnyAddr, word16 port, func_args* args)
1939 {
1940 SOCKADDR_IN_T addr;
1941
1942 (void)args;
1943 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0);
1944 tcp_socket(sockfd, 1, 0);
1945
1946
1947 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
1948 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1949 {
1950 int res, on = 1;
1951 socklen_t len = sizeof(on);
1952 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
1953 if (res < 0)
1954 err_sys_with_errno("setsockopt SO_REUSEADDR failed\n");
1955 }
1956 #ifdef SO_REUSEPORT
1957 {
1958 int res, on = 1;
1959 socklen_t len = sizeof(on);
1960 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len);
1961 if (res < 0)
1962 err_sys_with_errno("setsockopt SO_REUSEPORT failed\n");
1963 }
1964 #endif
1965 #endif
1966
1967 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1968 err_sys_with_errno("tcp bind failed");
1969
1970 #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
1971 if (port == 0) {
1972 socklen_t len = sizeof(addr);
1973 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
1974 #ifndef TEST_IPV6
1975 port = XNTOHS(addr.sin_port);
1976 #else
1977 port = XNTOHS(addr.sin6_port);
1978 #endif
1979 }
1980 }
1981 #endif
1982
1983 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
1984 /* signal ready to accept data */
1985 {
1986 tcp_ready* ready = args->signal;
1987 pthread_mutex_lock(&ready->mutex);
1988 ready->ready = 1;
1989 ready->port = port;
1990 pthread_cond_signal(&ready->cond);
1991 pthread_mutex_unlock(&ready->mutex);
1992 }
1993 #elif defined (WOLFSSL_TIRTOS)
1994 /* Need mutex? */
1995 tcp_ready* ready = args->signal;
1996 ready->ready = 1;
1997 ready->port = port;
1998 #elif defined(NETOS)
1999 {
2000 tcp_ready* ready = args->signal;
2001 (void)tx_mutex_get(&ready->mutex, TX_WAIT_FOREVER);
2002 ready->ready = 1;
2003 ready->port = port;
2004 (void)tx_mutex_put(&ready->mutex);
2005 }
2006 #else
2007 (void)port;
2008 #endif
2009
2010 *clientfd = *sockfd;
2011 }
2012
tcp_accept(SOCKET_T * sockfd,SOCKET_T * clientfd,func_args * args,word16 port,int useAnyAddr,int udp,int sctp,int ready_file,int do_listen,SOCKADDR_IN_T * client_addr,socklen_t * client_len)2013 static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
2014 func_args* args, word16 port, int useAnyAddr,
2015 int udp, int sctp, int ready_file, int do_listen,
2016 SOCKADDR_IN_T *client_addr, socklen_t *client_len)
2017 {
2018 tcp_ready* ready = NULL;
2019
2020 (void) ready; /* Account for case when "ready" is not used */
2021
2022 if (udp) {
2023 udp_accept(sockfd, clientfd, useAnyAddr, port, args);
2024 return;
2025 }
2026
2027 if(do_listen) {
2028 tcp_listen(sockfd, &port, useAnyAddr, udp, sctp);
2029
2030 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
2031 /* signal ready to tcp_accept */
2032 if (args)
2033 ready = args->signal;
2034 if (ready) {
2035 pthread_mutex_lock(&ready->mutex);
2036 ready->ready = 1;
2037 ready->port = port;
2038 pthread_cond_signal(&ready->cond);
2039 pthread_mutex_unlock(&ready->mutex);
2040 }
2041 #elif defined (WOLFSSL_TIRTOS)
2042 /* Need mutex? */
2043 if (args)
2044 ready = args->signal;
2045 if (ready) {
2046 ready->ready = 1;
2047 ready->port = port;
2048 }
2049 #elif defined(NETOS)
2050 /* signal ready to tcp_accept */
2051 if (args)
2052 ready = args->signal;
2053 if (ready) {
2054 (void)tx_mutex_get(&ready->mutex, TX_WAIT_FOREVER);
2055 ready->ready = 1;
2056 ready->port = port;
2057 (void)tx_mutex_put(&ready->mutex);
2058 }
2059 #endif
2060
2061 if (ready_file) {
2062 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) && \
2063 !defined(NETOS)
2064 XFILE srf = NULL;
2065 if (args)
2066 ready = args->signal;
2067
2068 if (ready) {
2069 srf = XFOPEN(ready->srfName, "w");
2070
2071 if (srf) {
2072 /* let's write port sever is listening on to ready file
2073 external monitor can then do ephemeral ports by passing
2074 -p 0 to server on supported platforms with -R ready_file
2075 client can then wait for existence of ready_file and see
2076 which port the server is listening on. */
2077 fprintf(srf, "%d\n", (int)port);
2078 fclose(srf);
2079 }
2080 }
2081 #endif
2082 }
2083 }
2084
2085 *clientfd = accept(*sockfd, (struct sockaddr*)client_addr,
2086 (ACCEPT_THIRD_T)client_len);
2087 if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
2088 err_sys_with_errno("tcp accept failed");
2089 }
2090 }
2091
2092
tcp_set_nonblocking(SOCKET_T * sockfd)2093 static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
2094 {
2095 #ifdef USE_WINDOWS_API
2096 unsigned long blocking = 1;
2097 int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
2098 if (ret == SOCKET_ERROR)
2099 err_sys_with_errno("ioctlsocket failed");
2100 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
2101 || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \
2102 || defined(WOLFSSL_ZEPHYR)
2103 /* non blocking not supported, for now */
2104 #else
2105 int flags = fcntl(*sockfd, F_GETFL, 0);
2106 if (flags < 0)
2107 err_sys_with_errno("fcntl get failed");
2108 flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
2109 if (flags < 0)
2110 err_sys_with_errno("fcntl set failed");
2111 #endif
2112 }
2113
2114
2115 #ifndef NO_PSK
2116
2117 /* identity is OpenSSL testing default for openssl s_client, keep same */
2118 static const char* kIdentityStr = "Client_identity";
2119
my_psk_client_cb(WOLFSSL * ssl,const char * hint,char * identity,unsigned int id_max_len,unsigned char * key,unsigned int key_max_len)2120 static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
2121 char* identity, unsigned int id_max_len, unsigned char* key,
2122 unsigned int key_max_len)
2123 {
2124 (void)ssl;
2125 (void)hint;
2126 (void)key_max_len;
2127
2128 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
2129 XSTRNCPY(identity, kIdentityStr, id_max_len);
2130
2131 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
2132 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
2133 unsigned binary */
2134 key[0] = 0x1a;
2135 key[1] = 0x2b;
2136 key[2] = 0x3c;
2137 key[3] = 0x4d;
2138
2139 return 4; /* length of key in octets or 0 for error */
2140 }
2141 else {
2142 int i;
2143 int b = 0x01;
2144
2145 for (i = 0; i < 32; i++, b += 0x22) {
2146 if (b >= 0x100)
2147 b = 0x01;
2148 key[i] = b;
2149 }
2150
2151 return 32; /* length of key in octets or 0 for error */
2152 }
2153 }
2154
2155
my_psk_server_cb(WOLFSSL * ssl,const char * identity,unsigned char * key,unsigned int key_max_len)2156 static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
2157 unsigned char* key, unsigned int key_max_len)
2158 {
2159 (void)ssl;
2160 (void)key_max_len;
2161
2162 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
2163 if (XSTRNCMP(identity, kIdentityStr, XSTRLEN(kIdentityStr)) != 0)
2164 return 0;
2165
2166 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
2167 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
2168 unsigned binary */
2169 key[0] = 0x1a;
2170 key[1] = 0x2b;
2171 key[2] = 0x3c;
2172 key[3] = 0x4d;
2173
2174 return 4; /* length of key in octets or 0 for error */
2175 }
2176 else {
2177 int i;
2178 int b = 0x01;
2179
2180 for (i = 0; i < 32; i++, b += 0x22) {
2181 if (b >= 0x100)
2182 b = 0x01;
2183 key[i] = b;
2184 }
2185
2186 return 32; /* length of key in octets or 0 for error */
2187 }
2188 }
2189
2190 #ifdef WOLFSSL_TLS13
my_psk_client_tls13_cb(WOLFSSL * ssl,const char * hint,char * identity,unsigned int id_max_len,unsigned char * key,unsigned int key_max_len,const char ** ciphersuite)2191 static WC_INLINE unsigned int my_psk_client_tls13_cb(WOLFSSL* ssl,
2192 const char* hint, char* identity, unsigned int id_max_len,
2193 unsigned char* key, unsigned int key_max_len, const char** ciphersuite)
2194 {
2195 int i;
2196 int b = 0x01;
2197 const char* userCipher = (const char*)wolfSSL_get_psk_callback_ctx(ssl);
2198
2199 (void)ssl;
2200 (void)hint;
2201 (void)key_max_len;
2202
2203 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
2204 XSTRNCPY(identity, kIdentityStr, id_max_len);
2205
2206 for (i = 0; i < 32; i++, b += 0x22) {
2207 if (b >= 0x100)
2208 b = 0x01;
2209 key[i] = b;
2210 }
2211
2212 *ciphersuite = userCipher ? userCipher : "TLS13-AES128-GCM-SHA256";
2213
2214 return 32; /* length of key in octets or 0 for error */
2215 }
2216
2217
my_psk_server_tls13_cb(WOLFSSL * ssl,const char * identity,unsigned char * key,unsigned int key_max_len,const char ** ciphersuite)2218 static WC_INLINE unsigned int my_psk_server_tls13_cb(WOLFSSL* ssl,
2219 const char* identity, unsigned char* key, unsigned int key_max_len,
2220 const char** ciphersuite)
2221 {
2222 int i;
2223 int b = 0x01;
2224 int kIdLen = (int)XSTRLEN(kIdentityStr);
2225 const char* userCipher = (const char*)wolfSSL_get_psk_callback_ctx(ssl);
2226
2227 (void)ssl;
2228 (void)key_max_len;
2229
2230 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
2231 if (XSTRNCMP(identity, kIdentityStr, kIdLen) != 0)
2232 return 0;
2233 if (identity[kIdLen] != '\0') {
2234 userCipher = wolfSSL_get_cipher_name_by_hash(ssl, identity + kIdLen);
2235 }
2236
2237 for (i = 0; i < 32; i++, b += 0x22) {
2238 if (b >= 0x100)
2239 b = 0x01;
2240 key[i] = b;
2241 }
2242
2243 *ciphersuite = userCipher ? userCipher : "TLS13-AES128-GCM-SHA256";
2244
2245 return 32; /* length of key in octets or 0 for error */
2246 }
2247 #endif
2248
2249 #if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
2250 !defined(NO_FILESYSTEM)
2251 static unsigned char local_psk[32];
2252 #endif
my_psk_use_session_cb(WOLFSSL * ssl,const WOLFSSL_EVP_MD * md,const unsigned char ** id,size_t * idlen,WOLFSSL_SESSION ** sess)2253 static WC_INLINE int my_psk_use_session_cb(WOLFSSL* ssl,
2254 const WOLFSSL_EVP_MD* md, const unsigned char **id,
2255 size_t* idlen, WOLFSSL_SESSION **sess)
2256 {
2257 #if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
2258 !defined(NO_FILESYSTEM)
2259 int i;
2260 int b = 0x01;
2261 WOLFSSL_SESSION* lsess;
2262 char buf[256];
2263 const char* cipher_id = "TLS13-AES128-GCM-SHA256";
2264 const SSL_CIPHER* cipher = NULL;
2265 STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
2266 int numCiphers = 0;
2267 (void)ssl;
2268 (void)md;
2269
2270 printf("use psk session callback \n");
2271
2272 lsess = SSL_SESSION_new();
2273 if (lsess == NULL) {
2274 return 0;
2275 }
2276 supportedCiphers = SSL_get_ciphers(ssl);
2277 numCiphers = sk_num(supportedCiphers);
2278
2279 for (i = 0; i < numCiphers; ++i) {
2280
2281 if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
2282 SSL_CIPHER_description(cipher, buf, sizeof(buf));
2283 }
2284
2285 if (XMEMCMP(cipher_id, buf, XSTRLEN(cipher_id)) == 0) {
2286 break;
2287 }
2288 }
2289
2290 if (i != numCiphers) {
2291 SSL_SESSION_set_cipher(lsess, cipher);
2292 for (i = 0; i < 32; i++, b += 0x22) {
2293 if (b >= 0x100)
2294 b = 0x01;
2295 local_psk[i] = b;
2296 }
2297
2298 *id = local_psk;
2299 *idlen = 32;
2300 *sess = lsess;
2301
2302 return 1;
2303 }
2304 else {
2305 *id = NULL;
2306 *idlen = 0;
2307 *sess = NULL;
2308 SSL_SESSION_free(lsess);
2309 return 0;
2310 }
2311 #else
2312 (void)ssl;
2313 (void)md;
2314 (void)id;
2315 (void)idlen;
2316 (void)sess;
2317
2318 return 0;
2319 #endif
2320 }
2321
my_psk_client_cs_cb(WOLFSSL * ssl,const char * hint,char * identity,unsigned int id_max_len,unsigned char * key,unsigned int key_max_len,const char * ciphersuite)2322 static WC_INLINE unsigned int my_psk_client_cs_cb(WOLFSSL* ssl,
2323 const char* hint, char* identity, unsigned int id_max_len,
2324 unsigned char* key, unsigned int key_max_len, const char* ciphersuite)
2325 {
2326 int i;
2327 int b = 0x01;
2328
2329 (void)ssl;
2330 (void)hint;
2331 (void)key_max_len;
2332
2333 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
2334 XSTRNCPY(identity, kIdentityStr, id_max_len);
2335 XSTRNCAT(identity, ciphersuite + XSTRLEN(ciphersuite) - 6, id_max_len);
2336
2337 for (i = 0; i < 32; i++, b += 0x22) {
2338 if (b >= 0x100)
2339 b = 0x01;
2340 key[i] = b;
2341 }
2342
2343 return 32; /* length of key in octets or 0 for error */
2344 }
2345
2346 #endif /* !NO_PSK */
2347
2348
2349 #if defined(WOLFSSL_USER_CURRTIME)
2350 extern double current_time(int reset);
2351
2352 #elif defined(USE_WINDOWS_API)
2353
2354 #define WIN32_LEAN_AND_MEAN
2355 #include <windows.h>
2356
current_time(int reset)2357 static WC_INLINE double current_time(int reset)
2358 {
2359 static int init = 0;
2360 static LARGE_INTEGER freq;
2361
2362 LARGE_INTEGER count;
2363
2364 if (!init) {
2365 QueryPerformanceFrequency(&freq);
2366 init = 1;
2367 }
2368
2369 QueryPerformanceCounter(&count);
2370
2371 (void)reset;
2372 return (double)count.QuadPart / freq.QuadPart;
2373 }
2374
2375 #elif defined(WOLFSSL_TIRTOS)
2376 extern double current_time();
2377 #elif defined(WOLFSSL_ZEPHYR)
2378 extern double current_time();
2379 #else
2380
2381 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS)
2382 #ifndef NETOS
2383 #include <sys/time.h>
2384 #endif
2385
current_time(int reset)2386 static WC_INLINE double current_time(int reset)
2387 {
2388 struct timeval tv;
2389 gettimeofday(&tv, NULL);
2390 (void)reset;
2391
2392 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
2393 }
2394 #else
2395 extern double current_time(int reset);
2396 #endif
2397 #endif /* USE_WINDOWS_API */
2398
2399
2400 #if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP)
OCSPIOCb(void * ioCtx,const char * url,int urlSz,unsigned char * request,int requestSz,unsigned char ** response)2401 static WC_INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz,
2402 unsigned char* request, int requestSz, unsigned char** response)
2403 {
2404 #ifdef TEST_NONBLOCK_CERTS
2405 static int ioCbCnt = 0;
2406 #endif
2407
2408 (void)ioCtx;
2409 (void)url;
2410 (void)urlSz;
2411 (void)request;
2412 (void)requestSz;
2413 (void)response;
2414
2415 #ifdef TEST_NONBLOCK_CERTS
2416 if (ioCbCnt) {
2417 ioCbCnt = 0;
2418 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
2419 }
2420 else {
2421 ioCbCnt = 1;
2422 return WOLFSSL_CBIO_ERR_WANT_READ;
2423 }
2424 #else
2425 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
2426 #endif
2427 }
2428
OCSPRespFreeCb(void * ioCtx,unsigned char * response)2429 static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response)
2430 {
2431 return EmbedOcspRespFree(ioCtx, response);
2432 }
2433 #endif
2434
2435 #if !defined(NO_CERTS)
2436 #if !defined(NO_FILESYSTEM) || \
2437 (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST)) && \
2438 !defined(NETOS)
2439
2440 /* reads file size, allocates buffer, reads into buffer, returns buffer */
load_file(const char * fname,byte ** buf,size_t * bufLen)2441 static WC_INLINE int load_file(const char* fname, byte** buf, size_t* bufLen)
2442 {
2443 int ret;
2444 long int fileSz;
2445 XFILE lFile;
2446
2447 if (fname == NULL || buf == NULL || bufLen == NULL)
2448 return BAD_FUNC_ARG;
2449
2450 /* set defaults */
2451 *buf = NULL;
2452 *bufLen = 0;
2453
2454 /* open file (read-only binary) */
2455 lFile = XFOPEN(fname, "rb");
2456 if (!lFile) {
2457 printf("Error loading %s\n", fname);
2458 return BAD_PATH_ERROR;
2459 }
2460
2461 fseek(lFile, 0, SEEK_END);
2462 fileSz = (int)ftell(lFile);
2463 rewind(lFile);
2464 if (fileSz > 0) {
2465 *bufLen = (size_t)fileSz;
2466 *buf = (byte*)malloc(*bufLen);
2467 if (*buf == NULL) {
2468 ret = MEMORY_E;
2469 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen);
2470 }
2471 else {
2472 size_t readLen = fread(*buf, *bufLen, 1, lFile);
2473
2474 /* check response code */
2475 ret = (readLen > 0) ? 0 : -1;
2476 }
2477 }
2478 else {
2479 ret = BUFFER_E;
2480 }
2481 fclose(lFile);
2482
2483 return ret;
2484 }
2485
2486 enum {
2487 WOLFSSL_CA = 1,
2488 WOLFSSL_CERT = 2,
2489 WOLFSSL_KEY = 3,
2490 WOLFSSL_CERT_CHAIN = 4,
2491 };
2492
load_buffer(WOLFSSL_CTX * ctx,const char * fname,int type)2493 static WC_INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
2494 {
2495 int format = WOLFSSL_FILETYPE_PEM;
2496 byte* buff = NULL;
2497 size_t sz = 0;
2498
2499 if (load_file(fname, &buff, &sz) != 0) {
2500 err_sys("can't open file for buffer load "
2501 "Please run from wolfSSL home directory if not");
2502 }
2503
2504 /* determine format */
2505 if (strstr(fname, ".der"))
2506 format = WOLFSSL_FILETYPE_ASN1;
2507
2508 if (type == WOLFSSL_CA) {
2509 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
2510 != WOLFSSL_SUCCESS)
2511 err_sys("can't load buffer ca file");
2512 }
2513 else if (type == WOLFSSL_CERT) {
2514 if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz,
2515 format) != WOLFSSL_SUCCESS)
2516 err_sys("can't load buffer cert file");
2517 }
2518 else if (type == WOLFSSL_KEY) {
2519 if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz,
2520 format) != WOLFSSL_SUCCESS)
2521 err_sys("can't load buffer key file");
2522 }
2523 else if (type == WOLFSSL_CERT_CHAIN) {
2524 if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff,
2525 (long)sz, format) != WOLFSSL_SUCCESS)
2526 err_sys("can't load cert chain buffer");
2527 }
2528
2529 if (buff)
2530 free(buff);
2531 }
2532
load_ssl_buffer(WOLFSSL * ssl,const char * fname,int type)2533 static WC_INLINE void load_ssl_buffer(WOLFSSL* ssl, const char* fname, int type)
2534 {
2535 int format = WOLFSSL_FILETYPE_PEM;
2536 byte* buff = NULL;
2537 size_t sz = 0;
2538
2539 if (load_file(fname, &buff, &sz) != 0) {
2540 err_sys("can't open file for buffer load "
2541 "Please run from wolfSSL home directory if not");
2542 }
2543
2544 /* determine format */
2545 if (strstr(fname, ".der"))
2546 format = WOLFSSL_FILETYPE_ASN1;
2547
2548 if (type == WOLFSSL_CA) {
2549 /* verify certs (CA's) use the shared ctx->cm (WOLFSSL_CERT_MANAGER) */
2550 WOLFSSL_CTX* ctx = wolfSSL_get_SSL_CTX(ssl);
2551 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
2552 != WOLFSSL_SUCCESS)
2553 err_sys("can't load buffer ca file");
2554 }
2555 else if (type == WOLFSSL_CERT) {
2556 if (wolfSSL_use_certificate_buffer(ssl, buff, (long)sz,
2557 format) != WOLFSSL_SUCCESS)
2558 err_sys("can't load buffer cert file");
2559 }
2560 else if (type == WOLFSSL_KEY) {
2561 if (wolfSSL_use_PrivateKey_buffer(ssl, buff, (long)sz,
2562 format) != WOLFSSL_SUCCESS)
2563 err_sys("can't load buffer key file");
2564 }
2565 else if (type == WOLFSSL_CERT_CHAIN) {
2566 if (wolfSSL_use_certificate_chain_buffer_format(ssl, buff,
2567 (long)sz, format) != WOLFSSL_SUCCESS)
2568 err_sys("can't load cert chain buffer");
2569 }
2570
2571 if (buff)
2572 free(buff);
2573 }
2574
2575 #ifdef TEST_PK_PRIVKEY
load_key_file(const char * fname,byte ** derBuf,word32 * derLen)2576 static WC_INLINE int load_key_file(const char* fname, byte** derBuf, word32* derLen)
2577 {
2578 int ret;
2579 byte* buf = NULL;
2580 size_t bufLen;
2581
2582 ret = load_file(fname, &buf, &bufLen);
2583 if (ret != 0)
2584 return ret;
2585
2586 *derBuf = (byte*)malloc(bufLen);
2587 if (*derBuf == NULL) {
2588 free(buf);
2589 return MEMORY_E;
2590 }
2591
2592 ret = wc_KeyPemToDer(buf, (word32)bufLen, *derBuf, (word32)bufLen, NULL);
2593 if (ret < 0) {
2594 free(buf);
2595 free(*derBuf);
2596 return ret;
2597 }
2598 *derLen = ret;
2599 free(buf);
2600
2601 return 0;
2602 }
2603 #endif /* TEST_PK_PRIVKEY */
2604
2605 #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */
2606 #endif /* !NO_CERTS */
2607
2608 enum {
2609 VERIFY_OVERRIDE_ERROR,
2610 VERIFY_FORCE_FAIL,
2611 VERIFY_USE_PREVERFIY,
2612 VERIFY_OVERRIDE_DATE_ERR,
2613 };
2614 static THREAD_LS_T int myVerifyAction = VERIFY_OVERRIDE_ERROR;
2615
2616 /* The verify callback is called for every certificate only when
2617 * --enable-opensslextra is defined because it sets WOLFSSL_ALWAYS_VERIFY_CB and
2618 * WOLFSSL_VERIFY_CB_ALL_CERTS.
2619 * Normal cases of the verify callback only occur on certificate failures when the
2620 * wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, myVerifyCb); is called
2621 */
2622
myVerify(int preverify,WOLFSSL_X509_STORE_CTX * store)2623 static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
2624 {
2625 char buffer[WOLFSSL_MAX_ERROR_SZ];
2626 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2627 WOLFSSL_X509* peer;
2628 #if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
2629 WOLFSSL_BIO* bio = NULL;
2630 WOLFSSL_STACK* sk = NULL;
2631 X509* x509 = NULL;
2632 int i = 0;
2633 #endif
2634 #endif
2635 (void)preverify;
2636
2637 /* Verify Callback Arguments:
2638 * preverify: 1=Verify Okay, 0=Failure
2639 * store->error: Failure error code (0 indicates no failure)
2640 * store->current_cert: Current WOLFSSL_X509 object (only with OPENSSL_EXTRA)
2641 * store->error_depth: Current Index
2642 * store->domain: Subject CN as string (null term)
2643 * store->totalCerts: Number of certs presented by peer
2644 * store->certs[i]: A `WOLFSSL_BUFFER_INFO` with plain DER for each cert
2645 * store->store: WOLFSSL_X509_STORE with CA cert chain
2646 * store->store->cm: WOLFSSL_CERT_MANAGER
2647 * store->ex_data: The WOLFSSL object pointer
2648 * store->discardSessionCerts: When set to non-zero value session certs
2649 will be discarded (only with SESSION_CERTS)
2650 */
2651
2652 printf("In verification callback, error = %d, %s\n", store->error,
2653 wolfSSL_ERR_error_string(store->error, buffer));
2654 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2655 peer = store->current_cert;
2656 if (peer) {
2657 char* issuer = wolfSSL_X509_NAME_oneline(
2658 wolfSSL_X509_get_issuer_name(peer), 0, 0);
2659 char* subject = wolfSSL_X509_NAME_oneline(
2660 wolfSSL_X509_get_subject_name(peer), 0, 0);
2661 printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer,
2662 subject);
2663 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
2664 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
2665 #if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
2666 /* avoid printing duplicate certs */
2667 if (store->depth == 1) {
2668 /* retrieve x509 certs and display them on stdout */
2669 sk = wolfSSL_X509_STORE_GetCerts(store);
2670
2671 for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
2672 x509 = wolfSSL_sk_X509_value(sk, i);
2673 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
2674 if (bio != NULL) {
2675 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
2676 wolfSSL_X509_print(bio, x509);
2677 wolfSSL_BIO_free(bio);
2678 }
2679 }
2680 wolfSSL_sk_X509_free(sk);
2681 }
2682 #endif
2683 }
2684 else
2685 printf("\tPeer has no cert!\n");
2686 #else
2687 printf("\tPeer certs: %d\n", store->totalCerts);
2688 #ifdef SHOW_CERTS
2689 { int i;
2690 for (i=0; i<store->totalCerts; i++) {
2691 WOLFSSL_BUFFER_INFO* cert = &store->certs[i];
2692 printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length);
2693 }
2694 }
2695 #endif /* SHOW_CERTS */
2696 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
2697
2698 printf("\tSubject's domain name at %d is %s\n", store->error_depth, store->domain);
2699
2700 /* Testing forced fail case by return zero */
2701 if (myVerifyAction == VERIFY_FORCE_FAIL) {
2702 return 0; /* test failure case */
2703 }
2704
2705 if (myVerifyAction == VERIFY_OVERRIDE_DATE_ERR &&
2706 (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E)) {
2707 printf("Overriding cert date error as example for bad clock testing\n");
2708 return 1;
2709 }
2710
2711 /* If error indicate we are overriding it for testing purposes */
2712 if (store->error != 0 && myVerifyAction == VERIFY_OVERRIDE_ERROR) {
2713 printf("\tAllowing failed certificate check, testing only "
2714 "(shouldn't do this in production)\n");
2715 }
2716
2717 /* A non-zero return code indicates failure override */
2718 return (myVerifyAction == VERIFY_OVERRIDE_ERROR) ? 1 : preverify;
2719 }
2720
2721
2722 #ifdef HAVE_EXT_CACHE
2723
mySessGetCb(WOLFSSL * ssl,const unsigned char * id,int id_len,int * copy)2724 static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl,
2725 const unsigned char* id, int id_len, int* copy)
2726 {
2727 (void)ssl;
2728 (void)id;
2729 (void)id_len;
2730 (void)copy;
2731
2732 /* using internal cache, this is for testing only */
2733 return NULL;
2734 }
2735
mySessNewCb(WOLFSSL * ssl,WOLFSSL_SESSION * session)2736 static WC_INLINE int mySessNewCb(WOLFSSL* ssl, WOLFSSL_SESSION* session)
2737 {
2738 (void)ssl;
2739 (void)session;
2740
2741 /* using internal cache, this is for testing only */
2742 return 0;
2743 }
2744
mySessRemCb(WOLFSSL_CTX * ctx,WOLFSSL_SESSION * session)2745 static WC_INLINE void mySessRemCb(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
2746 {
2747 (void)ctx;
2748 (void)session;
2749
2750 /* using internal cache, this is for testing only */
2751 }
2752
2753 #endif /* HAVE_EXT_CACHE */
2754
2755
2756 #ifdef HAVE_CRL
2757
CRL_CallBack(const char * url)2758 static WC_INLINE void CRL_CallBack(const char* url)
2759 {
2760 printf("CRL callback url = %s\n", url);
2761 }
2762
2763 #endif
2764
2765 #ifndef NO_DH
SetDH(WOLFSSL * ssl)2766 static WC_INLINE void SetDH(WOLFSSL* ssl)
2767 {
2768 /* dh1024 p */
2769 static const unsigned char p[] =
2770 {
2771 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
2772 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
2773 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
2774 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
2775 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
2776 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
2777 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
2778 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
2779 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
2780 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
2781 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
2782 };
2783
2784 /* dh1024 g */
2785 static const unsigned char g[] =
2786 {
2787 0x02,
2788 };
2789
2790 wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
2791 }
2792
SetDHCtx(WOLFSSL_CTX * ctx)2793 static WC_INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
2794 {
2795 /* dh1024 p */
2796 static const unsigned char p[] =
2797 {
2798 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
2799 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
2800 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
2801 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
2802 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
2803 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
2804 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
2805 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
2806 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
2807 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
2808 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
2809 };
2810
2811 /* dh1024 g */
2812 static const unsigned char g[] =
2813 {
2814 0x02,
2815 };
2816
2817 wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
2818 }
2819 #endif /* NO_DH */
2820
2821 #ifndef NO_CERTS
2822
CaCb(unsigned char * der,int sz,int type)2823 static WC_INLINE void CaCb(unsigned char* der, int sz, int type)
2824 {
2825 (void)der;
2826 printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
2827 }
2828
2829 #endif /* !NO_CERTS */
2830
2831
2832 /* Wolf Root Directory Helper */
2833 /* KEIL-RL File System does not support relative directory */
2834 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS)
2835 /* Maximum depth to search for WolfSSL root */
2836 #define MAX_WOLF_ROOT_DEPTH 5
2837
ChangeToWolfRoot(void)2838 static WC_INLINE int ChangeToWolfRoot(void)
2839 {
2840 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) && \
2841 !defined(NETOS)
2842 int depth, res;
2843 XFILE keyFile;
2844 for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
2845 keyFile = XFOPEN(dhParamFile, "rb");
2846 if (keyFile != NULL) {
2847 fclose(keyFile);
2848 return depth;
2849 }
2850 #ifdef USE_WINDOWS_API
2851 res = SetCurrentDirectoryA("..\\");
2852 #elif defined(NETOS)
2853 return 0;
2854 #else
2855 res = chdir("../");
2856 #endif
2857 if (res < 0) {
2858 printf("chdir to ../ failed!\n");
2859 break;
2860 }
2861 }
2862
2863 err_sys("wolf root not found");
2864 return -1;
2865 #else
2866 return 0;
2867 #endif
2868 }
2869 #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */
2870
2871 #ifdef HAVE_STACK_SIZE
2872
2873 typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
2874 #define STACK_CHECK_VAL 0x01
2875
2876 struct stack_size_debug_context {
2877 unsigned char *myStack;
2878 size_t stackSize;
2879 #ifdef HAVE_STACK_SIZE_VERBOSE
2880 size_t *stackSizeHWM_ptr;
2881 thread_func fn;
2882 void *args;
2883 #endif
2884 };
2885
2886 #ifdef HAVE_STACK_SIZE_VERBOSE
2887
2888 /* per-subtest stack high water mark tracking.
2889 *
2890 * enable with
2891 *
2892 * ./configure --enable-stacksize=verbose [...]
2893 */
2894
debug_stack_size_verbose_shim(struct stack_size_debug_context * shim_args)2895 static THREAD_RETURN debug_stack_size_verbose_shim(struct stack_size_debug_context *shim_args) {
2896 StackSizeCheck_myStack = shim_args->myStack;
2897 StackSizeCheck_stackSize = shim_args->stackSize;
2898 StackSizeCheck_stackSizeHWM_ptr = shim_args->stackSizeHWM_ptr;
2899 return shim_args->fn(shim_args->args);
2900 }
2901
StackSizeSetOffset(const char * funcname,void * p)2902 static WC_INLINE int StackSizeSetOffset(const char *funcname, void *p)
2903 {
2904 if (StackSizeCheck_myStack == NULL)
2905 return -BAD_FUNC_ARG;
2906
2907 StackSizeCheck_stackOffsetPointer = p;
2908
2909 printf("setting stack relative offset reference mark in %s to +%lu\n",
2910 funcname, (unsigned long)((char*)(StackSizeCheck_myStack +
2911 StackSizeCheck_stackSize) - (char *)p));
2912
2913 return 0;
2914 }
2915
StackSizeHWM(void)2916 static WC_INLINE ssize_t StackSizeHWM(void)
2917 {
2918 size_t i;
2919 ssize_t used;
2920
2921 if (StackSizeCheck_myStack == NULL)
2922 return -BAD_FUNC_ARG;
2923
2924 for (i = 0; i < StackSizeCheck_stackSize; i++) {
2925 if (StackSizeCheck_myStack[i] != STACK_CHECK_VAL) {
2926 break;
2927 }
2928 }
2929
2930 used = StackSizeCheck_stackSize - i;
2931 if ((ssize_t)*StackSizeCheck_stackSizeHWM_ptr < used)
2932 *StackSizeCheck_stackSizeHWM_ptr = used;
2933
2934 return used;
2935 }
2936
StackSizeHWM_OffsetCorrected(void)2937 static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void)
2938 {
2939 ssize_t used = StackSizeHWM();
2940 if (used < 0)
2941 return used;
2942 if (StackSizeCheck_stackOffsetPointer)
2943 used -= (ssize_t)(((char *)StackSizeCheck_myStack + StackSizeCheck_stackSize) - (char *)StackSizeCheck_stackOffsetPointer);
2944 return used;
2945 }
2946
2947 static
2948 #ifdef __GNUC__
2949 __attribute__((unused)) __attribute__((noinline))
2950 #endif
StackSizeHWMReset(void)2951 int StackSizeHWMReset(void)
2952 {
2953 volatile ssize_t i;
2954
2955 if (StackSizeCheck_myStack == NULL)
2956 return -BAD_FUNC_ARG;
2957
2958 for (i = (ssize_t)((char *)&i - (char *)StackSizeCheck_myStack) - (ssize_t)sizeof i - 1; i >= 0; --i)
2959 {
2960 StackSizeCheck_myStack[i] = STACK_CHECK_VAL;
2961 }
2962
2963 return 0;
2964 }
2965
2966 #define STACK_SIZE_CHECKPOINT(...) ({ \
2967 ssize_t HWM = StackSizeHWM_OffsetCorrected(); \
2968 __VA_ARGS__; \
2969 printf(" relative stack peak usage = %ld bytes\n", HWM); \
2970 StackSizeHWMReset(); \
2971 })
2972
2973 #define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) ({ \
2974 ssize_t HWM = StackSizeHWM_OffsetCorrected(); \
2975 int _ret; \
2976 __VA_ARGS__; \
2977 printf(" relative stack peak usage = %ld bytes\n", HWM); \
2978 _ret = StackSizeHWMReset(); \
2979 if ((max >= 0) && (HWM > (ssize_t)(max))) { \
2980 printf(" relative stack usage at %s L%d exceeds designated max %ld bytes.\n", __FILE__, __LINE__, (ssize_t)(max)); \
2981 _ret = -1; \
2982 } \
2983 _ret; \
2984 })
2985
2986
2987 #ifdef __GNUC__
2988 #define STACK_SIZE_INIT() (void)StackSizeSetOffset(__FUNCTION__, __builtin_frame_address(0))
2989 #endif
2990
2991 #endif /* HAVE_STACK_SIZE_VERBOSE */
2992
StackSizeCheck(func_args * args,thread_func tf)2993 static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
2994 {
2995 size_t i;
2996 int ret;
2997 void* status;
2998 unsigned char* myStack = NULL;
2999 size_t stackSize = 1024*1024;
3000 pthread_attr_t myAttr;
3001 pthread_t threadId;
3002 #ifdef HAVE_STACK_SIZE_VERBOSE
3003 struct stack_size_debug_context shim_args;
3004 #endif
3005
3006 #ifdef PTHREAD_STACK_MIN
3007 if (stackSize < PTHREAD_STACK_MIN)
3008 stackSize = PTHREAD_STACK_MIN;
3009 #endif
3010
3011 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
3012 if (ret != 0 || myStack == NULL)
3013 err_sys_with_errno("posix_memalign failed\n");
3014
3015 XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
3016
3017 ret = pthread_attr_init(&myAttr);
3018 if (ret != 0)
3019 err_sys("attr_init failed");
3020
3021 ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
3022 if (ret != 0)
3023 err_sys("attr_setstackaddr failed");
3024
3025 #ifdef HAVE_STACK_SIZE_VERBOSE
3026 StackSizeCheck_stackSizeHWM = 0;
3027 shim_args.myStack = myStack;
3028 shim_args.stackSize = stackSize;
3029 shim_args.stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
3030 shim_args.fn = tf;
3031 shim_args.args = args;
3032 ret = pthread_create(&threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)&shim_args);
3033 #else
3034 ret = pthread_create(&threadId, &myAttr, tf, args);
3035 #endif
3036 if (ret != 0) {
3037 perror("pthread_create failed");
3038 exit(EXIT_FAILURE);
3039 }
3040
3041 ret = pthread_join(threadId, &status);
3042 if (ret != 0)
3043 err_sys("pthread_join failed");
3044
3045 for (i = 0; i < stackSize; i++) {
3046 if (myStack[i] != STACK_CHECK_VAL) {
3047 break;
3048 }
3049 }
3050
3051 free(myStack);
3052 #ifdef HAVE_STACK_SIZE_VERBOSE
3053 printf("stack used = %lu\n", StackSizeCheck_stackSizeHWM > (stackSize - i)
3054 ? (unsigned long)StackSizeCheck_stackSizeHWM
3055 : (unsigned long)(stackSize - i));
3056 #else
3057 {
3058 size_t used = stackSize - i;
3059 printf("stack used = %lu\n", (unsigned long)used);
3060 }
3061 #endif
3062
3063 return (int)((size_t)status);
3064 }
3065
StackSizeCheck_launch(func_args * args,thread_func tf,pthread_t * threadId,void ** stack_context)3066 static WC_INLINE int StackSizeCheck_launch(func_args* args, thread_func tf, pthread_t *threadId, void **stack_context)
3067 {
3068 int ret;
3069 unsigned char* myStack = NULL;
3070 size_t stackSize = 1024*1024;
3071 pthread_attr_t myAttr;
3072
3073 #ifdef PTHREAD_STACK_MIN
3074 if (stackSize < PTHREAD_STACK_MIN)
3075 stackSize = PTHREAD_STACK_MIN;
3076 #endif
3077
3078 struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)malloc(sizeof *shim_args);
3079 if (! shim_args) {
3080 perror("malloc");
3081 exit(EXIT_FAILURE);
3082 }
3083
3084 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
3085 if (ret != 0 || myStack == NULL)
3086 err_sys_with_errno("posix_memalign failed\n");
3087
3088 XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
3089
3090 ret = pthread_attr_init(&myAttr);
3091 if (ret != 0)
3092 err_sys("attr_init failed");
3093
3094 ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
3095 if (ret != 0)
3096 err_sys("attr_setstackaddr failed");
3097
3098 shim_args->myStack = myStack;
3099 shim_args->stackSize = stackSize;
3100 #ifdef HAVE_STACK_SIZE_VERBOSE
3101 shim_args->stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
3102 shim_args->fn = tf;
3103 shim_args->args = args;
3104 ret = pthread_create(threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)shim_args);
3105 #else
3106 ret = pthread_create(threadId, &myAttr, tf, args);
3107 #endif
3108 if (ret != 0) {
3109 fprintf(stderr,"pthread_create failed: %s",strerror(ret));
3110 exit(EXIT_FAILURE);
3111 }
3112
3113 *stack_context = (void *)shim_args;
3114
3115 return 0;
3116 }
3117
StackSizeCheck_reap(pthread_t threadId,void * stack_context)3118 static WC_INLINE int StackSizeCheck_reap(pthread_t threadId, void *stack_context)
3119 {
3120 struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)stack_context;
3121 size_t i;
3122 void *status;
3123 int ret = pthread_join(threadId, &status);
3124 if (ret != 0)
3125 err_sys("pthread_join failed");
3126
3127 for (i = 0; i < shim_args->stackSize; i++) {
3128 if (shim_args->myStack[i] != STACK_CHECK_VAL) {
3129 break;
3130 }
3131 }
3132
3133 free(shim_args->myStack);
3134 #ifdef HAVE_STACK_SIZE_VERBOSE
3135 printf("stack used = %lu\n",
3136 *shim_args->stackSizeHWM_ptr > (shim_args->stackSize - i)
3137 ? (unsigned long)*shim_args->stackSizeHWM_ptr
3138 : (unsigned long)(shim_args->stackSize - i));
3139 #else
3140 {
3141 size_t used = shim_args->stackSize - i;
3142 printf("stack used = %lu\n", (unsigned long)used);
3143 }
3144 #endif
3145 free(shim_args);
3146
3147 return (int)((size_t)status);
3148 }
3149
3150
3151 #endif /* HAVE_STACK_SIZE */
3152
3153 #ifndef STACK_SIZE_CHECKPOINT
3154 #define STACK_SIZE_CHECKPOINT(...) (__VA_ARGS__)
3155 #endif
3156 #ifndef STACK_SIZE_INIT
3157 #define STACK_SIZE_INIT()
3158 #endif
3159
3160 #ifdef STACK_TRAP
3161
3162 /* good settings
3163 --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
3164
3165 */
3166
3167 #ifdef HAVE_STACK_SIZE
3168 /* client only for now, setrlimit will fail if pthread_create() called */
3169 /* STACK_SIZE does pthread_create() on client */
3170 #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
3171 #endif /* HAVE_STACK_SIZE */
3172
StackTrap(void)3173 static WC_INLINE void StackTrap(void)
3174 {
3175 struct rlimit rl;
3176 if (getrlimit(RLIMIT_STACK, &rl) != 0)
3177 err_sys_with_errno("getrlimit failed");
3178 printf("rlim_cur = %llu\n", rl.rlim_cur);
3179 rl.rlim_cur = 1024*21; /* adjust trap size here */
3180 if (setrlimit(RLIMIT_STACK, &rl) != 0)
3181 err_sys_with_errno("setrlimit failed");
3182 }
3183
3184 #else /* STACK_TRAP */
3185
StackTrap(void)3186 static WC_INLINE void StackTrap(void)
3187 {
3188 }
3189
3190 #endif /* STACK_TRAP */
3191
3192
3193 #if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
3194
3195 /* Atomic Encrypt Context example */
3196 typedef struct AtomicEncCtx {
3197 int keySetup; /* have we done key setup yet */
3198 Aes aes; /* for aes example */
3199 } AtomicEncCtx;
3200
3201
3202 /* Atomic Decrypt Context example */
3203 typedef struct AtomicDecCtx {
3204 int keySetup; /* have we done key setup yet */
3205 Aes aes; /* for aes example */
3206 } AtomicDecCtx;
3207
3208 #if !defined(NO_HMAC) && !defined(NO_AES) && defined(HAVE_AES_CBC)
myMacEncryptCb(WOLFSSL * ssl,unsigned char * macOut,const unsigned char * macIn,unsigned int macInSz,int macContent,int macVerify,unsigned char * encOut,const unsigned char * encIn,unsigned int encSz,void * ctx)3209 static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut,
3210 const unsigned char* macIn, unsigned int macInSz, int macContent,
3211 int macVerify, unsigned char* encOut, const unsigned char* encIn,
3212 unsigned int encSz, void* ctx)
3213 {
3214 int ret;
3215 Hmac hmac;
3216 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
3217 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
3218 const char* tlsStr = "TLS";
3219
3220 /* example supports (d)tls aes */
3221 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
3222 printf("myMacEncryptCb not using AES\n");
3223 return -1;
3224 }
3225
3226 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
3227 printf("myMacEncryptCb not using (D)TLS\n");
3228 return -1;
3229 }
3230
3231 /* hmac, not needed if aead mode */
3232 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
3233
3234 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
3235 if (ret != 0)
3236 return ret;
3237 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
3238 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
3239 if (ret != 0)
3240 return ret;
3241 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
3242 if (ret != 0)
3243 return ret;
3244 ret = wc_HmacUpdate(&hmac, macIn, macInSz);
3245 if (ret != 0)
3246 return ret;
3247 ret = wc_HmacFinal(&hmac, macOut);
3248 if (ret != 0)
3249 return ret;
3250
3251
3252 /* encrypt setup on first time */
3253 if (encCtx->keySetup == 0) {
3254 int keyLen = wolfSSL_GetKeySize(ssl);
3255 const byte* key;
3256 const byte* iv;
3257
3258 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
3259 key = wolfSSL_GetClientWriteKey(ssl);
3260 iv = wolfSSL_GetClientWriteIV(ssl);
3261 }
3262 else {
3263 key = wolfSSL_GetServerWriteKey(ssl);
3264 iv = wolfSSL_GetServerWriteIV(ssl);
3265 }
3266
3267 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
3268 if (ret != 0) {
3269 printf("AesSetKey failed in myMacEncryptCb\n");
3270 return ret;
3271 }
3272 encCtx->keySetup = 1;
3273 }
3274
3275 /* encrypt */
3276 return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
3277 }
3278
myDecryptVerifyCb(WOLFSSL * ssl,unsigned char * decOut,const unsigned char * decIn,unsigned int decSz,int macContent,int macVerify,unsigned int * padSz,void * ctx)3279 static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl,
3280 unsigned char* decOut, const unsigned char* decIn,
3281 unsigned int decSz, int macContent, int macVerify,
3282 unsigned int* padSz, void* ctx)
3283 {
3284 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
3285 int ret = 0;
3286 int macInSz = 0;
3287 int ivExtra = 0;
3288 int digestSz = wolfSSL_GetHmacSize(ssl);
3289 unsigned int pad = 0;
3290 unsigned int padByte = 0;
3291 Hmac hmac;
3292 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
3293 byte verify[WC_MAX_DIGEST_SIZE];
3294 const char* tlsStr = "TLS";
3295
3296 /* example supports (d)tls aes */
3297 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
3298 printf("myMacEncryptCb not using AES\n");
3299 return -1;
3300 }
3301
3302 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
3303 printf("myMacEncryptCb not using (D)TLS\n");
3304 return -1;
3305 }
3306
3307 /*decrypt */
3308 if (decCtx->keySetup == 0) {
3309 int keyLen = wolfSSL_GetKeySize(ssl);
3310 const byte* key;
3311 const byte* iv;
3312
3313 /* decrypt is from other side (peer) */
3314 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
3315 key = wolfSSL_GetClientWriteKey(ssl);
3316 iv = wolfSSL_GetClientWriteIV(ssl);
3317 }
3318 else {
3319 key = wolfSSL_GetServerWriteKey(ssl);
3320 iv = wolfSSL_GetServerWriteIV(ssl);
3321 }
3322
3323 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
3324 if (ret != 0) {
3325 printf("AesSetKey failed in myDecryptVerifyCb\n");
3326 return ret;
3327 }
3328 decCtx->keySetup = 1;
3329 }
3330
3331 /* decrypt */
3332 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
3333 if (ret != 0)
3334 return ret;
3335
3336 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
3337 *padSz = wolfSSL_GetAeadMacSize(ssl);
3338 return 0; /* hmac, not needed if aead mode */
3339 }
3340
3341 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
3342 pad = *(decOut + decSz - 1);
3343 padByte = 1;
3344 if (wolfSSL_IsTLSv1_1(ssl))
3345 ivExtra = wolfSSL_GetCipherBlockSize(ssl);
3346 }
3347
3348 *padSz = wolfSSL_GetHmacSize(ssl) + pad + padByte;
3349 macInSz = decSz - ivExtra - digestSz - pad - padByte;
3350
3351 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
3352
3353 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
3354 if (ret != 0)
3355 return ret;
3356 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
3357 wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
3358 if (ret != 0)
3359 return ret;
3360 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
3361 if (ret != 0)
3362 return ret;
3363 ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
3364 if (ret != 0)
3365 return ret;
3366 ret = wc_HmacFinal(&hmac, verify);
3367 if (ret != 0)
3368 return ret;
3369
3370 if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte,
3371 digestSz) != 0) {
3372 printf("myDecryptVerify verify failed\n");
3373 return -1;
3374 }
3375
3376 return ret;
3377 }
3378
3379 #ifdef HAVE_ENCRYPT_THEN_MAC
3380
myEncryptMacCb(WOLFSSL * ssl,unsigned char * macOut,int content,int macVerify,unsigned char * encOut,const unsigned char * encIn,unsigned int encSz,void * ctx)3381 static WC_INLINE int myEncryptMacCb(WOLFSSL* ssl, unsigned char* macOut,
3382 int content, int macVerify, unsigned char* encOut,
3383 const unsigned char* encIn, unsigned int encSz, void* ctx)
3384 {
3385 int ret;
3386 Hmac hmac;
3387 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
3388 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
3389 const char* tlsStr = "TLS";
3390
3391 /* example supports (d)tls aes */
3392 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
3393 printf("myMacEncryptCb not using AES\n");
3394 return -1;
3395 }
3396
3397 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
3398 printf("myMacEncryptCb not using (D)TLS\n");
3399 return -1;
3400 }
3401
3402 /* encrypt setup on first time */
3403 if (encCtx->keySetup == 0) {
3404 int keyLen = wolfSSL_GetKeySize(ssl);
3405 const byte* key;
3406 const byte* iv;
3407
3408 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
3409 key = wolfSSL_GetClientWriteKey(ssl);
3410 iv = wolfSSL_GetClientWriteIV(ssl);
3411 }
3412 else {
3413 key = wolfSSL_GetServerWriteKey(ssl);
3414 iv = wolfSSL_GetServerWriteIV(ssl);
3415 }
3416
3417 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
3418 if (ret != 0) {
3419 printf("AesSetKey failed in myMacEncryptCb\n");
3420 return ret;
3421 }
3422 encCtx->keySetup = 1;
3423 }
3424
3425 /* encrypt */
3426 ret = wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
3427 if (ret != 0)
3428 return ret;
3429
3430 /* Reconstruct record header. */
3431 wolfSSL_SetTlsHmacInner(ssl, myInner, encSz, content, macVerify);
3432
3433 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
3434 if (ret != 0)
3435 return ret;
3436 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
3437 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
3438 if (ret != 0)
3439 return ret;
3440 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
3441 if (ret != 0)
3442 return ret;
3443 ret = wc_HmacUpdate(&hmac, encOut, encSz);
3444 if (ret != 0)
3445 return ret;
3446 return wc_HmacFinal(&hmac, macOut);
3447 }
3448
3449
myVerifyDecryptCb(WOLFSSL * ssl,unsigned char * decOut,const unsigned char * decIn,unsigned int decSz,int content,int macVerify,unsigned int * padSz,void * ctx)3450 static WC_INLINE int myVerifyDecryptCb(WOLFSSL* ssl,
3451 unsigned char* decOut, const unsigned char* decIn,
3452 unsigned int decSz, int content, int macVerify,
3453 unsigned int* padSz, void* ctx)
3454 {
3455 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
3456 int ret = 0;
3457 int digestSz = wolfSSL_GetHmacSize(ssl);
3458 Hmac hmac;
3459 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
3460 byte verify[WC_MAX_DIGEST_SIZE];
3461 const char* tlsStr = "TLS";
3462
3463 /* example supports (d)tls aes */
3464 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
3465 printf("myMacEncryptCb not using AES\n");
3466 return -1;
3467 }
3468
3469 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
3470 printf("myMacEncryptCb not using (D)TLS\n");
3471 return -1;
3472 }
3473
3474 /* Reconstruct record header. */
3475 wolfSSL_SetTlsHmacInner(ssl, myInner, decSz, content, macVerify);
3476
3477 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
3478 if (ret != 0)
3479 return ret;
3480 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
3481 wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
3482 if (ret != 0)
3483 return ret;
3484 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
3485 if (ret != 0)
3486 return ret;
3487 ret = wc_HmacUpdate(&hmac, decIn, decSz);
3488 if (ret != 0)
3489 return ret;
3490 ret = wc_HmacFinal(&hmac, verify);
3491 if (ret != 0)
3492 return ret;
3493
3494 if (XMEMCMP(verify, decOut + decSz, digestSz) != 0) {
3495 printf("myDecryptVerify verify failed\n");
3496 return -1;
3497 }
3498
3499 /* decrypt */
3500 if (decCtx->keySetup == 0) {
3501 int keyLen = wolfSSL_GetKeySize(ssl);
3502 const byte* key;
3503 const byte* iv;
3504
3505 /* decrypt is from other side (peer) */
3506 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
3507 key = wolfSSL_GetClientWriteKey(ssl);
3508 iv = wolfSSL_GetClientWriteIV(ssl);
3509 }
3510 else {
3511 key = wolfSSL_GetServerWriteKey(ssl);
3512 iv = wolfSSL_GetServerWriteIV(ssl);
3513 }
3514
3515 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
3516 if (ret != 0) {
3517 printf("AesSetKey failed in myDecryptVerifyCb\n");
3518 return ret;
3519 }
3520 decCtx->keySetup = 1;
3521 }
3522
3523 /* decrypt */
3524 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
3525 if (ret != 0)
3526 return ret;
3527
3528 *padSz = *(decOut + decSz - 1) + 1;
3529
3530 return 0;
3531 }
3532
3533 #endif /* HAVE_ENCRYPT_THEN_MAC */
3534 #endif /* !NO_HMAC && !NO_AES && HAVE_AES_CBC */
3535
3536
SetupAtomicUser(WOLFSSL_CTX * ctx,WOLFSSL * ssl)3537 static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
3538 {
3539 AtomicEncCtx* encCtx;
3540 AtomicDecCtx* decCtx;
3541
3542 encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
3543 if (encCtx == NULL)
3544 err_sys_with_errno("AtomicEncCtx malloc failed");
3545 XMEMSET(encCtx, 0, sizeof(AtomicEncCtx));
3546
3547 decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
3548 if (decCtx == NULL) {
3549 free(encCtx);
3550 err_sys_with_errno("AtomicDecCtx malloc failed");
3551 }
3552 XMEMSET(decCtx, 0, sizeof(AtomicDecCtx));
3553
3554 #if !defined(NO_HMAC) && !defined(NO_AES) && defined(HAVE_AES_CBC)
3555 wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
3556 wolfSSL_SetMacEncryptCtx(ssl, encCtx);
3557
3558 wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
3559 wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
3560
3561 #ifdef HAVE_ENCRYPT_THEN_MAC
3562 wolfSSL_CTX_SetEncryptMacCb(ctx, myEncryptMacCb);
3563 wolfSSL_SetEncryptMacCtx(ssl, encCtx);
3564
3565 wolfSSL_CTX_SetVerifyDecryptCb(ctx, myVerifyDecryptCb);
3566 wolfSSL_SetVerifyDecryptCtx(ssl, decCtx);
3567 #endif
3568 #else
3569 (void)ctx;
3570 (void)ssl;
3571 #endif
3572 }
3573
3574
FreeAtomicUser(WOLFSSL * ssl)3575 static WC_INLINE void FreeAtomicUser(WOLFSSL* ssl)
3576 {
3577 AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
3578 AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
3579
3580 /* Encrypt-Then-MAC callbacks use same contexts. */
3581
3582 free(decCtx);
3583 free(encCtx);
3584 }
3585
3586 #endif /* ATOMIC_USER */
3587
3588 #ifdef WOLFSSL_STATIC_MEMORY
wolfSSL_PrintStats(WOLFSSL_MEM_STATS * stats)3589 static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats)
3590 {
3591 word16 i;
3592
3593 if (stats == NULL) {
3594 return 0;
3595 }
3596
3597 /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */
3598 fprintf(stderr, "Total mallocs = %d\n", stats->totalAlloc);
3599 fprintf(stderr, "Total frees = %d\n", stats->totalFr);
3600 fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc);
3601 fprintf(stderr, "Available IO = %d\n", stats->avaIO);
3602 fprintf(stderr, "Max con. handshakes = %d\n", stats->maxHa);
3603 fprintf(stderr, "Max con. IO = %d\n", stats->maxIO);
3604 fprintf(stderr, "State of memory blocks: size : available \n");
3605 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
3606 fprintf(stderr, " : %d\t : %d\n", stats->blockSz[i],
3607 stats->avaBlock[i]);
3608 }
3609
3610 return 1;
3611 }
3612
wolfSSL_PrintStatsConn(WOLFSSL_MEM_CONN_STATS * stats)3613 static WC_INLINE int wolfSSL_PrintStatsConn(WOLFSSL_MEM_CONN_STATS* stats)
3614 {
3615 if (stats == NULL) {
3616 return 0;
3617 }
3618
3619 fprintf(stderr, "peak connection memory = %d\n", stats->peakMem);
3620 fprintf(stderr, "current memory in use = %d\n", stats->curMem);
3621 fprintf(stderr, "peak connection allocs = %d\n", stats->peakAlloc);
3622 fprintf(stderr, "current connection allocs = %d\n",stats->curAlloc);
3623 fprintf(stderr, "total connection allocs = %d\n", stats->totalAlloc);
3624 fprintf(stderr, "total connection frees = %d\n\n", stats->totalFr);
3625
3626 return 1;
3627 }
3628 #endif /* WOLFSSL_STATIC_MEMORY */
3629
3630 #ifdef HAVE_PK_CALLBACKS
3631
3632 typedef struct PkCbInfo {
3633 const char* ourKey;
3634 #ifdef TEST_PK_PRIVKEY
3635 union {
3636 #ifdef HAVE_ECC
3637 ecc_key ecc;
3638 #endif
3639 #ifdef HAVE_CURVE25519
3640 curve25519_key curve;
3641 #endif
3642 #ifdef HAVE_CURVE448
3643 curve448_key curve;
3644 #endif
3645 } keyGen;
3646 int hasKeyGen;
3647 #endif
3648 } PkCbInfo;
3649
3650 #if defined(DEBUG_PK_CB) || defined(TEST_PK_PRIVKEY)
3651 #define WOLFSSL_PKMSG(...) printf(__VA_ARGS__)
3652 #else
3653 #define WOLFSSL_PKMSG(...)
3654 #endif
3655
3656 #ifdef HAVE_ECC
3657
myEccKeyGen(WOLFSSL * ssl,ecc_key * key,word32 keySz,int ecc_curve,void * ctx)3658 static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz,
3659 int ecc_curve, void* ctx)
3660 {
3661 int ret;
3662 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3663 ecc_key* new_key;
3664
3665 #ifdef TEST_PK_PRIVKEY
3666 new_key = cbInfo ? &cbInfo->keyGen.ecc : key;
3667 #else
3668 new_key = key;
3669 #endif
3670
3671 (void)ssl;
3672 (void)cbInfo;
3673
3674 WOLFSSL_PKMSG("PK ECC KeyGen: keySz %d, Curve ID %d\n", keySz, ecc_curve);
3675
3676 ret = wc_ecc_init(new_key);
3677 if (ret == 0) {
3678 WC_RNG *rng = wolfSSL_GetRNG(ssl);
3679
3680 /* create new key */
3681 ret = wc_ecc_make_key_ex(rng, keySz, new_key, ecc_curve);
3682
3683 #ifdef TEST_PK_PRIVKEY
3684 if (ret == 0 && new_key != key) {
3685 byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES];
3686 word32 qxLen = sizeof(qx), qyLen = sizeof(qy);
3687
3688 /* extract public portion from new key into `key` arg */
3689 ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen);
3690 if (ret == 0) {
3691 /* load public portion only into key */
3692 ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ecc_curve);
3693 }
3694 (void)qxLen;
3695 (void)qyLen;
3696 }
3697 if (ret == 0 && cbInfo != NULL) {
3698 cbInfo->hasKeyGen = 1;
3699 }
3700 #endif
3701 }
3702
3703 WOLFSSL_PKMSG("PK ECC KeyGen: ret %d\n", ret);
3704
3705 return ret;
3706 }
3707
myEccSign(WOLFSSL * ssl,const byte * in,word32 inSz,byte * out,word32 * outSz,const byte * key,word32 keySz,void * ctx)3708 static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
3709 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
3710 {
3711 int ret;
3712 word32 idx = 0;
3713 ecc_key myKey;
3714 byte* keyBuf = (byte*)key;
3715 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3716
3717 (void)ssl;
3718 (void)cbInfo;
3719
3720 WOLFSSL_PKMSG("PK ECC Sign: inSz %d, keySz %d\n", inSz, keySz);
3721
3722 #ifdef TEST_PK_PRIVKEY
3723 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3724 if (ret != 0)
3725 return ret;
3726 #endif
3727
3728 ret = wc_ecc_init(&myKey);
3729 if (ret == 0) {
3730 ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3731 if (ret == 0) {
3732 WC_RNG *rng = wolfSSL_GetRNG(ssl);
3733
3734 WOLFSSL_PKMSG("PK ECC Sign: Curve ID %d\n", myKey.dp->id);
3735 ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng, &myKey);
3736 }
3737 wc_ecc_free(&myKey);
3738 }
3739
3740 #ifdef TEST_PK_PRIVKEY
3741 free(keyBuf);
3742 #endif
3743
3744 WOLFSSL_PKMSG("PK ECC Sign: ret %d outSz %d\n", ret, *outSz);
3745
3746 return ret;
3747 }
3748
3749
myEccVerify(WOLFSSL * ssl,const byte * sig,word32 sigSz,const byte * hash,word32 hashSz,const byte * key,word32 keySz,int * result,void * ctx)3750 static WC_INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
3751 const byte* hash, word32 hashSz, const byte* key, word32 keySz,
3752 int* result, void* ctx)
3753 {
3754 int ret;
3755 word32 idx = 0;
3756 ecc_key myKey;
3757 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3758
3759 (void)ssl;
3760 (void)cbInfo;
3761
3762 WOLFSSL_PKMSG("PK ECC Verify: sigSz %d, hashSz %d, keySz %d\n", sigSz, hashSz, keySz);
3763
3764 ret = wc_ecc_init(&myKey);
3765 if (ret == 0) {
3766 ret = wc_EccPublicKeyDecode(key, &idx, &myKey, keySz);
3767 if (ret == 0)
3768 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
3769 wc_ecc_free(&myKey);
3770 }
3771
3772 WOLFSSL_PKMSG("PK ECC Verify: ret %d, result %d\n", ret, *result);
3773
3774 return ret;
3775 }
3776
myEccSharedSecret(WOLFSSL * ssl,ecc_key * otherKey,unsigned char * pubKeyDer,unsigned int * pubKeySz,unsigned char * out,unsigned int * outlen,int side,void * ctx)3777 static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
3778 unsigned char* pubKeyDer, unsigned int* pubKeySz,
3779 unsigned char* out, unsigned int* outlen,
3780 int side, void* ctx)
3781 {
3782 int ret;
3783 ecc_key* privKey = NULL;
3784 ecc_key* pubKey = NULL;
3785 ecc_key tmpKey;
3786 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3787
3788 (void)ssl;
3789 (void)cbInfo;
3790
3791 WOLFSSL_PKMSG("PK ECC PMS: Side %s, Peer Curve %d\n",
3792 side == WOLFSSL_CLIENT_END ? "client" : "server", otherKey->dp->id);
3793
3794 ret = wc_ecc_init(&tmpKey);
3795 if (ret != 0) {
3796 return ret;
3797 }
3798
3799 /* for client: create and export public key */
3800 if (side == WOLFSSL_CLIENT_END) {
3801 #ifdef TEST_PK_PRIVKEY
3802 privKey = cbInfo ? &cbInfo->keyGen.ecc : &tmpKey;
3803 #else
3804 privKey = &tmpKey;
3805 #endif
3806 pubKey = otherKey;
3807
3808 /* TLS v1.2 and older we must generate a key here for the client ony.
3809 * TLS v1.3 calls key gen early with key share */
3810 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
3811 ret = myEccKeyGen(ssl, privKey, 0, otherKey->dp->id, ctx);
3812 if (ret == 0) {
3813 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
3814 }
3815 }
3816 }
3817
3818 /* for server: import public key */
3819 else if (side == WOLFSSL_SERVER_END) {
3820 #ifdef TEST_PK_PRIVKEY
3821 privKey = cbInfo ? &cbInfo->keyGen.ecc : otherKey;
3822 #else
3823 privKey = otherKey;
3824 #endif
3825 pubKey = &tmpKey;
3826
3827 ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey,
3828 otherKey->dp->id);
3829 }
3830 else {
3831 ret = BAD_FUNC_ARG;
3832 }
3833
3834 if (privKey == NULL || pubKey == NULL) {
3835 ret = BAD_FUNC_ARG;
3836 }
3837
3838 #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_FIPS) && \
3839 !defined(HAVE_SELFTEST)
3840 if (ret == 0) {
3841 ret = wc_ecc_set_rng(privKey, wolfSSL_GetRNG(ssl));
3842 }
3843 #endif
3844
3845 /* generate shared secret and return it */
3846 if (ret == 0) {
3847 ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
3848
3849 #ifdef WOLFSSL_ASYNC_CRYPT
3850 if (ret == WC_PENDING_E) {
3851 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
3852 }
3853 #endif
3854 }
3855
3856 #ifdef TEST_PK_PRIVKEY
3857 if (cbInfo && cbInfo->hasKeyGen) {
3858 wc_ecc_free(&cbInfo->keyGen.ecc);
3859 cbInfo->hasKeyGen = 0;
3860 }
3861 #endif
3862
3863 wc_ecc_free(&tmpKey);
3864
3865 WOLFSSL_PKMSG("PK ECC PMS: ret %d, PubKeySz %d, OutLen %d\n", ret, *pubKeySz, *outlen);
3866
3867 return ret;
3868 }
3869
3870 #endif /* HAVE_ECC */
3871
3872 #ifdef HAVE_HKDF
myHkdfExtract(byte * prk,const byte * salt,word32 saltLen,byte * ikm,word32 ikmLen,int digest,void * ctx)3873 static WC_INLINE int myHkdfExtract(byte* prk, const byte* salt, word32 saltLen,
3874 byte* ikm, word32 ikmLen, int digest, void* ctx)
3875 {
3876 int ret;
3877 int len = 0;
3878
3879 switch (digest) {
3880 #ifndef NO_SHA256
3881 case WC_SHA256:
3882 len = WC_SHA256_DIGEST_SIZE;
3883 break;
3884 #endif
3885
3886 #ifdef WOLFSSL_SHA384
3887 case WC_SHA384:
3888 len = WC_SHA384_DIGEST_SIZE;
3889 break;
3890 #endif
3891
3892 #ifdef WOLFSSL_TLS13_SHA512
3893 case WC_SHA512:
3894 len = WC_SHA512_DIGEST_SIZE;
3895 break;
3896 #endif
3897 default:
3898 return BAD_FUNC_ARG;
3899 }
3900
3901 /* When length is 0 then use zeroed data of digest length. */
3902 if (ikmLen == 0) {
3903 ikmLen = len;
3904 XMEMSET(ikm, 0, len);
3905 }
3906
3907 (void)ctx;
3908 ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
3909 WOLFSSL_PKMSG("PK HKDF Extract: ret %d saltLen %d ikmLen %d\n", ret, saltLen,
3910 ikmLen);
3911 return ret;
3912 }
3913 #endif /* HAVE_HKDF */
3914
3915 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
3916 #ifdef HAVE_ED25519_SIGN
myEd25519Sign(WOLFSSL * ssl,const byte * in,word32 inSz,byte * out,word32 * outSz,const byte * key,word32 keySz,void * ctx)3917 static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
3918 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
3919 {
3920 int ret;
3921 word32 idx = 0;
3922 ed25519_key myKey;
3923 byte* keyBuf = (byte*)key;
3924 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3925
3926 (void)ssl;
3927 (void)cbInfo;
3928
3929 WOLFSSL_PKMSG("PK 25519 Sign: inSz %d, keySz %d\n", inSz, keySz);
3930
3931 #ifdef TEST_PK_PRIVKEY
3932 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3933 if (ret != 0)
3934 return ret;
3935 #endif
3936
3937 ret = wc_ed25519_init(&myKey);
3938 if (ret == 0) {
3939 ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3940 if (ret == 0)
3941 ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey);
3942 wc_ed25519_free(&myKey);
3943 }
3944
3945 #ifdef TEST_PK_PRIVKEY
3946 free(keyBuf);
3947 #endif
3948
3949 WOLFSSL_PKMSG("PK 25519 Sign: ret %d, outSz %d\n", ret, *outSz);
3950
3951 return ret;
3952 }
3953 #endif /* HAVE_ED25519_SIGN */
3954
3955
3956 #ifdef HAVE_ED25519_VERIFY
myEd25519Verify(WOLFSSL * ssl,const byte * sig,word32 sigSz,const byte * msg,word32 msgSz,const byte * key,word32 keySz,int * result,void * ctx)3957 static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
3958 const byte* msg, word32 msgSz, const byte* key, word32 keySz,
3959 int* result, void* ctx)
3960 {
3961 int ret;
3962 ed25519_key myKey;
3963 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3964
3965 (void)ssl;
3966 (void)cbInfo;
3967
3968 WOLFSSL_PKMSG("PK 25519 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz, keySz);
3969
3970 ret = wc_ed25519_init(&myKey);
3971 if (ret == 0) {
3972 ret = wc_ed25519_import_public(key, keySz, &myKey);
3973 if (ret == 0) {
3974 ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
3975 }
3976 wc_ed25519_free(&myKey);
3977 }
3978
3979 WOLFSSL_PKMSG("PK 25519 Verify: ret %d, result %d\n", ret, *result);
3980
3981 return ret;
3982 }
3983 #endif /* HAVE_ED25519_VERIFY */
3984 #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
3985
3986 #ifdef HAVE_CURVE25519
myX25519KeyGen(WOLFSSL * ssl,curve25519_key * key,unsigned int keySz,void * ctx)3987 static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key,
3988 unsigned int keySz, void* ctx)
3989 {
3990 int ret;
3991 WC_RNG rng;
3992 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3993
3994 (void)ssl;
3995 (void)cbInfo;
3996
3997 WOLFSSL_PKMSG("PK 25519 KeyGen: keySz %d\n", keySz);
3998
3999 ret = wc_InitRng(&rng);
4000 if (ret != 0)
4001 return ret;
4002
4003 ret = wc_curve25519_make_key(&rng, keySz, key);
4004
4005 wc_FreeRng(&rng);
4006
4007 WOLFSSL_PKMSG("PK 25519 KeyGen: ret %d\n", ret);
4008
4009 return ret;
4010 }
4011
myX25519SharedSecret(WOLFSSL * ssl,curve25519_key * otherKey,unsigned char * pubKeyDer,unsigned int * pubKeySz,unsigned char * out,unsigned int * outlen,int side,void * ctx)4012 static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey,
4013 unsigned char* pubKeyDer, unsigned int* pubKeySz,
4014 unsigned char* out, unsigned int* outlen,
4015 int side, void* ctx)
4016 {
4017 int ret;
4018 curve25519_key* privKey = NULL;
4019 curve25519_key* pubKey = NULL;
4020 curve25519_key tmpKey;
4021 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4022
4023 (void)ssl;
4024 (void)cbInfo;
4025
4026 WOLFSSL_PKMSG("PK 25519 PMS: side %s\n",
4027 side == WOLFSSL_CLIENT_END ? "client" : "server");
4028
4029 ret = wc_curve25519_init(&tmpKey);
4030 if (ret != 0) {
4031 return ret;
4032 }
4033
4034 /* for client: create and export public key */
4035 if (side == WOLFSSL_CLIENT_END) {
4036 WC_RNG rng;
4037
4038 privKey = &tmpKey;
4039 pubKey = otherKey;
4040
4041 ret = wc_InitRng(&rng);
4042 if (ret == 0) {
4043 ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, privKey);
4044 if (ret == 0) {
4045 ret = wc_curve25519_export_public_ex(privKey, pubKeyDer,
4046 pubKeySz, EC25519_LITTLE_ENDIAN);
4047 }
4048 wc_FreeRng(&rng);
4049 }
4050 }
4051
4052 /* for server: import public key */
4053 else if (side == WOLFSSL_SERVER_END) {
4054 privKey = otherKey;
4055 pubKey = &tmpKey;
4056
4057 ret = wc_curve25519_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
4058 EC25519_LITTLE_ENDIAN);
4059 }
4060 else {
4061 ret = BAD_FUNC_ARG;
4062 }
4063
4064 /* generate shared secret and return it */
4065 if (ret == 0) {
4066 ret = wc_curve25519_shared_secret_ex(privKey, pubKey, out, outlen,
4067 EC25519_LITTLE_ENDIAN);
4068 }
4069
4070 wc_curve25519_free(&tmpKey);
4071
4072 WOLFSSL_PKMSG("PK 25519 PMS: ret %d, pubKeySz %d, outLen %d\n",
4073 ret, *pubKeySz, *outlen);
4074
4075 return ret;
4076 }
4077 #endif /* HAVE_CURVE25519 */
4078
4079 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
4080 #ifdef HAVE_ED448_SIGN
myEd448Sign(WOLFSSL * ssl,const byte * in,word32 inSz,byte * out,word32 * outSz,const byte * key,word32 keySz,void * ctx)4081 static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
4082 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
4083 {
4084 int ret;
4085 word32 idx = 0;
4086 ed448_key myKey;
4087 byte* keyBuf = (byte*)key;
4088 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4089
4090 (void)ssl;
4091 (void)cbInfo;
4092
4093 WOLFSSL_PKMSG("PK 448 Sign: inSz %d, keySz %d\n", inSz, keySz);
4094
4095 #ifdef TEST_PK_PRIVKEY
4096 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
4097 if (ret != 0)
4098 return ret;
4099 #endif
4100
4101 ret = wc_ed448_init(&myKey);
4102 if (ret == 0) {
4103 ret = wc_Ed448PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
4104 if (ret == 0)
4105 ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey, NULL, 0);
4106 wc_ed448_free(&myKey);
4107 }
4108
4109 #ifdef TEST_PK_PRIVKEY
4110 free(keyBuf);
4111 #endif
4112
4113 WOLFSSL_PKMSG("PK 448 Sign: ret %d, outSz %d\n", ret, *outSz);
4114
4115 return ret;
4116 }
4117 #endif /* HAVE_ED448_SIGN */
4118
4119
4120 #ifdef HAVE_ED448_VERIFY
myEd448Verify(WOLFSSL * ssl,const byte * sig,word32 sigSz,const byte * msg,word32 msgSz,const byte * key,word32 keySz,int * result,void * ctx)4121 static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
4122 const byte* msg, word32 msgSz, const byte* key, word32 keySz,
4123 int* result, void* ctx)
4124 {
4125 int ret;
4126 ed448_key myKey;
4127 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4128
4129 (void)ssl;
4130 (void)cbInfo;
4131
4132 WOLFSSL_PKMSG("PK 448 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz,
4133 keySz);
4134
4135 ret = wc_ed448_init(&myKey);
4136 if (ret == 0) {
4137 ret = wc_ed448_import_public(key, keySz, &myKey);
4138 if (ret == 0) {
4139 ret = wc_ed448_verify_msg(sig, sigSz, msg, msgSz, result, &myKey,
4140 NULL, 0);
4141 }
4142 wc_ed448_free(&myKey);
4143 }
4144
4145 WOLFSSL_PKMSG("PK 448 Verify: ret %d, result %d\n", ret, *result);
4146
4147 return ret;
4148 }
4149 #endif /* HAVE_ED448_VERIFY */
4150 #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
4151
4152 #ifdef HAVE_CURVE448
myX448KeyGen(WOLFSSL * ssl,curve448_key * key,unsigned int keySz,void * ctx)4153 static WC_INLINE int myX448KeyGen(WOLFSSL* ssl, curve448_key* key,
4154 unsigned int keySz, void* ctx)
4155 {
4156 int ret;
4157 WC_RNG rng;
4158 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4159
4160 (void)ssl;
4161 (void)cbInfo;
4162
4163 WOLFSSL_PKMSG("PK 448 KeyGen: keySz %d\n", keySz);
4164
4165 ret = wc_InitRng(&rng);
4166 if (ret != 0)
4167 return ret;
4168
4169 ret = wc_curve448_make_key(&rng, keySz, key);
4170
4171 wc_FreeRng(&rng);
4172
4173 WOLFSSL_PKMSG("PK 448 KeyGen: ret %d\n", ret);
4174
4175 return ret;
4176 }
4177
myX448SharedSecret(WOLFSSL * ssl,curve448_key * otherKey,unsigned char * pubKeyDer,unsigned int * pubKeySz,unsigned char * out,unsigned int * outlen,int side,void * ctx)4178 static WC_INLINE int myX448SharedSecret(WOLFSSL* ssl, curve448_key* otherKey,
4179 unsigned char* pubKeyDer, unsigned int* pubKeySz,
4180 unsigned char* out, unsigned int* outlen,
4181 int side, void* ctx)
4182 {
4183 int ret;
4184 curve448_key* privKey = NULL;
4185 curve448_key* pubKey = NULL;
4186 curve448_key tmpKey;
4187 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4188
4189 (void)ssl;
4190 (void)cbInfo;
4191
4192 WOLFSSL_PKMSG("PK 448 PMS: side %s\n",
4193 side == WOLFSSL_CLIENT_END ? "client" : "server");
4194
4195 ret = wc_curve448_init(&tmpKey);
4196 if (ret != 0) {
4197 return ret;
4198 }
4199
4200 /* for client: create and export public key */
4201 if (side == WOLFSSL_CLIENT_END) {
4202 WC_RNG rng;
4203
4204 privKey = &tmpKey;
4205 pubKey = otherKey;
4206
4207 ret = wc_InitRng(&rng);
4208 if (ret == 0) {
4209 ret = wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, privKey);
4210 if (ret == 0) {
4211 ret = wc_curve448_export_public_ex(privKey, pubKeyDer,
4212 pubKeySz, EC448_LITTLE_ENDIAN);
4213 }
4214 wc_FreeRng(&rng);
4215 }
4216 }
4217
4218 /* for server: import public key */
4219 else if (side == WOLFSSL_SERVER_END) {
4220 privKey = otherKey;
4221 pubKey = &tmpKey;
4222
4223 ret = wc_curve448_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
4224 EC448_LITTLE_ENDIAN);
4225 }
4226 else {
4227 ret = BAD_FUNC_ARG;
4228 }
4229
4230 /* generate shared secret and return it */
4231 if (ret == 0) {
4232 ret = wc_curve448_shared_secret_ex(privKey, pubKey, out, outlen,
4233 EC448_LITTLE_ENDIAN);
4234 }
4235
4236 wc_curve448_free(&tmpKey);
4237
4238 WOLFSSL_PKMSG("PK 448 PMS: ret %d, pubKeySz %d, outLen %d\n",
4239 ret, *pubKeySz, *outlen);
4240
4241 return ret;
4242 }
4243 #endif /* HAVE_CURVE448 */
4244
4245 #ifndef NO_DH
myDhCallback(WOLFSSL * ssl,struct DhKey * key,const unsigned char * priv,unsigned int privSz,const unsigned char * pubKeyDer,unsigned int pubKeySz,unsigned char * out,unsigned int * outlen,void * ctx)4246 static WC_INLINE int myDhCallback(WOLFSSL* ssl, struct DhKey* key,
4247 const unsigned char* priv, unsigned int privSz,
4248 const unsigned char* pubKeyDer, unsigned int pubKeySz,
4249 unsigned char* out, unsigned int* outlen,
4250 void* ctx)
4251 {
4252 int ret;
4253 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4254
4255 (void)ssl;
4256 (void)cbInfo;
4257
4258 /* return 0 on success */
4259 ret = wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz);
4260
4261 WOLFSSL_PKMSG("PK ED Agree: ret %d, privSz %d, pubKeySz %d, outlen %d\n",
4262 ret, privSz, pubKeySz, *outlen);
4263
4264 return ret;
4265 }
4266
4267 #endif /* !NO_DH */
4268
4269 #ifndef NO_RSA
4270
myRsaSign(WOLFSSL * ssl,const byte * in,word32 inSz,byte * out,word32 * outSz,const byte * key,word32 keySz,void * ctx)4271 static WC_INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
4272 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
4273 {
4274 WC_RNG rng;
4275 int ret;
4276 word32 idx = 0;
4277 RsaKey myKey;
4278 byte* keyBuf = (byte*)key;
4279 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4280
4281 (void)ssl;
4282 (void)cbInfo;
4283
4284 WOLFSSL_PKMSG("PK RSA Sign: inSz %d, keySz %d\n", inSz, keySz);
4285
4286 #ifdef TEST_PK_PRIVKEY
4287 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
4288 if (ret != 0)
4289 return ret;
4290 #endif
4291
4292 ret = wc_InitRng(&rng);
4293 if (ret != 0)
4294 return ret;
4295
4296 ret = wc_InitRsaKey(&myKey, NULL);
4297 if (ret == 0) {
4298 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
4299 if (ret == 0)
4300 ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
4301 if (ret > 0) { /* save and convert to 0 success */
4302 *outSz = ret;
4303 ret = 0;
4304 }
4305 wc_FreeRsaKey(&myKey);
4306 }
4307 wc_FreeRng(&rng);
4308
4309 #ifdef TEST_PK_PRIVKEY
4310 free(keyBuf);
4311 #endif
4312
4313 WOLFSSL_PKMSG("PK RSA Sign: ret %d, outSz %d\n", ret, *outSz);
4314
4315 return ret;
4316 }
4317
4318
myRsaVerify(WOLFSSL * ssl,byte * sig,word32 sigSz,byte ** out,const byte * key,word32 keySz,void * ctx)4319 static WC_INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
4320 byte** out, const byte* key, word32 keySz, void* ctx)
4321 {
4322 int ret;
4323 word32 idx = 0;
4324 RsaKey myKey;
4325 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4326
4327 (void)ssl;
4328 (void)cbInfo;
4329
4330 WOLFSSL_PKMSG("PK RSA Verify: sigSz %d, keySz %d\n", sigSz, keySz);
4331
4332 ret = wc_InitRsaKey(&myKey, NULL);
4333 if (ret == 0) {
4334 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
4335 if (ret == 0)
4336 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
4337 wc_FreeRsaKey(&myKey);
4338 }
4339
4340 WOLFSSL_PKMSG("PK RSA Verify: ret %d\n", ret);
4341
4342 return ret;
4343 }
4344
myRsaSignCheck(WOLFSSL * ssl,byte * sig,word32 sigSz,byte ** out,const byte * key,word32 keySz,void * ctx)4345 static WC_INLINE int myRsaSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
4346 byte** out, const byte* key, word32 keySz, void* ctx)
4347 {
4348 int ret;
4349 word32 idx = 0;
4350 RsaKey myKey;
4351 byte* keyBuf = (byte*)key;
4352 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4353
4354 (void)ssl;
4355 (void)cbInfo;
4356
4357 WOLFSSL_PKMSG("PK RSA SignCheck: sigSz %d, keySz %d\n", sigSz, keySz);
4358
4359 #ifdef TEST_PK_PRIVKEY
4360 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
4361 if (ret != 0)
4362 return ret;
4363 #endif
4364
4365 ret = wc_InitRsaKey(&myKey, NULL);
4366 if (ret == 0) {
4367 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
4368 if (ret == 0)
4369 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
4370 wc_FreeRsaKey(&myKey);
4371 }
4372 #ifdef TEST_PK_PRIVKEY
4373 free(keyBuf);
4374 #endif
4375
4376 WOLFSSL_PKMSG("PK RSA SignCheck: ret %d\n", ret);
4377
4378 return ret;
4379 }
4380
4381 #ifdef WC_RSA_PSS
myRsaPssSign(WOLFSSL * ssl,const byte * in,word32 inSz,byte * out,word32 * outSz,int hash,int mgf,const byte * key,word32 keySz,void * ctx)4382 static WC_INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
4383 byte* out, word32* outSz, int hash, int mgf, const byte* key,
4384 word32 keySz, void* ctx)
4385 {
4386 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
4387 WC_RNG rng;
4388 int ret;
4389 word32 idx = 0;
4390 RsaKey myKey;
4391 byte* keyBuf = (byte*)key;
4392 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4393
4394 (void)ssl;
4395 (void)cbInfo;
4396
4397 WOLFSSL_PKMSG("PK RSA PSS Sign: inSz %d, hash %d, mgf %d, keySz %d\n",
4398 inSz, hash, mgf, keySz);
4399
4400 #ifdef TEST_PK_PRIVKEY
4401 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
4402 if (ret != 0)
4403 return ret;
4404 #endif
4405
4406 switch (hash) {
4407 #ifndef NO_SHA256
4408 case SHA256h:
4409 hashType = WC_HASH_TYPE_SHA256;
4410 break;
4411 #endif
4412 #ifdef WOLFSSL_SHA384
4413 case SHA384h:
4414 hashType = WC_HASH_TYPE_SHA384;
4415 break;
4416 #endif
4417 #ifdef WOLFSSL_SHA512
4418 case SHA512h:
4419 hashType = WC_HASH_TYPE_SHA512;
4420 break;
4421 #endif
4422 }
4423
4424 ret = wc_InitRng(&rng);
4425 if (ret != 0)
4426 return ret;
4427
4428 ret = wc_InitRsaKey(&myKey, NULL);
4429 if (ret == 0) {
4430 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
4431 if (ret == 0) {
4432 ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey,
4433 &rng);
4434 }
4435 if (ret > 0) { /* save and convert to 0 success */
4436 *outSz = ret;
4437 ret = 0;
4438 }
4439 wc_FreeRsaKey(&myKey);
4440 }
4441 wc_FreeRng(&rng);
4442
4443 #ifdef TEST_PK_PRIVKEY
4444 free(keyBuf);
4445 #endif
4446
4447 WOLFSSL_PKMSG("PK RSA PSS Sign: ret %d, outSz %d\n", ret, *outSz);
4448
4449 return ret;
4450 }
4451
4452
myRsaPssVerify(WOLFSSL * ssl,byte * sig,word32 sigSz,byte ** out,int hash,int mgf,const byte * key,word32 keySz,void * ctx)4453 static WC_INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
4454 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
4455 {
4456 int ret;
4457 word32 idx = 0;
4458 RsaKey myKey;
4459 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4460 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
4461
4462 (void)ssl;
4463 (void)cbInfo;
4464
4465 WOLFSSL_PKMSG("PK RSA PSS Verify: sigSz %d, hash %d, mgf %d, keySz %d\n",
4466 sigSz, hash, mgf, keySz);
4467
4468 switch (hash) {
4469 #ifndef NO_SHA256
4470 case SHA256h:
4471 hashType = WC_HASH_TYPE_SHA256;
4472 break;
4473 #endif
4474 #ifdef WOLFSSL_SHA384
4475 case SHA384h:
4476 hashType = WC_HASH_TYPE_SHA384;
4477 break;
4478 #endif
4479 #ifdef WOLFSSL_SHA512
4480 case SHA512h:
4481 hashType = WC_HASH_TYPE_SHA512;
4482 break;
4483 #endif
4484 }
4485
4486 ret = wc_InitRsaKey(&myKey, NULL);
4487 if (ret == 0) {
4488 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
4489 if (ret == 0) {
4490 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
4491 &myKey);
4492 }
4493 wc_FreeRsaKey(&myKey);
4494 }
4495
4496 WOLFSSL_PKMSG("PK RSA PSS Verify: ret %d\n", ret);
4497
4498 return ret;
4499 }
4500
myRsaPssSignCheck(WOLFSSL * ssl,byte * sig,word32 sigSz,byte ** out,int hash,int mgf,const byte * key,word32 keySz,void * ctx)4501 static WC_INLINE int myRsaPssSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
4502 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
4503 {
4504 int ret;
4505 word32 idx = 0;
4506 RsaKey myKey;
4507 byte* keyBuf = (byte*)key;
4508 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4509 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
4510
4511 (void)ssl;
4512 (void)cbInfo;
4513
4514 WOLFSSL_PKMSG("PK RSA PSS SignCheck: sigSz %d, hash %d, mgf %d, keySz %d\n",
4515 sigSz, hash, mgf, keySz);
4516
4517 #ifdef TEST_PK_PRIVKEY
4518 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
4519 if (ret != 0)
4520 return ret;
4521 #endif
4522
4523 switch (hash) {
4524 #ifndef NO_SHA256
4525 case SHA256h:
4526 hashType = WC_HASH_TYPE_SHA256;
4527 break;
4528 #endif
4529 #ifdef WOLFSSL_SHA384
4530 case SHA384h:
4531 hashType = WC_HASH_TYPE_SHA384;
4532 break;
4533 #endif
4534 #ifdef WOLFSSL_SHA512
4535 case SHA512h:
4536 hashType = WC_HASH_TYPE_SHA512;
4537 break;
4538 #endif
4539 }
4540
4541 ret = wc_InitRsaKey(&myKey, NULL);
4542 if (ret == 0) {
4543 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
4544 if (ret == 0) {
4545 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
4546 &myKey);
4547 }
4548 wc_FreeRsaKey(&myKey);
4549 }
4550
4551 #ifdef TEST_PK_PRIVKEY
4552 free(keyBuf);
4553 #endif
4554
4555 WOLFSSL_PKMSG("PK RSA PSS SignCheck: ret %d\n", ret);
4556
4557 return ret;
4558 }
4559 #endif
4560
4561
myRsaEnc(WOLFSSL * ssl,const byte * in,word32 inSz,byte * out,word32 * outSz,const byte * key,word32 keySz,void * ctx)4562 static WC_INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
4563 byte* out, word32* outSz, const byte* key,
4564 word32 keySz, void* ctx)
4565 {
4566 int ret;
4567 word32 idx = 0;
4568 RsaKey myKey;
4569 WC_RNG rng;
4570 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4571
4572 (void)ssl;
4573 (void)cbInfo;
4574
4575 WOLFSSL_PKMSG("PK RSA Enc: inSz %d, keySz %d\n", inSz, keySz);
4576
4577 ret = wc_InitRng(&rng);
4578 if (ret != 0)
4579 return ret;
4580
4581 ret = wc_InitRsaKey(&myKey, NULL);
4582 if (ret == 0) {
4583 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
4584 if (ret == 0) {
4585 ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
4586 if (ret > 0) {
4587 *outSz = ret;
4588 ret = 0; /* reset to success */
4589 }
4590 }
4591 wc_FreeRsaKey(&myKey);
4592 }
4593 wc_FreeRng(&rng);
4594
4595 WOLFSSL_PKMSG("PK RSA Enc: ret %d, outSz %d\n", ret, *outSz);
4596
4597 return ret;
4598 }
4599
myRsaDec(WOLFSSL * ssl,byte * in,word32 inSz,byte ** out,const byte * key,word32 keySz,void * ctx)4600 static WC_INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
4601 byte** out,
4602 const byte* key, word32 keySz, void* ctx)
4603 {
4604 int ret;
4605 word32 idx = 0;
4606 RsaKey myKey;
4607 byte* keyBuf = (byte*)key;
4608 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4609
4610 (void)ssl;
4611 (void)cbInfo;
4612
4613 WOLFSSL_PKMSG("PK RSA Dec: inSz %d, keySz %d\n", inSz, keySz);
4614
4615 #ifdef TEST_PK_PRIVKEY
4616 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
4617 if (ret != 0)
4618 return ret;
4619 #endif
4620
4621 ret = wc_InitRsaKey(&myKey, NULL);
4622 if (ret == 0) {
4623 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
4624 if (ret == 0) {
4625 #ifdef WC_RSA_BLINDING
4626 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl));
4627 if (ret != 0) {
4628 wc_FreeRsaKey(&myKey);
4629 return ret;
4630 }
4631 #endif
4632 ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
4633 }
4634 wc_FreeRsaKey(&myKey);
4635 }
4636
4637 #ifdef TEST_PK_PRIVKEY
4638 free(keyBuf);
4639 #endif
4640
4641 WOLFSSL_PKMSG("PK RSA Dec: ret %d\n", ret);
4642
4643 return ret;
4644 }
4645
4646 #endif /* NO_RSA */
4647
myGenMaster(WOLFSSL * ssl,void * ctx)4648 static WC_INLINE int myGenMaster(WOLFSSL* ssl, void* ctx)
4649 {
4650 int ret;
4651 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4652
4653 (void)ssl;
4654 (void)cbInfo;
4655
4656 WOLFSSL_PKMSG("Gen Master");
4657 /* fall through to original routine */
4658 ret = PROTOCOLCB_UNAVAILABLE;
4659 WOLFSSL_PKMSG("Gen Master: ret %d\n", ret);
4660
4661 return ret;
4662 }
4663
myGenPreMaster(WOLFSSL * ssl,byte * premaster,word32 preSz,void * ctx)4664 static WC_INLINE int myGenPreMaster(WOLFSSL* ssl, byte *premaster,
4665 word32 preSz, void* ctx)
4666 {
4667 int ret;
4668 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4669
4670 (void) ssl;
4671 (void) cbInfo;
4672 (void) premaster;
4673 (void) preSz;
4674
4675 WOLFSSL_PKMSG("Gen Pre-Master Cb");
4676 /* fall through to original routine */
4677 ret = PROTOCOLCB_UNAVAILABLE;
4678 WOLFSSL_PKMSG("Gen Pre-Master Cb: ret %d\n", ret);
4679
4680 return ret;
4681 }
4682
myGenSessionKey(WOLFSSL * ssl,void * ctx)4683 static WC_INLINE int myGenSessionKey(WOLFSSL* ssl, void* ctx)
4684 {
4685 int ret;
4686 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4687
4688 (void)ssl;
4689 (void)cbInfo;
4690
4691 WOLFSSL_PKMSG("Gen Master Cb");
4692 /* fall through to original routine */
4693 ret = PROTOCOLCB_UNAVAILABLE;
4694 WOLFSSL_PKMSG("Gen Master Cb: ret %d\n", ret);
4695
4696 return ret;
4697 }
4698
mySetEncryptKeys(WOLFSSL * ssl,void * ctx)4699 static WC_INLINE int mySetEncryptKeys(WOLFSSL* ssl, void* ctx)
4700 {
4701 int ret;
4702 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4703
4704 (void)ssl;
4705 (void)cbInfo;
4706
4707 WOLFSSL_PKMSG("Set Encrypt Keys Cb");
4708 /* fall through to original routine */
4709 ret = PROTOCOLCB_UNAVAILABLE;
4710 WOLFSSL_PKMSG("Set Encrypt Keys Cb: ret %d\n", ret);
4711
4712 return ret;
4713 }
4714
4715 #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
myVerifyMac(WOLFSSL * ssl,const byte * message,word32 messageSz,word32 macSz,word32 content,void * ctx)4716 static WC_INLINE int myVerifyMac(WOLFSSL *ssl, const byte* message,
4717 word32 messageSz, word32 macSz, word32 content, void* ctx)
4718 {
4719 int ret;
4720 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4721
4722 (void)ssl;
4723 (void)message;
4724 (void)messageSz;
4725 (void)macSz;
4726 (void)content;
4727 (void)cbInfo;
4728
4729 WOLFSSL_PKMSG("Verify Mac Cb");
4730 /* fall through to original routine */
4731 ret = PROTOCOLCB_UNAVAILABLE;
4732 WOLFSSL_PKMSG("Verify Mac Cb: ret %d\n", ret);
4733
4734 return ret;
4735 }
4736 #endif
4737
myTlsFinished(WOLFSSL * ssl,const byte * side,const byte * handshake_hash,byte * hashes,void * ctx)4738 static WC_INLINE int myTlsFinished(WOLFSSL* ssl,
4739 const byte *side,
4740 const byte *handshake_hash,
4741 byte *hashes, void* ctx)
4742 {
4743 int ret;
4744 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
4745
4746 (void)ssl;
4747 (void)cbInfo;
4748 (void)side;
4749 (void)handshake_hash;
4750 (void)hashes;
4751
4752 WOLFSSL_PKMSG("Tls Finished Cb");
4753 /* fall through to original routine */
4754 ret = PROTOCOLCB_UNAVAILABLE;
4755 WOLFSSL_PKMSG("Tls Finished Cb: ret %d\n", ret);
4756
4757 return ret;
4758 }
4759
SetupPkCallbacks(WOLFSSL_CTX * ctx)4760 static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx)
4761 {
4762 (void)ctx;
4763
4764 #ifdef HAVE_ECC
4765 wolfSSL_CTX_SetEccKeyGenCb(ctx, myEccKeyGen);
4766 wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
4767 wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
4768 wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
4769 #endif /* HAVE_ECC */
4770 #ifdef HAVE_HKDF
4771 wolfSSL_CTX_SetHKDFExtractCb(ctx, myHkdfExtract);
4772 #endif /* HAVE_HKDF */
4773 #ifndef NO_DH
4774 wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback);
4775 #endif
4776 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
4777 #ifdef HAVE_ED25519_SIGN
4778 wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign);
4779 #endif
4780 #ifdef HAVE_ED25519_VERIFY
4781 wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify);
4782 #endif
4783 #endif
4784 #ifdef HAVE_CURVE25519
4785 wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen);
4786 wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
4787 #endif
4788 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
4789 #if defined(HAVE_ED448_SIGN)
4790 wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign);
4791 #endif
4792 #if defined(HAVE_ED448_VERIFY)
4793 wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify);
4794 #endif
4795 #endif
4796 #ifdef HAVE_CURVE448
4797 wolfSSL_CTX_SetX448KeyGenCb(ctx, myX448KeyGen);
4798 wolfSSL_CTX_SetX448SharedSecretCb(ctx, myX448SharedSecret);
4799 #endif
4800 #ifndef NO_RSA
4801 wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
4802 wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
4803 wolfSSL_CTX_SetRsaSignCheckCb(ctx, myRsaSignCheck);
4804 #ifdef WC_RSA_PSS
4805 wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
4806 wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify);
4807 wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, myRsaPssSignCheck);
4808 #endif
4809 wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
4810 wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
4811 #endif /* NO_RSA */
4812
4813 #ifndef NO_CERTS
4814 wolfSSL_CTX_SetGenMasterSecretCb(ctx, myGenMaster);
4815 wolfSSL_CTX_SetGenPreMasterCb(ctx, myGenPreMaster);
4816 wolfSSL_CTX_SetGenSessionKeyCb(ctx, myGenSessionKey);
4817 wolfSSL_CTX_SetEncryptKeysCb(ctx, mySetEncryptKeys);
4818
4819 #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
4820 wolfSSL_CTX_SetVerifyMacCb(ctx, myVerifyMac);
4821 #endif
4822
4823 wolfSSL_CTX_SetTlsFinishedCb(ctx, myTlsFinished);
4824 #endif /* NO_CERTS */
4825 }
4826
SetupPkCallbackContexts(WOLFSSL * ssl,void * myCtx)4827 static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx)
4828 {
4829 #ifdef HAVE_ECC
4830 wolfSSL_SetEccKeyGenCtx(ssl, myCtx);
4831 wolfSSL_SetEccSignCtx(ssl, myCtx);
4832 wolfSSL_SetEccVerifyCtx(ssl, myCtx);
4833 wolfSSL_SetEccSharedSecretCtx(ssl, myCtx);
4834 #endif /* HAVE_ECC */
4835 #ifdef HAVE_HKDF
4836 wolfSSL_SetHKDFExtractCtx(ssl, myCtx);
4837 #endif /* HAVE_HKDF */
4838 #ifndef NO_DH
4839 wolfSSL_SetDhAgreeCtx(ssl, myCtx);
4840 #endif
4841 #ifdef HAVE_ED25519
4842 wolfSSL_SetEd25519SignCtx(ssl, myCtx);
4843 wolfSSL_SetEd25519VerifyCtx(ssl, myCtx);
4844 #endif
4845 #ifdef HAVE_CURVE25519
4846 wolfSSL_SetX25519KeyGenCtx(ssl, myCtx);
4847 wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx);
4848 #endif
4849 #ifdef HAVE_ED448
4850 wolfSSL_SetEd448SignCtx(ssl, myCtx);
4851 wolfSSL_SetEd448VerifyCtx(ssl, myCtx);
4852 #endif
4853 #ifdef HAVE_CURVE448
4854 wolfSSL_SetX448KeyGenCtx(ssl, myCtx);
4855 wolfSSL_SetX448SharedSecretCtx(ssl, myCtx);
4856 #endif
4857 #ifndef NO_RSA
4858 wolfSSL_SetRsaSignCtx(ssl, myCtx);
4859 wolfSSL_SetRsaVerifyCtx(ssl, myCtx);
4860 #ifdef WC_RSA_PSS
4861 wolfSSL_SetRsaPssSignCtx(ssl, myCtx);
4862 wolfSSL_SetRsaPssVerifyCtx(ssl, myCtx);
4863 #endif
4864 wolfSSL_SetRsaEncCtx(ssl, myCtx);
4865 wolfSSL_SetRsaDecCtx(ssl, myCtx);
4866 #endif /* NO_RSA */
4867
4868 #ifndef NO_CERTS
4869 wolfSSL_SetGenMasterSecretCtx(ssl, myCtx);
4870 wolfSSL_SetGenPreMasterCtx(ssl, myCtx);
4871 wolfSSL_SetGenSessionKeyCtx(ssl, myCtx);
4872 wolfSSL_SetEncryptKeysCtx(ssl, myCtx);
4873
4874 #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
4875 wolfSSL_SetVerifyMacCtx(ssl, myCtx);
4876 #endif
4877
4878 wolfSSL_SetTlsFinishedCtx(ssl, myCtx);
4879 #endif
4880 }
4881
4882 #endif /* HAVE_PK_CALLBACKS */
4883
4884 #ifdef USE_WOLFSSL_IO
SimulateWantWriteIOSendCb(WOLFSSL * ssl,char * buf,int sz,void * ctx)4885 static WC_INLINE int SimulateWantWriteIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
4886 {
4887 static int wantWriteFlag = 1;
4888
4889 int sent;
4890 int sd = *(int*)ctx;
4891
4892 (void)ssl;
4893
4894 if (!wantWriteFlag)
4895 {
4896 wantWriteFlag = 1;
4897
4898 sent = wolfIO_Send(sd, buf, sz, 0);
4899 if (sent < 0) {
4900 int err = errno;
4901
4902 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
4903 return WOLFSSL_CBIO_ERR_WANT_WRITE;
4904 }
4905 else if (err == SOCKET_ECONNRESET) {
4906 return WOLFSSL_CBIO_ERR_CONN_RST;
4907 }
4908 else if (err == SOCKET_EINTR) {
4909 return WOLFSSL_CBIO_ERR_ISR;
4910 }
4911 else if (err == SOCKET_EPIPE) {
4912 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
4913 }
4914 else {
4915 return WOLFSSL_CBIO_ERR_GENERAL;
4916 }
4917 }
4918
4919 return sent;
4920 }
4921 else
4922 {
4923 wantWriteFlag = 0;
4924 return WOLFSSL_CBIO_ERR_WANT_WRITE;
4925 }
4926 }
4927 #endif /* USE_WOLFSSL_IO */
4928
4929 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
4930 || defined(_MSC_VER)
4931
4932 /* HP/UX doesn't have strsep, needed by test/suites.c */
strsep(char ** stringp,const char * delim)4933 static WC_INLINE char* strsep(char **stringp, const char *delim)
4934 {
4935 char* start;
4936 char* end;
4937
4938 start = *stringp;
4939 if (start == NULL)
4940 return NULL;
4941
4942 if ((end = strpbrk(start, delim))) {
4943 *end++ = '\0';
4944 *stringp = end;
4945 } else {
4946 *stringp = NULL;
4947 }
4948
4949 return start;
4950 }
4951
4952 #endif /* __hpux__ and others */
4953
4954 /* Create unique filename, len is length of tempfn name, assuming
4955 len does not include null terminating character,
4956 num is number of characters in tempfn name to randomize */
mymktemp(char * tempfn,int len,int num)4957 static WC_INLINE const char* mymktemp(char *tempfn, int len, int num)
4958 {
4959 int x, size;
4960 static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
4961 "abcdefghijklmnopqrstuvwxyz";
4962 WC_RNG rng;
4963 byte out;
4964
4965 if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
4966 printf("Bad input\n");
4967 return NULL;
4968 }
4969
4970 size = len - 1;
4971
4972 if (wc_InitRng(&rng) != 0) {
4973 printf("InitRng failed\n");
4974 return NULL;
4975 }
4976
4977 for (x = size; x > size - num; x--) {
4978 if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
4979 printf("RNG_GenerateBlock failed\n");
4980 return NULL;
4981 }
4982 tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
4983 }
4984 tempfn[len] = '\0';
4985
4986 wc_FreeRng(&rng);
4987 (void)rng; /* for WC_NO_RNG case */
4988
4989 return tempfn;
4990 }
4991
4992
4993
4994 #if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
4995 ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
4996 defined(HAVE_AESGCM))
4997
4998 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
4999 #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
5000 #define WOLFSSL_TICKET_KEY_SZ CHACHA20_POLY1305_AEAD_KEYSIZE
5001 #elif defined(HAVE_AESGCM)
5002 #include <wolfssl/wolfcrypt/aes.h>
5003 #include <wolfssl/wolfcrypt/wc_encrypt.h> /* AES IV sizes in FIPS mode */
5004 #define WOLFSSL_TICKET_KEY_SZ AES_256_KEY_SIZE
5005 #endif
5006
5007 typedef struct key_ctx {
5008 byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */
5009 byte key[WOLFSSL_TICKET_KEY_SZ]; /* cipher key */
5010 } key_ctx;
5011
5012 static THREAD_LS_T key_ctx myKey_ctx;
5013 static THREAD_LS_T WC_RNG myKey_rng;
5014
TicketInit(void)5015 static WC_INLINE int TicketInit(void)
5016 {
5017 int ret = wc_InitRng(&myKey_rng);
5018 if (ret != 0) return ret;
5019
5020 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key));
5021 if (ret != 0) return ret;
5022
5023 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name));
5024 if (ret != 0) return ret;
5025
5026 return 0;
5027 }
5028
TicketCleanup(void)5029 static WC_INLINE void TicketCleanup(void)
5030 {
5031 wc_FreeRng(&myKey_rng);
5032 }
5033
myTicketEncCb(WOLFSSL * ssl,byte key_name[WOLFSSL_TICKET_NAME_SZ],byte iv[WOLFSSL_TICKET_IV_SZ],byte mac[WOLFSSL_TICKET_MAC_SZ],int enc,byte * ticket,int inLen,int * outLen,void * userCtx)5034 static WC_INLINE int myTicketEncCb(WOLFSSL* ssl,
5035 byte key_name[WOLFSSL_TICKET_NAME_SZ],
5036 byte iv[WOLFSSL_TICKET_IV_SZ],
5037 byte mac[WOLFSSL_TICKET_MAC_SZ],
5038 int enc, byte* ticket, int inLen, int* outLen,
5039 void* userCtx)
5040 {
5041 int ret;
5042 word16 sLen = XHTONS(inLen);
5043 byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
5044 int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
5045 byte* tmp = aad;
5046 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
5047 /* chahca20/poly1305 */
5048 #elif defined(HAVE_AESGCM)
5049 Aes aes;
5050 #endif
5051
5052 (void)ssl;
5053 (void)userCtx;
5054
5055 /* encrypt */
5056 if (enc) {
5057 XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
5058
5059 ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ);
5060 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
5061
5062 /* build aad from key name, iv, and length */
5063 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
5064 tmp += WOLFSSL_TICKET_NAME_SZ;
5065 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
5066 tmp += WOLFSSL_TICKET_IV_SZ;
5067 XMEMCPY(tmp, &sLen, sizeof(sLen));
5068
5069 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
5070 ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
5071 aad, aadSz,
5072 ticket, inLen,
5073 ticket,
5074 mac);
5075 #elif defined(HAVE_AESGCM)
5076 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
5077 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
5078
5079 ret = wc_AesGcmSetKey(&aes, myKey_ctx.key, sizeof(myKey_ctx.key));
5080 if (ret == 0) {
5081 ret = wc_AesGcmEncrypt(&aes, ticket, ticket, inLen,
5082 iv, GCM_NONCE_MID_SZ, mac, AES_BLOCK_SIZE,
5083 aad, aadSz);
5084 }
5085 wc_AesFree(&aes);
5086 #endif
5087
5088 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
5089 *outLen = inLen; /* no padding in this mode */
5090 }
5091 /* decrypt */
5092 else {
5093 /* see if we know this key */
5094 if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
5095 printf("client presented unknown ticket key name %s\n", key_name);
5096 return WOLFSSL_TICKET_RET_FATAL;
5097 }
5098
5099 /* build aad from key name, iv, and length */
5100 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
5101 tmp += WOLFSSL_TICKET_NAME_SZ;
5102 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
5103 tmp += WOLFSSL_TICKET_IV_SZ;
5104 XMEMCPY(tmp, &sLen, sizeof(sLen));
5105
5106 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
5107 ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
5108 aad, aadSz,
5109 ticket, inLen,
5110 mac,
5111 ticket);
5112 #elif defined(HAVE_AESGCM)
5113 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
5114 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
5115
5116 ret = wc_AesGcmSetKey(&aes, myKey_ctx.key, sizeof(myKey_ctx.key));
5117 if (ret == 0) {
5118 ret = wc_AesGcmDecrypt(&aes, ticket, ticket, inLen,
5119 iv, GCM_NONCE_MID_SZ, mac, AES_BLOCK_SIZE,
5120 aad, aadSz);
5121 }
5122 wc_AesFree(&aes);
5123 #endif
5124
5125 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
5126 *outLen = inLen; /* no padding in this mode */
5127 }
5128
5129 return WOLFSSL_TICKET_RET_OK;
5130 }
5131
5132 #endif /* HAVE_SESSION_TICKET && ((HAVE_CHACHA && HAVE_POLY1305) || HAVE_AESGCM) */
5133
5134
GetRandomPort(void)5135 static WC_INLINE word16 GetRandomPort(void)
5136 {
5137 word16 port = 0;
5138
5139 /* Generate random port for testing */
5140 WC_RNG rng;
5141 if (wc_InitRng(&rng) == 0) {
5142 if (wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port)) == 0) {
5143 port |= 0xC000; /* Make sure its in the 49152 - 65535 range */
5144 }
5145 wc_FreeRng(&rng);
5146 }
5147 (void)rng; /* for WC_NO_RNG case */
5148 return port;
5149 }
5150
5151 #ifdef WOLFSSL_EARLY_DATA
EarlyDataStatus(WOLFSSL * ssl)5152 static WC_INLINE void EarlyDataStatus(WOLFSSL* ssl)
5153 {
5154 int earlyData_status;
5155 #ifdef OPENSSL_EXTRA
5156 earlyData_status = SSL_get_early_data_status(ssl);
5157 #else
5158 earlyData_status = wolfSSL_get_early_data_status(ssl);
5159 #endif
5160 if (earlyData_status < 0) return;
5161
5162 printf("Early Data was ");
5163
5164 switch(earlyData_status) {
5165 case WOLFSSL_EARLY_DATA_NOT_SENT:
5166 printf("not sent.\n");
5167 break;
5168 case WOLFSSL_EARLY_DATA_REJECTED:
5169 printf("rejected.\n");
5170 break;
5171 case WOLFSSL_EARLY_DATA_ACCEPTED:
5172 printf("accepted\n");
5173 break;
5174 default:
5175 printf("unknown...\n");
5176 }
5177 }
5178 #endif /* WOLFSSL_EARLY_DATA */
5179
5180
5181 #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
5182 defined(DEBUG_UNIT_TEST_CERTS)
5183 void DEBUG_WRITE_CERT_X509(WOLFSSL_X509* x509, const char* fileName);
5184 void DEBUG_WRITE_DER(const byte* der, int derSz, const char* fileName);
5185 #endif
5186
5187 #endif /* wolfSSL_TEST_H */
5188