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