source: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfssl/test.h@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 102.3 KB
Line 
1/* test.h */
2
3#ifndef wolfSSL_TEST_H
4#define wolfSSL_TEST_H
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <assert.h>
9#include <ctype.h>
10#include <wolfssl/wolfcrypt/types.h>
11#include <wolfssl/wolfcrypt/error-crypt.h>
12#include <wolfssl/wolfcrypt/random.h>
13#include <wolfssl/wolfcrypt/mem_track.h>
14#if defined(SHOW_CERTS) && \
15 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
16 #include <wolfssl/wolfcrypt/asn.h> /* for domain component NID value */
17#endif
18
19#ifdef ATOMIC_USER
20 #include <wolfssl/wolfcrypt/aes.h>
21 #include <wolfssl/wolfcrypt/arc4.h>
22 #include <wolfssl/wolfcrypt/hmac.h>
23#endif
24#ifdef HAVE_PK_CALLBACKS
25 #include <wolfssl/wolfcrypt/asn.h>
26 #ifndef NO_RSA
27 #include <wolfssl/wolfcrypt/rsa.h>
28 #endif
29 #ifdef HAVE_ECC
30 #include <wolfssl/wolfcrypt/ecc.h>
31 #endif /* HAVE_ECC */
32 #ifndef NO_DH
33 #include <wolfssl/wolfcrypt/dh.h>
34 #endif /* !NO_DH */
35 #ifdef HAVE_ED25519
36 #include <wolfssl/wolfcrypt/ed25519.h>
37 #endif /* HAVE_ED25519 */
38 #ifdef HAVE_CURVE25519
39 #include <wolfssl/wolfcrypt/curve25519.h>
40 #endif /* HAVE_ECC */
41 #ifdef HAVE_ED448
42 #include <wolfssl/wolfcrypt/ed448.h>
43 #endif /* HAVE_ED448 */
44 #ifdef HAVE_CURVE448
45 #include <wolfssl/wolfcrypt/curve448.h>
46 #endif /* HAVE_ECC */
47#endif /*HAVE_PK_CALLBACKS */
48
49#ifdef USE_WINDOWS_API
50 #include <winsock2.h>
51 #include <process.h>
52 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */
53 #include <ws2tcpip.h>
54 #include <wspiapi.h>
55 #endif
56 #define SOCKET_T SOCKET
57 #define SNPRINTF _snprintf
58#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
59 #include <string.h>
60 #include "rl_net.h"
61 #define SOCKET_T int
62 typedef int socklen_t ;
63 #define inet_addr wolfSSL_inet_addr
64 static unsigned long wolfSSL_inet_addr(const char *cp)
65 {
66 unsigned int a[4] ; unsigned long ret ;
67 sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
68 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
69 return(ret) ;
70 }
71 #if defined(HAVE_KEIL_RTX)
72 #define sleep(t) os_dly_wait(t/1000+1);
73 #elif defined(WOLFSSL_CMSIS_RTOS) || defined(WOLFSSL_CMSIS_RTOSv2)
74 #define sleep(t) osDelay(t/1000+1);
75 #endif
76#elif defined(WOLFSSL_TIRTOS)
77 #include <string.h>
78 #include <netdb.h>
79 #include <sys/types.h>
80 #include <arpa/inet.h>
81 #include <sys/socket.h>
82 #include <ti/sysbios/knl/Task.h>
83 struct hostent {
84 char *h_name; /* official name of host */
85 char **h_aliases; /* alias list */
86 int h_addrtype; /* host address type */
87 int h_length; /* length of address */
88 char **h_addr_list; /* list of addresses from name server */
89 };
90 #define SOCKET_T int
91#elif defined(WOLFSSL_VXWORKS)
92 #include <hostLib.h>
93 #include <sockLib.h>
94 #include <arpa/inet.h>
95 #include <string.h>
96 #include <selectLib.h>
97 #include <sys/types.h>
98 #include <netinet/in.h>
99 #include <fcntl.h>
100 #include <sys/time.h>
101 #include <netdb.h>
102 #include <pthread.h>
103 #define SOCKET_T int
104#elif defined(WOLFSSL_ZEPHYR)
105 #include <string.h>
106 #include <sys/types.h>
107 #include <net/socket.h>
108 #define SOCKET_T int
109 #define SOL_SOCKET 1
110 #define SO_REUSEADDR 201
111 #define WOLFSSL_USE_GETADDRINFO
112
113 static unsigned long inet_addr(const char *cp)
114 {
115 unsigned int a[4]; unsigned long ret;
116 int i, j;
117 for (i=0, j=0; i<4; i++) {
118 a[i] = 0;
119 while (cp[j] != '.' && cp[j] != '\0') {
120 a[i] *= 10;
121 a[i] += cp[j] - '0';
122 j++;
123 }
124 }
125 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
126 return(ret) ;
127 }
128#else
129 #include <string.h>
130 #include <sys/types.h>
131#ifndef WOLFSSL_LEANPSK
132 #include <unistd.h>
133 #include <netdb.h>
134 #include <netinet/in.h>
135 #include <netinet/tcp.h>
136 #include <arpa/inet.h>
137 #include <sys/ioctl.h>
138 #include <sys/time.h>
139 #include <sys/socket.h>
140 #include <pthread.h>
141 #include <fcntl.h>
142 #ifdef TEST_IPV6
143 #include <netdb.h>
144 #endif
145#endif
146 #define SOCKET_T int
147 #ifndef SO_NOSIGPIPE
148 #include <signal.h> /* ignore SIGPIPE */
149 #endif
150 #define SNPRINTF snprintf
151#endif /* USE_WINDOWS_API */
152
153#ifdef WOLFSSL_ASYNC_CRYPT
154 #include <wolfssl/wolfcrypt/async.h>
155#endif
156#ifdef HAVE_CAVIUM
157 #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h>
158#endif
159#ifdef _MSC_VER
160 /* disable conversion warning */
161 /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
162 #pragma warning(disable:4244 4996)
163#endif
164
165#ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
166 #define WOLFSSL_CIPHER_LIST_MAX_SIZE 4096
167#endif
168/* Buffer for benchmark tests */
169#ifndef TEST_BUFFER_SIZE
170 #define TEST_BUFFER_SIZE 16384
171#endif
172
173#ifndef WOLFSSL_HAVE_MIN
174 #define WOLFSSL_HAVE_MIN
175 static WC_INLINE word32 min(word32 a, word32 b)
176 {
177 return a > b ? b : a;
178 }
179#endif /* WOLFSSL_HAVE_MIN */
180
181/* Socket Handling */
182#ifndef WOLFSSL_SOCKET_INVALID
183#ifdef USE_WINDOWS_API
184 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET)
185#elif defined(WOLFSSL_TIRTOS)
186 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1)
187#else
188 #define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0)
189#endif
190#endif /* WOLFSSL_SOCKET_INVALID */
191
192#ifndef WOLFSSL_SOCKET_IS_INVALID
193#if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS)
194 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
195#else
196 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID)
197#endif
198#endif /* WOLFSSL_SOCKET_IS_INVALID */
199
200#if defined(__MACH__) || defined(USE_WINDOWS_API)
201 #ifndef _SOCKLEN_T
202 typedef int socklen_t;
203 #endif
204#endif
205
206
207/* HPUX doesn't use socklent_t for third parameter to accept, unless
208 _XOPEN_SOURCE_EXTENDED is defined */
209#if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\
210 && !defined(WOLFSSL_ROWLEY_ARM) && !defined(WOLFSSL_KEIL_TCP_NET)
211 typedef socklen_t* ACCEPT_THIRD_T;
212#else
213 #if defined _XOPEN_SOURCE_EXTENDED
214 typedef socklen_t* ACCEPT_THIRD_T;
215 #else
216 typedef int* ACCEPT_THIRD_T;
217 #endif
218#endif
219
220
221
222#ifdef SINGLE_THREADED
223 typedef unsigned int THREAD_RETURN;
224 typedef void* THREAD_TYPE;
225 #define WOLFSSL_THREAD
226#else
227 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
228 typedef void* THREAD_RETURN;
229 typedef pthread_t THREAD_TYPE;
230 #define WOLFSSL_THREAD
231 #define INFINITE -1
232 #define WAIT_OBJECT_0 0L
233 #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
234 typedef unsigned int THREAD_RETURN;
235 typedef int THREAD_TYPE;
236 #define WOLFSSL_THREAD
237 #elif defined(WOLFSSL_TIRTOS)
238 typedef void THREAD_RETURN;
239 typedef Task_Handle THREAD_TYPE;
240 #define WOLFSSL_THREAD
241 #elif defined(WOLFSSL_ZEPHYR)
242 typedef void THREAD_RETURN;
243 typedef struct k_thread THREAD_TYPE;
244 #define WOLFSSL_THREAD
245 #else
246 typedef unsigned int THREAD_RETURN;
247 typedef intptr_t THREAD_TYPE;
248 #define WOLFSSL_THREAD __stdcall
249 #endif
250#endif
251
252
253#ifdef TEST_IPV6
254 typedef struct sockaddr_in6 SOCKADDR_IN_T;
255 #define AF_INET_V AF_INET6
256#else
257 typedef struct sockaddr_in SOCKADDR_IN_T;
258 #define AF_INET_V AF_INET
259#endif
260
261
262#ifndef WOLFSSL_NO_TLS12
263#define SERVER_DEFAULT_VERSION 3
264#else
265#define SERVER_DEFAULT_VERSION 4
266#endif
267#define SERVER_DTLS_DEFAULT_VERSION (-2)
268#define SERVER_INVALID_VERSION (-99)
269#define SERVER_DOWNGRADE_VERSION (-98)
270#ifndef WOLFSSL_NO_TLS12
271#define CLIENT_DEFAULT_VERSION 3
272#else
273#define CLIENT_DEFAULT_VERSION 4
274#endif
275#define CLIENT_DTLS_DEFAULT_VERSION (-2)
276#define CLIENT_INVALID_VERSION (-99)
277#define CLIENT_DOWNGRADE_VERSION (-98)
278#define EITHER_DOWNGRADE_VERSION (-97)
279#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
280 #define DEFAULT_MIN_DHKEY_BITS 2048
281 #define DEFAULT_MAX_DHKEY_BITS 3072
282#else
283 #define DEFAULT_MIN_DHKEY_BITS 1024
284 #define DEFAULT_MAX_DHKEY_BITS 2048
285#endif
286#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
287 #define DEFAULT_MIN_RSAKEY_BITS 2048
288#else
289 #define DEFAULT_MIN_RSAKEY_BITS 1024
290#endif
291#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
292 #define DEFAULT_MIN_ECCKEY_BITS 256
293#else
294 #define DEFAULT_MIN_ECCKEY_BITS 224
295#endif
296
297/* all certs relative to wolfSSL home directory now */
298#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
299#define caCertFile "certs/ca-cert.pem"
300#define eccCertFile "certs/server-ecc.pem"
301#define eccKeyFile "certs/ecc-key.pem"
302#define eccRsaCertFile "certs/server-ecc-rsa.pem"
303#define svrCertFile "certs/server-cert.pem"
304#define svrKeyFile "certs/server-key.pem"
305#define cliCertFile "certs/client-cert.pem"
306#define cliCertDerFile "certs/client-cert.der"
307#define cliCertFileExt "certs/client-cert-ext.pem"
308#define cliCertDerFileExt "certs/client-cert-ext.der"
309#define cliKeyFile "certs/client-key.pem"
310#define ntruCertFile "certs/ntru-cert.pem"
311#define ntruKeyFile "certs/ntru-key.raw"
312#define dhParamFile "certs/dh2048.pem"
313#define cliEccKeyFile "certs/ecc-client-key.pem"
314#define cliEccCertFile "certs/client-ecc-cert.pem"
315#define caEccCertFile "certs/ca-ecc-cert.pem"
316#define crlPemDir "certs/crl"
317#define edCertFile "certs/ed25519/server-ed25519-cert.pem"
318#define edKeyFile "certs/ed25519/server-ed25519-priv.pem"
319#define cliEdCertFile "certs/ed25519/client-ed25519.pem"
320#define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem"
321#define caEdCertFile "certs/ed25519/ca-ed25519.pem"
322#define ed448CertFile "certs/ed448/server-ed448-cert.pem"
323#define ed448KeyFile "certs/ed448/server-ed448-priv.pem"
324#define cliEd448CertFile "certs/ed448/client-ed448.pem"
325#define cliEd448KeyFile "certs/ed448/client-ed448-priv.pem"
326#define caEd448CertFile "certs/ed448/ca-ed448.pem"
327#ifdef HAVE_WNR
328 /* Whitewood netRandom default config file */
329 #define wnrConfig "wnr-example.conf"
330#endif
331#else
332#define caCertFile "./certs/ca-cert.pem"
333#define eccCertFile "./certs/server-ecc.pem"
334#define eccKeyFile "./certs/ecc-key.pem"
335#define eccRsaCertFile "./certs/server-ecc-rsa.pem"
336#define svrCertFile "./certs/server-cert.pem"
337#define svrKeyFile "./certs/server-key.pem"
338#define cliCertFile "./certs/client-cert.pem"
339#define cliCertDerFile "./certs/client-cert.der"
340#define cliCertFileExt "./certs/client-cert-ext.pem"
341#define cliCertDerFileExt "./certs/client-cert-ext.der"
342#define cliKeyFile "./certs/client-key.pem"
343#define ntruCertFile "./certs/ntru-cert.pem"
344#define ntruKeyFile "./certs/ntru-key.raw"
345#define dhParamFile "./certs/dh2048.pem"
346#define cliEccKeyFile "./certs/ecc-client-key.pem"
347#define cliEccCertFile "./certs/client-ecc-cert.pem"
348#define caEccCertFile "./certs/ca-ecc-cert.pem"
349#define crlPemDir "./certs/crl"
350#define edCertFile "./certs/ed25519/server-ed25519-cert.pem"
351#define edKeyFile "./certs/ed25519/server-ed25519-priv.pem"
352#define cliEdCertFile "./certs/ed25519/client-ed25519.pem"
353#define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem"
354#define caEdCertFile "./certs/ed25519/ca-ed25519.pem"
355#define ed448CertFile "./certs/ed448/server-ed448-cert.pem"
356#define ed448KeyFile "./certs/ed448/server-ed448-priv.pem"
357#define cliEd448CertFile "./certs/ed448/client-ed448.pem"
358#define cliEd448KeyFile "./certs/ed448/client-ed448-priv.pem"
359#define caEd448CertFile "./certs/ed448/ca-ed448.pem"
360#ifdef HAVE_WNR
361 /* Whitewood netRandom default config file */
362 #define wnrConfig "./wnr-example.conf"
363#endif
364#endif
365
366typedef struct tcp_ready {
367 word16 ready; /* predicate */
368 word16 port;
369 char* srfName; /* server ready file name */
370#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
371 pthread_mutex_t mutex;
372 pthread_cond_t cond;
373#endif
374} tcp_ready;
375
376
377static WC_INLINE void InitTcpReady(tcp_ready* ready)
378{
379 ready->ready = 0;
380 ready->port = 0;
381 ready->srfName = NULL;
382#ifdef SINGLE_THREADED
383#elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
384 pthread_mutex_init(&ready->mutex, 0);
385 pthread_cond_init(&ready->cond, 0);
386#endif
387}
388
389
390static WC_INLINE void FreeTcpReady(tcp_ready* ready)
391{
392#ifdef SINGLE_THREADED
393 (void)ready;
394#elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
395 pthread_mutex_destroy(&ready->mutex);
396 pthread_cond_destroy(&ready->cond);
397#else
398 (void)ready;
399#endif
400}
401
402typedef WOLFSSL_METHOD* (*method_provider)(void);
403typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
404typedef void (*ssl_callback)(WOLFSSL* ssl);
405
406typedef struct callback_functions {
407 method_provider method;
408 ctx_callback ctx_ready;
409 ssl_callback ssl_ready;
410 ssl_callback on_result;
411 WOLFSSL_CTX* ctx;
412} callback_functions;
413
414typedef struct func_args {
415 int argc;
416 char** argv;
417 int return_code;
418 tcp_ready* signal;
419 callback_functions *callbacks;
420} func_args;
421
422
423
424
425void wait_tcp_ready(func_args*);
426
427#ifdef WOLFSSL_ZEPHYR
428typedef void THREAD_FUNC(void*, void*, void*);
429#else
430typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
431#endif
432
433void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
434void join_thread(THREAD_TYPE);
435
436/* wolfSSL */
437#ifndef TEST_IPV6
438 static const char* const wolfSSLIP = "127.0.0.1";
439#else
440 static const char* const wolfSSLIP = "::1";
441#endif
442static const word16 wolfSSLPort = 11111;
443
444
445
446#ifndef MY_EX_USAGE
447#define MY_EX_USAGE 2
448#endif
449
450#ifndef EXIT_FAILURE
451#define EXIT_FAILURE 1
452#endif
453
454#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
455 #ifndef EXIT_SUCCESS
456 #define EXIT_SUCCESS 0
457 #endif
458 #define XEXIT(rc) return rc
459 #define XEXIT_T(rc) return (THREAD_RETURN)rc
460#else
461 #define XEXIT(rc) exit((int)(rc))
462 #define XEXIT_T(rc) exit((int)(rc))
463#endif
464
465
466static WC_INLINE
467#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
468THREAD_RETURN
469#else
470WC_NORETURN void
471#endif
472err_sys(const char* msg)
473{
474 printf("wolfSSL error: %s\n", msg);
475
476#if !defined(__GNUC__)
477 /* scan-build (which pretends to be gnuc) can get confused and think the
478 * msg pointer can be null even when hardcoded and then it won't exit,
479 * making null pointer checks above the err_sys() call useless.
480 * We could just always exit() but some compilers will complain about no
481 * possible return, with gcc we know the attribute to handle that with
482 * WC_NORETURN. */
483 if (msg)
484#endif
485 {
486 XEXIT_T(EXIT_FAILURE);
487 }
488}
489
490
491extern int myoptind;
492extern char* myoptarg;
493
494static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
495{
496 static char* next = NULL;
497
498 char c;
499 char* cp;
500
501 /* Added sanity check becuase scan-build complains argv[myoptind] access
502 * results in a null pointer dereference. */
503 if (argv == NULL) {
504 myoptarg = NULL;
505 return -1;
506 }
507
508 if (myoptind == 0)
509 next = NULL; /* we're starting new/over */
510
511 if (next == NULL || *next == '\0') {
512 if (myoptind == 0)
513 myoptind++;
514
515 if (myoptind >= argc || argv[myoptind] == NULL ||
516 argv[myoptind][0] != '-' || argv[myoptind][1] == '\0') {
517 myoptarg = NULL;
518 if (myoptind < argc)
519 myoptarg = argv[myoptind];
520
521 return -1;
522 }
523
524 if (strcmp(argv[myoptind], "--") == 0) {
525 myoptind++;
526 myoptarg = NULL;
527
528 if (myoptind < argc)
529 myoptarg = argv[myoptind];
530
531 return -1;
532 }
533
534 next = argv[myoptind];
535 next++; /* skip - */
536 myoptind++;
537 }
538
539 c = *next++;
540 /* The C++ strchr can return a different value */
541 cp = (char*)strchr(optstring, c);
542
543 if (cp == NULL || c == ':')
544 return '?';
545
546 cp++;
547
548 if (*cp == ':') {
549 if (*next != '\0') {
550 myoptarg = next;
551 next = NULL;
552 }
553 else if (myoptind < argc) {
554 myoptarg = argv[myoptind];
555 myoptind++;
556 }
557 else
558 return '?';
559 }
560
561 return c;
562}
563
564
565#ifdef WOLFSSL_ENCRYPTED_KEYS
566
567static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
568{
569 (void)rw;
570 (void)userdata;
571 if (userdata != NULL) {
572 strncpy(passwd, (char*)userdata, sz);
573 return (int)XSTRLEN((char*)userdata);
574 }
575 else {
576 strncpy(passwd, "yassl123", sz);
577 return 8;
578 }
579}
580
581#endif
582
583static const char* client_showpeer_msg[][8] = {
584 /* English */
585 {
586 "SSL version is",
587 "SSL cipher suite is",
588 "SSL curve name is",
589 "SSL DH size is",
590 "SSL reused session",
591 "Alternate cert chain used",
592 "peer's cert info:",
593 NULL
594 },
595#ifndef NO_MULTIBYTE_PRINT
596 /* Japanese */
597 {
598 "SSL バージョンは",
599 "SSL 暗号スイートは",
600 "SSL 曲線名は",
601 "SSL DH サイズは",
602 "SSL 再利用セッション",
603 "代替証明チェーンを使用",
604 "相手方証明書情報",
605 NULL
606 },
607#endif
608};
609
610#if defined(KEEP_PEER_CERT) || defined(KEEP_OUR_CERT) || defined(SESSION_CERTS)
611static const char* client_showx509_msg[][5] = {
612 /* English */
613 {
614 "issuer",
615 "subject",
616 "altname",
617 "serial number",
618 NULL
619 },
620#ifndef NO_MULTIBYTE_PRINT
621 /* Japanese */
622 {
623 "発行者",
624 "サブジェクト",
625 "代替名",
626 "シリアル番号",
627 NULL
628 },
629#endif
630};
631
632/* lng_index is to specify the language for displaying message. */
633/* 0:English, 1:Japanese */
634static WC_INLINE void ShowX509Ex(WOLFSSL_X509* x509, const char* hdr,
635 int lng_index)
636{
637 char* altName;
638 char* issuer;
639 char* subject;
640 byte serial[32];
641 int ret;
642 int sz = sizeof(serial);
643 const char** words = client_showx509_msg[lng_index];
644
645 if (x509 == NULL) {
646 printf("%s No Cert\n", hdr);
647 return;
648 }
649
650 issuer = wolfSSL_X509_NAME_oneline(
651 wolfSSL_X509_get_issuer_name(x509), 0, 0);
652 subject = wolfSSL_X509_NAME_oneline(
653 wolfSSL_X509_get_subject_name(x509), 0, 0);
654
655 printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject);
656
657 while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
658 printf(" %s = %s\n", words[2], altName);
659
660 ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
661 if (ret == WOLFSSL_SUCCESS) {
662 int i;
663 int strLen;
664 char serialMsg[80];
665
666 /* testsuite has multiple threads writing to stdout, get output
667 message ready to write once */
668 strLen = sprintf(serialMsg, " %s", words[3]);
669 for (i = 0; i < sz; i++)
670 sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
671 printf("%s\n", serialMsg);
672 }
673
674 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
675 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
676
677#if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA)
678 {
679 WOLFSSL_BIO* bio;
680 char buf[256]; /* should be size of ASN_NAME_MAX */
681 int textSz;
682
683 /* print out domain component if certificate has it */
684 textSz = wolfSSL_X509_NAME_get_text_by_NID(
685 wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
686 buf, sizeof(buf));
687 if (textSz > 0) {
688 printf("Domain Component = %s\n", buf);
689 }
690
691 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
692 if (bio != NULL) {
693 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
694 wolfSSL_X509_print(bio, x509);
695 wolfSSL_BIO_free(bio);
696 }
697 }
698#endif /* SHOW_CERTS && OPENSSL_EXTRA */
699}
700/* original ShowX509 to maintain compatibility */
701static WC_INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
702{
703 ShowX509Ex(x509, hdr, 0);
704}
705
706#endif /* KEEP_PEER_CERT || KEEP_OUR_CERT || SESSION_CERTS */
707
708#if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \
709 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
710static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count,
711 const char* hdr)
712{
713 int i;
714 int length;
715 unsigned char buffer[3072];
716 WOLFSSL_X509* chainX509;
717
718 for (i = 0; i < count; i++) {
719 wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length);
720 buffer[length] = 0;
721 printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer);
722
723 chainX509 = wolfSSL_get_chain_X509(chain, i);
724 if (chainX509)
725 ShowX509(chainX509, hdr);
726 else
727 printf("get_chain_X509 failed\n");
728 wolfSSL_FreeX509(chainX509);
729 }
730}
731#endif /* SHOW_CERTS && SESSION_CERTS */
732
733/* lng_index is to specify the language for displaying message. */
734/* 0:English, 1:Japanese */
735static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index)
736{
737 WOLFSSL_CIPHER* cipher;
738 const char** words = client_showpeer_msg[lng_index];
739
740#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
741 !defined(NO_DH)
742 const char *name;
743#endif
744#ifndef NO_DH
745 int bits;
746#endif
747#ifdef KEEP_PEER_CERT
748 WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
749 if (peer)
750 ShowX509Ex(peer, words[6], lng_index);
751 else
752 printf("peer has no cert!\n");
753 wolfSSL_FreeX509(peer);
754#endif
755#if defined(SHOW_CERTS) && defined(KEEP_OUR_CERT) && \
756 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
757 ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
758 printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
759#endif /* SHOW_CERTS && KEEP_OUR_CERT */
760 printf("%s %s\n", words[0], wolfSSL_get_version(ssl));
761
762 cipher = wolfSSL_get_current_cipher(ssl);
763#ifdef HAVE_QSH
764 printf("%s %s%s\n", words[1], (wolfSSL_isQSH(ssl))? "QSH:": "",
765 wolfSSL_CIPHER_get_name(cipher));
766#else
767 printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
768#endif
769#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
770 !defined(NO_DH)
771 if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
772 printf("%s %s\n", words[2], name);
773#endif
774#ifndef NO_DH
775 else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
776 printf("%s %d bits\n", words[3], bits);
777#endif
778 if (wolfSSL_session_reused(ssl))
779 printf("%s\n", words[4]);
780#ifdef WOLFSSL_ALT_CERT_CHAINS
781 if (wolfSSL_is_peer_alt_cert_chain(ssl))
782 printf("%s\n", words[5]);
783#endif
784
785#if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \
786 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
787 {
788 WOLFSSL_X509_CHAIN* chain;
789
790 chain = wolfSSL_get_peer_chain(ssl);
791 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert");
792
793 #ifdef WOLFSSL_ALT_CERT_CHAINS
794 if (wolfSSL_is_peer_alt_cert_chain(ssl)) {
795 chain = wolfSSL_get_peer_alt_chain(ssl);
796 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert");
797 }
798 #endif
799 }
800#endif /* SHOW_CERTS && SESSION_CERTS */
801 (void)ssl;
802}
803/* original showPeer to maintain compatibility */
804static WC_INLINE void showPeer(WOLFSSL* ssl)
805{
806 showPeerEx(ssl, 0);
807}
808
809static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
810 word16 port, int udp, int sctp)
811{
812 int useLookup = 0;
813 (void)useLookup;
814 (void)udp;
815 (void)sctp;
816
817 if (addr == NULL)
818 err_sys("invalid argument to build_addr, addr is NULL");
819
820 XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T));
821
822#ifndef TEST_IPV6
823 /* peer could be in human readable form */
824 if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) {
825 #ifndef WOLFSSL_USE_GETADDRINFO
826 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
827 int err;
828 struct hostent* entry = gethostbyname(peer, &err);
829 #elif defined(WOLFSSL_TIRTOS)
830 struct hostent* entry = DNSGetHostByName(peer);
831 #elif defined(WOLFSSL_VXWORKS)
832 struct hostent* entry = (struct hostent*)hostGetByName((char*)peer);
833 #else
834 struct hostent* entry = gethostbyname(peer);
835 #endif
836
837 if (entry) {
838 XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0],
839 entry->h_length);
840 useLookup = 1;
841 }
842 #else
843 struct zsock_addrinfo hints, *addrInfo;
844 char portStr[6];
845 XSNPRINTF(portStr, sizeof(portStr), "%d", port);
846 memset(&hints, 0, sizeof(hints));
847 hints.ai_family = AF_UNSPEC;
848 hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
849 hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
850 if (getaddrinfo((char*)peer, portStr, &hints, &addrInfo) == 0) {
851 XMEMCPY(addr, addrInfo->ai_addr, sizeof(*addr));
852 useLookup = 1;
853 }
854 #endif
855 else
856 err_sys("no entry for host");
857 }
858#endif
859
860
861#ifndef TEST_IPV6
862 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
863 addr->sin_family = PF_INET;
864 #else
865 addr->sin_family = AF_INET_V;
866 #endif
867 addr->sin_port = XHTONS(port);
868 if ((size_t)peer == INADDR_ANY)
869 addr->sin_addr.s_addr = INADDR_ANY;
870 else {
871 if (!useLookup)
872 addr->sin_addr.s_addr = inet_addr(peer);
873 }
874#else
875 addr->sin6_family = AF_INET_V;
876 addr->sin6_port = XHTONS(port);
877 if ((size_t)peer == INADDR_ANY) {
878 addr->sin6_addr = in6addr_any;
879 }
880 else {
881 #if defined(HAVE_GETADDRINFO) || defined(WOLF_C99)
882 struct addrinfo hints;
883 struct addrinfo* answer = NULL;
884 int ret;
885 char strPort[80];
886
887 XMEMSET(&hints, 0, sizeof(hints));
888
889 hints.ai_family = AF_INET_V;
890 if (udp) {
891 hints.ai_socktype = SOCK_DGRAM;
892 hints.ai_protocol = IPPROTO_UDP;
893 }
894 #ifdef WOLFSSL_SCTP
895 else if (sctp) {
896 hints.ai_socktype = SOCK_STREAM;
897 hints.ai_protocol = IPPROTO_SCTP;
898 }
899 #endif
900 else {
901 hints.ai_socktype = SOCK_STREAM;
902 hints.ai_protocol = IPPROTO_TCP;
903 }
904
905 SNPRINTF(strPort, sizeof(strPort), "%d", port);
906 strPort[79] = '\0';
907
908 ret = getaddrinfo(peer, strPort, &hints, &answer);
909 if (ret < 0 || answer == NULL)
910 err_sys("getaddrinfo failed");
911
912 XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen);
913 freeaddrinfo(answer);
914 #else
915 printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
916 addr->sin6_addr = in6addr_loopback;
917 #endif
918 }
919#endif
920}
921
922
923static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
924{
925 (void)sctp;
926
927 if (udp)
928 *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
929#ifdef WOLFSSL_SCTP
930 else if (sctp)
931 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
932#endif
933 else
934 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
935
936 if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
937 err_sys("socket failed\n");
938 }
939
940#ifndef USE_WINDOWS_API
941#ifdef SO_NOSIGPIPE
942 {
943 int on = 1;
944 socklen_t len = sizeof(on);
945 int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
946 if (res < 0)
947 err_sys("setsockopt SO_NOSIGPIPE failed\n");
948 }
949#elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
950 defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR)
951 /* nothing to define */
952#else /* no S_NOSIGPIPE */
953 signal(SIGPIPE, SIG_IGN);
954#endif /* S_NOSIGPIPE */
955
956#if defined(TCP_NODELAY)
957 if (!udp && !sctp)
958 {
959 int on = 1;
960 socklen_t len = sizeof(on);
961 int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
962 if (res < 0)
963 err_sys("setsockopt TCP_NODELAY failed\n");
964 }
965#endif
966#endif /* USE_WINDOWS_API */
967}
968
969static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
970 int udp, int sctp, WOLFSSL* ssl)
971{
972 SOCKADDR_IN_T addr;
973 build_addr(&addr, ip, port, udp, sctp);
974 if (udp) {
975 wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
976 }
977 tcp_socket(sockfd, udp, sctp);
978
979 if (!udp) {
980 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
981 err_sys("tcp connect failed");
982 }
983}
984
985
986static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
987{
988 if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
989 err_sys("tcp connect failed");
990}
991
992
993enum {
994 TEST_SELECT_FAIL,
995 TEST_TIMEOUT,
996 TEST_RECV_READY,
997 TEST_SEND_READY,
998 TEST_ERROR_READY
999};
1000
1001
1002#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
1003 !defined(WOLFSSL_TIRTOS)
1004static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx)
1005{
1006 fd_set fds, errfds;
1007 fd_set* recvfds = NULL;
1008 fd_set* sendfds = NULL;
1009 SOCKET_T nfds = socketfd + 1;
1010#if !defined(__INTEGRITY)
1011 struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0};
1012#else
1013 struct timeval timeout;
1014#endif
1015 int result;
1016
1017 FD_ZERO(&fds);
1018 FD_SET(socketfd, &fds);
1019 FD_ZERO(&errfds);
1020 FD_SET(socketfd, &errfds);
1021
1022 if (rx)
1023 recvfds = &fds;
1024 else
1025 sendfds = &fds;
1026
1027#if defined(__INTEGRITY)
1028 timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0;
1029#endif
1030 result = select(nfds, recvfds, sendfds, &errfds, &timeout);
1031
1032 if (result == 0)
1033 return TEST_TIMEOUT;
1034 else if (result > 0) {
1035 if (FD_ISSET(socketfd, &fds)) {
1036 if (rx)
1037 return TEST_RECV_READY;
1038 else
1039 return TEST_SEND_READY;
1040 }
1041 else if(FD_ISSET(socketfd, &errfds))
1042 return TEST_ERROR_READY;
1043 }
1044
1045 return TEST_SELECT_FAIL;
1046}
1047
1048static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
1049{
1050 return tcp_select_ex(socketfd, to_sec, 1);
1051}
1052
1053static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
1054{
1055 return tcp_select_ex(socketfd, to_sec, 0);
1056}
1057
1058#elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET)
1059static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
1060{
1061 return TEST_RECV_READY;
1062}
1063static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
1064{
1065 return TEST_SEND_READY;
1066}
1067#endif /* !WOLFSSL_MDK_ARM */
1068
1069
1070static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
1071 int udp, int sctp)
1072{
1073 SOCKADDR_IN_T addr;
1074
1075 /* don't use INADDR_ANY by default, firewall may block, make user switch
1076 on */
1077 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp);
1078 tcp_socket(sockfd, udp, sctp);
1079
1080#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
1081 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1082 {
1083 int res, on = 1;
1084 socklen_t len = sizeof(on);
1085 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
1086 if (res < 0)
1087 err_sys("setsockopt SO_REUSEADDR failed\n");
1088 }
1089#endif
1090
1091 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1092 err_sys("tcp bind failed");
1093 if (!udp) {
1094 #ifdef WOLFSSL_KEIL_TCP_NET
1095 #define SOCK_LISTEN_MAX_QUEUE 1
1096 #else
1097 #define SOCK_LISTEN_MAX_QUEUE 5
1098 #endif
1099 if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0)
1100 err_sys("tcp listen failed");
1101 }
1102 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) \
1103 && !defined(WOLFSSL_ZEPHYR)
1104 if (*port == 0) {
1105 socklen_t len = sizeof(addr);
1106 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
1107 #ifndef TEST_IPV6
1108 *port = XNTOHS(addr.sin_port);
1109 #else
1110 *port = XNTOHS(addr.sin6_port);
1111 #endif
1112 }
1113 }
1114 #endif
1115}
1116
1117
1118#if 0
1119static WC_INLINE int udp_read_connect(SOCKET_T sockfd)
1120{
1121 SOCKADDR_IN_T cliaddr;
1122 byte b[1500];
1123 int n;
1124 socklen_t len = sizeof(cliaddr);
1125
1126 n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
1127 (struct sockaddr*)&cliaddr, &len);
1128 if (n > 0) {
1129 if (connect(sockfd, (const struct sockaddr*)&cliaddr,
1130 sizeof(cliaddr)) != 0)
1131 err_sys("udp connect failed");
1132 }
1133 else
1134 err_sys("recvfrom failed");
1135
1136 return sockfd;
1137}
1138#endif
1139
1140static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
1141 int useAnyAddr, word16 port, func_args* args)
1142{
1143 SOCKADDR_IN_T addr;
1144
1145 (void)args;
1146 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0);
1147 tcp_socket(sockfd, 1, 0);
1148
1149
1150#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
1151 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1152 {
1153 int res, on = 1;
1154 socklen_t len = sizeof(on);
1155 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
1156 if (res < 0)
1157 err_sys("setsockopt SO_REUSEADDR failed\n");
1158 }
1159#endif
1160
1161 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1162 err_sys("tcp bind failed");
1163
1164 #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
1165 if (port == 0) {
1166 socklen_t len = sizeof(addr);
1167 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
1168 #ifndef TEST_IPV6
1169 port = XNTOHS(addr.sin_port);
1170 #else
1171 port = XNTOHS(addr.sin6_port);
1172 #endif
1173 }
1174 }
1175 #endif
1176
1177#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
1178 /* signal ready to accept data */
1179 {
1180 tcp_ready* ready = args->signal;
1181 pthread_mutex_lock(&ready->mutex);
1182 ready->ready = 1;
1183 ready->port = port;
1184 pthread_cond_signal(&ready->cond);
1185 pthread_mutex_unlock(&ready->mutex);
1186 }
1187#elif defined (WOLFSSL_TIRTOS)
1188 /* Need mutex? */
1189 tcp_ready* ready = args->signal;
1190 ready->ready = 1;
1191 ready->port = port;
1192#else
1193 (void)port;
1194#endif
1195
1196 *clientfd = *sockfd;
1197}
1198
1199static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
1200 func_args* args, word16 port, int useAnyAddr,
1201 int udp, int sctp, int ready_file, int do_listen)
1202{
1203 SOCKADDR_IN_T client;
1204 socklen_t client_len = sizeof(client);
1205 tcp_ready* ready = NULL;
1206
1207 (void) ready; /* Account for case when "ready" is not used */
1208
1209 if (udp) {
1210 udp_accept(sockfd, clientfd, useAnyAddr, port, args);
1211 return;
1212 }
1213
1214 if(do_listen) {
1215 tcp_listen(sockfd, &port, useAnyAddr, udp, sctp);
1216
1217 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
1218 /* signal ready to tcp_accept */
1219 if (args)
1220 ready = args->signal;
1221 if (ready) {
1222 pthread_mutex_lock(&ready->mutex);
1223 ready->ready = 1;
1224 ready->port = port;
1225 pthread_cond_signal(&ready->cond);
1226 pthread_mutex_unlock(&ready->mutex);
1227 }
1228 #elif defined (WOLFSSL_TIRTOS)
1229 /* Need mutex? */
1230 if (args)
1231 ready = args->signal;
1232 if (ready) {
1233 ready->ready = 1;
1234 ready->port = port;
1235 }
1236 #endif
1237
1238 if (ready_file) {
1239 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
1240 XFILE srf = NULL;
1241 if (args)
1242 ready = args->signal;
1243
1244 if (ready) {
1245 srf = XFOPEN(ready->srfName, "w");
1246
1247 if (srf) {
1248 /* let's write port sever is listening on to ready file
1249 external monitor can then do ephemeral ports by passing
1250 -p 0 to server on supported platforms with -R ready_file
1251 client can then wait for existence of ready_file and see
1252 which port the server is listening on. */
1253 fprintf(srf, "%d\n", (int)port);
1254 fclose(srf);
1255 }
1256 }
1257 #endif
1258 }
1259 }
1260
1261 *clientfd = accept(*sockfd, (struct sockaddr*)&client,
1262 (ACCEPT_THIRD_T)&client_len);
1263 if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
1264 err_sys("tcp accept failed");
1265 }
1266}
1267
1268
1269static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
1270{
1271 #ifdef USE_WINDOWS_API
1272 unsigned long blocking = 1;
1273 int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
1274 if (ret == SOCKET_ERROR)
1275 err_sys("ioctlsocket failed");
1276 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
1277 || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \
1278 || defined(WOLFSSL_ZEPHYR)
1279 /* non blocking not supported, for now */
1280 #else
1281 int flags = fcntl(*sockfd, F_GETFL, 0);
1282 if (flags < 0)
1283 err_sys("fcntl get failed");
1284 flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
1285 if (flags < 0)
1286 err_sys("fcntl set failed");
1287 #endif
1288}
1289
1290
1291#ifndef NO_PSK
1292
1293/* identity is OpenSSL testing default for openssl s_client, keep same */
1294static const char* kIdentityStr = "Client_identity";
1295
1296static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
1297 char* identity, unsigned int id_max_len, unsigned char* key,
1298 unsigned int key_max_len)
1299{
1300 (void)ssl;
1301 (void)hint;
1302 (void)key_max_len;
1303
1304 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1305 strncpy(identity, kIdentityStr, id_max_len);
1306
1307 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
1308 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
1309 unsigned binary */
1310 key[0] = 0x1a;
1311 key[1] = 0x2b;
1312 key[2] = 0x3c;
1313 key[3] = 0x4d;
1314
1315 return 4; /* length of key in octets or 0 for error */
1316 }
1317 else {
1318 int i;
1319 int b = 0x01;
1320
1321 for (i = 0; i < 32; i++, b += 0x22) {
1322 if (b >= 0x100)
1323 b = 0x01;
1324 key[i] = b;
1325 }
1326
1327 return 32; /* length of key in octets or 0 for error */
1328 }
1329}
1330
1331
1332static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
1333 unsigned char* key, unsigned int key_max_len)
1334{
1335 (void)ssl;
1336 (void)key_max_len;
1337
1338 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1339 if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0)
1340 return 0;
1341
1342 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
1343 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
1344 unsigned binary */
1345 key[0] = 0x1a;
1346 key[1] = 0x2b;
1347 key[2] = 0x3c;
1348 key[3] = 0x4d;
1349
1350 return 4; /* length of key in octets or 0 for error */
1351 }
1352 else {
1353 int i;
1354 int b = 0x01;
1355
1356 for (i = 0; i < 32; i++, b += 0x22) {
1357 if (b >= 0x100)
1358 b = 0x01;
1359 key[i] = b;
1360 }
1361
1362 return 32; /* length of key in octets or 0 for error */
1363 }
1364}
1365
1366
1367static WC_INLINE unsigned int my_psk_client_tls13_cb(WOLFSSL* ssl,
1368 const char* hint, char* identity, unsigned int id_max_len,
1369 unsigned char* key, unsigned int key_max_len, const char** ciphersuite)
1370{
1371 int i;
1372 int b = 0x01;
1373
1374 (void)ssl;
1375 (void)hint;
1376 (void)key_max_len;
1377
1378 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1379 strncpy(identity, kIdentityStr, id_max_len);
1380
1381 for (i = 0; i < 32; i++, b += 0x22) {
1382 if (b >= 0x100)
1383 b = 0x01;
1384 key[i] = b;
1385 }
1386
1387 *ciphersuite = "TLS13-AES128-GCM-SHA256";
1388
1389 return 32; /* length of key in octets or 0 for error */
1390}
1391
1392
1393static WC_INLINE unsigned int my_psk_server_tls13_cb(WOLFSSL* ssl,
1394 const char* identity, unsigned char* key, unsigned int key_max_len,
1395 const char** ciphersuite)
1396{
1397 int i;
1398 int b = 0x01;
1399
1400 (void)ssl;
1401 (void)key_max_len;
1402
1403 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1404 if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0)
1405 return 0;
1406
1407 for (i = 0; i < 32; i++, b += 0x22) {
1408 if (b >= 0x100)
1409 b = 0x01;
1410 key[i] = b;
1411 }
1412
1413 *ciphersuite = "TLS13-AES128-GCM-SHA256";
1414
1415 return 32; /* length of key in octets or 0 for error */
1416}
1417
1418#endif /* NO_PSK */
1419
1420
1421#if defined(WOLFSSL_USER_CURRTIME)
1422 extern double current_time(int reset);
1423
1424#elif defined(USE_WINDOWS_API)
1425
1426 #define WIN32_LEAN_AND_MEAN
1427 #include <windows.h>
1428
1429 static WC_INLINE double current_time(int reset)
1430 {
1431 static int init = 0;
1432 static LARGE_INTEGER freq;
1433
1434 LARGE_INTEGER count;
1435
1436 if (!init) {
1437 QueryPerformanceFrequency(&freq);
1438 init = 1;
1439 }
1440
1441 QueryPerformanceCounter(&count);
1442
1443 (void)reset;
1444 return (double)count.QuadPart / freq.QuadPart;
1445 }
1446
1447#elif defined(WOLFSSL_TIRTOS)
1448 extern double current_time();
1449#elif defined(WOLFSSL_ZEPHYR)
1450 extern double current_time();
1451#else
1452
1453#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS)
1454 #include <sys/time.h>
1455
1456 static WC_INLINE double current_time(int reset)
1457 {
1458 struct timeval tv;
1459 gettimeofday(&tv, 0);
1460 (void)reset;
1461
1462 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
1463 }
1464#else
1465 extern double current_time(int reset);
1466#endif
1467#endif /* USE_WINDOWS_API */
1468
1469
1470#if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP)
1471static WC_INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz,
1472 unsigned char* request, int requestSz, unsigned char** response)
1473{
1474#ifdef TEST_NONBLOCK_CERTS
1475 static int ioCbCnt = 0;
1476#endif
1477
1478 (void)ioCtx;
1479 (void)url;
1480 (void)urlSz;
1481 (void)request;
1482 (void)requestSz;
1483 (void)response;
1484
1485#ifdef TEST_NONBLOCK_CERTS
1486 if (ioCbCnt) {
1487 ioCbCnt = 0;
1488 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
1489 }
1490 else {
1491 ioCbCnt = 1;
1492 return WOLFSSL_CBIO_ERR_WANT_READ;
1493 }
1494#else
1495 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
1496#endif
1497}
1498
1499static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response)
1500{
1501 (void)ioCtx;
1502 (void)response;
1503}
1504#endif
1505
1506#if !defined(NO_CERTS)
1507 #if !defined(NO_FILESYSTEM) || \
1508 (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST))
1509
1510 /* reads file size, allocates buffer, reads into buffer, returns buffer */
1511 static WC_INLINE int load_file(const char* fname, byte** buf, size_t* bufLen)
1512 {
1513 int ret;
1514 long int fileSz;
1515 XFILE file;
1516
1517 if (fname == NULL || buf == NULL || bufLen == NULL)
1518 return BAD_FUNC_ARG;
1519
1520 /* set defaults */
1521 *buf = NULL;
1522 *bufLen = 0;
1523
1524 /* open file (read-only binary) */
1525 file = XFOPEN(fname, "rb");
1526 if (!file) {
1527 printf("Error loading %s\n", fname);
1528 return BAD_PATH_ERROR;
1529 }
1530
1531 fseek(file, 0, SEEK_END);
1532 fileSz = (int)ftell(file);
1533 rewind(file);
1534 if (fileSz > 0) {
1535 *bufLen = (size_t)fileSz;
1536 *buf = (byte*)malloc(*bufLen);
1537 if (*buf == NULL) {
1538 ret = MEMORY_E;
1539 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen);
1540 }
1541 else {
1542 size_t readLen = fread(*buf, *bufLen, 1, file);
1543
1544 /* check response code */
1545 ret = (readLen > 0) ? 0 : -1;
1546 }
1547 }
1548 else {
1549 ret = BUFFER_E;
1550 }
1551 fclose(file);
1552
1553 return ret;
1554 }
1555
1556 enum {
1557 WOLFSSL_CA = 1,
1558 WOLFSSL_CERT = 2,
1559 WOLFSSL_KEY = 3,
1560 WOLFSSL_CERT_CHAIN = 4,
1561 };
1562
1563 static WC_INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
1564 {
1565 int format = WOLFSSL_FILETYPE_PEM;
1566 byte* buff = NULL;
1567 size_t sz = 0;
1568
1569 if (load_file(fname, &buff, &sz) != 0) {
1570 err_sys("can't open file for buffer load "
1571 "Please run from wolfSSL home directory if not");
1572 }
1573
1574 /* determine format */
1575 if (strstr(fname, ".der"))
1576 format = WOLFSSL_FILETYPE_ASN1;
1577
1578 if (type == WOLFSSL_CA) {
1579 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
1580 != WOLFSSL_SUCCESS)
1581 err_sys("can't load buffer ca file");
1582 }
1583 else if (type == WOLFSSL_CERT) {
1584 if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz,
1585 format) != WOLFSSL_SUCCESS)
1586 err_sys("can't load buffer cert file");
1587 }
1588 else if (type == WOLFSSL_KEY) {
1589 if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz,
1590 format) != WOLFSSL_SUCCESS)
1591 err_sys("can't load buffer key file");
1592 }
1593 else if (type == WOLFSSL_CERT_CHAIN) {
1594 if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff,
1595 (long)sz, format) != WOLFSSL_SUCCESS)
1596 err_sys("can't load cert chain buffer");
1597 }
1598
1599 if (buff)
1600 free(buff);
1601 }
1602
1603 static WC_INLINE void load_ssl_buffer(WOLFSSL* ssl, const char* fname, int type)
1604 {
1605 int format = WOLFSSL_FILETYPE_PEM;
1606 byte* buff = NULL;
1607 size_t sz = 0;
1608
1609 if (load_file(fname, &buff, &sz) != 0) {
1610 err_sys("can't open file for buffer load "
1611 "Please run from wolfSSL home directory if not");
1612 }
1613
1614 /* determine format */
1615 if (strstr(fname, ".der"))
1616 format = WOLFSSL_FILETYPE_ASN1;
1617
1618 if (type == WOLFSSL_CA) {
1619 /* verify certs (CA's) use the shared ctx->cm (WOLFSSL_CERT_MANAGER) */
1620 WOLFSSL_CTX* ctx = wolfSSL_get_SSL_CTX(ssl);
1621 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
1622 != WOLFSSL_SUCCESS)
1623 err_sys("can't load buffer ca file");
1624 }
1625 else if (type == WOLFSSL_CERT) {
1626 if (wolfSSL_use_certificate_buffer(ssl, buff, (long)sz,
1627 format) != WOLFSSL_SUCCESS)
1628 err_sys("can't load buffer cert file");
1629 }
1630 else if (type == WOLFSSL_KEY) {
1631 if (wolfSSL_use_PrivateKey_buffer(ssl, buff, (long)sz,
1632 format) != WOLFSSL_SUCCESS)
1633 err_sys("can't load buffer key file");
1634 }
1635 else if (type == WOLFSSL_CERT_CHAIN) {
1636 if (wolfSSL_use_certificate_chain_buffer_format(ssl, buff,
1637 (long)sz, format) != WOLFSSL_SUCCESS)
1638 err_sys("can't load cert chain buffer");
1639 }
1640
1641 if (buff)
1642 free(buff);
1643 }
1644
1645 #ifdef TEST_PK_PRIVKEY
1646 static WC_INLINE int load_key_file(const char* fname, byte** derBuf, word32* derLen)
1647 {
1648 int ret;
1649 byte* buf = NULL;
1650 size_t bufLen;
1651
1652 ret = load_file(fname, &buf, &bufLen);
1653 if (ret != 0)
1654 return ret;
1655
1656 *derBuf = (byte*)malloc(bufLen);
1657 if (*derBuf == NULL) {
1658 free(buf);
1659 return MEMORY_E;
1660 }
1661
1662 ret = wc_KeyPemToDer(buf, (word32)bufLen, *derBuf, (word32)bufLen, NULL);
1663 if (ret < 0) {
1664 free(buf);
1665 free(*derBuf);
1666 return ret;
1667 }
1668 *derLen = ret;
1669 free(buf);
1670
1671 return 0;
1672 }
1673 #endif /* TEST_PK_PRIVKEY */
1674
1675 #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */
1676#endif /* !NO_CERTS */
1677
1678static int myVerifyFail = 0;
1679
1680/* The verify callback is called for every certificate only when
1681 * --enable-opensslextra is defined because it sets WOLFSSL_ALWAYS_VERIFY_CB and
1682 * WOLFSSL_VERIFY_CB_ALL_CERTS.
1683 * Normal cases of the verify callback only occur on certificate failures when the
1684 * wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, myVerifyCb); is called
1685*/
1686
1687static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
1688{
1689 char buffer[WOLFSSL_MAX_ERROR_SZ];
1690#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1691 WOLFSSL_X509* peer;
1692#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
1693 WOLFSSL_BIO* bio = NULL;
1694 WOLFSSL_STACK* sk = NULL;
1695 X509* x509 = NULL;
1696 int i = 0;
1697#endif
1698#endif
1699 (void)preverify;
1700
1701 /* Verify Callback Arguments:
1702 * preverify: 1=Verify Okay, 0=Failure
1703 * store->error: Failure error code (0 indicates no failure)
1704 * store->current_cert: Current WOLFSSL_X509 object (only with OPENSSL_EXTRA)
1705 * store->error_depth: Current Index
1706 * store->domain: Subject CN as string (null term)
1707 * store->totalCerts: Number of certs presented by peer
1708 * store->certs[i]: A `WOLFSSL_BUFFER_INFO` with plain DER for each cert
1709 * store->store: WOLFSSL_X509_STORE with CA cert chain
1710 * store->store->cm: WOLFSSL_CERT_MANAGER
1711 * store->ex_data: The WOLFSSL object pointer
1712 * store->discardSessionCerts: When set to non-zero value session certs
1713 will be discarded (only with SESSION_CERTS)
1714 */
1715
1716 printf("In verification callback, error = %d, %s\n", store->error,
1717 wolfSSL_ERR_error_string(store->error, buffer));
1718#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1719 peer = store->current_cert;
1720 if (peer) {
1721 char* issuer = wolfSSL_X509_NAME_oneline(
1722 wolfSSL_X509_get_issuer_name(peer), 0, 0);
1723 char* subject = wolfSSL_X509_NAME_oneline(
1724 wolfSSL_X509_get_subject_name(peer), 0, 0);
1725 printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer,
1726 subject);
1727 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
1728 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
1729#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
1730/* avoid printing duplicate certs */
1731 if (store->depth == 1) {
1732 /* retrieve x509 certs and display them on stdout */
1733 sk = wolfSSL_X509_STORE_GetCerts(store);
1734
1735 for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
1736 x509 = wolfSSL_sk_X509_value(sk, i);
1737 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
1738 if (bio != NULL) {
1739 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
1740 wolfSSL_X509_print(bio, x509);
1741 wolfSSL_BIO_free(bio);
1742 }
1743 }
1744 wolfSSL_sk_X509_free(sk);
1745 }
1746#endif
1747 }
1748 else
1749 printf("\tPeer has no cert!\n");
1750#else
1751 printf("\tPeer certs: %d\n", store->totalCerts);
1752 #ifdef SHOW_CERTS
1753 { int i;
1754 for (i=0; i<store->totalCerts; i++) {
1755 WOLFSSL_BUFFER_INFO* cert = &store->certs[i];
1756 printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length);
1757 }
1758 }
1759 #endif /* SHOW_CERTS */
1760#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1761
1762 printf("\tSubject's domain name at %d is %s\n", store->error_depth, store->domain);
1763
1764 /* Testing forced fail case by return zero */
1765 if (myVerifyFail) {
1766 return 0; /* test failure case */
1767 }
1768
1769 /* If error indicate we are overriding it for testing purposes */
1770 if (store->error != 0) {
1771 printf("\tAllowing failed certificate check, testing only "
1772 "(shouldn't do this in production)\n");
1773 }
1774
1775 /* A non-zero return code indicates failure override */
1776 return 1;
1777}
1778
1779
1780static WC_INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store)
1781{
1782 char buffer[WOLFSSL_MAX_ERROR_SZ];
1783 (void)preverify;
1784
1785 printf("In verification callback, error = %d, %s\n", store->error,
1786 wolfSSL_ERR_error_string(store->error, buffer));
1787 printf("Subject's domain name is %s\n", store->domain);
1788
1789 if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
1790 printf("Overriding cert date error as example for bad clock testing\n");
1791 return 1;
1792 }
1793 printf("Cert error is not date error, not overriding\n");
1794
1795 return 0;
1796}
1797
1798
1799#ifdef HAVE_EXT_CACHE
1800
1801static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, unsigned char* id,
1802 int id_len, int* copy)
1803{
1804 (void)ssl;
1805 (void)id;
1806 (void)id_len;
1807 (void)copy;
1808
1809 /* using internal cache, this is for testing only */
1810 return NULL;
1811}
1812
1813static WC_INLINE int mySessNewCb(WOLFSSL* ssl, WOLFSSL_SESSION* session)
1814{
1815 (void)ssl;
1816 (void)session;
1817
1818 /* using internal cache, this is for testing only */
1819 return 0;
1820}
1821
1822static WC_INLINE void mySessRemCb(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
1823{
1824 (void)ctx;
1825 (void)session;
1826
1827 /* using internal cache, this is for testing only */
1828}
1829
1830#endif /* HAVE_EXT_CACHE */
1831
1832
1833#ifdef HAVE_CRL
1834
1835static WC_INLINE void CRL_CallBack(const char* url)
1836{
1837 printf("CRL callback url = %s\n", url);
1838}
1839
1840#endif
1841
1842#ifndef NO_DH
1843static WC_INLINE void SetDH(WOLFSSL* ssl)
1844{
1845 /* dh1024 p */
1846 static const unsigned char p[] =
1847 {
1848 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
1849 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
1850 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
1851 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
1852 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
1853 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
1854 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
1855 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
1856 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
1857 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
1858 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
1859 };
1860
1861 /* dh1024 g */
1862 static const unsigned char g[] =
1863 {
1864 0x02,
1865 };
1866
1867 wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
1868}
1869
1870static WC_INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
1871{
1872 /* dh1024 p */
1873 static const unsigned char p[] =
1874 {
1875 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
1876 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
1877 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
1878 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
1879 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
1880 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
1881 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
1882 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
1883 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
1884 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
1885 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
1886 };
1887
1888 /* dh1024 g */
1889 static const unsigned char g[] =
1890 {
1891 0x02,
1892 };
1893
1894 wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
1895}
1896#endif /* NO_DH */
1897
1898#ifndef NO_CERTS
1899
1900static WC_INLINE void CaCb(unsigned char* der, int sz, int type)
1901{
1902 (void)der;
1903 printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
1904}
1905
1906#endif /* !NO_CERTS */
1907
1908
1909/* Wolf Root Directory Helper */
1910/* KEIL-RL File System does not support relative directory */
1911#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS)
1912 /* Maximum depth to search for WolfSSL root */
1913 #define MAX_WOLF_ROOT_DEPTH 5
1914
1915 static WC_INLINE int ChangeToWolfRoot(void)
1916 {
1917 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
1918 int depth, res;
1919 XFILE file;
1920 for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
1921 file = XFOPEN(ntruKeyFile, "rb");
1922 if (file != NULL) {
1923 fclose(file);
1924 return depth;
1925 }
1926 #ifdef USE_WINDOWS_API
1927 res = SetCurrentDirectoryA("..\\");
1928 #else
1929 res = chdir("../");
1930 #endif
1931 if (res < 0) {
1932 printf("chdir to ../ failed!\n");
1933 break;
1934 }
1935 }
1936
1937 err_sys("wolf root not found");
1938 return -1;
1939 #else
1940 return 0;
1941 #endif
1942 }
1943#endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */
1944
1945#ifdef HAVE_STACK_SIZE
1946
1947typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
1948#define STACK_CHECK_VAL 0x01
1949
1950static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
1951{
1952 int ret, i, used;
1953 void* status;
1954 unsigned char* myStack = NULL;
1955 int stackSize = 1024*152;
1956 pthread_attr_t myAttr;
1957 pthread_t threadId;
1958
1959#ifdef PTHREAD_STACK_MIN
1960 if (stackSize < PTHREAD_STACK_MIN)
1961 stackSize = PTHREAD_STACK_MIN;
1962#endif
1963
1964 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
1965 if (ret != 0 || myStack == NULL)
1966 err_sys("posix_memalign failed\n");
1967
1968 XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
1969
1970 ret = pthread_attr_init(&myAttr);
1971 if (ret != 0)
1972 err_sys("attr_init failed");
1973
1974 ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
1975 if (ret != 0)
1976 err_sys("attr_setstackaddr failed");
1977
1978 ret = pthread_create(&threadId, &myAttr, tf, args);
1979 if (ret != 0) {
1980 perror("pthread_create failed");
1981 exit(EXIT_FAILURE);
1982 }
1983
1984 ret = pthread_join(threadId, &status);
1985 if (ret != 0)
1986 err_sys("pthread_join failed");
1987
1988 for (i = 0; i < stackSize; i++) {
1989 if (myStack[i] != STACK_CHECK_VAL) {
1990 break;
1991 }
1992 }
1993
1994 free(myStack);
1995
1996 used = stackSize - i;
1997 printf("stack used = %d\n", used);
1998
1999 return (int)((size_t)status);
2000}
2001
2002
2003#endif /* HAVE_STACK_SIZE */
2004
2005
2006#ifdef STACK_TRAP
2007
2008/* good settings
2009 --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
2010
2011*/
2012
2013#ifdef HAVE_STACK_SIZE
2014 /* client only for now, setrlimit will fail if pthread_create() called */
2015 /* STACK_SIZE does pthread_create() on client */
2016 #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
2017#endif /* HAVE_STACK_SIZE */
2018
2019static WC_INLINE void StackTrap(void)
2020{
2021 struct rlimit rl;
2022 if (getrlimit(RLIMIT_STACK, &rl) != 0)
2023 err_sys("getrlimit failed");
2024 printf("rlim_cur = %llu\n", rl.rlim_cur);
2025 rl.rlim_cur = 1024*21; /* adjust trap size here */
2026 if (setrlimit(RLIMIT_STACK, &rl) != 0) {
2027 perror("setrlimit");
2028 err_sys("setrlimit failed");
2029 }
2030}
2031
2032#else /* STACK_TRAP */
2033
2034static WC_INLINE void StackTrap(void)
2035{
2036}
2037
2038#endif /* STACK_TRAP */
2039
2040
2041#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
2042
2043/* Atomic Encrypt Context example */
2044typedef struct AtomicEncCtx {
2045 int keySetup; /* have we done key setup yet */
2046 Aes aes; /* for aes example */
2047} AtomicEncCtx;
2048
2049
2050/* Atomic Decrypt Context example */
2051typedef struct AtomicDecCtx {
2052 int keySetup; /* have we done key setup yet */
2053 Aes aes; /* for aes example */
2054} AtomicDecCtx;
2055
2056
2057static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut,
2058 const unsigned char* macIn, unsigned int macInSz, int macContent,
2059 int macVerify, unsigned char* encOut, const unsigned char* encIn,
2060 unsigned int encSz, void* ctx)
2061{
2062 int ret;
2063 Hmac hmac;
2064 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2065 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
2066 const char* tlsStr = "TLS";
2067
2068 /* example supports (d)tls aes */
2069 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2070 printf("myMacEncryptCb not using AES\n");
2071 return -1;
2072 }
2073
2074 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2075 printf("myMacEncryptCb not using (D)TLS\n");
2076 return -1;
2077 }
2078
2079 /* hmac, not needed if aead mode */
2080 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
2081
2082 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2083 if (ret != 0)
2084 return ret;
2085 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2086 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
2087 if (ret != 0)
2088 return ret;
2089 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2090 if (ret != 0)
2091 return ret;
2092 ret = wc_HmacUpdate(&hmac, macIn, macInSz);
2093 if (ret != 0)
2094 return ret;
2095 ret = wc_HmacFinal(&hmac, macOut);
2096 if (ret != 0)
2097 return ret;
2098
2099
2100 /* encrypt setup on first time */
2101 if (encCtx->keySetup == 0) {
2102 int keyLen = wolfSSL_GetKeySize(ssl);
2103 const byte* key;
2104 const byte* iv;
2105
2106 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
2107 key = wolfSSL_GetClientWriteKey(ssl);
2108 iv = wolfSSL_GetClientWriteIV(ssl);
2109 }
2110 else {
2111 key = wolfSSL_GetServerWriteKey(ssl);
2112 iv = wolfSSL_GetServerWriteIV(ssl);
2113 }
2114
2115 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
2116 if (ret != 0) {
2117 printf("AesSetKey failed in myMacEncryptCb\n");
2118 return ret;
2119 }
2120 encCtx->keySetup = 1;
2121 }
2122
2123 /* encrypt */
2124 return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
2125}
2126
2127
2128static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl,
2129 unsigned char* decOut, const unsigned char* decIn,
2130 unsigned int decSz, int macContent, int macVerify,
2131 unsigned int* padSz, void* ctx)
2132{
2133 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
2134 int ret = 0;
2135 int macInSz = 0;
2136 int ivExtra = 0;
2137 int digestSz = wolfSSL_GetHmacSize(ssl);
2138 unsigned int pad = 0;
2139 unsigned int padByte = 0;
2140 Hmac hmac;
2141 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2142 byte verify[WC_MAX_DIGEST_SIZE];
2143 const char* tlsStr = "TLS";
2144
2145 /* example supports (d)tls aes */
2146 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2147 printf("myMacEncryptCb not using AES\n");
2148 return -1;
2149 }
2150
2151 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2152 printf("myMacEncryptCb not using (D)TLS\n");
2153 return -1;
2154 }
2155
2156 /*decrypt */
2157 if (decCtx->keySetup == 0) {
2158 int keyLen = wolfSSL_GetKeySize(ssl);
2159 const byte* key;
2160 const byte* iv;
2161
2162 /* decrypt is from other side (peer) */
2163 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
2164 key = wolfSSL_GetClientWriteKey(ssl);
2165 iv = wolfSSL_GetClientWriteIV(ssl);
2166 }
2167 else {
2168 key = wolfSSL_GetServerWriteKey(ssl);
2169 iv = wolfSSL_GetServerWriteIV(ssl);
2170 }
2171
2172 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
2173 if (ret != 0) {
2174 printf("AesSetKey failed in myDecryptVerifyCb\n");
2175 return ret;
2176 }
2177 decCtx->keySetup = 1;
2178 }
2179
2180 /* decrypt */
2181 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
2182 if (ret != 0)
2183 return ret;
2184
2185 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
2186 *padSz = wolfSSL_GetAeadMacSize(ssl);
2187 return 0; /* hmac, not needed if aead mode */
2188 }
2189
2190 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
2191 pad = *(decOut + decSz - 1);
2192 padByte = 1;
2193 if (wolfSSL_IsTLSv1_1(ssl))
2194 ivExtra = wolfSSL_GetCipherBlockSize(ssl);
2195 }
2196
2197 *padSz = wolfSSL_GetHmacSize(ssl) + pad + padByte;
2198 macInSz = decSz - ivExtra - digestSz - pad - padByte;
2199
2200 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
2201
2202 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2203 if (ret != 0)
2204 return ret;
2205 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2206 wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
2207 if (ret != 0)
2208 return ret;
2209 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2210 if (ret != 0)
2211 return ret;
2212 ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
2213 if (ret != 0)
2214 return ret;
2215 ret = wc_HmacFinal(&hmac, verify);
2216 if (ret != 0)
2217 return ret;
2218
2219 if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte,
2220 digestSz) != 0) {
2221 printf("myDecryptVerify verify failed\n");
2222 return -1;
2223 }
2224
2225 return ret;
2226}
2227
2228#if defined(HAVE_ENCRYPT_THEN_MAC)
2229
2230static WC_INLINE int myEncryptMacCb(WOLFSSL* ssl, unsigned char* macOut,
2231 int content, int macVerify, unsigned char* encOut,
2232 const unsigned char* encIn, unsigned int encSz, void* ctx)
2233{
2234 int ret;
2235 Hmac hmac;
2236 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
2237 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2238 const char* tlsStr = "TLS";
2239
2240 /* example supports (d)tls aes */
2241 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2242 printf("myMacEncryptCb not using AES\n");
2243 return -1;
2244 }
2245
2246 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2247 printf("myMacEncryptCb not using (D)TLS\n");
2248 return -1;
2249 }
2250
2251 /* encrypt setup on first time */
2252 if (encCtx->keySetup == 0) {
2253 int keyLen = wolfSSL_GetKeySize(ssl);
2254 const byte* key;
2255 const byte* iv;
2256
2257 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
2258 key = wolfSSL_GetClientWriteKey(ssl);
2259 iv = wolfSSL_GetClientWriteIV(ssl);
2260 }
2261 else {
2262 key = wolfSSL_GetServerWriteKey(ssl);
2263 iv = wolfSSL_GetServerWriteIV(ssl);
2264 }
2265
2266 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
2267 if (ret != 0) {
2268 printf("AesSetKey failed in myMacEncryptCb\n");
2269 return ret;
2270 }
2271 encCtx->keySetup = 1;
2272 }
2273
2274 /* encrypt */
2275 ret = wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
2276 if (ret != 0)
2277 return ret;
2278
2279 /* Reconstruct record header. */
2280 wolfSSL_SetTlsHmacInner(ssl, myInner, encSz, content, macVerify);
2281
2282 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2283 if (ret != 0)
2284 return ret;
2285 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2286 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
2287 if (ret != 0)
2288 return ret;
2289 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2290 if (ret != 0)
2291 return ret;
2292 ret = wc_HmacUpdate(&hmac, encOut, encSz);
2293 if (ret != 0)
2294 return ret;
2295 return wc_HmacFinal(&hmac, macOut);
2296}
2297
2298
2299static WC_INLINE int myVerifyDecryptCb(WOLFSSL* ssl,
2300 unsigned char* decOut, const unsigned char* decIn,
2301 unsigned int decSz, int content, int macVerify,
2302 unsigned int* padSz, void* ctx)
2303{
2304 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
2305 int ret = 0;
2306 int digestSz = wolfSSL_GetHmacSize(ssl);
2307 Hmac hmac;
2308 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2309 byte verify[WC_MAX_DIGEST_SIZE];
2310 const char* tlsStr = "TLS";
2311
2312 /* example supports (d)tls aes */
2313 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2314 printf("myMacEncryptCb not using AES\n");
2315 return -1;
2316 }
2317
2318 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2319 printf("myMacEncryptCb not using (D)TLS\n");
2320 return -1;
2321 }
2322
2323 /* Reconstruct record header. */
2324 wolfSSL_SetTlsHmacInner(ssl, myInner, decSz, content, macVerify);
2325
2326 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2327 if (ret != 0)
2328 return ret;
2329 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2330 wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
2331 if (ret != 0)
2332 return ret;
2333 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2334 if (ret != 0)
2335 return ret;
2336 ret = wc_HmacUpdate(&hmac, decIn, decSz);
2337 if (ret != 0)
2338 return ret;
2339 ret = wc_HmacFinal(&hmac, verify);
2340 if (ret != 0)
2341 return ret;
2342
2343 if (XMEMCMP(verify, decOut + decSz, digestSz) != 0) {
2344 printf("myDecryptVerify verify failed\n");
2345 return -1;
2346 }
2347
2348 /* decrypt */
2349 if (decCtx->keySetup == 0) {
2350 int keyLen = wolfSSL_GetKeySize(ssl);
2351 const byte* key;
2352 const byte* iv;
2353
2354 /* decrypt is from other side (peer) */
2355 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
2356 key = wolfSSL_GetClientWriteKey(ssl);
2357 iv = wolfSSL_GetClientWriteIV(ssl);
2358 }
2359 else {
2360 key = wolfSSL_GetServerWriteKey(ssl);
2361 iv = wolfSSL_GetServerWriteIV(ssl);
2362 }
2363
2364 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
2365 if (ret != 0) {
2366 printf("AesSetKey failed in myDecryptVerifyCb\n");
2367 return ret;
2368 }
2369 decCtx->keySetup = 1;
2370 }
2371
2372 /* decrypt */
2373 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
2374 if (ret != 0)
2375 return ret;
2376
2377 *padSz = *(decOut + decSz - 1) + 1;
2378
2379 return 0;
2380}
2381
2382#endif
2383
2384
2385static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2386{
2387 AtomicEncCtx* encCtx;
2388 AtomicDecCtx* decCtx;
2389
2390 encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
2391 if (encCtx == NULL)
2392 err_sys("AtomicEncCtx malloc failed");
2393 XMEMSET(encCtx, 0, sizeof(AtomicEncCtx));
2394
2395 decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
2396 if (decCtx == NULL) {
2397 free(encCtx);
2398 err_sys("AtomicDecCtx malloc failed");
2399 }
2400 XMEMSET(decCtx, 0, sizeof(AtomicDecCtx));
2401
2402 wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
2403 wolfSSL_SetMacEncryptCtx(ssl, encCtx);
2404
2405 wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
2406 wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
2407
2408#if defined(HAVE_ENCRYPT_THEN_MAC)
2409 wolfSSL_CTX_SetEncryptMacCb(ctx, myEncryptMacCb);
2410 wolfSSL_SetEncryptMacCtx(ssl, encCtx);
2411
2412 wolfSSL_CTX_SetVerifyDecryptCb(ctx, myVerifyDecryptCb);
2413 wolfSSL_SetVerifyDecryptCtx(ssl, decCtx);
2414#endif
2415}
2416
2417
2418static WC_INLINE void FreeAtomicUser(WOLFSSL* ssl)
2419{
2420 AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
2421 AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
2422
2423 /* Encrypt-Then-MAC callbacks use same contexts. */
2424
2425 free(decCtx);
2426 free(encCtx);
2427}
2428
2429#endif /* ATOMIC_USER */
2430
2431#ifdef WOLFSSL_STATIC_MEMORY
2432static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats)
2433{
2434 word16 i;
2435
2436 if (stats == NULL) {
2437 return 0;
2438 }
2439
2440 /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */
2441 fprintf(stderr, "Total mallocs = %d\n", stats->totalAlloc);
2442 fprintf(stderr, "Total frees = %d\n", stats->totalFr);
2443 fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc);
2444 fprintf(stderr, "Available IO = %d\n", stats->avaIO);
2445 fprintf(stderr, "Max con. handshakes = %d\n", stats->maxHa);
2446 fprintf(stderr, "Max con. IO = %d\n", stats->maxIO);
2447 fprintf(stderr, "State of memory blocks: size : available \n");
2448 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
2449 fprintf(stderr, " : %d\t : %d\n", stats->blockSz[i],
2450 stats->avaBlock[i]);
2451 }
2452
2453 return 1;
2454}
2455#endif /* WOLFSSL_STATIC_MEMORY */
2456
2457#ifdef HAVE_PK_CALLBACKS
2458
2459typedef struct PkCbInfo {
2460 const char* ourKey;
2461#ifdef TEST_PK_PRIVKEY
2462 union {
2463 #ifdef HAVE_ECC
2464 ecc_key ecc;
2465 #endif
2466 #ifdef HAVE_CURVE25519
2467 curve25519_key curve;
2468 #endif
2469 #ifdef HAVE_CURVE448
2470 curve448_key curve;
2471 #endif
2472 } keyGen;
2473#endif
2474} PkCbInfo;
2475
2476#if defined(DEBUG_PK_CB) || defined(TEST_PK_PRIVKEY)
2477 #define WOLFSSL_PKMSG(_f_, ...) printf(_f_, ##__VA_ARGS__)
2478#else
2479 #define WOLFSSL_PKMSG(_f_, ...)
2480#endif
2481
2482#ifdef HAVE_ECC
2483
2484static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz,
2485 int ecc_curve, void* ctx)
2486{
2487 int ret;
2488 WC_RNG rng;
2489 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2490 ecc_key* new_key;
2491#ifdef TEST_PK_PRIVKEY
2492 byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES];
2493 word32 qxLen = sizeof(qx), qyLen = sizeof(qy);
2494
2495 new_key = &cbInfo->keyGen.ecc;
2496#else
2497 new_key = key;
2498#endif
2499
2500 (void)ssl;
2501 (void)cbInfo;
2502
2503 WOLFSSL_PKMSG("PK ECC KeyGen: keySz %d, Curve ID %d\n", keySz, ecc_curve);
2504
2505 ret = wc_InitRng(&rng);
2506 if (ret != 0)
2507 return ret;
2508
2509 ret = wc_ecc_init(new_key);
2510 if (ret == 0) {
2511 /* create new key */
2512 ret = wc_ecc_make_key_ex(&rng, keySz, new_key, ecc_curve);
2513
2514 #ifdef TEST_PK_PRIVKEY
2515 if (ret == 0) {
2516 /* extract public portion from new key into `key` arg */
2517 ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen);
2518 if (ret == 0) {
2519 /* load public portion only into key */
2520 ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ecc_curve);
2521 }
2522 (void)qxLen;
2523 (void)qyLen;
2524 }
2525 #endif
2526 }
2527
2528 WOLFSSL_PKMSG("PK ECC KeyGen: ret %d\n", ret);
2529
2530 wc_FreeRng(&rng);
2531
2532 return ret;
2533}
2534
2535static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
2536 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
2537{
2538 int ret;
2539 WC_RNG rng;
2540 word32 idx = 0;
2541 ecc_key myKey;
2542 byte* keyBuf = (byte*)key;
2543 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2544
2545 (void)ssl;
2546 (void)cbInfo;
2547
2548 WOLFSSL_PKMSG("PK ECC Sign: inSz %d, keySz %d\n", inSz, keySz);
2549
2550#ifdef TEST_PK_PRIVKEY
2551 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
2552 if (ret != 0)
2553 return ret;
2554#endif
2555
2556 ret = wc_InitRng(&rng);
2557 if (ret != 0)
2558 return ret;
2559
2560 ret = wc_ecc_init(&myKey);
2561 if (ret == 0) {
2562 ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
2563 if (ret == 0) {
2564 WOLFSSL_PKMSG("PK ECC Sign: Curve ID %d\n", myKey.dp->id);
2565 ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
2566 }
2567 wc_ecc_free(&myKey);
2568 }
2569 wc_FreeRng(&rng);
2570
2571#ifdef TEST_PK_PRIVKEY
2572 free(keyBuf);
2573#endif
2574
2575 WOLFSSL_PKMSG("PK ECC Sign: ret %d outSz %d\n", ret, *outSz);
2576
2577 return ret;
2578}
2579
2580
2581static WC_INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
2582 const byte* hash, word32 hashSz, const byte* key, word32 keySz,
2583 int* result, void* ctx)
2584{
2585 int ret;
2586 word32 idx = 0;
2587 ecc_key myKey;
2588 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2589
2590 (void)ssl;
2591 (void)cbInfo;
2592
2593 WOLFSSL_PKMSG("PK ECC Verify: sigSz %d, hashSz %d, keySz %d\n", sigSz, hashSz, keySz);
2594
2595 ret = wc_ecc_init(&myKey);
2596 if (ret == 0) {
2597 ret = wc_EccPublicKeyDecode(key, &idx, &myKey, keySz);
2598 if (ret == 0)
2599 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
2600 wc_ecc_free(&myKey);
2601 }
2602
2603 WOLFSSL_PKMSG("PK ECC Verify: ret %d, result %d\n", ret, *result);
2604
2605 return ret;
2606}
2607
2608static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
2609 unsigned char* pubKeyDer, unsigned int* pubKeySz,
2610 unsigned char* out, unsigned int* outlen,
2611 int side, void* ctx)
2612{
2613 int ret;
2614 ecc_key* privKey = NULL;
2615 ecc_key* pubKey = NULL;
2616 ecc_key tmpKey;
2617 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2618
2619 (void)ssl;
2620 (void)cbInfo;
2621
2622 WOLFSSL_PKMSG("PK ECC PMS: Side %s, Peer Curve %d\n",
2623 side == WOLFSSL_CLIENT_END ? "client" : "server", otherKey->dp->id);
2624
2625 ret = wc_ecc_init(&tmpKey);
2626 if (ret != 0) {
2627 return ret;
2628 }
2629
2630 /* for client: create and export public key */
2631 if (side == WOLFSSL_CLIENT_END) {
2632 WC_RNG rng;
2633
2634 privKey = &tmpKey;
2635 pubKey = otherKey;
2636
2637 ret = wc_InitRng(&rng);
2638 if (ret == 0) {
2639 ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id);
2640 #ifdef WOLFSSL_ASYNC_CRYPT
2641 if (ret == WC_PENDING_E) {
2642 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_NONE);
2643 }
2644 #endif
2645 if (ret == 0)
2646 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
2647 wc_FreeRng(&rng);
2648 }
2649 }
2650
2651 /* for server: import public key */
2652 else if (side == WOLFSSL_SERVER_END) {
2653 #ifdef TEST_PK_PRIVKEY
2654 privKey = &cbInfo->keyGen.ecc;
2655 #else
2656 privKey = otherKey;
2657 #endif
2658 pubKey = &tmpKey;
2659
2660 ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey,
2661 otherKey->dp->id);
2662 }
2663 else {
2664 ret = BAD_FUNC_ARG;
2665 }
2666
2667 /* generate shared secret and return it */
2668 if (ret == 0) {
2669 ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
2670
2671 #ifdef WOLFSSL_ASYNC_CRYPT
2672 if (ret == WC_PENDING_E) {
2673 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
2674 }
2675 #endif
2676 }
2677
2678#ifdef TEST_PK_PRIVKEY
2679 if (side == WOLFSSL_SERVER_END) {
2680 wc_ecc_free(&cbInfo->keyGen.ecc);
2681 }
2682#endif
2683
2684 wc_ecc_free(&tmpKey);
2685
2686 WOLFSSL_PKMSG("PK ECC PMS: ret %d, PubKeySz %d, OutLen %d\n", ret, *pubKeySz, *outlen);
2687
2688 return ret;
2689}
2690
2691#ifdef HAVE_ED25519
2692static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
2693 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
2694{
2695 int ret;
2696 word32 idx = 0;
2697 ed25519_key myKey;
2698 byte* keyBuf = (byte*)key;
2699 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2700
2701 (void)ssl;
2702 (void)cbInfo;
2703
2704 WOLFSSL_PKMSG("PK 25519 Sign: inSz %d, keySz %d\n", inSz, keySz);
2705
2706#ifdef TEST_PK_PRIVKEY
2707 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
2708 if (ret != 0)
2709 return ret;
2710#endif
2711
2712 ret = wc_ed25519_init(&myKey);
2713 if (ret == 0) {
2714 ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
2715 if (ret == 0)
2716 ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey);
2717 wc_ed25519_free(&myKey);
2718 }
2719
2720#ifdef TEST_PK_PRIVKEY
2721 free(keyBuf);
2722#endif
2723
2724 WOLFSSL_PKMSG("PK 25519 Sign: ret %d, outSz %d\n", ret, *outSz);
2725
2726 return ret;
2727}
2728
2729
2730static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
2731 const byte* msg, word32 msgSz, const byte* key, word32 keySz,
2732 int* result, void* ctx)
2733{
2734 int ret;
2735 ed25519_key myKey;
2736 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2737
2738 (void)ssl;
2739 (void)cbInfo;
2740
2741 WOLFSSL_PKMSG("PK 25519 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz, keySz);
2742
2743 ret = wc_ed25519_init(&myKey);
2744 if (ret == 0) {
2745 ret = wc_ed25519_import_public(key, keySz, &myKey);
2746 if (ret == 0) {
2747 ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
2748 }
2749 wc_ed25519_free(&myKey);
2750 }
2751
2752 WOLFSSL_PKMSG("PK 25519 Verify: ret %d, result %d\n", ret, *result);
2753
2754 return ret;
2755}
2756#endif /* HAVE_ED25519 */
2757
2758#ifdef HAVE_CURVE25519
2759static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key,
2760 unsigned int keySz, void* ctx)
2761{
2762 int ret;
2763 WC_RNG rng;
2764 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2765
2766 (void)ssl;
2767 (void)cbInfo;
2768
2769 WOLFSSL_PKMSG("PK 25519 KeyGen: keySz %d\n", keySz);
2770
2771 ret = wc_InitRng(&rng);
2772 if (ret != 0)
2773 return ret;
2774
2775 ret = wc_curve25519_make_key(&rng, keySz, key);
2776
2777 wc_FreeRng(&rng);
2778
2779 WOLFSSL_PKMSG("PK 25519 KeyGen: ret %d\n", ret);
2780
2781 return ret;
2782}
2783
2784static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey,
2785 unsigned char* pubKeyDer, unsigned int* pubKeySz,
2786 unsigned char* out, unsigned int* outlen,
2787 int side, void* ctx)
2788{
2789 int ret;
2790 curve25519_key* privKey = NULL;
2791 curve25519_key* pubKey = NULL;
2792 curve25519_key tmpKey;
2793 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2794
2795 (void)ssl;
2796 (void)cbInfo;
2797
2798 WOLFSSL_PKMSG("PK 25519 PMS: side %s\n",
2799 side == WOLFSSL_CLIENT_END ? "client" : "server");
2800
2801 ret = wc_curve25519_init(&tmpKey);
2802 if (ret != 0) {
2803 return ret;
2804 }
2805
2806 /* for client: create and export public key */
2807 if (side == WOLFSSL_CLIENT_END) {
2808 WC_RNG rng;
2809
2810 privKey = &tmpKey;
2811 pubKey = otherKey;
2812
2813 ret = wc_InitRng(&rng);
2814 if (ret == 0) {
2815 ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, privKey);
2816 if (ret == 0) {
2817 ret = wc_curve25519_export_public_ex(privKey, pubKeyDer,
2818 pubKeySz, EC25519_LITTLE_ENDIAN);
2819 }
2820 wc_FreeRng(&rng);
2821 }
2822 }
2823
2824 /* for server: import public key */
2825 else if (side == WOLFSSL_SERVER_END) {
2826 privKey = otherKey;
2827 pubKey = &tmpKey;
2828
2829 ret = wc_curve25519_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
2830 EC25519_LITTLE_ENDIAN);
2831 }
2832 else {
2833 ret = BAD_FUNC_ARG;
2834 }
2835
2836 /* generate shared secret and return it */
2837 if (ret == 0) {
2838 ret = wc_curve25519_shared_secret_ex(privKey, pubKey, out, outlen,
2839 EC25519_LITTLE_ENDIAN);
2840 }
2841
2842 wc_curve25519_free(&tmpKey);
2843
2844 WOLFSSL_PKMSG("PK 25519 PMS: ret %d, pubKeySz %d, outLen %d\n",
2845 ret, *pubKeySz, *outlen);
2846
2847 return ret;
2848}
2849#endif /* HAVE_CURVE25519 */
2850
2851#ifdef HAVE_ED448
2852static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
2853 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
2854{
2855 int ret;
2856 word32 idx = 0;
2857 ed448_key myKey;
2858 byte* keyBuf = (byte*)key;
2859 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2860
2861 (void)ssl;
2862 (void)cbInfo;
2863
2864 WOLFSSL_PKMSG("PK 448 Sign: inSz %d, keySz %d\n", inSz, keySz);
2865
2866#ifdef TEST_PK_PRIVKEY
2867 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
2868 if (ret != 0)
2869 return ret;
2870#endif
2871
2872 ret = wc_ed448_init(&myKey);
2873 if (ret == 0) {
2874 ret = wc_Ed448PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
2875 if (ret == 0)
2876 ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey);
2877 wc_ed448_free(&myKey);
2878 }
2879
2880#ifdef TEST_PK_PRIVKEY
2881 free(keyBuf);
2882#endif
2883
2884 WOLFSSL_PKMSG("PK 448 Sign: ret %d, outSz %d\n", ret, *outSz);
2885
2886 return ret;
2887}
2888
2889
2890static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
2891 const byte* msg, word32 msgSz, const byte* key, word32 keySz,
2892 int* result, void* ctx)
2893{
2894 int ret;
2895 ed448_key myKey;
2896 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2897
2898 (void)ssl;
2899 (void)cbInfo;
2900
2901 WOLFSSL_PKMSG("PK 448 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz,
2902 keySz);
2903
2904 ret = wc_ed448_init(&myKey);
2905 if (ret == 0) {
2906 ret = wc_ed448_import_public(key, keySz, &myKey);
2907 if (ret == 0) {
2908 ret = wc_ed448_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
2909 }
2910 wc_ed448_free(&myKey);
2911 }
2912
2913 WOLFSSL_PKMSG("PK 448 Verify: ret %d, result %d\n", ret, *result);
2914
2915 return ret;
2916}
2917#endif /* HAVE_ED448 */
2918
2919#ifdef HAVE_CURVE448
2920static WC_INLINE int myX448KeyGen(WOLFSSL* ssl, curve448_key* key,
2921 unsigned int keySz, void* ctx)
2922{
2923 int ret;
2924 WC_RNG rng;
2925 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2926
2927 (void)ssl;
2928 (void)cbInfo;
2929
2930 WOLFSSL_PKMSG("PK 448 KeyGen: keySz %d\n", keySz);
2931
2932 ret = wc_InitRng(&rng);
2933 if (ret != 0)
2934 return ret;
2935
2936 ret = wc_curve448_make_key(&rng, keySz, key);
2937
2938 wc_FreeRng(&rng);
2939
2940 WOLFSSL_PKMSG("PK 448 KeyGen: ret %d\n", ret);
2941
2942 return ret;
2943}
2944
2945static WC_INLINE int myX448SharedSecret(WOLFSSL* ssl, curve448_key* otherKey,
2946 unsigned char* pubKeyDer, unsigned int* pubKeySz,
2947 unsigned char* out, unsigned int* outlen,
2948 int side, void* ctx)
2949{
2950 int ret;
2951 curve448_key* privKey = NULL;
2952 curve448_key* pubKey = NULL;
2953 curve448_key tmpKey;
2954 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2955
2956 (void)ssl;
2957 (void)cbInfo;
2958
2959 WOLFSSL_PKMSG("PK 448 PMS: side %s\n",
2960 side == WOLFSSL_CLIENT_END ? "client" : "server");
2961
2962 ret = wc_curve448_init(&tmpKey);
2963 if (ret != 0) {
2964 return ret;
2965 }
2966
2967 /* for client: create and export public key */
2968 if (side == WOLFSSL_CLIENT_END) {
2969 WC_RNG rng;
2970
2971 privKey = &tmpKey;
2972 pubKey = otherKey;
2973
2974 ret = wc_InitRng(&rng);
2975 if (ret == 0) {
2976 ret = wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, privKey);
2977 if (ret == 0) {
2978 ret = wc_curve448_export_public_ex(privKey, pubKeyDer,
2979 pubKeySz, EC448_LITTLE_ENDIAN);
2980 }
2981 wc_FreeRng(&rng);
2982 }
2983 }
2984
2985 /* for server: import public key */
2986 else if (side == WOLFSSL_SERVER_END) {
2987 privKey = otherKey;
2988 pubKey = &tmpKey;
2989
2990 ret = wc_curve448_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
2991 EC448_LITTLE_ENDIAN);
2992 }
2993 else {
2994 ret = BAD_FUNC_ARG;
2995 }
2996
2997 /* generate shared secret and return it */
2998 if (ret == 0) {
2999 ret = wc_curve448_shared_secret_ex(privKey, pubKey, out, outlen,
3000 EC448_LITTLE_ENDIAN);
3001 }
3002
3003 wc_curve448_free(&tmpKey);
3004
3005 WOLFSSL_PKMSG("PK 448 PMS: ret %d, pubKeySz %d, outLen %d\n",
3006 ret, *pubKeySz, *outlen);
3007
3008 return ret;
3009}
3010#endif /* HAVE_CURVE448 */
3011
3012#endif /* HAVE_ECC */
3013
3014#ifndef NO_DH
3015static WC_INLINE int myDhCallback(WOLFSSL* ssl, struct DhKey* key,
3016 const unsigned char* priv, unsigned int privSz,
3017 const unsigned char* pubKeyDer, unsigned int pubKeySz,
3018 unsigned char* out, unsigned int* outlen,
3019 void* ctx)
3020{
3021 int ret;
3022 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3023
3024 (void)ssl;
3025 (void)cbInfo;
3026
3027 /* return 0 on success */
3028 ret = wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz);
3029
3030 WOLFSSL_PKMSG("PK ED Agree: ret %d, privSz %d, pubKeySz %d, outlen %d\n",
3031 ret, privSz, pubKeySz, *outlen);
3032
3033 return ret;
3034};
3035
3036#endif /* !NO_DH */
3037
3038#ifndef NO_RSA
3039
3040static WC_INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
3041 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
3042{
3043 WC_RNG rng;
3044 int ret;
3045 word32 idx = 0;
3046 RsaKey myKey;
3047 byte* keyBuf = (byte*)key;
3048 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3049
3050 (void)ssl;
3051 (void)cbInfo;
3052
3053 WOLFSSL_PKMSG("PK RSA Sign: inSz %d, keySz %d\n", inSz, keySz);
3054
3055#ifdef TEST_PK_PRIVKEY
3056 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3057 if (ret != 0)
3058 return ret;
3059#endif
3060
3061 ret = wc_InitRng(&rng);
3062 if (ret != 0)
3063 return ret;
3064
3065 ret = wc_InitRsaKey(&myKey, NULL);
3066 if (ret == 0) {
3067 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3068 if (ret == 0)
3069 ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
3070 if (ret > 0) { /* save and convert to 0 success */
3071 *outSz = ret;
3072 ret = 0;
3073 }
3074 wc_FreeRsaKey(&myKey);
3075 }
3076 wc_FreeRng(&rng);
3077
3078#ifdef TEST_PK_PRIVKEY
3079 free(keyBuf);
3080#endif
3081
3082 WOLFSSL_PKMSG("PK RSA Sign: ret %d, outSz %d\n", ret, *outSz);
3083
3084 return ret;
3085}
3086
3087
3088static WC_INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
3089 byte** out, const byte* key, word32 keySz, void* ctx)
3090{
3091 int ret;
3092 word32 idx = 0;
3093 RsaKey myKey;
3094 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3095
3096 (void)ssl;
3097 (void)cbInfo;
3098
3099 WOLFSSL_PKMSG("PK RSA Verify: sigSz %d, keySz %d\n", sigSz, keySz);
3100
3101 ret = wc_InitRsaKey(&myKey, NULL);
3102 if (ret == 0) {
3103 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
3104 if (ret == 0)
3105 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
3106 wc_FreeRsaKey(&myKey);
3107 }
3108
3109 WOLFSSL_PKMSG("PK RSA Verify: ret %d\n", ret);
3110
3111 return ret;
3112}
3113
3114static WC_INLINE int myRsaSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
3115 byte** out, const byte* key, word32 keySz, void* ctx)
3116{
3117 int ret;
3118 word32 idx = 0;
3119 RsaKey myKey;
3120 byte* keyBuf = (byte*)key;
3121 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3122
3123 (void)ssl;
3124 (void)cbInfo;
3125
3126 WOLFSSL_PKMSG("PK RSA SignCheck: sigSz %d, keySz %d\n", sigSz, keySz);
3127
3128#ifdef TEST_PK_PRIVKEY
3129 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3130 if (ret != 0)
3131 return ret;
3132#endif
3133
3134 ret = wc_InitRsaKey(&myKey, NULL);
3135 if (ret == 0) {
3136 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3137 if (ret == 0)
3138 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
3139 wc_FreeRsaKey(&myKey);
3140 }
3141#ifdef TEST_PK_PRIVKEY
3142 free(keyBuf);
3143#endif
3144
3145 WOLFSSL_PKMSG("PK RSA SignCheck: ret %d\n", ret);
3146
3147 return ret;
3148}
3149
3150#ifdef WC_RSA_PSS
3151static WC_INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
3152 byte* out, word32* outSz, int hash, int mgf, const byte* key,
3153 word32 keySz, void* ctx)
3154{
3155 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3156 WC_RNG rng;
3157 int ret;
3158 word32 idx = 0;
3159 RsaKey myKey;
3160 byte* keyBuf = (byte*)key;
3161 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3162
3163 (void)ssl;
3164 (void)cbInfo;
3165
3166 WOLFSSL_PKMSG("PK RSA PSS Sign: inSz %d, hash %d, mgf %d, keySz %d\n",
3167 inSz, hash, mgf, keySz);
3168
3169#ifdef TEST_PK_PRIVKEY
3170 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3171 if (ret != 0)
3172 return ret;
3173#endif
3174
3175 switch (hash) {
3176#ifndef NO_SHA256
3177 case SHA256h:
3178 hashType = WC_HASH_TYPE_SHA256;
3179 break;
3180#endif
3181#ifdef WOLFSSL_SHA384
3182 case SHA384h:
3183 hashType = WC_HASH_TYPE_SHA384;
3184 break;
3185#endif
3186#ifdef WOLFSSL_SHA512
3187 case SHA512h:
3188 hashType = WC_HASH_TYPE_SHA512;
3189 break;
3190#endif
3191 }
3192
3193 ret = wc_InitRng(&rng);
3194 if (ret != 0)
3195 return ret;
3196
3197 ret = wc_InitRsaKey(&myKey, NULL);
3198 if (ret == 0) {
3199 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3200 if (ret == 0) {
3201 ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey,
3202 &rng);
3203 }
3204 if (ret > 0) { /* save and convert to 0 success */
3205 *outSz = ret;
3206 ret = 0;
3207 }
3208 wc_FreeRsaKey(&myKey);
3209 }
3210 wc_FreeRng(&rng);
3211
3212#ifdef TEST_PK_PRIVKEY
3213 free(keyBuf);
3214#endif
3215
3216 WOLFSSL_PKMSG("PK RSA PSS Sign: ret %d, outSz %d\n", ret, *outSz);
3217
3218 return ret;
3219}
3220
3221
3222static WC_INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
3223 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
3224{
3225 int ret;
3226 word32 idx = 0;
3227 RsaKey myKey;
3228 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3229 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3230
3231 (void)ssl;
3232 (void)cbInfo;
3233
3234 WOLFSSL_PKMSG("PK RSA PSS Verify: sigSz %d, hash %d, mgf %d, keySz %d\n",
3235 sigSz, hash, mgf, keySz);
3236
3237 switch (hash) {
3238#ifndef NO_SHA256
3239 case SHA256h:
3240 hashType = WC_HASH_TYPE_SHA256;
3241 break;
3242#endif
3243#ifdef WOLFSSL_SHA384
3244 case SHA384h:
3245 hashType = WC_HASH_TYPE_SHA384;
3246 break;
3247#endif
3248#ifdef WOLFSSL_SHA512
3249 case SHA512h:
3250 hashType = WC_HASH_TYPE_SHA512;
3251 break;
3252#endif
3253 }
3254
3255 ret = wc_InitRsaKey(&myKey, NULL);
3256 if (ret == 0) {
3257 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
3258 if (ret == 0) {
3259 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
3260 &myKey);
3261 }
3262 wc_FreeRsaKey(&myKey);
3263 }
3264
3265 WOLFSSL_PKMSG("PK RSA PSS Verify: ret %d\n", ret);
3266
3267 return ret;
3268}
3269
3270static WC_INLINE int myRsaPssSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
3271 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
3272{
3273 int ret;
3274 word32 idx = 0;
3275 RsaKey myKey;
3276 byte* keyBuf = (byte*)key;
3277 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3278 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3279
3280 (void)ssl;
3281 (void)cbInfo;
3282
3283 WOLFSSL_PKMSG("PK RSA PSS SignCheck: sigSz %d, hash %d, mgf %d, keySz %d\n",
3284 sigSz, hash, mgf, keySz);
3285
3286#ifdef TEST_PK_PRIVKEY
3287 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3288 if (ret != 0)
3289 return ret;
3290#endif
3291
3292 switch (hash) {
3293#ifndef NO_SHA256
3294 case SHA256h:
3295 hashType = WC_HASH_TYPE_SHA256;
3296 break;
3297#endif
3298#ifdef WOLFSSL_SHA384
3299 case SHA384h:
3300 hashType = WC_HASH_TYPE_SHA384;
3301 break;
3302#endif
3303#ifdef WOLFSSL_SHA512
3304 case SHA512h:
3305 hashType = WC_HASH_TYPE_SHA512;
3306 break;
3307#endif
3308 }
3309
3310 ret = wc_InitRsaKey(&myKey, NULL);
3311 if (ret == 0) {
3312 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3313 if (ret == 0) {
3314 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
3315 &myKey);
3316 }
3317 wc_FreeRsaKey(&myKey);
3318 }
3319
3320#ifdef TEST_PK_PRIVKEY
3321 free(keyBuf);
3322#endif
3323
3324 WOLFSSL_PKMSG("PK RSA PSS SignCheck: ret %d\n", ret);
3325
3326 return ret;
3327}
3328#endif
3329
3330
3331static WC_INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
3332 byte* out, word32* outSz, const byte* key,
3333 word32 keySz, void* ctx)
3334{
3335 int ret;
3336 word32 idx = 0;
3337 RsaKey myKey;
3338 WC_RNG rng;
3339 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3340
3341 (void)ssl;
3342 (void)cbInfo;
3343
3344 WOLFSSL_PKMSG("PK RSA Enc: inSz %d, keySz %d\n", inSz, keySz);
3345
3346 ret = wc_InitRng(&rng);
3347 if (ret != 0)
3348 return ret;
3349
3350 ret = wc_InitRsaKey(&myKey, NULL);
3351 if (ret == 0) {
3352 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
3353 if (ret == 0) {
3354 ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
3355 if (ret > 0) {
3356 *outSz = ret;
3357 ret = 0; /* reset to success */
3358 }
3359 }
3360 wc_FreeRsaKey(&myKey);
3361 }
3362 wc_FreeRng(&rng);
3363
3364 WOLFSSL_PKMSG("PK RSA Enc: ret %d, outSz %d\n", ret, *outSz);
3365
3366 return ret;
3367}
3368
3369static WC_INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
3370 byte** out,
3371 const byte* key, word32 keySz, void* ctx)
3372{
3373 int ret;
3374 word32 idx = 0;
3375 RsaKey myKey;
3376 byte* keyBuf = (byte*)key;
3377 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3378
3379 (void)ssl;
3380 (void)cbInfo;
3381
3382 WOLFSSL_PKMSG("PK RSA Dec: inSz %d, keySz %d\n", inSz, keySz);
3383
3384#ifdef TEST_PK_PRIVKEY
3385 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3386 if (ret != 0)
3387 return ret;
3388#endif
3389
3390 ret = wc_InitRsaKey(&myKey, NULL);
3391 if (ret == 0) {
3392 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3393 if (ret == 0) {
3394 #ifdef WC_RSA_BLINDING
3395 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl));
3396 if (ret != 0) {
3397 wc_FreeRsaKey(&myKey);
3398 return ret;
3399 }
3400 #endif
3401 ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
3402 }
3403 wc_FreeRsaKey(&myKey);
3404 }
3405
3406#ifdef TEST_PK_PRIVKEY
3407 free(keyBuf);
3408#endif
3409
3410 WOLFSSL_PKMSG("PK RSA Dec: ret %d\n", ret);
3411
3412 return ret;
3413}
3414
3415#endif /* NO_RSA */
3416
3417static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx)
3418{
3419 (void)ctx;
3420
3421 #ifdef HAVE_ECC
3422 wolfSSL_CTX_SetEccKeyGenCb(ctx, myEccKeyGen);
3423 wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
3424 wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
3425 wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
3426 #endif /* HAVE_ECC */
3427 #ifndef NO_DH
3428 wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback);
3429 #endif
3430 #ifdef HAVE_ED25519
3431 wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign);
3432 wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify);
3433 #endif
3434 #ifdef HAVE_CURVE25519
3435 wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen);
3436 wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
3437 #endif
3438 #ifdef HAVE_ED448
3439 wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign);
3440 wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify);
3441 #endif
3442 #ifdef HAVE_CURVE448
3443 wolfSSL_CTX_SetX448KeyGenCb(ctx, myX448KeyGen);
3444 wolfSSL_CTX_SetX448SharedSecretCb(ctx, myX448SharedSecret);
3445 #endif
3446 #ifndef NO_RSA
3447 wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
3448 wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
3449 wolfSSL_CTX_SetRsaSignCheckCb(ctx, myRsaSignCheck);
3450 #ifdef WC_RSA_PSS
3451 wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
3452 wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify);
3453 wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, myRsaPssSignCheck);
3454 #endif
3455 wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
3456 wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
3457 #endif /* NO_RSA */
3458}
3459
3460static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx)
3461{
3462 #ifdef HAVE_ECC
3463 wolfSSL_SetEccKeyGenCtx(ssl, myCtx);
3464 wolfSSL_SetEccSignCtx(ssl, myCtx);
3465 wolfSSL_SetEccVerifyCtx(ssl, myCtx);
3466 wolfSSL_SetEccSharedSecretCtx(ssl, myCtx);
3467 #endif /* HAVE_ECC */
3468 #ifndef NO_DH
3469 wolfSSL_SetDhAgreeCtx(ssl, myCtx);
3470 #endif
3471 #ifdef HAVE_ED25519
3472 wolfSSL_SetEd25519SignCtx(ssl, myCtx);
3473 wolfSSL_SetEd25519VerifyCtx(ssl, myCtx);
3474 #endif
3475 #ifdef HAVE_CURVE25519
3476 wolfSSL_SetX25519KeyGenCtx(ssl, myCtx);
3477 wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx);
3478 #endif
3479 #ifdef HAVE_ED448
3480 wolfSSL_SetEd448SignCtx(ssl, myCtx);
3481 wolfSSL_SetEd448VerifyCtx(ssl, myCtx);
3482 #endif
3483 #ifdef HAVE_CURVE448
3484 wolfSSL_SetX448KeyGenCtx(ssl, myCtx);
3485 wolfSSL_SetX448SharedSecretCtx(ssl, myCtx);
3486 #endif
3487 #ifndef NO_RSA
3488 wolfSSL_SetRsaSignCtx(ssl, myCtx);
3489 wolfSSL_SetRsaVerifyCtx(ssl, myCtx);
3490 #ifdef WC_RSA_PSS
3491 wolfSSL_SetRsaPssSignCtx(ssl, myCtx);
3492 wolfSSL_SetRsaPssVerifyCtx(ssl, myCtx);
3493 #endif
3494 wolfSSL_SetRsaEncCtx(ssl, myCtx);
3495 wolfSSL_SetRsaDecCtx(ssl, myCtx);
3496 #endif /* NO_RSA */
3497}
3498
3499#endif /* HAVE_PK_CALLBACKS */
3500
3501
3502
3503
3504#if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
3505 || defined(_MSC_VER)
3506
3507/* HP/UX doesn't have strsep, needed by test/suites.c */
3508static WC_INLINE char* strsep(char **stringp, const char *delim)
3509{
3510 char* start;
3511 char* end;
3512
3513 start = *stringp;
3514 if (start == NULL)
3515 return NULL;
3516
3517 if ((end = strpbrk(start, delim))) {
3518 *end++ = '\0';
3519 *stringp = end;
3520 } else {
3521 *stringp = NULL;
3522 }
3523
3524 return start;
3525}
3526
3527#endif /* __hpux__ and others */
3528
3529/* Create unique filename, len is length of tempfn name, assuming
3530 len does not include null terminating character,
3531 num is number of characters in tempfn name to randomize */
3532static WC_INLINE const char* mymktemp(char *tempfn, int len, int num)
3533{
3534 int x, size;
3535 static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3536 "abcdefghijklmnopqrstuvwxyz";
3537 WC_RNG rng;
3538 byte out;
3539
3540 if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
3541 printf("Bad input\n");
3542 return NULL;
3543 }
3544
3545 size = len - 1;
3546
3547 if (wc_InitRng(&rng) != 0) {
3548 printf("InitRng failed\n");
3549 return NULL;
3550 }
3551
3552 for (x = size; x > size - num; x--) {
3553 if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
3554 printf("RNG_GenerateBlock failed\n");
3555 return NULL;
3556 }
3557 tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
3558 }
3559 tempfn[len] = '\0';
3560
3561 wc_FreeRng(&rng);
3562 (void)rng; /* for WC_NO_RNG case */
3563
3564 return tempfn;
3565}
3566
3567
3568
3569#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
3570 defined(HAVE_POLY1305)
3571
3572 #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
3573
3574 typedef struct key_ctx {
3575 byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */
3576 byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */
3577 } key_ctx;
3578
3579 static THREAD_LS_T key_ctx myKey_ctx;
3580 static THREAD_LS_T WC_RNG myKey_rng;
3581
3582 static WC_INLINE int TicketInit(void)
3583 {
3584 int ret = wc_InitRng(&myKey_rng);
3585 if (ret != 0) return ret;
3586
3587 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key));
3588 if (ret != 0) return ret;
3589
3590 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name));
3591 if (ret != 0) return ret;
3592
3593 return 0;
3594 }
3595
3596 static WC_INLINE void TicketCleanup(void)
3597 {
3598 wc_FreeRng(&myKey_rng);
3599 }
3600
3601 static WC_INLINE int myTicketEncCb(WOLFSSL* ssl,
3602 byte key_name[WOLFSSL_TICKET_NAME_SZ],
3603 byte iv[WOLFSSL_TICKET_IV_SZ],
3604 byte mac[WOLFSSL_TICKET_MAC_SZ],
3605 int enc, byte* ticket, int inLen, int* outLen,
3606 void* userCtx)
3607 {
3608 (void)ssl;
3609 (void)userCtx;
3610
3611 int ret;
3612 word16 sLen = XHTONS(inLen);
3613 byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
3614 int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
3615 byte* tmp = aad;
3616
3617 if (enc) {
3618 XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
3619
3620 ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ);
3621 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
3622
3623 /* build aad from key name, iv, and length */
3624 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
3625 tmp += WOLFSSL_TICKET_NAME_SZ;
3626 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
3627 tmp += WOLFSSL_TICKET_IV_SZ;
3628 XMEMCPY(tmp, &sLen, 2);
3629
3630 ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
3631 aad, aadSz,
3632 ticket, inLen,
3633 ticket,
3634 mac);
3635 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
3636 *outLen = inLen; /* no padding in this mode */
3637 } else {
3638 /* decrypt */
3639
3640 /* see if we know this key */
3641 if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
3642 printf("client presented unknown ticket key name ");
3643 return WOLFSSL_TICKET_RET_FATAL;
3644 }
3645
3646 /* build aad from key name, iv, and length */
3647 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
3648 tmp += WOLFSSL_TICKET_NAME_SZ;
3649 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
3650 tmp += WOLFSSL_TICKET_IV_SZ;
3651 XMEMCPY(tmp, &sLen, 2);
3652
3653 ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
3654 aad, aadSz,
3655 ticket, inLen,
3656 mac,
3657 ticket);
3658 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
3659 *outLen = inLen; /* no padding in this mode */
3660 }
3661
3662 return WOLFSSL_TICKET_RET_OK;
3663 }
3664
3665#endif /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */
3666
3667static WC_INLINE word16 GetRandomPort(void)
3668{
3669 word16 port = 0;
3670
3671 /* Generate random port for testing */
3672 WC_RNG rng;
3673 if (wc_InitRng(&rng) == 0) {
3674 if (wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port)) == 0) {
3675 port |= 0xC000; /* Make sure its in the 49152 - 65535 range */
3676 }
3677 wc_FreeRng(&rng);
3678 }
3679 (void)rng; /* for WC_NO_RNG case */
3680 return port;
3681}
3682
3683#endif /* wolfSSL_TEST_H */
Note: See TracBrowser for help on using the repository browser.