1 /* sniffer.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <wolfssl/wolfcrypt/settings.h>
28 #include <wolfssl/wolfcrypt/types.h>
29 #include <wolfssl/wolfcrypt/wc_port.h>
30
31 /* xctime */
32 #ifndef XCTIME
33 #define XCTIME ctime
34 #endif
35
36 /* only in this file, to avoid confusing future ports leave
37 * these defines here. Do not move to wc_port.h */
38 #ifdef USER_CUSTOM_SNIFFX
39 /* To be implemented in user_settings.h */
40 #elif defined(FUSION_RTOS)
41 #include <fcl_network.h>
42 #define XINET_NTOA FNS_INET_NTOA
43 #define XINET_ATON FNS_INET_ATON
44 #define XINET_PTON(a,b,c,d) FNS_INET_PTON((a),(b),(c),(d),NULL)
45 #define XINET_NTOP(a,b,c,d) FNS_INET_NTOP((a),(b),(c),(d),NULL)
46 #define XINET_ADDR FNS_INET_ADDR
47 #define XHTONS FNS_HTONS
48 #define XNTOHS FNS_NTOHS
49 #define XHTONL FNS_HTONL
50 #define XNTOHL FNS_NTOHL
51 #define XINADDR_NONE FNS_INADDR_NONE
52 #else
53 /* default */
54 #define XINET_NTOA inet_ntoa
55 #define XINET_ATON inet_aton
56 #define XINET_PTON(a,b,c) inet_pton((a),(b),(c))
57 #define XINET_NTOP inet_ntop
58 #define XINET_ADDR inet_addr
59 #define XHTONS htons
60 #define XNTOHS ntohs
61 #define XHTONL htonl
62 #define XNTOHL ntohl
63 #define XINADDR_NONE INADDR_NONE
64 #endif
65
66 #if !defined(WOLFCRYPT_ONLY) && !defined(NO_FILESYSTEM)
67 #ifdef WOLFSSL_SNIFFER
68
69 #include <time.h>
70
71 #ifdef FUSION_RTOS
72 #include <fns_inet.h>
73 #ifdef TCP_PROTOCOL
74 #undef TCP_PROTOCOL
75 #endif
76 #else
77 #ifndef _WIN32
78 #include <arpa/inet.h>
79 #else
80 #include <ws2tcpip.h>
81 #endif
82 #endif
83
84 #ifdef _WIN32
85 #define SNPRINTF _snprintf
86 #else
87 #define SNPRINTF snprintf
88 #endif
89
90 #include <wolfssl/internal.h>
91 #include <wolfssl/error-ssl.h>
92 #include <wolfssl/sniffer.h>
93 #include <wolfssl/sniffer_error.h>
94
95 #ifndef NO_RSA
96 #include <wolfssl/wolfcrypt/rsa.h>
97 #endif
98 #ifndef NO_DH
99 #include <wolfssl/wolfcrypt/dh.h>
100 #endif
101 #ifdef HAVE_ECC
102 #include <wolfssl/wolfcrypt/ecc.h>
103 #endif
104 #ifdef HAVE_CURVE25519
105 #include <wolfssl/wolfcrypt/curve25519.h>
106 #endif
107
108 #ifdef NO_INLINE
109 #include <wolfssl/wolfcrypt/misc.h>
110 #else
111 #define WOLFSSL_MISC_INCLUDED
112 #include <wolfcrypt/src/misc.c>
113 #endif
114
115 #ifdef WOLF_CRYPTO_CB
116 #include <wolfssl/wolfcrypt/cryptocb.h>
117 #ifdef HAVE_INTEL_QA_SYNC
118 #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
119 #endif
120 #ifdef HAVE_CAVIUM_OCTEON_SYNC
121 #include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
122 #endif
123 #endif
124
125
126 #ifndef WOLFSSL_SNIFFER_TIMEOUT
127 #define WOLFSSL_SNIFFER_TIMEOUT 900
128 /* Cache unclosed Sessions for 15 minutes since last used */
129 #endif
130
131 /* Misc constants */
132 enum {
133 MAX_SERVER_ADDRESS = 128, /* maximum server address length */
134 MAX_SERVER_NAME = 128, /* maximum server name length */
135 MAX_ERROR_LEN = 80, /* maximum error length */
136 ETHER_IF_ADDR_LEN = 6, /* ethernet interface address length */
137 LOCAL_IF_ADDR_LEN = 4, /* localhost interface address length, !windows */
138 TCP_PROTO = 6, /* TCP_PROTOCOL */
139 IP_HDR_SZ = 20, /* IPv4 header length, min */
140 IP6_HDR_SZ = 40, /* IPv6 header length, min */
141 TCP_HDR_SZ = 20, /* TCP header length, min */
142 IPV4 = 4, /* IP version 4 */
143 IPV6 = 6, /* IP version 6 */
144 TCP_PROTOCOL = 6, /* TCP Protocol id */
145 NO_NEXT_HEADER = 59, /* IPv6 no headers follow */
146 TRACE_MSG_SZ = 80, /* Trace Message buffer size */
147 HASH_SIZE = 499, /* Session Hash Table Rows */
148 PSEUDO_HDR_SZ = 12, /* TCP Pseudo Header size in bytes */
149 FATAL_ERROR_STATE = 1, /* SnifferSession fatal error state */
150 TICKET_HINT_LEN = 4, /* Session Ticket Hint length */
151 TICKET_HINT_AGE_LEN= 4, /* Session Ticket Age add length */
152 EXT_TYPE_SZ = 2, /* Extension type length */
153 MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
154 MTU_EXTRA, /* Max input sz of reassembly */
155
156 /* TLS Extensions */
157 EXT_SERVER_NAME = 0x0000, /* a.k.a. SNI */
158 EXT_MAX_FRAGMENT_LENGTH = 0x0001,
159 EXT_TRUSTED_CA_KEYS = 0x0003,
160 EXT_TRUNCATED_HMAC = 0x0004,
161 EXT_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stapling */
162 EXT_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */
163 EXT_EC_POINT_FORMATS = 0x000b,
164 EXT_SIGNATURE_ALGORITHMS = 0x000d,
165 EXT_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */
166 EXT_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */
167 EXT_ENCRYPT_THEN_MAC = 0x0016, /* RFC 7366 */
168 EXT_MASTER_SECRET = 0x0017, /* Extended Master Secret Extension ID */
169 EXT_TICKET_ID = 0x0023, /* Session Ticket Extension ID */
170 EXT_PRE_SHARED_KEY = 0x0029,
171 EXT_EARLY_DATA = 0x002a,
172 EXT_SUPPORTED_VERSIONS = 0x002b,
173 EXT_COOKIE = 0x002c,
174 EXT_PSK_KEY_EXCHANGE_MODES = 0x002d,
175 EXT_POST_HANDSHAKE_AUTH = 0x0031,
176 EXT_SIGNATURE_ALGORITHMS_CERT = 0x0032,
177 EXT_KEY_SHARE = 0x0033,
178 EXT_RENEGOTIATION_INFO = 0xff01
179 };
180
181
182 #ifdef _WIN32
183
184 static HMODULE dllModule; /* for error string resources */
185
DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)186 BOOL APIENTRY DllMain( HMODULE hModule,
187 DWORD ul_reason_for_call,
188 LPVOID lpReserved
189 )
190 {
191 static int didInit = 0;
192
193 switch (ul_reason_for_call)
194 {
195 case DLL_PROCESS_ATTACH:
196 if (didInit == 0) {
197 dllModule = hModule;
198 ssl_InitSniffer();
199 didInit = 1;
200 }
201 break;
202 case DLL_THREAD_ATTACH:
203 break;
204 case DLL_THREAD_DETACH:
205 break;
206 case DLL_PROCESS_DETACH:
207 if (didInit) {
208 ssl_FreeSniffer();
209 didInit = 0;
210 }
211 break;
212 }
213 return TRUE;
214 }
215
216 #endif /* _WIN32 */
217
218
219 static WOLFSSL_GLOBAL int TraceOn = 0; /* Trace is off by default */
220 static WOLFSSL_GLOBAL XFILE TraceFile = 0;
221
222
223 /* windows uses .rc table for this */
224 #ifndef _WIN32
225
226 static const char* const msgTable[] =
227 {
228 /* 1 */
229 "Out of Memory",
230 "New SSL Sniffer Server Registered",
231 "Checking IP Header",
232 "SSL Sniffer Server Not Registered",
233 "Checking TCP Header",
234
235 /* 6 */
236 "SSL Sniffer Server Port Not Registered",
237 "RSA Private Decrypt Error",
238 "RSA Private Decode Error",
239 "Set Cipher Spec Error",
240 "Server Hello Input Malformed",
241
242 /* 11 */
243 "Couldn't Resume Session Error",
244 "Server Did Resumption",
245 "Client Hello Input Malformed",
246 "Client Trying to Resume",
247 "Handshake Input Malformed",
248
249 /* 16 */
250 "Got Hello Verify msg",
251 "Got Server Hello msg",
252 "Got Cert Request msg",
253 "Got Server Key Exchange msg",
254 "Got Cert msg",
255
256 /* 21 */
257 "Got Server Hello Done msg",
258 "Got Finished msg",
259 "Got Client Hello msg",
260 "Got Client Key Exchange msg",
261 "Got Cert Verify msg",
262
263 /* 26 */
264 "Got Unknown Handshake msg",
265 "New SSL Sniffer Session created",
266 "Couldn't create new SSL",
267 "Got a Packet to decode",
268 "No data present",
269
270 /* 31 */
271 "Session Not Found",
272 "Got an Old Client Hello msg",
273 "Old Client Hello Input Malformed",
274 "Old Client Hello OK",
275 "Bad Old Client Hello",
276
277 /* 36 */
278 "Bad Record Header",
279 "Record Header Input Malformed",
280 "Got a HandShake msg",
281 "Bad HandShake msg",
282 "Got a Change Cipher Spec msg",
283
284 /* 41 */
285 "Got Application Data msg",
286 "Bad Application Data",
287 "Got an Alert msg",
288 "Another msg to Process",
289 "Removing Session From Table",
290
291 /* 46 */
292 "Bad Key File",
293 "Wrong IP Version",
294 "Wrong Protocol type",
295 "Packet Short for header processing",
296 "Got Unknown Record Type",
297
298 /* 51 */
299 "Can't Open Trace File",
300 "Session in Fatal Error State",
301 "Partial SSL record received",
302 "Buffer Error, malformed input",
303 "Added to Partial Input",
304
305 /* 56 */
306 "Received a Duplicate Packet",
307 "Received an Out of Order Packet",
308 "Received an Overlap Duplicate Packet",
309 "Received an Overlap Reassembly Begin Duplicate Packet",
310 "Received an Overlap Reassembly End Duplicate Packet",
311
312 /* 61 */
313 "Missed the Client Hello Entirely",
314 "Got Hello Request msg",
315 "Got Session Ticket msg",
316 "Bad Input",
317 "Bad Decrypt Type",
318
319 /* 66 */
320 "Bad Finished Message Processing",
321 "Bad Compression Type",
322 "Bad DeriveKeys Error",
323 "Saw ACK for Missing Packet Error",
324 "Bad Decrypt Operation",
325
326 /* 71 */
327 "Decrypt Keys Not Set Up",
328 "Late Key Load Error",
329 "Got Certificate Status msg",
330 "RSA Key Missing Error",
331 "Secure Renegotiation Not Supported",
332
333 /* 76 */
334 "Get Session Stats Failure",
335 "Reassembly Buffer Size Exceeded",
336 "Dropping Lost Fragment",
337 "Dropping Partial Record",
338 "Clear ACK Fault",
339
340 /* 81 */
341 "Bad Decrypt Size",
342 "Extended Master Secret Hash Error",
343 "Handshake Message Split Across TLS Records",
344 "ECC Private Decode Error",
345 "ECC Public Decode Error",
346
347 /* 86 */
348 "Watch callback not set",
349 "Watch hash failed",
350 "Watch callback failed",
351 "Bad Certificate Message",
352 "Store data callback not set",
353
354 /* 91 */
355 "No data destination Error",
356 "Store data callback failed",
357 "Loading chain input",
358 "Got encrypted extension",
359 "Got Hello Retry Request",
360 };
361
362
363 /* *nix version uses table above */
GetError(int idx,char * str)364 static void GetError(int idx, char* str)
365 {
366 if (str == NULL ||
367 idx < 0 || idx > (int)(sizeof(msgTable)/sizeof(const char* const)))
368 return;
369 XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN-1);
370 str[MAX_ERROR_LEN-1] = '\0';
371 }
372
373
374 #else /* _WIN32 */
375
376
377 /* Windows version uses .rc table */
GetError(int idx,char * buffer)378 static void GetError(int idx, char* buffer)
379 {
380 if (buffer == NULL)
381 return;
382 if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
383 buffer[0] = 0;
384 }
385
386
387 #endif /* _WIN32 */
388
389
390 /* Packet Buffer for reassembly list and ready list */
391 typedef struct PacketBuffer {
392 word32 begin; /* relative sequence begin */
393 word32 end; /* relative sequence end */
394 byte* data; /* actual data */
395 struct PacketBuffer* next; /* next on reassembly list or ready list */
396 } PacketBuffer;
397
398
399 #ifdef HAVE_SNI
400
401 /* NamedKey maps a SNI name to a specific private key */
402 typedef struct NamedKey {
403 char name[MAX_SERVER_NAME]; /* server DNS name */
404 word32 nameSz; /* size of server DNS name */
405 byte* key; /* DER private key */
406 word32 keySz; /* size of DER private key */
407 int isEphemeralKey;
408 struct NamedKey* next; /* for list */
409 } NamedKey;
410
411 #endif
412
413
414 typedef struct IpAddrInfo {
415 int version;
416 union {
417 word32 ip4;
418 byte ip6[16];
419 };
420 } IpAddrInfo;
421
422
423 /* Sniffer Server holds info for each server/port monitored */
424 typedef struct SnifferServer {
425 WOLFSSL_CTX* ctx; /* SSL context */
426 char address[MAX_SERVER_ADDRESS]; /* passed in server address */
427 IpAddrInfo server; /* network order address */
428 int port; /* server port */
429 #ifdef HAVE_SNI
430 NamedKey* namedKeys; /* mapping of names and keys */
431 wolfSSL_Mutex namedKeysMutex; /* mutex for namedKey list */
432 #endif
433 struct SnifferServer* next; /* for list */
434 } SnifferServer;
435
436
437 /* Session Flags */
438 typedef struct Flags {
439 byte side; /* which end is current packet headed */
440 byte serverCipherOn; /* indicates whether cipher is active */
441 byte clientCipherOn; /* indicates whether cipher is active */
442 byte resuming; /* did this session come from resumption */
443 byte cached; /* have we cached this session yet */
444 byte clientHello; /* processed client hello yet, for SSLv2 */
445 byte finCount; /* get both FINs before removing */
446 byte fatalError; /* fatal error state */
447 byte cliAckFault; /* client acked unseen data from server */
448 byte srvAckFault; /* server acked unseen data from client */
449 byte cliSkipPartial; /* client skips partial data to catch up */
450 byte srvSkipPartial; /* server skips partial data to catch up */
451 #ifdef HAVE_EXTENDED_MASTER
452 byte expectEms; /* expect extended master secret */
453 #endif
454 byte gotFinished; /* processed finished */
455 byte secRenegEn; /* secure renegotiation enabled */
456 } Flags;
457
458
459 /* Out of Order FIN capture */
460 typedef struct FinCapture {
461 word32 cliFinSeq; /* client relative sequence FIN 0 is no */
462 word32 srvFinSeq; /* server relative sequence FIN, 0 is no */
463 byte cliCounted; /* did we count yet, detects duplicates */
464 byte srvCounted; /* did we count yet, detects duplicates */
465 } FinCapture;
466
467
468 typedef struct HsHashes {
469 #ifndef NO_OLD_TLS
470 #ifndef NO_SHA
471 wc_Sha hashSha;
472 #endif
473 #ifndef NO_MD5
474 wc_Md5 hashMd5;
475 #endif
476 #endif /* !NO_OLD_TLS */
477 #ifndef NO_SHA256
478 wc_Sha256 hashSha256;
479 #endif
480 #ifdef WOLFSSL_SHA384
481 wc_Sha384 hashSha384;
482 #endif
483 } HsHashes;
484
485 typedef struct KeyShareInfo {
486 word16 named_group;
487 int key_len;
488 const byte* key;
489
490 /* additional info */
491 int dh_key_bits;
492 int curve_id;
493 } KeyShareInfo;
494
495 /* maximum previous acks to capture */
496 #ifndef WC_SNIFFER_HS_ACK_HIST_MAX
497 #define WC_SNIFFER_HS_ACK_HIST_MAX 10
498 #endif
499
500 /* Sniffer Session holds info for each client/server SSL/TLS session */
501 typedef struct SnifferSession {
502 SnifferServer* context; /* server context */
503 WOLFSSL* sslServer; /* SSL server side decode */
504 WOLFSSL* sslClient; /* SSL client side decode */
505 IpAddrInfo server; /* server address in network byte order */
506 IpAddrInfo client; /* client address in network byte order */
507 word16 srvPort; /* server port */
508 word16 cliPort; /* client port */
509 word32 cliSeqStart; /* client start sequence */
510 word32 srvSeqStart; /* server start sequence */
511 word32 cliExpected; /* client expected sequence (relative) */
512 word32 srvExpected; /* server expected sequence (relative) */
513 word32 cliAcks[WC_SNIFFER_HS_ACK_HIST_MAX]; /* history of acks during handshake */
514 word32 srvAcks[WC_SNIFFER_HS_ACK_HIST_MAX]; /* history of acks during handshake */
515 FinCapture finCapture; /* retain out of order FIN s */
516 Flags flags; /* session flags */
517 time_t lastUsed; /* last used ticks */
518 word32 keySz; /* size of the private key */
519 PacketBuffer* cliReassemblyList; /* client out of order packets */
520 PacketBuffer* srvReassemblyList; /* server out of order packets */
521 word32 cliReassemblyMemory; /* client packet memory used */
522 word32 srvReassemblyMemory; /* server packet memory used */
523 struct SnifferSession* next; /* for hash table list */
524 byte* ticketID; /* mac ID of session ticket */
525 #ifdef HAVE_MAX_FRAGMENT
526 byte* tlsFragBuf;
527 word32 tlsFragOffset;
528 word32 tlsFragSize;
529 #endif
530 #ifdef HAVE_SNI
531 const char* sni; /* server name indication */
532 #endif
533 #ifdef HAVE_EXTENDED_MASTER
534 HsHashes* hash;
535 #endif
536 #ifdef WOLFSSL_TLS13
537 byte* cliKeyShare;
538 word32 cliKeyShareSz;
539 KeyShareInfo srvKs;
540 KeyShareInfo cliKs;
541 #endif
542 } SnifferSession;
543
544
545 /* Sniffer Server List and mutex */
546 static WOLFSSL_GLOBAL SnifferServer* ServerList = NULL;
547 static WOLFSSL_GLOBAL wolfSSL_Mutex ServerListMutex;
548
549 /* Session Hash Table, mutex, and count */
550 static WOLFSSL_GLOBAL SnifferSession* SessionTable[HASH_SIZE];
551 static WOLFSSL_GLOBAL wolfSSL_Mutex SessionMutex;
552 static WOLFSSL_GLOBAL int SessionCount = 0;
553
554 /* Recovery of missed data switches and stats */
555 static WOLFSSL_GLOBAL wolfSSL_Mutex RecoveryMutex; /* for stats */
556 static WOLFSSL_GLOBAL int RecoveryEnabled = 0; /* global switch */
557 static WOLFSSL_GLOBAL int MaxRecoveryMemory = -1;
558 /* per session max recovery memory */
559 static WOLFSSL_GLOBAL word32 MissedDataSessions = 0;
560 /* # of sessions with missed data */
561
562 /* Connection Info Callback */
563 static WOLFSSL_GLOBAL SSLConnCb ConnectionCb;
564 static WOLFSSL_GLOBAL void* ConnectionCbCtx = NULL;
565
566 #ifdef WOLFSSL_SNIFFER_STATS
567 /* Sessions Statistics */
568 static WOLFSSL_GLOBAL SSLStats SnifferStats;
569 static WOLFSSL_GLOBAL wolfSSL_Mutex StatsMutex;
570 #endif
571
572 #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
573 static WOLFSSL_GLOBAL SSLKeyCb KeyCb;
574 static WOLFSSL_GLOBAL void* KeyCbCtx = NULL;
575 #endif
576
577 #ifdef WOLFSSL_SNIFFER_WATCH
578 /* Watch Key Callback */
579 static WOLFSSL_GLOBAL SSLWatchCb WatchCb;
580 static WOLFSSL_GLOBAL void* WatchCbCtx = NULL;
581 #endif
582
583 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
584 /* Store Data Callback */
585 static WOLFSSL_GLOBAL SSLStoreDataCb StoreDataCb;
586 #endif
587
588
UpdateMissedDataSessions(void)589 static void UpdateMissedDataSessions(void)
590 {
591 wc_LockMutex(&RecoveryMutex);
592 MissedDataSessions += 1;
593 wc_UnLockMutex(&RecoveryMutex);
594 }
595
596
597 #ifdef WOLFSSL_SNIFFER_STATS
598 #define LOCK_STAT() do { wc_LockMutex(&StatsMutex); } while (0)
599 #define UNLOCK_STAT() do { wc_UnLockMutex(&StatsMutex); } while (0)
600 #define NOLOCK_ADD_TO_STAT(x,y) do { TraceStat(#x, y); x += y; } while (0)
601 #define NOLOCK_INC_STAT(x) NOLOCK_ADD_TO_STAT(x,1)
602 #define ADD_TO_STAT(x,y) do { LOCK_STAT(); \
603 NOLOCK_ADD_TO_STAT(x,y); UNLOCK_STAT(); } while (0)
604 #define INC_STAT(x) do { LOCK_STAT(); \
605 NOLOCK_INC_STAT(x); UNLOCK_STAT(); } while (0)
606 #endif
607
608
609 #ifdef WOLF_CRYPTO_CB
610 static WOLFSSL_GLOBAL int CryptoDeviceId = INVALID_DEVID;
611 #endif
612
613
614 /* Initialize overall Sniffer */
ssl_InitSniffer(void)615 void ssl_InitSniffer(void)
616 {
617 wolfSSL_Init();
618 wc_InitMutex(&ServerListMutex);
619 wc_InitMutex(&SessionMutex);
620 wc_InitMutex(&RecoveryMutex);
621 #ifdef WOLFSSL_SNIFFER_STATS
622 XMEMSET(&SnifferStats, 0, sizeof(SSLStats));
623 wc_InitMutex(&StatsMutex);
624 #endif
625 #ifdef WOLF_CRYPTO_CB
626 #ifdef HAVE_INTEL_QA_SYNC
627 CryptoDeviceId = wc_CryptoCb_InitIntelQa();
628 if (INVALID_DEVID == CryptoDeviceId) {
629 printf("Couldn't init the Intel QA\n");
630 }
631 #endif
632 #ifdef HAVE_CAVIUM_OCTEON_SYNC
633 CryptoDeviceId = wc_CryptoCb_InitOcteon();
634 if (INVALID_DEVID == CryptoDeviceId) {
635 printf("Couldn't init the Intel QA\n");
636 }
637 #endif
638 #endif
639 }
640
641
642 #ifdef HAVE_SNI
643
644 /* Free Named Key and the zero out the private key it holds */
FreeNamedKey(NamedKey * in)645 static void FreeNamedKey(NamedKey* in)
646 {
647 if (in) {
648 if (in->key) {
649 ForceZero(in->key, in->keySz);
650 XFREE(in->key, NULL, DYNAMIC_TYPE_X509);
651 }
652 XFREE(in, NULL, DYNAMIC_TYPE_SNIFFER_NAMED_KEY);
653 }
654 }
655
656
FreeNamedKeyList(NamedKey * in)657 static void FreeNamedKeyList(NamedKey* in)
658 {
659 NamedKey* next;
660
661 while (in) {
662 next = in->next;
663 FreeNamedKey(in);
664 in = next;
665 }
666 }
667
668 #endif
669
670
671 /* Free Sniffer Server's resources/self */
FreeSnifferServer(SnifferServer * srv)672 static void FreeSnifferServer(SnifferServer* srv)
673 {
674 if (srv) {
675 #ifdef HAVE_SNI
676 wc_LockMutex(&srv->namedKeysMutex);
677 FreeNamedKeyList(srv->namedKeys);
678 wc_UnLockMutex(&srv->namedKeysMutex);
679 wc_FreeMutex(&srv->namedKeysMutex);
680 #endif
681 wolfSSL_CTX_free(srv->ctx);
682 }
683 XFREE(srv, NULL, DYNAMIC_TYPE_SNIFFER_SERVER);
684 }
685
686
687 /* free PacketBuffer's resources/self */
FreePacketBuffer(PacketBuffer * del)688 static void FreePacketBuffer(PacketBuffer* del)
689 {
690 if (del) {
691 XFREE(del->data, NULL, DYNAMIC_TYPE_SNIFFER_PB_BUFFER);
692 XFREE(del, NULL, DYNAMIC_TYPE_SNIFFER_PB);
693 }
694 }
695
696
697 /* remove PacketBuffer List */
FreePacketList(PacketBuffer * in)698 static void FreePacketList(PacketBuffer* in)
699 {
700 if (in) {
701 PacketBuffer* del;
702 PacketBuffer* packet = in;
703
704 while (packet) {
705 del = packet;
706 packet = packet->next;
707 FreePacketBuffer(del);
708 }
709 }
710 }
711
712
713 /* Free Sniffer Session's resources/self */
FreeSnifferSession(SnifferSession * session)714 static void FreeSnifferSession(SnifferSession* session)
715 {
716 if (session) {
717 wolfSSL_free(session->sslClient);
718 wolfSSL_free(session->sslServer);
719
720 FreePacketList(session->cliReassemblyList);
721 FreePacketList(session->srvReassemblyList);
722
723 XFREE(session->ticketID, NULL, DYNAMIC_TYPE_SNIFFER_TICKET_ID);
724 #ifdef HAVE_EXTENDED_MASTER
725 XFREE(session->hash, NULL, DYNAMIC_TYPE_HASHES);
726 #endif
727 #ifdef WOLFSSL_TLS13
728 if (session->cliKeyShare)
729 XFREE(session->cliKeyShare, NULL, DYNAMIC_TYPE_TMP_BUFFER);
730 #endif
731 #ifdef HAVE_MAX_FRAGMENT
732 if (session->tlsFragBuf) {
733 XFREE(session->tlsFragBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
734 session->tlsFragBuf = NULL;
735 }
736 #endif
737 }
738 XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
739 }
740
741
742 /* Free overall Sniffer */
ssl_FreeSniffer(void)743 void ssl_FreeSniffer(void)
744 {
745 SnifferServer* srv;
746 SnifferServer* removeServer;
747 SnifferSession* session;
748 SnifferSession* removeSession;
749 int i;
750
751 wc_LockMutex(&ServerListMutex);
752 wc_LockMutex(&SessionMutex);
753
754 /* Free sessions (wolfSSL objects) first */
755 for (i = 0; i < HASH_SIZE; i++) {
756 session = SessionTable[i];
757 while (session) {
758 removeSession = session;
759 session = session->next;
760 FreeSnifferSession(removeSession);
761 }
762 }
763 SessionCount = 0;
764
765 /* Then server (wolfSSL_CTX) */
766 srv = ServerList;
767 while (srv) {
768 removeServer = srv;
769 srv = srv->next;
770 FreeSnifferServer(removeServer);
771 }
772 ServerList = NULL;
773
774 wc_UnLockMutex(&SessionMutex);
775 wc_UnLockMutex(&ServerListMutex);
776
777 wc_FreeMutex(&RecoveryMutex);
778 wc_FreeMutex(&SessionMutex);
779 wc_FreeMutex(&ServerListMutex);
780
781 #ifdef WOLF_CRYPTO_CB
782 #ifdef HAVE_INTEL_QA_SYNC
783 wc_CryptoCb_CleanupIntelQa(&CryptoDeviceId);
784 #endif
785 #ifdef HAVE_CAVIUM_OCTEON_SYNC
786 wc_CryptoCb_CleanupOcteon(&CryptoDeviceId);
787 #endif
788 #endif
789
790 if (TraceFile) {
791 TraceOn = 0;
792 XFCLOSE(TraceFile);
793 TraceFile = NULL;
794 }
795
796 wolfSSL_Cleanup();
797 }
798
799
800 #ifdef HAVE_EXTENDED_MASTER
801
HashInit(HsHashes * hash)802 static int HashInit(HsHashes* hash)
803 {
804 int ret = 0;
805
806 XMEMSET(hash, 0, sizeof(HsHashes));
807
808 #ifndef NO_OLD_TLS
809 #ifndef NO_SHA
810 if (ret == 0)
811 ret = wc_InitSha(&hash->hashSha);
812 #endif
813 #ifndef NO_MD5
814 if (ret == 0)
815 ret = wc_InitMd5(&hash->hashMd5);
816 #endif
817 #endif /* !NO_OLD_TLS */
818 #ifndef NO_SHA256
819 if (ret == 0)
820 ret = wc_InitSha256(&hash->hashSha256);
821 #endif
822 #ifdef WOLFSSL_SHA384
823 if (ret == 0)
824 ret = wc_InitSha384(&hash->hashSha384);
825 #endif
826
827 return ret;
828 }
829
HashUpdate(HsHashes * hash,const byte * input,int sz)830 static int HashUpdate(HsHashes* hash, const byte* input, int sz)
831 {
832 int ret = 0;
833
834 input -= HANDSHAKE_HEADER_SZ;
835 sz += HANDSHAKE_HEADER_SZ;
836
837 #ifndef NO_OLD_TLS
838 #ifndef NO_SHA
839 if (ret == 0)
840 ret = wc_ShaUpdate(&hash->hashSha, input, sz);
841 #endif
842 #ifndef NO_MD5
843 if (ret == 0)
844 ret = wc_Md5Update(&hash->hashMd5, input, sz);
845 #endif
846 #endif /* !NO_OLD_TLS */
847 #ifndef NO_SHA256
848 if (ret == 0)
849 ret = wc_Sha256Update(&hash->hashSha256, input, sz);
850 #endif
851 #ifdef WOLFSSL_SHA384
852 if (ret == 0)
853 ret = wc_Sha384Update(&hash->hashSha384, input, sz);
854 #endif
855
856 return ret;
857 }
858
HashCopy(HS_Hashes * d,HsHashes * s)859 static int HashCopy(HS_Hashes* d, HsHashes* s)
860 {
861 #ifndef NO_OLD_TLS
862 #ifndef NO_SHA
863 XMEMCPY(&d->hashSha, &s->hashSha, sizeof(wc_Sha));
864 #endif
865 #ifndef NO_MD5
866 XMEMCPY(&d->hashMd5, &s->hashMd5, sizeof(wc_Md5));
867 #endif
868 #endif /* !NO_OLD_TLS */
869 #ifndef NO_SHA256
870 XMEMCPY(&d->hashSha256, &s->hashSha256, sizeof(wc_Sha256));
871 #endif
872 #ifdef WOLFSSL_SHA384
873 XMEMCPY(&d->hashSha384, &s->hashSha384, sizeof(wc_Sha384));
874 #endif
875
876 return 0;
877 }
878
879 #endif
880
881
882 /* Initialize a SnifferServer */
InitSnifferServer(SnifferServer * sniffer)883 static void InitSnifferServer(SnifferServer* sniffer)
884 {
885 XMEMSET(sniffer, 0, sizeof(SnifferServer));
886 }
887
888
889 /* Initialize session flags */
InitFlags(Flags * flags)890 static void InitFlags(Flags* flags)
891 {
892 XMEMSET(flags, 0, sizeof(Flags));
893 }
894
895
896 /* Initialize FIN Capture */
InitFinCapture(FinCapture * cap)897 static void InitFinCapture(FinCapture* cap)
898 {
899 XMEMSET(cap, 0, sizeof(FinCapture));
900 }
901
902
903 /* Initialize a Sniffer Session */
InitSession(SnifferSession * session)904 static void InitSession(SnifferSession* session)
905 {
906 XMEMSET(session, 0, sizeof(SnifferSession));
907 InitFlags(&session->flags);
908 InitFinCapture(&session->finCapture);
909 }
910
911
912 /* IP Info from IP Header */
913 typedef struct IpInfo {
914 int length; /* length of this header */
915 int total; /* total length of fragment */
916 IpAddrInfo src; /* network order source address */
917 IpAddrInfo dst; /* network order destination address */
918 } IpInfo;
919
920
921 /* TCP Info from TCP Header */
922 typedef struct TcpInfo {
923 int srcPort; /* source port */
924 int dstPort; /* source port */
925 int length; /* length of this header */
926 word32 sequence; /* sequence number */
927 word32 ackNumber; /* ack number */
928 byte fin; /* FIN set */
929 byte rst; /* RST set */
930 byte syn; /* SYN set */
931 byte ack; /* ACK set */
932 } TcpInfo;
933
934
935 /* Tcp Pseudo Header for Checksum calculation */
936 typedef struct TcpPseudoHdr {
937 word32 src; /* source address */
938 word32 dst; /* destination address */
939 byte rsv; /* reserved, always 0 */
940 byte protocol; /* IP protocol */
941 word16 length; /* tcp header length + data length (doesn't include */
942 /* pseudo header length) network order */
943 } TcpPseudoHdr;
944
945
946 /* Password Setting Callback */
SetPassword(char * passwd,int sz,int rw,void * userdata)947 static int SetPassword(char* passwd, int sz, int rw, void* userdata)
948 {
949 (void)rw;
950 XSTRNCPY(passwd, (const char*)userdata, sz);
951 return (int)XSTRLEN((const char*)userdata);
952 }
953
954
955 /* Ethernet Header */
956 typedef struct EthernetHdr {
957 byte dst[ETHER_IF_ADDR_LEN]; /* destination host address */
958 byte src[ETHER_IF_ADDR_LEN]; /* source host address */
959 word16 type; /* IP, ARP, etc */
960 } EthernetHdr;
961
962
963 /* IPv4 Header */
964 typedef struct IpHdr {
965 byte ver_hl; /* version/header length */
966 byte tos; /* type of service */
967 word16 length; /* total length */
968 word16 id; /* identification */
969 word16 offset; /* fragment offset field */
970 byte ttl; /* time to live */
971 byte protocol; /* protocol */
972 word16 sum; /* checksum */
973 word32 src; /* source address */
974 word32 dst; /* destination address */
975 } IpHdr;
976
977
978 /* IPv6 Header */
979 typedef struct Ip6Hdr {
980 byte ver_hl; /* version/traffic class high */
981 byte tc_fl; /* traffic class low/flow label high */
982 word16 fl; /* flow label low */
983 word16 length; /* payload length */
984 byte next_header; /* next header (6 for TCP, any other skip) */
985 byte hl; /* hop limit */
986 byte src[16]; /* source address */
987 byte dst[16]; /* destination address */
988 } Ip6Hdr;
989
990
991 /* IPv6 extension header */
992 typedef struct Ip6ExtHdr {
993 byte next_header; /* next header (6 for TCP, any other skip) */
994 byte length; /* length in 8-octet units - 1 */
995 byte reserved[6];
996 } Ip6ExtHdr;
997
998
999 #define IP_HL(ip) ( (((ip)->ver_hl) & 0x0f) * 4)
1000 #define IP_V(ip) ( ((ip)->ver_hl) >> 4)
1001
1002 /* TCP Header */
1003 typedef struct TcpHdr {
1004 word16 srcPort; /* source port */
1005 word16 dstPort; /* destination port */
1006 word32 sequence; /* sequence number */
1007 word32 ack; /* acknowledgment number */
1008 byte offset; /* data offset, reserved */
1009 byte flags; /* option flags */
1010 word16 window; /* window */
1011 word16 sum; /* checksum */
1012 word16 urgent; /* urgent pointer */
1013 } TcpHdr;
1014
1015 #define TCP_LEN(tcp) ( (((tcp)->offset & 0xf0) >> 4) * 4)
1016 #define TCP_FIN 0x01
1017 #define TCP_SYN 0x02
1018 #define TCP_RST 0x04
1019 #define TCP_ACK 0x10
1020
1021
1022
1023
1024
1025 /* Use platform specific GetError to write to trace file if tracing */
TraceError(int idx,char * error)1026 static void TraceError(int idx, char* error)
1027 {
1028 if (TraceOn) {
1029 char myBuffer[MAX_ERROR_LEN];
1030 if (error == NULL) {
1031 error = myBuffer;
1032 GetError(idx, myBuffer);
1033 }
1034 XFPRINTF(TraceFile, "\t%s\n", error);
1035 #ifdef DEBUG_SNIFFER
1036 XFPRINTF(stderr, "\t%s\n", error);
1037 #endif
1038 }
1039 }
1040
Trace(int idx)1041 static void Trace(int idx)
1042 {
1043 TraceError(idx, NULL);
1044 }
1045
1046
1047 /* Show TimeStamp for beginning of packet Trace */
TraceHeader(void)1048 static void TraceHeader(void)
1049 {
1050 if (TraceOn) {
1051 time_t ticks = XTIME(NULL);
1052 XFPRINTF(TraceFile, "\n%s", XCTIME(&ticks));
1053 }
1054 }
1055
1056
1057 /* Show Set Server info for Trace */
TraceSetServer(const char * srv,int port,const char * keyFile)1058 static void TraceSetServer(const char* srv, int port, const char* keyFile)
1059 {
1060 if (TraceOn) {
1061 XFPRINTF(TraceFile, "\tTrying to install a new Sniffer Server with\n");
1062 XFPRINTF(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
1063 keyFile);
1064 }
1065 }
1066
1067
1068 #ifdef HAVE_SNI
1069
1070 /* Show Set Named Server info for Trace */
TraceSetNamedServer(const char * name,const char * srv,int port,const char * keyFile)1071 static void TraceSetNamedServer(const char* name,
1072 const char* srv, int port, const char* keyFile)
1073 {
1074 if (TraceOn) {
1075 XFPRINTF(TraceFile, "\tTrying to install a new Sniffer Server with\n");
1076 XFPRINTF(TraceFile, "\tname: %s, server: %s, port: %d, keyFile: %s\n",
1077 name ? name : "",
1078 srv ? srv : "",
1079 port,
1080 keyFile ? keyFile : "");
1081 }
1082 }
1083
1084 #endif
1085
1086
1087 /* Trace got packet number */
TracePacket(void)1088 static void TracePacket(void)
1089 {
1090 if (TraceOn) {
1091 static word32 packetNumber = 0;
1092 XFPRINTF(TraceFile, "\tGot a Packet to decode, packet %u\n",
1093 ++packetNumber);
1094 }
1095 }
1096
1097
1098 /* Convert network byte order address into human readable */
IpToS(int version,void * src,char * dst)1099 static const char* IpToS(int version, void* src, char* dst)
1100 {
1101 return XINET_NTOP(version, src, dst, TRACE_MSG_SZ);
1102 }
1103
1104
1105 /* Show destination and source address from Ip Hdr for packet Trace */
TraceIP(IpHdr * iphdr)1106 static void TraceIP(IpHdr* iphdr)
1107 {
1108 if (TraceOn) {
1109 char src[TRACE_MSG_SZ];
1110 char dst[TRACE_MSG_SZ];
1111 XFPRINTF(TraceFile, "\tdst:%s src:%s\n",
1112 IpToS(AF_INET, &iphdr->dst, dst),
1113 IpToS(AF_INET, &iphdr->src, src));
1114 }
1115 }
1116
1117
1118 /* Show destination and source address from Ip6Hdr for packet Trace */
TraceIP6(Ip6Hdr * iphdr)1119 static void TraceIP6(Ip6Hdr* iphdr)
1120 {
1121 if (TraceOn) {
1122 char src[TRACE_MSG_SZ];
1123 char dst[TRACE_MSG_SZ];
1124 XFPRINTF(TraceFile, "\tdst: %s src: %s\n",
1125 IpToS(AF_INET6, iphdr->dst, dst),
1126 IpToS(AF_INET6, iphdr->src, src));
1127 }
1128 }
1129
1130
1131 /* Show destination and source port from Tcp Hdr for packet Trace */
TraceTcp(TcpHdr * tcphdr)1132 static void TraceTcp(TcpHdr* tcphdr)
1133 {
1134 if (TraceOn) {
1135 XFPRINTF(TraceFile, "\tdstPort:%u srcPort:%u\n", XNTOHS(tcphdr->dstPort),
1136 XNTOHS(tcphdr->srcPort));
1137 }
1138 }
1139
1140
1141 /* Show sequence and payload length for Trace */
TraceSequence(word32 seq,int len)1142 static void TraceSequence(word32 seq, int len)
1143 {
1144 if (TraceOn) {
1145 XFPRINTF(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
1146 }
1147 }
1148
1149
1150 /* Show sequence and payload length for Trace */
TraceAck(word32 ack,word32 expected)1151 static void TraceAck(word32 ack, word32 expected)
1152 {
1153 if (TraceOn) {
1154 XFPRINTF(TraceFile, "\tAck:%u Expected:%u\n", ack, expected);
1155 }
1156 }
1157
1158
1159 /* Show relative expected and relative received sequences */
TraceRelativeSequence(word32 expected,word32 got)1160 static void TraceRelativeSequence(word32 expected, word32 got)
1161 {
1162 if (TraceOn) {
1163 XFPRINTF(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
1164 expected, got);
1165 }
1166 }
1167
1168
1169 /* Show server sequence startup from SYN */
TraceServerSyn(word32 seq)1170 static void TraceServerSyn(word32 seq)
1171 {
1172 if (TraceOn) {
1173 XFPRINTF(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
1174 }
1175 }
1176
1177
1178 /* Show client sequence startup from SYN */
TraceClientSyn(word32 seq)1179 static void TraceClientSyn(word32 seq)
1180 {
1181 if (TraceOn) {
1182 XFPRINTF(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
1183 }
1184 }
1185
1186
1187 /* Show client FIN capture */
TraceClientFin(word32 finSeq,word32 relSeq)1188 static void TraceClientFin(word32 finSeq, word32 relSeq)
1189 {
1190 if (TraceOn) {
1191 XFPRINTF(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
1192 finSeq, relSeq);
1193 }
1194 }
1195
1196
1197 /* Show server FIN capture */
TraceServerFin(word32 finSeq,word32 relSeq)1198 static void TraceServerFin(word32 finSeq, word32 relSeq)
1199 {
1200 if (TraceOn) {
1201 XFPRINTF(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
1202 finSeq, relSeq);
1203 }
1204 }
1205
1206
1207 /* Show number of SSL data bytes decoded, could be 0 (ok) */
TraceGotData(int bytes)1208 static void TraceGotData(int bytes)
1209 {
1210 if (TraceOn) {
1211 XFPRINTF(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
1212 }
1213 }
1214
1215
1216 /* Show bytes added to old SSL App data */
TraceAddedData(int newBytes,int existingBytes)1217 static void TraceAddedData(int newBytes, int existingBytes)
1218 {
1219 if (TraceOn) {
1220 XFPRINTF(TraceFile,
1221 "\t%d bytes added to %d existing bytes in User Buffer\n",
1222 newBytes, existingBytes);
1223 }
1224 }
1225
1226
1227 /* Show Stale Session */
TraceStaleSession(void)1228 static void TraceStaleSession(void)
1229 {
1230 if (TraceOn) {
1231 XFPRINTF(TraceFile, "\tFound a stale session\n");
1232 }
1233 }
1234
1235
1236 /* Show Finding Stale Sessions */
TraceFindingStale(void)1237 static void TraceFindingStale(void)
1238 {
1239 if (TraceOn) {
1240 XFPRINTF(TraceFile, "\tTrying to find Stale Sessions\n");
1241 }
1242 }
1243
1244
1245 /* Show Removed Session */
TraceRemovedSession(void)1246 static void TraceRemovedSession(void)
1247 {
1248 if (TraceOn) {
1249 XFPRINTF(TraceFile, "\tRemoved it\n");
1250 }
1251 }
1252
1253
1254 /* Show SSLInfo if provided and is valid. */
TraceSessionInfo(SSLInfo * sslInfo)1255 static void TraceSessionInfo(SSLInfo* sslInfo)
1256 {
1257 if (TraceOn) {
1258 if (sslInfo != NULL && sslInfo->isValid) {
1259 XFPRINTF(TraceFile,
1260 "\tver:(%u %u) suiteId:(%02x %02x) suiteName:(%s) "
1261 #ifdef HAVE_SNI
1262 "sni:(%s) "
1263 #endif
1264 "keySize:(%u)\n",
1265 sslInfo->protocolVersionMajor,
1266 sslInfo->protocolVersionMinor,
1267 sslInfo->serverCipherSuite0,
1268 sslInfo->serverCipherSuite,
1269 sslInfo->serverCipherSuiteName,
1270 #ifdef HAVE_SNI
1271 sslInfo->serverNameIndication,
1272 #endif
1273 sslInfo->keySize);
1274 }
1275 }
1276 }
1277
1278
1279 #ifdef WOLFSSL_SNIFFER_STATS
1280
1281 /* Show value added to a named statistic. */
TraceStat(const char * name,int add)1282 static void TraceStat(const char* name, int add)
1283 {
1284 if (TraceOn) {
1285 XFPRINTF(TraceFile, "\tAdding %d to %s\n", add, name);
1286 }
1287 }
1288
1289 #endif
1290
1291
1292 /* Set user error string */
SetError(int idx,char * error,SnifferSession * session,int fatal)1293 static void SetError(int idx, char* error, SnifferSession* session, int fatal)
1294 {
1295 GetError(idx, error);
1296 TraceError(idx, error);
1297 if (session && fatal == FATAL_ERROR_STATE)
1298 session->flags.fatalError = 1;
1299 }
1300
1301
1302 /* Compare IpAddrInfo structs */
MatchAddr(IpAddrInfo l,IpAddrInfo r)1303 static WC_INLINE int MatchAddr(IpAddrInfo l, IpAddrInfo r)
1304 {
1305 if (l.version == r.version) {
1306 if (l.version == IPV4)
1307 return (l.ip4 == r.ip4);
1308 else if (l.version == IPV6)
1309 return (0 == XMEMCMP(l.ip6, r.ip6, sizeof(l.ip6)));
1310 }
1311 return 0;
1312 }
1313
1314
1315 #ifndef WOLFSSL_SNIFFER_WATCH
1316
1317 /* See if this IPV4 network order address has been registered */
1318 /* return 1 is true, 0 is false */
IsServerRegistered(word32 addr)1319 static int IsServerRegistered(word32 addr)
1320 {
1321 int ret = 0; /* false */
1322 SnifferServer* sniffer;
1323
1324 wc_LockMutex(&ServerListMutex);
1325
1326 sniffer = ServerList;
1327 while (sniffer) {
1328 if (sniffer->server.ip4 == addr) {
1329 ret = 1;
1330 break;
1331 }
1332 sniffer = sniffer->next;
1333 }
1334
1335 wc_UnLockMutex(&ServerListMutex);
1336
1337 return ret;
1338 }
1339
1340
1341 /* See if this port has been registered to watch */
1342 /* See if this IPV4 network order address has been registered */
1343 /* return 1 is true, 0 is false */
IsServerRegistered6(byte * addr)1344 static int IsServerRegistered6(byte* addr)
1345 {
1346 int ret = 0; /* false */
1347 SnifferServer* sniffer;
1348
1349 wc_LockMutex(&ServerListMutex);
1350
1351 sniffer = ServerList;
1352 while (sniffer) {
1353 if (sniffer->server.version == IPV6 &&
1354 0 == XMEMCMP(sniffer->server.ip6, addr, sizeof(sniffer->server.ip6))) {
1355 ret = 1;
1356 break;
1357 }
1358 sniffer = sniffer->next;
1359 }
1360
1361 wc_UnLockMutex(&ServerListMutex);
1362
1363 return ret;
1364 }
1365
1366
1367 /* See if this port has been registered to watch */
1368 /* return 1 is true, 0 is false */
IsPortRegistered(word32 port)1369 static int IsPortRegistered(word32 port)
1370 {
1371 int ret = 0; /* false */
1372 SnifferServer* sniffer;
1373
1374 wc_LockMutex(&ServerListMutex);
1375
1376 sniffer = ServerList;
1377 while (sniffer) {
1378 if (sniffer->port == (int)port) {
1379 ret = 1;
1380 break;
1381 }
1382 sniffer = sniffer->next;
1383 }
1384
1385 wc_UnLockMutex(&ServerListMutex);
1386
1387 return ret;
1388 }
1389
1390 #endif
1391
1392
1393 /* Get SnifferServer from IP and Port */
GetSnifferServer(IpInfo * ipInfo,TcpInfo * tcpInfo)1394 static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
1395 {
1396 SnifferServer* sniffer;
1397
1398 wc_LockMutex(&ServerListMutex);
1399
1400 sniffer = ServerList;
1401
1402 #ifndef WOLFSSL_SNIFFER_WATCH
1403 while (sniffer) {
1404 if (sniffer->port == tcpInfo->srcPort &&
1405 MatchAddr(sniffer->server, ipInfo->src))
1406 break;
1407 if (sniffer->port == tcpInfo->dstPort &&
1408 MatchAddr(sniffer->server, ipInfo->dst))
1409 break;
1410
1411 sniffer = sniffer->next;
1412 }
1413 #else
1414 (void)ipInfo;
1415 (void)tcpInfo;
1416 #endif
1417
1418 wc_UnLockMutex(&ServerListMutex);
1419
1420 return sniffer;
1421 }
1422
1423
1424 /* Hash the Session Info, return hash row */
SessionHash(IpInfo * ipInfo,TcpInfo * tcpInfo)1425 static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
1426 {
1427 word32 hash = 1;
1428
1429 if (ipInfo->src.version == IPV4) {
1430 hash *= ipInfo->src.ip4 * ipInfo->dst.ip4;
1431 }
1432 else if (ipInfo->src.version == IPV6) {
1433 word32* x;
1434 word32 y;
1435 x = (word32*)ipInfo->src.ip6;
1436 y = x[0] ^ x[1] ^ x[2] ^ x[3];
1437 hash *= y;
1438 x = (word32*)ipInfo->dst.ip6;
1439 y = x[0] ^ x[1] ^ x[2] ^ x[3];
1440 hash *= y;
1441 }
1442 hash *= tcpInfo->srcPort * tcpInfo->dstPort;
1443
1444 return hash % HASH_SIZE;
1445 }
1446
1447
1448 /* Get Existing SnifferSession from IP and Port */
GetSnifferSession(IpInfo * ipInfo,TcpInfo * tcpInfo)1449 static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
1450 {
1451 SnifferSession* session;
1452 time_t currTime = XTIME(NULL);
1453 word32 row = SessionHash(ipInfo, tcpInfo);
1454
1455 wc_LockMutex(&SessionMutex);
1456
1457 session = SessionTable[row];
1458 while (session) {
1459 if (MatchAddr(session->server, ipInfo->src) &&
1460 MatchAddr(session->client, ipInfo->dst) &&
1461 session->srvPort == tcpInfo->srcPort &&
1462 session->cliPort == tcpInfo->dstPort)
1463 break;
1464
1465 if (MatchAddr(session->client, ipInfo->src) &&
1466 MatchAddr(session->server, ipInfo->dst) &&
1467 session->cliPort == tcpInfo->srcPort &&
1468 session->srvPort == tcpInfo->dstPort)
1469 break;
1470
1471 session = session->next;
1472 }
1473
1474 if (session)
1475 session->lastUsed= currTime; /* keep session alive, remove stale will */
1476 /* leave alone */
1477 wc_UnLockMutex(&SessionMutex);
1478
1479 /* determine side */
1480 if (session) {
1481 if (MatchAddr(ipInfo->dst, session->server) &&
1482 tcpInfo->dstPort == session->srvPort) {
1483
1484 session->flags.side = WOLFSSL_SERVER_END;
1485 }
1486 else {
1487 session->flags.side = WOLFSSL_CLIENT_END;
1488 }
1489 }
1490
1491 return session;
1492 }
1493
1494
1495 #if defined(HAVE_SNI) || defined(WOLFSSL_SNIFFER_WATCH)
1496
LoadKeyFile(byte ** keyBuf,word32 * keyBufSz,const char * keyFile,int keySz,int typeKey,const char * password)1497 static int LoadKeyFile(byte** keyBuf, word32* keyBufSz,
1498 const char* keyFile, int keySz, int typeKey,
1499 const char* password)
1500 {
1501 byte* loadBuf;
1502 long fileSz = 0;
1503 XFILE file;
1504 int ret = -1;
1505
1506 if (keyBuf == NULL || keyBufSz == NULL || keyFile == NULL) {
1507 return -1;
1508 }
1509
1510 if (keySz == 0) {
1511 /* load from file */
1512 file = XFOPEN(keyFile, "rb");
1513 if (file == XBADFILE) return -1;
1514 if(XFSEEK(file, 0, XSEEK_END) != 0) {
1515 XFCLOSE(file);
1516 return -1;
1517 }
1518 fileSz = XFTELL(file);
1519 if (fileSz > MAX_WOLFSSL_FILE_SIZE || fileSz < 0) {
1520 XFCLOSE(file);
1521 return -1;
1522 }
1523 XREWIND(file);
1524
1525 loadBuf = (byte*)XMALLOC(fileSz, NULL, DYNAMIC_TYPE_FILE);
1526 if (loadBuf == NULL) {
1527 XFCLOSE(file);
1528 return -1;
1529 }
1530
1531 ret = (int)XFREAD(loadBuf, 1, fileSz, file);
1532 XFCLOSE(file);
1533
1534 if (ret != fileSz) {
1535 XFREE(loadBuf, NULL, DYNAMIC_TYPE_FILE);
1536 return -1;
1537 }
1538 }
1539 else {
1540 /* use buffer directly */
1541 loadBuf = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_FILE);
1542 if (loadBuf == NULL) {
1543 return -1;
1544 }
1545 fileSz = keySz;
1546 XMEMCPY(loadBuf, keyFile, fileSz);
1547 }
1548
1549 if (typeKey == WOLFSSL_FILETYPE_PEM) {
1550 byte* saveBuf = (byte*)XMALLOC(fileSz, NULL, DYNAMIC_TYPE_X509);
1551 int saveBufSz = 0;
1552
1553 ret = -1;
1554 if (saveBuf != NULL) {
1555 saveBufSz = wc_KeyPemToDer(loadBuf, (int)fileSz,
1556 saveBuf, (int)fileSz, password);
1557 if (saveBufSz < 0) {
1558 saveBufSz = 0;
1559 XFREE(saveBuf, NULL, DYNAMIC_TYPE_X509);
1560 saveBuf = NULL;
1561 }
1562 else
1563 ret = 0;
1564 }
1565
1566 ForceZero(loadBuf, (word32)fileSz);
1567 XFREE(loadBuf, NULL, DYNAMIC_TYPE_FILE);
1568
1569 if (saveBuf) {
1570 *keyBuf = saveBuf;
1571 *keyBufSz = (word32)saveBufSz;
1572 }
1573 }
1574 else {
1575 *keyBuf = loadBuf;
1576 *keyBufSz = (word32)fileSz;
1577 }
1578
1579 if (ret < 0) {
1580 return -1;
1581 }
1582
1583 return ret;
1584 }
1585
1586 #endif
1587
1588
1589 #ifdef WOLFSSL_SNIFFER_WATCH
1590
CreateWatchSnifferServer(char * error)1591 static int CreateWatchSnifferServer(char* error)
1592 {
1593 SnifferServer* sniffer;
1594
1595 sniffer = (SnifferServer*)XMALLOC(sizeof(SnifferServer), NULL,
1596 DYNAMIC_TYPE_SNIFFER_SERVER);
1597 if (sniffer == NULL) {
1598 SetError(MEMORY_STR, error, NULL, 0);
1599 return -1;
1600 }
1601 InitSnifferServer(sniffer);
1602 sniffer->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
1603 if (!sniffer->ctx) {
1604 SetError(MEMORY_STR, error, NULL, 0);
1605 FreeSnifferServer(sniffer);
1606 return -1;
1607 }
1608 #ifdef WOLF_CRYPTO_CB
1609 if (CryptoDeviceId != INVALID_DEVID)
1610 wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDeviceId);
1611 #endif
1612
1613 /* add to server list */
1614 wc_LockMutex(&ServerListMutex);
1615 sniffer->next = ServerList;
1616 ServerList = sniffer;
1617 wc_UnLockMutex(&ServerListMutex);
1618
1619 return 0;
1620 }
1621
1622 #endif
1623
1624 /* Caller locks ServerListMutex */
SetNamedPrivateKey(const char * name,const char * address,int port,const char * keyFile,int keySz,int typeKey,const char * password,char * error,int isEphemeralKey)1625 static int SetNamedPrivateKey(const char* name, const char* address, int port,
1626 const char* keyFile, int keySz, int typeKey, const char* password,
1627 char* error, int isEphemeralKey)
1628 {
1629 SnifferServer* sniffer;
1630 int ret;
1631 int type = (typeKey == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
1632 WOLFSSL_FILETYPE_ASN1;
1633 int isNew = 0;
1634 IpAddrInfo serverIp;
1635
1636 #ifdef HAVE_SNI
1637 NamedKey* namedKey = NULL;
1638 #endif
1639
1640 (void)name;
1641 #ifdef HAVE_SNI
1642 if (name != NULL) {
1643 namedKey = (NamedKey*)XMALLOC(sizeof(NamedKey),
1644 NULL, DYNAMIC_TYPE_SNIFFER_NAMED_KEY);
1645 if (namedKey == NULL) {
1646 SetError(MEMORY_STR, error, NULL, 0);
1647 return -1;
1648 }
1649 XMEMSET(namedKey, 0, sizeof(NamedKey));
1650
1651 namedKey->nameSz = (word32)XSTRLEN(name);
1652 if (namedKey->nameSz > sizeof(namedKey->name)-1)
1653 namedKey->nameSz = sizeof(namedKey->name)-1;
1654 XSTRNCPY(namedKey->name, name, namedKey->nameSz);
1655 namedKey->name[MAX_SERVER_NAME-1] = '\0';
1656 namedKey->isEphemeralKey = isEphemeralKey;
1657 ret = LoadKeyFile(&namedKey->key, &namedKey->keySz,
1658 keyFile, keySz, type, password);
1659 if (ret < 0) {
1660 SetError(KEY_FILE_STR, error, NULL, 0);
1661 FreeNamedKey(namedKey);
1662 return -1;
1663 }
1664 }
1665 #endif
1666
1667 serverIp.version = IPV4;
1668 serverIp.ip4 = XINET_ADDR(address);
1669 if (serverIp.ip4 == XINADDR_NONE) {
1670 #ifdef FUSION_RTOS
1671 if (XINET_PTON(AF_INET6, address, serverIp.ip6,
1672 sizeof(serverIp.ip4)) == 1) {
1673 #else
1674 if (XINET_PTON(AF_INET6, address, serverIp.ip6) == 1) {
1675 #endif
1676 serverIp.version = IPV6;
1677 }
1678 }
1679
1680 sniffer = ServerList;
1681 while (sniffer != NULL &&
1682 (!MatchAddr(sniffer->server, serverIp) || sniffer->port != port)) {
1683 sniffer = sniffer->next;
1684 }
1685
1686 if (sniffer == NULL) {
1687 isNew = 1;
1688 sniffer = (SnifferServer*)XMALLOC(sizeof(SnifferServer),
1689 NULL, DYNAMIC_TYPE_SNIFFER_SERVER);
1690 if (sniffer == NULL) {
1691 SetError(MEMORY_STR, error, NULL, 0);
1692 #ifdef HAVE_SNI
1693 FreeNamedKey(namedKey);
1694 #endif
1695 return -1;
1696 }
1697 InitSnifferServer(sniffer);
1698
1699 XSTRNCPY(sniffer->address, address, MAX_SERVER_ADDRESS-1);
1700 sniffer->address[MAX_SERVER_ADDRESS-1] = '\0';
1701 sniffer->server = serverIp;
1702 sniffer->port = port;
1703
1704 sniffer->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
1705 if (!sniffer->ctx) {
1706 SetError(MEMORY_STR, error, NULL, 0);
1707 #ifdef HAVE_SNI
1708 FreeNamedKey(namedKey);
1709 #endif
1710 FreeSnifferServer(sniffer);
1711 return -1;
1712 }
1713 }
1714
1715 if (name == NULL) {
1716 if (password) {
1717 #ifdef WOLFSSL_ENCRYPTED_KEYS
1718 wolfSSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
1719 wolfSSL_CTX_set_default_passwd_cb_userdata(
1720 sniffer->ctx, (void*)password);
1721 #endif
1722 }
1723
1724 #ifdef WOLFSSL_STATIC_EPHEMERAL
1725 if (isEphemeralKey) {
1726 /* auto detect key type with WC_PK_TYPE_NONE */
1727 /* keySz == 0 mean load file */
1728 ret = wolfSSL_CTX_set_ephemeral_key(sniffer->ctx, WC_PK_TYPE_NONE,
1729 keyFile, keySz, type);
1730 if (ret == 0)
1731 ret = WOLFSSL_SUCCESS;
1732 }
1733 else
1734 #endif
1735 {
1736 if (keySz == 0) {
1737 ret = wolfSSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
1738 }
1739 else {
1740 ret = wolfSSL_CTX_use_PrivateKey_buffer(sniffer->ctx,
1741 (const byte*)keyFile, keySz, type);
1742 }
1743 }
1744 if (ret != WOLFSSL_SUCCESS) {
1745 SetError(KEY_FILE_STR, error, NULL, 0);
1746 if (isNew)
1747 FreeSnifferServer(sniffer);
1748 return -1;
1749 }
1750 #ifdef WOLF_CRYPTO_CB
1751 wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDeviceId);
1752 #endif
1753 }
1754 #ifdef HAVE_SNI
1755 else {
1756 wc_LockMutex(&sniffer->namedKeysMutex);
1757 namedKey->next = sniffer->namedKeys;
1758 sniffer->namedKeys = namedKey;
1759 wc_UnLockMutex(&sniffer->namedKeysMutex);
1760 }
1761 #endif
1762
1763 if (isNew) {
1764 sniffer->next = ServerList;
1765 ServerList = sniffer;
1766 }
1767
1768 return 0;
1769 }
1770
1771
1772 #ifdef HAVE_SNI
1773 /* Sets the private key for a specific name, server and port */
1774 /* returns 0 on success, -1 on error */
1775 int ssl_SetNamedPrivateKey(const char* name,
1776 const char* address, int port,
1777 const char* keyFile, int typeKey,
1778 const char* password, char* error)
1779 {
1780 int ret;
1781
1782 TraceHeader();
1783 TraceSetNamedServer(name, address, port, keyFile);
1784
1785 wc_LockMutex(&ServerListMutex);
1786 ret = SetNamedPrivateKey(name, address, port, keyFile, 0,
1787 typeKey, password, error, 0);
1788 wc_UnLockMutex(&ServerListMutex);
1789
1790 if (ret == 0)
1791 Trace(NEW_SERVER_STR);
1792
1793 return ret;
1794 }
1795
1796 int ssl_SetNamedPrivateKeyBuffer(const char* name,
1797 const char* address, int port,
1798 const char* keyBuf, int keySz, int typeKey,
1799 const char* password, char* error)
1800 {
1801 int ret;
1802
1803 TraceHeader();
1804 TraceSetNamedServer(name, address, port, NULL);
1805
1806 wc_LockMutex(&ServerListMutex);
1807 ret = SetNamedPrivateKey(name, address, port, keyBuf, keySz,
1808 typeKey, password, error, 0);
1809 wc_UnLockMutex(&ServerListMutex);
1810
1811 if (ret == 0)
1812 Trace(NEW_SERVER_STR);
1813
1814 return ret;
1815 }
1816 #endif /* HAVE_SNI */
1817
1818 /* Sets the private key for a specific server and port */
1819 /* returns 0 on success, -1 on error */
1820 int ssl_SetPrivateKey(const char* address, int port,
1821 const char* keyFile, int typeKey,
1822 const char* password, char* error)
1823 {
1824 int ret;
1825
1826 TraceHeader();
1827 TraceSetServer(address, port, keyFile);
1828
1829 wc_LockMutex(&ServerListMutex);
1830 ret = SetNamedPrivateKey(NULL, address, port, keyFile, 0,
1831 typeKey, password, error, 0);
1832 wc_UnLockMutex(&ServerListMutex);
1833
1834 if (ret == 0)
1835 Trace(NEW_SERVER_STR);
1836
1837 return ret;
1838 }
1839
1840 int ssl_SetPrivateKeyBuffer(const char* address, int port,
1841 const char* keyBuf, int keySz, int typeKey,
1842 const char* password, char* error)
1843 {
1844 int ret;
1845
1846 TraceHeader();
1847 TraceSetServer(address, port, "from buffer");
1848
1849 wc_LockMutex(&ServerListMutex);
1850 ret = SetNamedPrivateKey(NULL, address, port, keyBuf, keySz,
1851 typeKey, password, error, 0);
1852 wc_UnLockMutex(&ServerListMutex);
1853
1854 if (ret == 0)
1855 Trace(NEW_SERVER_STR);
1856
1857 return ret;
1858 }
1859
1860 #ifdef WOLFSSL_STATIC_EPHEMERAL
1861 #ifdef HAVE_SNI
1862 /* Sets the ephemeral key for a specific name, server and port */
1863 /* returns 0 on success, -1 on error */
1864 int ssl_SetNamedEphemeralKey(const char* name,
1865 const char* address, int port,
1866 const char* keyFile, int typeKey,
1867 const char* password, char* error)
1868 {
1869 int ret;
1870
1871 TraceHeader();
1872 TraceSetNamedServer(name, address, port, keyFile);
1873
1874 wc_LockMutex(&ServerListMutex);
1875 ret = SetNamedPrivateKey(name, address, port, keyFile, 0,
1876 typeKey, password, error, 1);
1877 wc_UnLockMutex(&ServerListMutex);
1878
1879 if (ret == 0)
1880 Trace(NEW_SERVER_STR);
1881
1882 return ret;
1883 }
1884
1885 int ssl_SetNamedEphemeralKeyBuffer(const char* name,
1886 const char* address, int port,
1887 const char* keyBuf, int keySz, int typeKey,
1888 const char* password, char* error)
1889 {
1890 int ret;
1891
1892 TraceHeader();
1893 TraceSetNamedServer(name, address, port, NULL);
1894
1895 wc_LockMutex(&ServerListMutex);
1896 ret = SetNamedPrivateKey(name, address, port, keyBuf, keySz,
1897 typeKey, password, error, 1);
1898 wc_UnLockMutex(&ServerListMutex);
1899
1900 if (ret == 0)
1901 Trace(NEW_SERVER_STR);
1902
1903 return ret;
1904 }
1905 #endif /* HAVE_SNI */
1906
1907 /* Sets the ephemeral key for a specific server and port */
1908 /* returns 0 on success, -1 on error */
1909 int ssl_SetEphemeralKey(const char* address, int port,
1910 const char* keyFile, int typeKey,
1911 const char* password, char* error)
1912 {
1913 int ret;
1914
1915 TraceHeader();
1916 TraceSetServer(address, port, keyFile);
1917
1918 wc_LockMutex(&ServerListMutex);
1919 ret = SetNamedPrivateKey(NULL, address, port, keyFile, 0,
1920 typeKey, password, error, 1);
1921 wc_UnLockMutex(&ServerListMutex);
1922
1923 if (ret == 0)
1924 Trace(NEW_SERVER_STR);
1925
1926 return ret;
1927 }
1928
1929 int ssl_SetEphemeralKeyBuffer(const char* address, int port,
1930 const char* keyBuf, int keySz, int typeKey,
1931 const char* password, char* error)
1932 {
1933 int ret;
1934
1935 TraceHeader();
1936 TraceSetServer(address, port, "from buffer");
1937
1938 wc_LockMutex(&ServerListMutex);
1939 ret = SetNamedPrivateKey(NULL, address, port, keyBuf, keySz,
1940 typeKey, password, error, 1);
1941 wc_UnLockMutex(&ServerListMutex);
1942
1943 if (ret == 0)
1944 Trace(NEW_SERVER_STR);
1945
1946 return ret;
1947 }
1948 #endif /* WOLFSSL_STATIC_EPHEMERAL */
1949
1950 /* Check IP Header for IPV6, TCP, and a registered server address */
1951 /* returns 0 on success, -1 on error */
1952 static int CheckIp6Hdr(Ip6Hdr* iphdr, IpInfo* info, int length, char* error)
1953 {
1954 int version = IP_V(iphdr);
1955 int exthdrsz = IP6_HDR_SZ;
1956
1957 TraceIP6(iphdr);
1958 Trace(IP_CHECK_STR);
1959
1960 if (version != IPV6) {
1961 SetError(BAD_IPVER_STR, error, NULL, 0);
1962 return -1;
1963 }
1964
1965 /* Here, we need to move onto next header if not TCP. */
1966 if (iphdr->next_header != TCP_PROTOCOL) {
1967 Ip6ExtHdr* exthdr = (Ip6ExtHdr*)((byte*)iphdr + IP6_HDR_SZ);
1968 do {
1969 int hdrsz = (exthdr->length + 1) * 8;
1970 if (hdrsz > length - exthdrsz) {
1971 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
1972 return -1;
1973 }
1974 exthdrsz += hdrsz;
1975 exthdr = (Ip6ExtHdr*)((byte*)exthdr + hdrsz);
1976 }
1977 while (exthdr->next_header != TCP_PROTOCOL &&
1978 exthdr->next_header != NO_NEXT_HEADER);
1979 }
1980
1981 #ifndef WOLFSSL_SNIFFER_WATCH
1982 if (!IsServerRegistered6(iphdr->src) && !IsServerRegistered6(iphdr->dst)) {
1983 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
1984 return -1;
1985 }
1986 #endif
1987
1988 info->length = exthdrsz;
1989 info->total = XNTOHS(iphdr->length) + info->length;
1990 /* IPv6 doesn't include its own header size in the length like v4. */
1991 info->src.version = IPV6;
1992 XMEMCPY(info->src.ip6, iphdr->src, sizeof(info->src.ip6));
1993 info->dst.version = IPV6;
1994 XMEMCPY(info->dst.ip6, iphdr->dst, sizeof(info->dst.ip6));
1995
1996 return 0;
1997 }
1998
1999
2000 /* Check IP Header for IPV4, TCP, and a registered server address */
2001 /* If header IPv6, pass to CheckIp6Hdr(). */
2002 /* returns 0 on success, -1 on error */
2003 static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
2004 {
2005 int version = IP_V(iphdr);
2006
2007 if (version == IPV6)
2008 return CheckIp6Hdr((Ip6Hdr*)iphdr, info, length, error);
2009
2010 TraceIP(iphdr);
2011 Trace(IP_CHECK_STR);
2012
2013 if (version != IPV4) {
2014 SetError(BAD_IPVER_STR, error, NULL, 0);
2015 return -1;
2016 }
2017
2018 if (iphdr->protocol != TCP_PROTOCOL) {
2019 SetError(BAD_PROTO_STR, error, NULL, 0);
2020 return -1;
2021 }
2022
2023 #ifndef WOLFSSL_SNIFFER_WATCH
2024 if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
2025 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
2026 return -1;
2027 }
2028 #endif
2029
2030 info->length = IP_HL(iphdr);
2031 info->total = XNTOHS(iphdr->length);
2032 info->src.version = IPV4;
2033 info->src.ip4 = iphdr->src;
2034 info->dst.version = IPV4;
2035 info->dst.ip4 = iphdr->dst;
2036
2037 if (info->total == 0)
2038 info->total = length; /* reassembled may be off */
2039
2040 return 0;
2041 }
2042
2043
2044 /* Check TCP Header for a registered port */
2045 /* returns 0 on success, -1 on error */
2046 static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
2047 {
2048 TraceTcp(tcphdr);
2049 Trace(TCP_CHECK_STR);
2050 info->srcPort = XNTOHS(tcphdr->srcPort);
2051 info->dstPort = XNTOHS(tcphdr->dstPort);
2052 info->length = TCP_LEN(tcphdr);
2053 info->sequence = XNTOHL(tcphdr->sequence);
2054 info->fin = tcphdr->flags & TCP_FIN;
2055 info->rst = tcphdr->flags & TCP_RST;
2056 info->syn = tcphdr->flags & TCP_SYN;
2057 info->ack = tcphdr->flags & TCP_ACK;
2058 if (info->ack)
2059 info->ackNumber = XNTOHL(tcphdr->ack);
2060
2061 #ifndef WOLFSSL_SNIFFER_WATCH
2062 if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
2063 SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
2064 return -1;
2065 }
2066 #else
2067 (void)error;
2068 #endif
2069
2070 return 0;
2071 }
2072
2073
2074 /* Decode Record Layer Header */
2075 static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
2076 {
2077 XMEMCPY(rh, input, RECORD_HEADER_SZ);
2078 *size = (rh->length[0] << 8) | rh->length[1];
2079
2080 if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
2081 return LENGTH_ERROR;
2082
2083 return 0;
2084 }
2085
2086
2087 /* Copies the session's information to the provided sslInfo. Skip copy if
2088 * SSLInfo is not provided. */
2089 static void CopySessionInfo(SnifferSession* session, SSLInfo* sslInfo)
2090 {
2091 if (NULL != sslInfo) {
2092 XMEMSET(sslInfo, 0, sizeof(SSLInfo));
2093
2094 /* Pass back Session Info after we have processed the Server Hello. */
2095 if (0 != session->sslServer->options.cipherSuite) {
2096 const char* pCipher;
2097
2098 sslInfo->isValid = 1;
2099 sslInfo->protocolVersionMajor = session->sslServer->version.major;
2100 sslInfo->protocolVersionMinor = session->sslServer->version.minor;
2101 sslInfo->serverCipherSuite0 =
2102 session->sslServer->options.cipherSuite0;
2103 sslInfo->serverCipherSuite =
2104 session->sslServer->options.cipherSuite;
2105
2106 pCipher = wolfSSL_get_cipher(session->sslServer);
2107 if (NULL != pCipher) {
2108 XSTRNCPY((char*)sslInfo->serverCipherSuiteName, pCipher,
2109 sizeof(sslInfo->serverCipherSuiteName));
2110 sslInfo->serverCipherSuiteName
2111 [sizeof(sslInfo->serverCipherSuiteName) - 1] = '\0';
2112 }
2113 sslInfo->keySize = session->keySz;
2114 #ifdef HAVE_SNI
2115 if (NULL != session->sni) {
2116 XSTRNCPY((char*)sslInfo->serverNameIndication,
2117 session->sni, sizeof(sslInfo->serverNameIndication));
2118 sslInfo->serverNameIndication
2119 [sizeof(sslInfo->serverNameIndication) - 1] = '\0';
2120 }
2121 #endif
2122 TraceSessionInfo(sslInfo);
2123 }
2124 }
2125 }
2126
2127
2128 /* Call the session connection start callback. */
2129 static void CallConnectionCb(SnifferSession* session)
2130 {
2131 if (ConnectionCb != NULL) {
2132 SSLInfo info;
2133 CopySessionInfo(session, &info);
2134 ConnectionCb((const void*)session, &info, ConnectionCbCtx);
2135 }
2136 }
2137
2138 #ifdef SHOW_SECRETS
2139 static void PrintSecret(const char* desc, const byte* buf, int sz)
2140 {
2141 int i;
2142 printf("%s: ", desc);
2143 for (i = 0; i < sz; i++) {
2144 printf("%02x", buf[i]);
2145 }
2146 printf("\n");
2147 }
2148
2149 static void ShowTlsSecrets(SnifferSession* session)
2150 {
2151 PrintSecret("server master secret", session->sslServer->arrays->masterSecret, SECRET_LEN);
2152 PrintSecret("client master secret", session->sslClient->arrays->masterSecret, SECRET_LEN);
2153 printf("server suite = %d\n", session->sslServer->options.cipherSuite);
2154 printf("client suite = %d\n", session->sslClient->options.cipherSuite);
2155 }
2156 #endif /* SHOW_SECRETS */
2157
2158
2159 /* Process Keys */
2160
2161 static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
2162 char* error, KeyShareInfo* ksInfo)
2163 {
2164 word32 idx = 0;
2165 int ret;
2166 DerBuffer* keyBuf = NULL;
2167 int keyBufFree = 0;
2168 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
2169 int useCurveId = 0;
2170 #endif
2171 int devId = INVALID_DEVID;
2172 WOLFSSL_CTX* ctx = session->context->ctx;
2173 WOLFSSL* ssl = session->sslServer;
2174
2175 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
2176 if (ksInfo && ksInfo->curve_id != 0)
2177 useCurveId = ksInfo->curve_id;
2178 #endif
2179 #ifdef WOLF_CRYPTO_CB
2180 devId = CryptoDeviceId;
2181 #endif
2182
2183 if (session->sslServer->arrays == NULL || session->sslClient->arrays == NULL) {
2184 /* secret's have already been established and released */
2185 /* this can happen with secure renegotiation */
2186 return 0;
2187 }
2188
2189 #ifndef NO_RSA
2190 /* Static RSA */
2191 if (ksInfo == NULL && ssl->buffers.key) {
2192 RsaKey key;
2193 int length;
2194 int keyInit = 0;
2195
2196 ret = wc_InitRsaKey_ex(&key, NULL, devId);
2197 if (ret == 0) {
2198 keyInit = 1;
2199 keyBuf = ssl->buffers.key;
2200
2201 ret = wc_RsaPrivateKeyDecode(keyBuf->buffer, &idx, &key,
2202 keyBuf->length);
2203 if (ret != 0) {
2204 #ifndef HAVE_ECC
2205 #ifdef WOLFSSL_SNIFFER_STATS
2206 INC_STAT(SnifferStats.sslKeyFails);
2207 #endif
2208 SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
2209 #else
2210 /* If we can do ECC, this isn't fatal. Not loading a key later
2211 * will be fatal, though. */
2212 SetError(RSA_DECODE_STR, error, session, 0);
2213 keyBuf = NULL;
2214 #endif
2215 }
2216 }
2217
2218 if (ret == 0) {
2219 length = wc_RsaEncryptSize(&key);
2220 if (IsTLS(session->sslServer)) {
2221 input += 2; /* tls pre length */
2222 }
2223
2224 if (length > *sslBytes) {
2225 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
2226 ret = -1;
2227 }
2228 }
2229
2230 #ifdef WC_RSA_BLINDING
2231 if (ret == 0) {
2232 ret = wc_RsaSetRNG(&key, session->sslServer->rng);
2233 if (ret != 0) {
2234 SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
2235 }
2236 }
2237 #endif
2238
2239 if (ret == 0) {
2240 session->keySz = length * WOLFSSL_BIT_SIZE;
2241 /* length is the key size in bytes */
2242 session->sslServer->arrays->preMasterSz = SECRET_LEN;
2243
2244 do {
2245 #ifdef WOLFSSL_ASYNC_CRYPT
2246 ret = wc_AsyncWait(ret, &key.asyncDev,
2247 WC_ASYNC_FLAG_CALL_AGAIN);
2248 #endif
2249 if (ret >= 0) {
2250 ret = wc_RsaPrivateDecrypt(input, length,
2251 session->sslServer->arrays->preMasterSecret,
2252 session->sslServer->arrays->preMasterSz, &key);
2253 }
2254 } while (ret == WC_PENDING_E);
2255
2256 if (ret != SECRET_LEN) {
2257 SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
2258 }
2259 }
2260
2261 if (keyInit) {
2262 wc_FreeRsaKey(&key);
2263 }
2264 }
2265 #endif /* !NO_RSA */
2266
2267 #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
2268 /* Static DH Key */
2269 if (ksInfo && ksInfo->dh_key_bits != 0 && keyBuf == NULL) {
2270 DhKey dhKey;
2271 #ifdef HAVE_PUBLIC_FFDHE
2272 const DhParams* params;
2273 #endif
2274 word32 privKeySz = 0, p_len = 0;
2275 byte privKey[52]; /* max for TLS */
2276 int keyInit = 0;
2277
2278 /* try and load static ephemeral */
2279 #ifdef WOLFSSL_STATIC_EPHEMERAL
2280 #ifndef SINGLE_THREADED
2281 int keyLocked = 0;
2282 if (ctx->staticKELockInit &&
2283 wc_LockMutex(&ctx->staticKELock) == 0)
2284 #endif
2285 {
2286 #ifndef SINGLE_THREADED
2287 keyLocked = 1;
2288 #endif
2289 keyBuf = ssl->staticKE.dhKey;
2290 if (keyBuf == NULL)
2291 keyBuf = ctx->staticKE.dhKey;
2292 }
2293 #endif
2294
2295 ret = 0;
2296 #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
2297 if (KeyCb != NULL) {
2298 if (keyBuf == NULL) {
2299 ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
2300 if (ret == 0)
2301 keyBufFree = 1;
2302 }
2303 ret = KeyCb(session, ksInfo->named_group,
2304 session->srvKs.key, session->srvKs.key_len,
2305 session->cliKs.key, session->cliKs.key_len,
2306 keyBuf, KeyCbCtx, error);
2307 if (ret != 0) {
2308 SetError(-1, error, session, FATAL_ERROR_STATE);
2309 }
2310 }
2311 #endif
2312 if (ret == 0 && keyBuf == NULL) {
2313 ret = BUFFER_E;
2314 }
2315
2316 #ifdef HAVE_PUBLIC_FFDHE
2317 if (ret == 0) {
2318 /* get DH params */
2319 switch (ksInfo->named_group) {
2320 #ifdef HAVE_FFDHE_2048
2321 case WOLFSSL_FFDHE_2048:
2322 params = wc_Dh_ffdhe2048_Get();
2323 privKeySz = 29;
2324 break;
2325 #endif
2326 #ifdef HAVE_FFDHE_3072
2327 case WOLFSSL_FFDHE_3072:
2328 params = wc_Dh_ffdhe3072_Get();
2329 privKeySz = 34;
2330 break;
2331 #endif
2332 #ifdef HAVE_FFDHE_4096
2333 case WOLFSSL_FFDHE_4096:
2334 params = wc_Dh_ffdhe4096_Get();
2335 privKeySz = 39;
2336 break;
2337 #endif
2338 #ifdef HAVE_FFDHE_6144
2339 case WOLFSSL_FFDHE_6144:
2340 params = wc_Dh_ffdhe6144_Get();
2341 privKeySz = 46;
2342 break;
2343 #endif
2344 #ifdef HAVE_FFDHE_8192
2345 case WOLFSSL_FFDHE_8192:
2346 params = wc_Dh_ffdhe8192_Get();
2347 privKeySz = 52;
2348 break;
2349 #endif
2350 default:
2351 ret = BAD_FUNC_ARG;
2352 }
2353 }
2354 #endif
2355
2356 if (ret == 0) {
2357 ret = wc_InitDhKey_ex(&dhKey, NULL, devId);
2358 if (ret == 0)
2359 keyInit = 1;
2360 }
2361 if (ret == 0) {
2362 #ifdef HAVE_PUBLIC_FFDHE
2363 ret = wc_DhSetKey(&dhKey,
2364 (byte*)params->p, params->p_len,
2365 (byte*)params->g, params->g_len);
2366 p_len = params->p_len;
2367 #else
2368 ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group);
2369 if (ret == 0) {
2370 privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group);
2371 ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group,
2372 &p_len, NULL, NULL);
2373 }
2374 #endif
2375 }
2376 if (ret == 0) {
2377 ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey,
2378 keyBuf->length);
2379 }
2380 if (ret == 0) {
2381 ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL,
2382 NULL);
2383 }
2384
2385 #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
2386 if (keyLocked) {
2387 wc_UnLockMutex(&ctx->staticKELock);
2388 }
2389 #endif
2390
2391 if (ret == 0) {
2392 /* Derive secret from private key and peer's public key */
2393 do {
2394 #ifdef WOLFSSL_ASYNC_CRYPT
2395 ret = wc_AsyncWait(ret, &dhKey.asyncDev,
2396 WC_ASYNC_FLAG_CALL_AGAIN);
2397 #endif
2398 if (ret >= 0) {
2399 PRIVATE_KEY_UNLOCK();
2400 ret = wc_DhAgree(&dhKey,
2401 session->sslServer->arrays->preMasterSecret,
2402 &session->sslServer->arrays->preMasterSz,
2403 privKey, privKeySz,
2404 input, *sslBytes);
2405 PRIVATE_KEY_LOCK();
2406 }
2407 } while (ret == WC_PENDING_E);
2408 }
2409
2410 if (keyInit)
2411 wc_FreeDhKey(&dhKey);
2412
2413 #ifdef WOLFSSL_SNIFFER_STATS
2414 if (ret != 0)
2415 INC_STAT(SnifferStats.sslKeyFails);
2416 #endif
2417
2418 /* left-padded with zeros up to the size of the prime */
2419 if (ret == 0 && p_len > session->sslServer->arrays->preMasterSz) {
2420 word32 diff = p_len - session->sslServer->arrays->preMasterSz;
2421 XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff,
2422 session->sslServer->arrays->preMasterSecret,
2423 session->sslServer->arrays->preMasterSz);
2424 XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff);
2425 session->sslServer->arrays->preMasterSz = p_len;
2426 }
2427 }
2428 #endif /* !NO_DH && WOLFSSL_DH_EXTRA */
2429
2430 #ifdef HAVE_ECC
2431 /* Static ECC Key */
2432 if (useCurveId >= 0 && keyBuf == NULL
2433 #ifdef HAVE_CURVE25519
2434 && useCurveId != ECC_X25519
2435 #endif
2436 #ifdef HAVE_CURVE448
2437 && useCurveId != ECC_X448
2438 #endif
2439 ) {
2440 ecc_key key, pubKey;
2441 int length, keyInit = 0, pubKeyInit = 0;
2442
2443 /* try and load static ephemeral */
2444 #ifdef WOLFSSL_STATIC_EPHEMERAL
2445 #ifndef SINGLE_THREADED
2446 int keyLocked = 0;
2447 if (ctx->staticKELockInit &&
2448 wc_LockMutex(&ctx->staticKELock) == 0)
2449 #endif
2450 {
2451 #ifndef SINGLE_THREADED
2452 keyLocked = 1;
2453 #endif
2454 keyBuf = ssl->staticKE.ecKey;
2455 if (keyBuf == NULL)
2456 keyBuf = ctx->staticKE.ecKey;
2457 }
2458 #endif
2459
2460 /* try static ECC */
2461 if (keyBuf == NULL) {
2462 keyBuf = session->sslServer->buffers.key;
2463 }
2464
2465 ret = 0;
2466 #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
2467 if (KeyCb != NULL && ksInfo) {
2468 if (keyBuf == NULL) {
2469 ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
2470 if (ret == 0)
2471 keyBufFree = 1;
2472 }
2473 ret = KeyCb(session, ksInfo->named_group,
2474 session->srvKs.key, session->srvKs.key_len,
2475 session->cliKs.key, session->cliKs.key_len,
2476 keyBuf, KeyCbCtx, error);
2477 if (ret != 0) {
2478 SetError(-1, error, session, FATAL_ERROR_STATE);
2479 }
2480 }
2481 #endif
2482
2483 if (ret == 0 && keyBuf == NULL) {
2484 ret = BUFFER_E;
2485 }
2486 if (ret == 0) {
2487 ret = wc_ecc_init_ex(&key, NULL, devId);
2488 if (ret == 0)
2489 keyInit = 1;
2490 }
2491 #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
2492 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
2493 !defined(HAVE_SELFTEST)
2494 if (ret == 0) {
2495 ret = wc_ecc_set_rng(&key, session->sslServer->rng);
2496 }
2497 #endif
2498 if (ret == 0) {
2499 idx = 0;
2500 ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length);
2501 if (ret != 0) {
2502 SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
2503 }
2504 }
2505
2506 #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
2507 if (keyLocked) {
2508 wc_UnLockMutex(&ctx->staticKELock);
2509 }
2510 #endif
2511
2512 if (ret == 0) {
2513 length = wc_ecc_size(&key) * 2 + 1;
2514 /* The length should be 2 times the key size (x and y), plus 1
2515 * for the type byte. */
2516 if (!IsAtLeastTLSv1_3(session->sslServer->version)) {
2517 input += 1; /* Don't include the TLS length for the key. */
2518 }
2519
2520 if (length > *sslBytes) {
2521 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
2522 ret = -1;
2523 }
2524
2525 /* if curve not provided in key share data, then use private key curve */
2526 if (useCurveId == 0 && key.dp) {
2527 useCurveId = key.dp->id;
2528 }
2529 }
2530 if (ret == 0) {
2531 ret = wc_ecc_init(&pubKey);
2532 if (ret == 0)
2533 pubKeyInit = 1;
2534 }
2535 if (ret == 0) {
2536 ret = wc_ecc_import_x963_ex(input, length, &pubKey, useCurveId);
2537 if (ret != 0) {
2538 SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
2539 }
2540 }
2541 if (ret == 0) {
2542 session->keySz = ((length - 1) / 2) * WOLFSSL_BIT_SIZE;
2543 /* Length is in bytes. Subtract 1 for the ECC key type. Divide
2544 * by two as the key is in (x,y) coordinates, where x and y are
2545 * the same size, the key size. Convert from bytes to bits. */
2546 session->sslServer->arrays->preMasterSz = ENCRYPT_LEN;
2547
2548 do {
2549 #ifdef WOLFSSL_ASYNC_CRYPT
2550 ret = wc_AsyncWait(ret, &key.asyncDev,
2551 WC_ASYNC_FLAG_CALL_AGAIN);
2552 #endif
2553 if (ret >= 0) {
2554 PRIVATE_KEY_UNLOCK();
2555 ret = wc_ecc_shared_secret(&key, &pubKey,
2556 session->sslServer->arrays->preMasterSecret,
2557 &session->sslServer->arrays->preMasterSz);
2558 PRIVATE_KEY_LOCK();
2559 }
2560 } while (ret == WC_PENDING_E);
2561 }
2562
2563 #ifdef WOLFSSL_SNIFFER_STATS
2564 if (ret != 0)
2565 INC_STAT(SnifferStats.sslKeyFails);
2566 #endif
2567
2568 if (keyInit)
2569 wc_ecc_free(&key);
2570 if (pubKeyInit)
2571 wc_ecc_free(&pubKey);
2572 }
2573 #endif /* HAVE_ECC */
2574
2575 #ifdef HAVE_CURVE25519
2576 /* Static Curve25519 Key */
2577 if (useCurveId == ECC_X25519) {
2578 curve25519_key key, pubKey;
2579 int length, keyInit = 0, pubKeyInit = 0;
2580
2581 /* try and load static ephemeral */
2582 #ifdef WOLFSSL_STATIC_EPHEMERAL
2583 #ifndef SINGLE_THREADED
2584 int keyLocked = 0;
2585 if (ctx->staticKELockInit &&
2586 wc_LockMutex(&ctx->staticKELock) == 0)
2587 #endif
2588 {
2589 #ifndef SINGLE_THREADED
2590 keyLocked = 1;
2591 #endif
2592 keyBuf = ssl->staticKE.x25519Key;
2593 if (keyBuf == NULL)
2594 keyBuf = ctx->staticKE.x25519Key;
2595 }
2596 #endif
2597
2598 ret = 0;
2599 #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
2600 if (KeyCb != NULL && ksInfo) {
2601 if (keyBuf == NULL) {
2602 ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
2603 if (ret == 0)
2604 keyBufFree = 1;
2605 }
2606 ret = KeyCb(session, ksInfo->named_group,
2607 session->srvKs.key, session->srvKs.key_len,
2608 session->cliKs.key, session->cliKs.key_len,
2609 keyBuf, KeyCbCtx, error);
2610 if (ret != 0) {
2611 SetError(-1, error, session, FATAL_ERROR_STATE);
2612 return ret;
2613 }
2614 }
2615 #endif
2616
2617 if (ret == 0 && keyBuf == NULL) {
2618 ret = BUFFER_E;
2619 }
2620 if (ret == 0) {
2621 ret = wc_curve25519_init_ex(&key, NULL, devId);
2622 if (ret == 0)
2623 keyInit = 1;
2624 }
2625 if (ret == 0) {
2626 idx = 0;
2627 ret = wc_Curve25519PrivateKeyDecode(keyBuf->buffer, &idx, &key,
2628 keyBuf->length);
2629 if (ret != 0) {
2630 SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
2631 }
2632 }
2633
2634 #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
2635 if (keyLocked) {
2636 wc_UnLockMutex(&ctx->staticKELock);
2637 }
2638 #endif
2639
2640 if (ret == 0) {
2641 length = CURVE25519_KEYSIZE;
2642 if (length > *sslBytes) {
2643 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
2644 ret = -1;
2645 }
2646 }
2647 if (ret == 0) {
2648 ret = wc_curve25519_init(&pubKey);
2649 if (ret == 0)
2650 pubKeyInit = 1;
2651 }
2652 if (ret == 0) {
2653 ret = wc_curve25519_import_public_ex(input, length, &pubKey,
2654 EC25519_LITTLE_ENDIAN);
2655 if (ret != 0) {
2656 SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
2657 }
2658 }
2659
2660 if (ret == 0) {
2661 /* For Curve25519 length is always 32 */
2662 session->keySz = CURVE25519_KEYSIZE;
2663 session->sslServer->arrays->preMasterSz = ENCRYPT_LEN;
2664
2665 ret = wc_curve25519_shared_secret_ex(&key, &pubKey,
2666 session->sslServer->arrays->preMasterSecret,
2667 &session->sslServer->arrays->preMasterSz, EC25519_LITTLE_ENDIAN);
2668 }
2669
2670 #ifdef WOLFSSL_SNIFFER_STATS
2671 if (ret != 0)
2672 INC_STAT(SnifferStats.sslKeyFails);
2673 #endif
2674
2675 if (keyInit)
2676 wc_curve25519_free(&key);
2677 if (pubKeyInit)
2678 wc_curve25519_free(&pubKey);
2679 }
2680 #endif /* HAVE_CURVE25519 */
2681
2682 #ifdef HAVE_CURVE448
2683 /* Static Curve448 Key */
2684 if (useCurveId == ECC_X448) {
2685 curve448_key key, pubKey;
2686 int length, keyInit = 0, pubKeyInit = 0;
2687
2688 /* try and load static ephemeral */
2689 #ifdef WOLFSSL_STATIC_EPHEMERAL
2690 #ifndef SINGLE_THREADED
2691 int keyLocked = 0;
2692 if (ctx->staticKELockInit &&
2693 wc_LockMutex(&ctx->staticKELock) == 0)
2694 #endif
2695 {
2696 #ifndef SINGLE_THREADED
2697 keyLocked = 1;
2698 #endif
2699 keyBuf = ssl->staticKE.x448Key;
2700 if (keyBuf == NULL)
2701 keyBuf = ctx->staticKE.x448Key;
2702 }
2703 #endif
2704
2705 ret = 0;
2706 #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
2707 if (KeyCb != NULL && ksInfo) {
2708 if (keyBuf == NULL) {
2709 ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
2710 if (ret == 0)
2711 keyBufFree = 1;
2712 }
2713 ret = KeyCb(session, ksInfo->named_group,
2714 session->srvKs.key, session->srvKs.key_len,
2715 session->cliKs.key, session->cliKs.key_len,
2716 keyBuf, KeyCbCtx, error);
2717 if (ret != 0) {
2718 SetError(-1, error, session, FATAL_ERROR_STATE);
2719 return ret;
2720 }
2721 }
2722 #endif
2723
2724 if (ret == 0 && keyBuf == NULL) {
2725 ret = BUFFER_E;
2726 }
2727 if (ret == 0) {
2728 ret = wc_curve448_init(&key);
2729 if (ret == 0)
2730 keyInit = 1;
2731 }
2732 if (ret == 0) {
2733 idx = 0;
2734 ret = wc_Curve448PrivateKeyDecode(keyBuf->buffer, &idx, &key,
2735 keyBuf->length);
2736 if (ret != 0) {
2737 SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
2738 }
2739 }
2740
2741 #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
2742 if (keyLocked) {
2743 wc_UnLockMutex(&ctx->staticKELock);
2744 }
2745 #endif
2746
2747 if (ret == 0) {
2748 length = CURVE448_KEY_SIZE;
2749 if (length > *sslBytes) {
2750 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
2751 ret = -1;
2752 }
2753 }
2754 if (ret == 0) {
2755 ret = wc_curve448_init(&pubKey);
2756 if (ret == 0)
2757 pubKeyInit = 1;
2758 }
2759 if (ret == 0) {
2760 ret = wc_curve448_import_public_ex(input, length, &pubKey,
2761 EC448_LITTLE_ENDIAN);
2762 if (ret != 0) {
2763 SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
2764 }
2765 }
2766
2767 if (ret == 0) {
2768 session->keySz = CURVE448_KEY_SIZE;
2769 session->sslServer->arrays->preMasterSz = ENCRYPT_LEN;
2770
2771 ret = wc_curve448_shared_secret_ex(&key, &pubKey,
2772 session->sslServer->arrays->preMasterSecret,
2773 &session->sslServer->arrays->preMasterSz, EC448_LITTLE_ENDIAN);
2774 }
2775
2776 #ifdef WOLFSSL_SNIFFER_STATS
2777 if (ret != 0)
2778 INC_STAT(SnifferStats.sslKeyFails);
2779 #endif
2780
2781 if (keyInit)
2782 wc_curve448_free(&key);
2783 if (pubKeyInit)
2784 wc_curve448_free(&pubKey);
2785 }
2786 #endif /* HAVE_CURVE448 */
2787
2788 if (keyBufFree && keyBuf != NULL) {
2789 FreeDer(&keyBuf);
2790 }
2791
2792 /* store for client side as well */
2793 XMEMCPY(session->sslClient->arrays->preMasterSecret,
2794 session->sslServer->arrays->preMasterSecret,
2795 session->sslServer->arrays->preMasterSz);
2796 session->sslClient->arrays->preMasterSz =
2797 session->sslServer->arrays->preMasterSz;
2798
2799 #ifdef SHOW_SECRETS
2800 PrintSecret("pre master secret",
2801 session->sslServer->arrays->preMasterSecret,
2802 session->sslServer->arrays->preMasterSz);
2803 #endif
2804
2805 if (SetCipherSpecs(session->sslServer) != 0) {
2806 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
2807 return -1;
2808 }
2809
2810 if (SetCipherSpecs(session->sslClient) != 0) {
2811 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
2812 return -1;
2813 }
2814
2815 #ifdef WOLFSSL_TLS13
2816 /* TLS v1.3 derive handshake key */
2817 if (IsAtLeastTLSv1_3(session->sslServer->version)) {
2818 ret = DeriveEarlySecret(session->sslServer);
2819 ret += DeriveEarlySecret(session->sslClient);
2820 ret += DeriveHandshakeSecret(session->sslServer);
2821 ret += DeriveHandshakeSecret(session->sslClient);
2822 ret += DeriveTls13Keys(session->sslServer, handshake_key, ENCRYPT_AND_DECRYPT_SIDE, 1);
2823 ret += DeriveTls13Keys(session->sslClient, handshake_key, ENCRYPT_AND_DECRYPT_SIDE, 1);
2824 #ifdef WOLFSSL_EARLY_DATA
2825 ret += SetKeysSide(session->sslServer, DECRYPT_SIDE_ONLY);
2826 ret += SetKeysSide(session->sslClient, DECRYPT_SIDE_ONLY);
2827 #else
2828 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
2829 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
2830 #endif
2831 }
2832 else
2833 #endif
2834 {
2835 ret = MakeMasterSecret(session->sslServer);
2836 ret += MakeMasterSecret(session->sslClient);
2837 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
2838 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
2839 }
2840 if (ret != 0) {
2841 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
2842 return -1;
2843 }
2844
2845 #ifdef SHOW_SECRETS
2846 #ifdef WOLFSSL_TLS13
2847 if (!IsAtLeastTLSv1_3(session->sslServer->version))
2848 #endif
2849 ShowTlsSecrets(session);
2850 #endif
2851
2852 CallConnectionCb(session);
2853
2854 return ret;
2855 }
2856
2857 /* Process Client Key Exchange */
2858 static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
2859 SnifferSession* session, char* error)
2860 {
2861 int ret;
2862
2863 #ifndef WOLFSSL_STATIC_EPHEMERAL
2864 if (session->sslServer->buffers.key == NULL ||
2865 session->sslServer->buffers.key->buffer == NULL ||
2866 session->sslServer->buffers.key->length == 0) {
2867
2868 SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
2869 return -1;
2870 }
2871 #endif
2872
2873 ret = SetupKeys(input, sslBytes, session, error, NULL);
2874
2875 return ret;
2876 }
2877
2878 #ifdef WOLFSSL_TLS13
2879 static int ProcessKeyShare(KeyShareInfo* info, const byte* input, int len,
2880 word16 filter_group)
2881 {
2882 int index = 0;
2883 while (index < len) {
2884 /* clear info (reset dh_key_bits and curve_id) */
2885 XMEMSET(info, 0, sizeof(KeyShareInfo));
2886
2887 /* Named group and public key */
2888 info->named_group = (word16)((input[index] << 8) | input[index+1]);
2889 index += OPAQUE16_LEN;
2890 info->key_len = 0;
2891 info->key = NULL;
2892 /* If key was provided... (a hello_retry_request will not send a key) */
2893 if (index + 2 <= len) {
2894 info->key_len = (word16)((input[index] << 8) | input[index+1]);
2895 index += OPAQUE16_LEN;
2896 if (info->key_len == 0 || info->key_len > len - index) {
2897 return -1;
2898 }
2899 info->key = &input[index];
2900 index += info->key_len;
2901 }
2902
2903 switch (info->named_group) {
2904 #ifndef NO_DH
2905 #ifdef HAVE_FFDHE_2048
2906 case WOLFSSL_FFDHE_2048:
2907 info->dh_key_bits = 2048;
2908 break;
2909 #endif
2910 #ifdef HAVE_FFDHE_3072
2911 case WOLFSSL_FFDHE_3072:
2912 info->dh_key_bits = 3072;
2913 break;
2914 #endif
2915 #ifdef HAVE_FFDHE_4096
2916 case WOLFSSL_FFDHE_4096:
2917 info->dh_key_bits = 4096;
2918 break;
2919 #endif
2920 #ifdef HAVE_FFDHE_6144
2921 case WOLFSSL_FFDHE_6144:
2922 info->dh_key_bits = 6144;
2923 break;
2924 #endif
2925 #ifdef HAVE_FFDHE_8192
2926 case WOLFSSL_FFDHE_8192:
2927 info->dh_key_bits = 8192;
2928 break;
2929 #endif
2930 #endif /* !NO_DH */
2931 #ifdef HAVE_ECC
2932 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
2933 #ifndef NO_ECC_SECP
2934 case WOLFSSL_ECC_SECP256R1:
2935 info->curve_id = ECC_SECP256R1;
2936 break;
2937 #endif /* !NO_ECC_SECP */
2938 #endif
2939 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
2940 #ifndef NO_ECC_SECP
2941 case WOLFSSL_ECC_SECP384R1:
2942 info->curve_id = ECC_SECP384R1;
2943 break;
2944 #endif /* !NO_ECC_SECP */
2945 #endif
2946 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
2947 #ifndef NO_ECC_SECP
2948 case WOLFSSL_ECC_SECP521R1:
2949 info->curve_id = ECC_SECP521R1;
2950 break;
2951 #endif /* !NO_ECC_SECP */
2952 #endif
2953 #endif /* HAVE_ECC */
2954 #ifdef HAVE_CURVE25519
2955 case WOLFSSL_ECC_X25519:
2956 info->curve_id = ECC_X25519;
2957 break;
2958 #endif
2959 #ifdef HAVE_CURVE448
2960 case WOLFSSL_ECC_X448:
2961 info->curve_id = ECC_X448;
2962 break;
2963 #endif
2964 default:
2965 /* do not throw error here, keep iterating the client key share */
2966 break;
2967 }
2968
2969 if (filter_group == 0 || filter_group == info->named_group) {
2970 return 0;
2971 }
2972 }
2973 return NO_PEER_KEY; /* unsupported key type */
2974 }
2975
2976 static int ProcessServerKeyShare(SnifferSession* session, const byte* input, int len,
2977 char* error)
2978 {
2979 int ret;
2980
2981 if (session->cliKeyShare == NULL || session->cliKeyShareSz == 0) {
2982 /* session->cliKeyShareSz could not be provided yet if the client_hello
2983 did not send a key share to force a hello_retry_request */
2984 return 0;
2985 }
2986
2987 /* Get server_hello key share (and key) */
2988 ret = ProcessKeyShare(&session->srvKs, input, len, 0);
2989 if (ret == 0 && session->srvKs.key_len > 0) {
2990 /* Get client_hello key share */
2991 ret = ProcessKeyShare(&session->cliKs, session->cliKeyShare,
2992 session->cliKeyShareSz, session->srvKs.named_group);
2993 }
2994 if (ret != 0) {
2995 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
2996 return -1;
2997 }
2998
2999 return ret;
3000 }
3001 #endif /* WOLFSSL_TLS13 */
3002
3003 /* Process Session Ticket */
3004 static int ProcessSessionTicket(const byte* input, int* sslBytes,
3005 SnifferSession* session, char* error)
3006 {
3007 word16 len;
3008
3009 #ifdef WOLFSSL_TLS13
3010 WOLFSSL* ssl;
3011
3012 if (session->flags.side == WOLFSSL_SERVER_END)
3013 ssl = session->sslServer;
3014 else
3015 ssl = session->sslClient;
3016 #endif
3017
3018 /* make sure can read through hint len */
3019 if (TICKET_HINT_LEN > *sslBytes) {
3020 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3021 return -1;
3022 }
3023 input += TICKET_HINT_LEN; /* skip over hint len */
3024 *sslBytes -= TICKET_HINT_LEN;
3025
3026 #ifdef WOLFSSL_TLS13
3027 /* TLS v1.3 has hint age and nonce */
3028 if (IsAtLeastTLSv1_3(ssl->version)) {
3029 /* make sure can read through hint age and nonce len */
3030 if (TICKET_HINT_AGE_LEN + 1 > *sslBytes) {
3031 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3032 return -1;
3033 }
3034 input += TICKET_HINT_AGE_LEN; /* skip over hint age */
3035 *sslBytes -= TICKET_HINT_AGE_LEN;
3036
3037 /* ticket nonce */
3038 len = input[0];
3039 if (len > MAX_TICKET_NONCE_SZ) {
3040 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3041 return -1;
3042 }
3043 input += OPAQUE8_LEN;
3044 *sslBytes -= OPAQUE8_LEN;
3045 #ifdef HAVE_SESSION_TICKET
3046 /* store nonce in server for DeriveResumptionPSK */
3047 session->sslServer->session.ticketNonce.len = len;
3048 if (len > 0)
3049 XMEMCPY(&session->sslServer->session.ticketNonce.data, input, len);
3050 #endif
3051 input += len;
3052 *sslBytes -= len;
3053 }
3054 #endif
3055
3056 /* make sure can read through len */
3057 if (OPAQUE16_LEN > *sslBytes) {
3058 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3059 return -1;
3060 }
3061
3062 len = (word16)((input[0] << 8) | input[1]);
3063 input += OPAQUE16_LEN;
3064 *sslBytes -= OPAQUE16_LEN;
3065
3066 /* make sure can read through ticket */
3067 if (len > *sslBytes) {
3068 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3069 return -1;
3070 }
3071
3072 #ifdef WOLFSSL_TLS13
3073 /* TLS v1.3 has hint age and nonce */
3074 if (IsAtLeastTLSv1_3(ssl->version)) {
3075 /* Note: Must use server session for sessions */
3076 #ifdef HAVE_SESSION_TICKET
3077 if (SetTicket(session->sslServer, input, len) != 0) {
3078 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3079 return -1;
3080 }
3081
3082 /* set haveSessionId to use the wolfSession cache */
3083 session->sslServer->options.haveSessionId = 1;
3084
3085 /* Use the wolf Session cache to retain resumption secret */
3086 if (session->flags.cached == 0) {
3087 WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL, 0);
3088 if (sess == NULL) {
3089 AddSession(session->sslServer); /* don't re add */
3090 #ifdef WOLFSSL_SNIFFER_STATS
3091 INC_STAT(SnifferStats.sslResumptionInserts);
3092 #endif
3093 }
3094 session->flags.cached = 1;
3095 }
3096 #endif /* HAVE_SESSION_TICKET */
3097 }
3098 else
3099 #endif /* WOLFSSL_TLS13 */
3100 {
3101 /* capture last part of sessionID as macID (32 bytes) */
3102 if (len < ID_LEN) {
3103 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
3104 return -1;
3105 }
3106 /* store session with macID as sessionID */
3107 session->sslServer->options.haveSessionId = 1;
3108 if (session->sslServer->arrays) {
3109 XMEMCPY(session->sslServer->arrays->sessionID,
3110 input + len - ID_LEN, ID_LEN);
3111 }
3112 }
3113
3114 return 0;
3115 }
3116
3117 static int DoResume(SnifferSession* session, char* error)
3118 {
3119 int ret = 0;
3120 WOLFSSL_SESSION* resume;
3121
3122 #ifdef WOLFSSL_TLS13
3123 if (IsAtLeastTLSv1_3(session->sslServer->version)) {
3124 resume = GetSession(session->sslServer,
3125 session->sslServer->session.masterSecret, 0);
3126 if (resume == NULL) {
3127 /* TLS v1.3 with hello_retry uses session_id even for new session,
3128 so ignore error here */
3129 return 0;
3130 }
3131 }
3132 else
3133 #endif
3134 {
3135 resume = GetSession(session->sslServer,
3136 session->sslServer->arrays->masterSecret, 0);
3137 if (resume == NULL) {
3138 #ifdef WOLFSSL_SNIFFER_STATS
3139 INC_STAT(SnifferStats.sslResumeMisses);
3140 #endif
3141 SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
3142 return -1;
3143 }
3144 }
3145
3146 /* make sure client has master secret too */
3147 #ifdef WOLFSSL_TLS13
3148 if (IsAtLeastTLSv1_3(session->sslServer->version)) {
3149 XMEMCPY(session->sslClient->session.masterSecret,
3150 session->sslServer->session.masterSecret, SECRET_LEN);
3151 }
3152 else
3153 #endif
3154 {
3155 XMEMCPY(session->sslClient->arrays->masterSecret,
3156 session->sslServer->arrays->masterSecret, SECRET_LEN);
3157 }
3158 session->flags.resuming = 1;
3159
3160 Trace(SERVER_DID_RESUMPTION_STR);
3161 #ifdef WOLFSSL_SNIFFER_STATS
3162 INC_STAT(SnifferStats.sslResumedConns);
3163 #endif
3164 if (SetCipherSpecs(session->sslServer) != 0) {
3165 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
3166 return -1;
3167 }
3168
3169 if (SetCipherSpecs(session->sslClient) != 0) {
3170 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
3171 return -1;
3172 }
3173
3174 #ifdef WOLFSSL_TLS13
3175 if (IsAtLeastTLSv1_3(session->sslServer->version)) {
3176 #ifdef HAVE_SESSION_TICKET
3177 /* Resumption PSK is resumption master secret. */
3178 session->sslServer->arrays->psk_keySz = session->sslServer->specs.hash_size;
3179 session->sslClient->arrays->psk_keySz = session->sslClient->specs.hash_size;
3180 ret = DeriveResumptionPSK(session->sslServer,
3181 session->sslServer->session.ticketNonce.data,
3182 session->sslServer->session.ticketNonce.len,
3183 session->sslServer->arrays->psk_key);
3184 /* Copy resumption PSK to client */
3185 XMEMCPY(session->sslClient->arrays->psk_key,
3186 session->sslServer->arrays->psk_key,
3187 session->sslServer->arrays->psk_keySz);
3188 #endif
3189 /* handshake key setup below and traffic keys done in SetupKeys */
3190 }
3191 else
3192 #endif
3193 {
3194 if (IsTLS(session->sslServer)) {
3195 ret = DeriveTlsKeys(session->sslServer);
3196 ret += DeriveTlsKeys(session->sslClient);
3197 }
3198 else {
3199 #ifndef NO_OLD_TLS
3200 ret = DeriveKeys(session->sslServer);
3201 ret += DeriveKeys(session->sslClient);
3202 #endif
3203 }
3204 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
3205 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
3206 }
3207
3208 if (ret != 0) {
3209 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
3210 return -1;
3211 }
3212
3213 return ret;
3214 }
3215
3216 /* Process Server Hello */
3217 static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes,
3218 SnifferSession* session, char* error)
3219 {
3220 int ret = 0;
3221 ProtocolVersion pv;
3222 byte b, b0;
3223 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
3224 int doResume = 0;
3225 const byte* inputHello = input;
3226 int initialBytes = *sslBytes;
3227
3228 (void)msgSz;
3229
3230 /* make sure we didn't miss ClientHello */
3231 if (session->flags.clientHello == 0 || session->sslClient->arrays == NULL) {
3232 SetError(MISSED_CLIENT_HELLO_STR, error, session, 0);
3233 return 0; /* do not throw error, just ignore packet */
3234 }
3235
3236 /* make sure can read through session len */
3237 if (toRead > *sslBytes) {
3238 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3239 return -1;
3240 }
3241
3242 XMEMCPY(&pv, input, VERSION_SZ);
3243 input += VERSION_SZ;
3244 *sslBytes -= VERSION_SZ;
3245
3246 session->sslServer->version = pv;
3247 session->sslClient->version = pv;
3248 if (pv.minor >= TLSv1_MINOR) {
3249 session->sslServer->options.tls = 1;
3250 session->sslClient->options.tls = 1;
3251 }
3252
3253 XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN);
3254 XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN);
3255 input += RAN_LEN;
3256 *sslBytes -= RAN_LEN;
3257
3258 b = *input++;
3259 *sslBytes -= 1;
3260
3261 /* make sure can read through compression */
3262 if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
3263 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3264 return -1;
3265 }
3266 if (b) {
3267 #ifdef WOLFSSL_TLS13
3268 XMEMCPY(session->sslServer->session.sessionID, input, ID_LEN);
3269 #endif
3270 XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN);
3271 session->sslServer->options.haveSessionId = 1;
3272 }
3273 input += b;
3274 *sslBytes -= b;
3275
3276 /* cipher suite */
3277 b0 = *input++; /* first byte, ECC or not */
3278 session->sslServer->options.cipherSuite0 = b0;
3279 session->sslClient->options.cipherSuite0 = b0;
3280 b = *input++;
3281 session->sslServer->options.cipherSuite = b;
3282 session->sslClient->options.cipherSuite = b;
3283 *sslBytes -= SUITE_LEN;
3284
3285 #ifdef WOLFSSL_SNIFFER_STATS
3286 {
3287 const CipherSuiteInfo* suites = GetCipherNames();
3288 int suitesSz = GetCipherNamesSize();
3289 int match = 0;
3290
3291 while (suitesSz) {
3292 if (b0 == suites->cipherSuite0 && b == suites->cipherSuite) {
3293 match = 1;
3294 break;
3295 }
3296 suites++;
3297 suitesSz--;
3298 }
3299 if (!match)
3300 INC_STAT(SnifferStats.sslCiphersUnsupported);
3301 }
3302 #endif /* WOLFSSL_SNIFFER_STATS */
3303
3304 /* compression */
3305 b = *input++;
3306 *sslBytes -= ENUM_LEN;
3307
3308 if (b) {
3309 SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
3310 return -1;
3311 }
3312
3313 /* extensions */
3314 if ((initialBytes - *sslBytes) < msgSz) {
3315 word16 len;
3316
3317 /* skip extensions until extended master secret */
3318 /* make sure can read len */
3319 if (SUITE_LEN > *sslBytes) {
3320 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3321 return -1;
3322 }
3323 len = (word16)((input[0] << 8) | input[1]);
3324 input += SUITE_LEN;
3325 *sslBytes -= SUITE_LEN;
3326 /* make sure can read through all extensions */
3327 if (len > *sslBytes) {
3328 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3329 return -1;
3330 }
3331
3332 while (len >= EXT_TYPE_SZ + LENGTH_SZ) {
3333 word16 extType;
3334 word16 extLen;
3335
3336 extType = (word16)((input[0] << 8) | input[1]);
3337 input += EXT_TYPE_SZ;
3338 *sslBytes -= EXT_TYPE_SZ;
3339
3340 extLen = (word16)((input[0] << 8) | input[1]);
3341 input += LENGTH_SZ;
3342 *sslBytes -= LENGTH_SZ;
3343
3344 /* make sure can read through individual extension */
3345 if (extLen > *sslBytes) {
3346 SetError(SERVER_HELLO_INPUT_STR, error, session,
3347 FATAL_ERROR_STATE);
3348 return -1;
3349 }
3350 #ifdef DEBUG_SNIFFER
3351 printf("\tserver_hello ext: 0x%02x (len %d)\n", extType, extLen);
3352 #endif
3353
3354 switch (extType) {
3355 #ifdef WOLFSSL_TLS13
3356 case EXT_KEY_SHARE:
3357 ret = ProcessServerKeyShare(session, input, extLen, error);
3358 if (ret != 0) {
3359 SetError(SERVER_HELLO_INPUT_STR, error, session,
3360 FATAL_ERROR_STATE);
3361 return -1;
3362 }
3363 break;
3364 #endif
3365 #ifdef HAVE_SESSION_TICKET
3366 case EXT_PRE_SHARED_KEY:
3367 /* indicates we want to use resumption */
3368 session->sslServer->options.resuming = 1;
3369 session->sslClient->options.resuming = 1;
3370 #ifdef WOLFSSL_TLS13
3371 /* default nonce to len = 1, data = 0 */
3372 session->sslServer->session.ticketNonce.len = 1;
3373 session->sslServer->session.ticketNonce.data[0] = 0;
3374 session->sslClient->session.ticketNonce.len = 1;
3375 session->sslClient->session.ticketNonce.data[0] = 0;
3376 #endif
3377 break;
3378 #endif
3379 #ifdef HAVE_MAX_FRAGMENT
3380 case EXT_MAX_FRAGMENT_LENGTH:
3381 {
3382 word16 max_fragment = MAX_RECORD_SIZE;
3383 switch (input[0]) {
3384 case WOLFSSL_MFL_2_8 : max_fragment = 256; break;
3385 case WOLFSSL_MFL_2_9 : max_fragment = 512; break;
3386 case WOLFSSL_MFL_2_10: max_fragment = 1024; break;
3387 case WOLFSSL_MFL_2_11: max_fragment = 2048; break;
3388 case WOLFSSL_MFL_2_12: max_fragment = 4096; break;
3389 case WOLFSSL_MFL_2_13: max_fragment = 8192; break;
3390 default: break;
3391 }
3392 session->sslServer->max_fragment = max_fragment;
3393 session->sslClient->max_fragment = max_fragment;
3394 break;
3395 }
3396 #endif
3397 case EXT_SUPPORTED_VERSIONS:
3398 session->sslServer->version.major = input[0];
3399 session->sslServer->version.minor = input[1];
3400 session->sslClient->version.major = input[0];
3401 session->sslClient->version.minor = input[1];
3402 if (IsAtLeastTLSv1_3(session->sslServer->version)) {
3403 /* The server side handshake encryption is on for future packets */
3404 session->flags.serverCipherOn = 1;
3405 }
3406 break;
3407 case EXT_MASTER_SECRET:
3408 #ifdef HAVE_EXTENDED_MASTER
3409 session->flags.expectEms = 1;
3410 #endif
3411 break;
3412 case EXT_RENEGOTIATION_INFO:
3413 session->flags.secRenegEn = 1;
3414 break;
3415 } /* switch (extType) */
3416
3417 input += extLen;
3418 *sslBytes -= extLen;
3419 len -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
3420 }
3421 }
3422
3423 #ifdef HAVE_EXTENDED_MASTER
3424 if (!session->flags.expectEms) {
3425 XFREE(session->hash, NULL, DYNAMIC_TYPE_HASHES);
3426 session->hash = NULL;
3427 }
3428 #endif
3429
3430 if (session->sslServer->options.haveSessionId) {
3431 if (XMEMCMP(session->sslServer->arrays->sessionID,
3432 session->sslClient->arrays->sessionID, ID_LEN) == 0) {
3433 doResume = 1;
3434 }
3435 }
3436 else if (session->sslClient->options.haveSessionId == 0 &&
3437 session->sslServer->options.haveSessionId == 0 &&
3438 session->ticketID) {
3439 doResume = 1;
3440 }
3441
3442 if (session->ticketID && doResume) {
3443 /* use ticketID to retrieve from session, prefer over sessionID */
3444 XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN);
3445 session->sslServer->options.haveSessionId = 1; /* may not have
3446 actual sessionID */
3447 }
3448
3449 #ifdef WOLFSSL_TLS13
3450 /* Is TLS v1.3 hello_retry_request? */
3451 if (IsAtLeastTLSv1_3(session->sslServer->version) && session->srvKs.key_len == 0) {
3452 Trace(GOT_HELLO_RETRY_REQ_STR);
3453
3454 /* do not compute keys yet */
3455 session->flags.serverCipherOn = 0;
3456
3457 /* make sure the mac and digest size are set */
3458 SetCipherSpecs(session->sslServer);
3459 SetCipherSpecs(session->sslClient);
3460
3461 /* reset hashes */
3462 RestartHandshakeHash(session->sslServer);
3463 RestartHandshakeHash(session->sslClient);
3464
3465 doResume = 0;
3466 }
3467 #endif
3468
3469 /* hash server_hello */
3470 HashRaw(session->sslServer, inputHello - HANDSHAKE_HEADER_SZ,
3471 initialBytes + HANDSHAKE_HEADER_SZ);
3472 HashRaw(session->sslClient, inputHello - HANDSHAKE_HEADER_SZ,
3473 initialBytes + HANDSHAKE_HEADER_SZ);
3474
3475 if (doResume) {
3476 ret = DoResume(session, error);
3477 if (ret != 0) {
3478 return ret;
3479 }
3480 }
3481 else {
3482 #ifdef WOLFSSL_SNIFFER_STATS
3483 INC_STAT(SnifferStats.sslStandardConns);
3484 #endif
3485 }
3486
3487 #ifdef SHOW_SECRETS
3488 printf("cipher suite = 0x%02x\n", session->sslServer->options.cipherSuite);
3489 PrintSecret("server random", session->sslServer->arrays->serverRandom, RAN_LEN);
3490 #endif
3491
3492 #ifdef WOLFSSL_TLS13
3493 /* Setup handshake keys */
3494 if (IsAtLeastTLSv1_3(session->sslServer->version) && session->srvKs.key_len > 0) {
3495 ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len,
3496 session, error, &session->cliKs);
3497 if (ret != 0) {
3498 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3499 return ret;
3500 }
3501
3502 if (session->flags.side == WOLFSSL_SERVER_END)
3503 session->flags.serverCipherOn = 1;
3504 else
3505 session->flags.clientCipherOn = 1;
3506 }
3507 #endif
3508
3509 return 0;
3510 }
3511
3512 #ifdef HAVE_SNI
3513 /* Function return value must be 0 for success */
3514 static int LoadNamedKey(SnifferSession* session, const byte* name, word16 nameSz)
3515 {
3516 int ret = 0;
3517 WOLFSSL* ssl = session->sslServer;
3518 NamedKey* namedKey;
3519
3520 wc_LockMutex(&session->context->namedKeysMutex);
3521 namedKey = session->context->namedKeys;
3522 while (namedKey != NULL) {
3523 if (nameSz == namedKey->nameSz &&
3524 XSTRNCMP((char*)name, namedKey->name, nameSz) == 0) {
3525 #ifdef WOLFSSL_STATIC_EPHEMERAL
3526 if (namedKey->isEphemeralKey) {
3527 /* auto detect key type with WC_PK_TYPE_NONE */
3528 ret = wolfSSL_set_ephemeral_key(ssl,
3529 WC_PK_TYPE_NONE, (const char*)namedKey->key,
3530 namedKey->keySz, WOLFSSL_FILETYPE_ASN1);
3531 }
3532 else
3533 #endif
3534 {
3535 ret = wolfSSL_use_PrivateKey_buffer(ssl,
3536 namedKey->key, namedKey->keySz,
3537 WOLFSSL_FILETYPE_ASN1);
3538 /* translate return code */
3539 ret = (ret == WOLFSSL_SUCCESS) ? 0 : -1;
3540 }
3541 if (ret == 0) {
3542 session->sni = namedKey->name;
3543 }
3544 break;
3545 }
3546 namedKey = namedKey->next;
3547 }
3548 wc_UnLockMutex(&session->context->namedKeysMutex);
3549 return ret;
3550 }
3551 #endif
3552
3553 /* Process normal Client Hello */
3554 static int ProcessClientHello(const byte* input, int* sslBytes,
3555 SnifferSession* session, char* error)
3556 {
3557 int ret = 0;
3558 byte bLen;
3559 word16 len;
3560 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
3561 const byte* inputHello = input;
3562 int inputHelloSz = *sslBytes;
3563 WOLFSSL* ssl = session->sslServer;
3564 int didHash = 0;
3565
3566 session->flags.clientHello = 1; /* don't process again */
3567
3568 /* make sure can read up to session len */
3569 if (toRead > *sslBytes) {
3570 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3571 return -1;
3572 }
3573
3574 /* skip, get negotiated one from server hello */
3575 input += VERSION_SZ;
3576 *sslBytes -= VERSION_SZ;
3577
3578 /* for secure renegotiation server arrays can be NULL */
3579 if (session->sslServer->arrays)
3580 XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN);
3581 if (session->sslClient->arrays)
3582 XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN);
3583
3584 input += RAN_LEN;
3585 *sslBytes -= RAN_LEN;
3586
3587 /* store session in case trying to resume */
3588 bLen = *input++;
3589 *sslBytes -= ENUM_LEN;
3590 if (bLen) {
3591 if (ID_LEN > *sslBytes) {
3592 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3593 return -1;
3594 }
3595 Trace(CLIENT_RESUME_TRY_STR);
3596 #ifdef WOLFSSL_TLS13
3597 XMEMCPY(session->sslClient->session.sessionID, input, ID_LEN);
3598 #endif
3599 if (session->sslClient->arrays)
3600 XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN);
3601 session->sslClient->options.haveSessionId = 1;
3602 }
3603
3604 #ifdef SHOW_SECRETS
3605 if (ssl->arrays)
3606 PrintSecret("client random", ssl->arrays->clientRandom, RAN_LEN);
3607 #endif
3608
3609 input += bLen;
3610 *sslBytes -= bLen;
3611
3612 /* skip cipher suites */
3613 /* make sure can read len */
3614 if (SUITE_LEN > *sslBytes) {
3615 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3616 return -1;
3617 }
3618 len = (word16)((input[0] << 8) | input[1]);
3619 input += SUITE_LEN;
3620 *sslBytes -= SUITE_LEN;
3621 /* make sure can read suites + comp len */
3622 if (len + ENUM_LEN > *sslBytes) {
3623 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3624 return -1;
3625 }
3626 input += len;
3627 *sslBytes -= len;
3628
3629 /* skip compression */
3630 bLen = *input++;
3631 *sslBytes -= ENUM_LEN;
3632 /* make sure can read len */
3633 if (bLen > *sslBytes) {
3634 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3635 return -1;
3636 }
3637 input += bLen;
3638 *sslBytes -= bLen;
3639
3640 if (*sslBytes == 0) {
3641 /* no extensions */
3642 return 0;
3643 }
3644
3645 /* skip extensions until session ticket */
3646 /* make sure can read len */
3647 if (SUITE_LEN > *sslBytes) {
3648 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3649 return -1;
3650 }
3651 len = (word16)((input[0] << 8) | input[1]);
3652 input += SUITE_LEN;
3653 *sslBytes -= SUITE_LEN;
3654 /* make sure can read through all extensions */
3655 if (len > *sslBytes) {
3656 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3657 return -1;
3658 }
3659
3660 while (len >= EXT_TYPE_SZ + LENGTH_SZ) {
3661 word16 extType;
3662 word16 extLen;
3663
3664 extType = (word16)((input[0] << 8) | input[1]);
3665 input += EXT_TYPE_SZ;
3666 *sslBytes -= EXT_TYPE_SZ;
3667
3668 extLen = (word16)((input[0] << 8) | input[1]);
3669 input += LENGTH_SZ;
3670 *sslBytes -= LENGTH_SZ;
3671
3672 /* make sure can read through individual extension */
3673 if (extLen > *sslBytes) {
3674 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3675 return -1;
3676 }
3677
3678 #ifdef DEBUG_SNIFFER
3679 printf("\tclient_hello ext: 0x%02x (len %d)\n", extType, extLen);
3680 #endif
3681
3682 switch (extType) {
3683 #ifdef HAVE_SNI
3684 case EXT_SERVER_NAME:
3685 {
3686 word16 listLen = 0, offset = 0;
3687
3688 ato16(input + offset, &listLen);
3689 offset += OPAQUE16_LEN;
3690
3691 if (extLen < offset + listLen)
3692 return BUFFER_ERROR;
3693
3694 while (listLen > ENUM_LEN + OPAQUE16_LEN) {
3695 byte sniType = input[offset++];
3696 word16 sniLen;
3697
3698 ato16(input + offset, &sniLen);
3699 offset += OPAQUE16_LEN;
3700
3701 if (extLen < offset + sniLen)
3702 return BUFFER_ERROR;
3703
3704 if (sniType == WOLFSSL_SNI_HOST_NAME) {
3705 ret = LoadNamedKey(session, input + offset, sniLen);
3706 if (ret < 0) {
3707 /* don't treat this as fatal error */
3708 SetError(CLIENT_HELLO_LATE_KEY_STR, error, session, 0);
3709 break;
3710 }
3711 }
3712 offset += sniLen;
3713 listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
3714 }
3715 break;
3716 }
3717 #endif
3718 #ifdef WOLFSSL_TLS13
3719 case EXT_KEY_SHARE:
3720 {
3721 word16 ksLen = (word16)((input[0] << 8) | input[1]);
3722 if (ksLen + OPAQUE16_LEN > extLen) {
3723 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3724 return -1;
3725 }
3726 /* cache key share data till server_hello */
3727 session->cliKeyShareSz = ksLen;
3728 session->cliKeyShare = (byte*)XMALLOC(ksLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3729 if (session->cliKeyShare == NULL) {
3730 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
3731 break;
3732 }
3733 XMEMCPY(session->cliKeyShare, &input[2], ksLen);
3734 break;
3735 }
3736 #ifdef HAVE_SESSION_TICKET
3737 case EXT_PRE_SHARED_KEY:
3738 {
3739 word16 idsLen, idLen, bindersLen, idx = 0;
3740 word32 ticketAge;
3741 const byte *identity, *binders;
3742
3743 idsLen = (word16)((input[idx] << 8) | input[idx+1]);
3744 if (idsLen + OPAQUE16_LEN + idx > extLen) {
3745 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3746 return -1;
3747 }
3748 idx += OPAQUE16_LEN;
3749
3750 /* PSK identity */
3751 idLen = (word16)((input[idx] << 8) | input[idx+1]);
3752 if (idLen + OPAQUE16_LEN + idx > extLen) {
3753 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3754 return -1;
3755 }
3756 idx += OPAQUE16_LEN;
3757 identity = &input[idx];
3758 idx += idLen;
3759
3760 /* Obfuscated Ticket Age 32-bits */
3761 ticketAge = (word32)((input[idx] << 24) | (input[idx+1] << 16) |
3762 (input[idx+2] << 8) | input[idx+3]);
3763 (void)ticketAge; /* not used */
3764 idx += OPAQUE32_LEN;
3765
3766 /* binders - all binders */
3767 bindersLen = (word16)((input[idx] << 8) | input[idx+1]);
3768 if (bindersLen + OPAQUE16_LEN + idx > extLen) {
3769 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
3770 return -1;
3771 }
3772 idx += OPAQUE16_LEN;
3773 binders = &input[idx];
3774 bindersLen += OPAQUE16_LEN; /* includes 2 bytes for total len */
3775 (void)binders; /* not used */
3776
3777 /* Hash data up to binders for deriving binders in PSK extension. */
3778 HashRaw(session->sslServer, inputHello - HANDSHAKE_HEADER_SZ,
3779 inputHelloSz - bindersLen + HANDSHAKE_HEADER_SZ);
3780 HashRaw(session->sslClient, inputHello - HANDSHAKE_HEADER_SZ,
3781 inputHelloSz - bindersLen + HANDSHAKE_HEADER_SZ);
3782
3783 /* call to decrypt session ticket */
3784 if (DoClientTicket(ssl, identity, idLen) != WOLFSSL_TICKET_RET_OK) {
3785 /* we aren't decrypting the resumption, since we know the master secret */
3786 /* ignore errors */
3787 }
3788 ssl->options.resuming = 1;
3789
3790 /* Hash the rest of the ClientHello. */
3791 HashRaw(session->sslServer, inputHello + inputHelloSz - bindersLen, bindersLen);
3792 HashRaw(session->sslClient, inputHello + inputHelloSz - bindersLen, bindersLen);
3793 didHash = 1;
3794 break;
3795 }
3796 #endif /* HAVE_SESSION_TICKET */
3797 #endif /* WOLFSSL_TLS13 */
3798 case EXT_SUPPORTED_VERSIONS:
3799 break;
3800 case EXT_TICKET_ID:
3801 /* make sure can read through ticket if there is a non blank one */
3802 if (extLen && extLen < ID_LEN) {
3803 SetError(CLIENT_HELLO_INPUT_STR, error, session,
3804 FATAL_ERROR_STATE);
3805 return -1;
3806 }
3807 if (extLen) {
3808 if (session->ticketID == NULL) {
3809 session->ticketID = (byte*)XMALLOC(ID_LEN,
3810 NULL, DYNAMIC_TYPE_SNIFFER_TICKET_ID);
3811 if (session->ticketID == 0) {
3812 SetError(MEMORY_STR, error, session,
3813 FATAL_ERROR_STATE);
3814 return -1;
3815 }
3816 }
3817 #ifdef HAVE_SESSION_TICKET
3818 ssl->options.useTicket = 1;
3819 #endif
3820 XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
3821 }
3822 break;
3823 }
3824
3825 input += extLen;
3826 *sslBytes -= extLen;
3827 len -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
3828 }
3829
3830 if (!didHash) {
3831 HashRaw(session->sslServer, inputHello - HANDSHAKE_HEADER_SZ,
3832 inputHelloSz + HANDSHAKE_HEADER_SZ);
3833 HashRaw(session->sslClient, inputHello - HANDSHAKE_HEADER_SZ,
3834 inputHelloSz + HANDSHAKE_HEADER_SZ);
3835 }
3836
3837 (void)ssl;
3838
3839 return ret;
3840 }
3841
3842
3843 #ifdef WOLFSSL_SNIFFER_WATCH
3844
3845 static int KeyWatchCall(SnifferSession* session, const byte* data, int dataSz,
3846 char* error)
3847 {
3848 int ret;
3849 Sha256 sha;
3850 byte digest[SHA256_DIGEST_SIZE];
3851
3852 if (WatchCb == NULL) {
3853 SetError(WATCH_CB_MISSING_STR, error, session, FATAL_ERROR_STATE);
3854 return -1;
3855 }
3856
3857 ret = wc_InitSha256(&sha);
3858 if (ret == 0)
3859 ret = wc_Sha256Update(&sha, data, dataSz);
3860 if (ret == 0)
3861 ret = wc_Sha256Final(&sha, digest);
3862 if (ret != 0) {
3863 SetError(WATCH_HASH_STR, error, session, FATAL_ERROR_STATE);
3864 return -1;
3865 }
3866
3867 ret = WatchCb((void*)session, digest, sizeof(digest),
3868 data, dataSz, WatchCbCtx, error);
3869 if (ret != 0) {
3870 #ifdef WOLFSSL_SNIFFER_STATS
3871 INC_STAT(SnifferStats.sslKeysUnmatched);
3872 #endif
3873 SetError(WATCH_FAIL_STR, error, session, FATAL_ERROR_STATE);
3874 ret = -1;
3875 }
3876 else {
3877 #ifdef WOLFSSL_SNIFFER_STATS
3878 INC_STAT(SnifferStats.sslKeyMatches);
3879 #endif
3880 }
3881 return ret;
3882 }
3883
3884 /* Process Certificate */
3885 static int ProcessCertificate(const byte* input, int* sslBytes,
3886 SnifferSession* session, char* error)
3887 {
3888 word32 certChainSz;
3889 word32 certSz;
3890
3891 /* If the receiver is the server, this is the client certificate message,
3892 * and it should be ignored at this point. */
3893 if (session->flags.side == WOLFSSL_SERVER_END)
3894 return 0;
3895
3896 if (*sslBytes < CERT_HEADER_SZ) {
3897 SetError(BAD_CERT_MSG_STR, error, session, FATAL_ERROR_STATE);
3898 return -1;
3899 }
3900
3901 #ifdef WOLFSSL_TLS13
3902 if (IsAtLeastTLSv1_3(session->sslServer->version)) {
3903 /* skip 1 byte (Request context len) */
3904 input += OPAQUE8_LEN;
3905 *sslBytes -= OPAQUE8_LEN;
3906 }
3907 #endif
3908
3909 ato24(input, &certChainSz);
3910 *sslBytes -= CERT_HEADER_SZ;
3911 input += CERT_HEADER_SZ;
3912
3913 if (*sslBytes < (int)certChainSz) {
3914 SetError(BAD_CERT_MSG_STR, error, session, FATAL_ERROR_STATE);
3915 return -1;
3916 }
3917
3918 ato24(input, &certSz);
3919 input += OPAQUE24_LEN;
3920 if (*sslBytes < (int)certSz) {
3921 SetError(BAD_CERT_MSG_STR, error, session, FATAL_ERROR_STATE);
3922 return -1;
3923 }
3924
3925 *sslBytes -= certChainSz;
3926
3927 return KeyWatchCall(session, input, certSz, error);
3928 }
3929
3930 #endif /* WOLFSSL_SNIFFER_WATCH */
3931
3932
3933 /* Process Finished */
3934 static int ProcessFinished(const byte* input, int size, int* sslBytes,
3935 SnifferSession* session, char* error)
3936 {
3937 WOLFSSL* ssl;
3938 word32 inOutIdx = 0;
3939 int ret;
3940
3941 if (session->flags.side == WOLFSSL_SERVER_END)
3942 ssl = session->sslServer;
3943 else
3944 ssl = session->sslClient;
3945
3946 #ifdef WOLFSSL_TLS13
3947 if (IsAtLeastTLSv1_3(ssl->version)) {
3948 ret = DoTls13Finished(ssl, input, &inOutIdx, (word32)size,
3949 (word32)*sslBytes, SNIFF);
3950
3951 ssl->options.handShakeState = HANDSHAKE_DONE;
3952 ssl->options.handShakeDone = 1;
3953 }
3954 else
3955 #endif
3956 {
3957 ret = DoFinished(ssl, input, &inOutIdx, (word32)size,
3958 (word32)*sslBytes, SNIFF);
3959 }
3960 *sslBytes -= (int)inOutIdx;
3961
3962 if (ret < 0) {
3963 SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
3964 return ret;
3965 }
3966
3967 if (ret == 0 && session->flags.cached == 0) {
3968 if (session->sslServer->options.haveSessionId) {
3969 #ifndef NO_SESSION_CACHE
3970 WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL, 0);
3971 if (sess == NULL) {
3972 AddSession(session->sslServer); /* don't re add */
3973 #ifdef WOLFSSL_SNIFFER_STATS
3974 INC_STAT(SnifferStats.sslResumptionInserts);
3975 #endif
3976 }
3977 session->flags.cached = 1;
3978 #endif
3979 }
3980 }
3981
3982 #ifdef WOLFSSL_TLS13
3983 /* Derive TLS v1.3 traffic keys */
3984 if (IsAtLeastTLSv1_3(ssl->version)) {
3985 if (!session->flags.gotFinished) {
3986 /* When either side gets "finished" derive master secret and keys */
3987 ret = DeriveMasterSecret(session->sslServer);
3988 ret += DeriveMasterSecret(session->sslClient);
3989 #ifdef WOLFSSL_EARLY_DATA
3990 ret += DeriveTls13Keys(session->sslServer, traffic_key, ENCRYPT_AND_DECRYPT_SIDE, ssl->earlyData == no_early_data);
3991 ret += DeriveTls13Keys(session->sslClient, traffic_key, ENCRYPT_AND_DECRYPT_SIDE, ssl->earlyData == no_early_data);
3992 #else
3993 ret += DeriveTls13Keys(session->sslServer, traffic_key, ENCRYPT_AND_DECRYPT_SIDE, 1);
3994 ret += DeriveTls13Keys(session->sslClient, traffic_key, ENCRYPT_AND_DECRYPT_SIDE, 1);
3995 #endif
3996
3997 if (ret != 0) {
3998 SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
3999 return -1;
4000 }
4001
4002 session->flags.gotFinished = 1;
4003 #ifdef SHOW_SECRETS
4004 ShowTlsSecrets(session);
4005 #endif
4006 }
4007
4008 if (session->flags.side == WOLFSSL_SERVER_END) {
4009 /* finished from client to server */
4010 ret = SetKeysSide(session->sslServer, DECRYPT_SIDE_ONLY);
4011 ret += SetKeysSide(session->sslClient, ENCRYPT_SIDE_ONLY);
4012
4013 #ifdef HAVE_SESSION_TICKET
4014 /* derive resumption secret for next session - on finished (from client) */
4015 ret += DeriveResumptionSecret(session->sslClient,
4016 session->sslClient->session.masterSecret);
4017
4018 /* copy resumption secret to server */
4019 XMEMCPY(session->sslServer->session.masterSecret,
4020 session->sslClient->session.masterSecret, SECRET_LEN);
4021 #ifdef SHOW_SECRETS
4022 PrintSecret("resumption secret",
4023 session->sslClient->session.masterSecret, SECRET_LEN);
4024 #endif
4025 #endif
4026 }
4027 else {
4028 /* finished from server to client */
4029 ret = SetKeysSide(session->sslServer, ENCRYPT_SIDE_ONLY);
4030 ret += SetKeysSide(session->sslClient, DECRYPT_SIDE_ONLY);
4031 }
4032
4033 if (ret != 0) {
4034 SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
4035 return -1;
4036 }
4037 }
4038 #endif
4039
4040 /* Do not free handshake resources yet if secure renegotiation */
4041 if (session->flags.secRenegEn == 0) {
4042 /* If receiving a finished message from one side, free the resources
4043 * from the other side's tracker. */
4044 if (session->flags.side == WOLFSSL_SERVER_END)
4045 FreeHandshakeResources(session->sslClient);
4046 else
4047 FreeHandshakeResources(session->sslServer);
4048 }
4049
4050 return ret;
4051 }
4052
4053
4054 /* Process HandShake input */
4055 static int DoHandShake(const byte* input, int* sslBytes,
4056 SnifferSession* session, char* error, word16 rhSize)
4057 {
4058 byte type;
4059 int size;
4060 int ret = 0;
4061 WOLFSSL* ssl;
4062 int startBytes;
4063
4064 (void)rhSize;
4065
4066 #ifdef HAVE_MAX_FRAGMENT
4067 if (session->tlsFragBuf) {
4068 XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
4069 session->tlsFragOffset += rhSize;
4070 *sslBytes -= rhSize;
4071
4072 if (session->tlsFragOffset < session->tlsFragSize) {
4073 return 0;
4074 }
4075
4076 /* reassembled complete fragment */
4077 input = session->tlsFragBuf;
4078 *sslBytes = session->tlsFragSize;
4079 rhSize = session->tlsFragSize;
4080 }
4081 #endif
4082
4083 if (*sslBytes < HANDSHAKE_HEADER_SZ) {
4084 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
4085 return -1;
4086 }
4087 type = input[0];
4088 size = (input[1] << 16) | (input[2] << 8) | input[3];
4089
4090 input += HANDSHAKE_HEADER_SZ;
4091 *sslBytes -= HANDSHAKE_HEADER_SZ;
4092 startBytes = *sslBytes;
4093
4094 if (*sslBytes < size) {
4095 Trace(SPLIT_HANDSHAKE_MSG_STR);
4096 *sslBytes = 0;
4097 return ret;
4098 }
4099
4100 if (session->flags.side == WOLFSSL_SERVER_END)
4101 ssl = session->sslServer;
4102 else
4103 ssl = session->sslClient;
4104
4105 #ifdef HAVE_MAX_FRAGMENT
4106 if (rhSize < size) {
4107 /* partial fragment, let's reassemble */
4108 if (session->tlsFragBuf == NULL) {
4109 session->tlsFragOffset = 0;
4110 session->tlsFragSize = size + HANDSHAKE_HEADER_SZ;
4111 session->tlsFragBuf = (byte*)XMALLOC(session->tlsFragSize, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4112 if (session->tlsFragBuf == NULL) {
4113 SetError(MEMORY_STR, error, NULL, 0);
4114 return 0;
4115 }
4116
4117 /* include the handshake header */
4118 input -= HANDSHAKE_HEADER_SZ;
4119 *sslBytes += HANDSHAKE_HEADER_SZ;
4120 }
4121
4122 XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
4123 session->tlsFragOffset += rhSize;
4124 *sslBytes -= rhSize;
4125 return 0;
4126 }
4127 #endif
4128
4129 #ifdef WOLFSSL_TLS13
4130 if (type != client_hello && type != server_hello) {
4131 /* For resumption the hash is before / after client_hello PSK binder */
4132 /* hash the packet including header */
4133 /* TLS v1.3 requires the hash for the handshake and transfer key derivation */
4134 /* we hash even for non TLS v1.3, since we don't know if its actually
4135 TLS v1.3 till later at EXT_SUPPORTED_VERSIONS in server_hello */
4136 /* hello retry request restarts hash prior to server_hello hash calc */
4137 HashRaw(session->sslServer, input - HANDSHAKE_HEADER_SZ, size + HANDSHAKE_HEADER_SZ);
4138 HashRaw(session->sslClient, input - HANDSHAKE_HEADER_SZ, size + HANDSHAKE_HEADER_SZ);
4139 }
4140 #endif
4141 #ifdef HAVE_EXTENDED_MASTER
4142 if (session->hash) {
4143 if (HashUpdate(session->hash, input, size) != 0) {
4144 SetError(EXTENDED_MASTER_HASH_STR, error,
4145 session, FATAL_ERROR_STATE);
4146 ret = -1;
4147 goto exit;
4148 }
4149 }
4150 #endif
4151
4152 switch (type) {
4153 case hello_verify_request:
4154 Trace(GOT_HELLO_VERIFY_STR);
4155 break;
4156 case hello_request:
4157 Trace(GOT_HELLO_REQUEST_STR);
4158 break;
4159 case session_ticket:
4160 Trace(GOT_SESSION_TICKET_STR);
4161 ret = ProcessSessionTicket(input, sslBytes, session, error);
4162 break;
4163 case server_hello:
4164 Trace(GOT_SERVER_HELLO_STR);
4165 ret = ProcessServerHello(size, input, sslBytes, session, error);
4166 break;
4167 case certificate_request:
4168 Trace(GOT_CERT_REQ_STR);
4169 break;
4170 case server_key_exchange:
4171 #ifdef WOLFSSL_SNIFFER_STATS
4172 INC_STAT(SnifferStats.sslEphemeralMisses);
4173 #endif
4174 Trace(GOT_SERVER_KEY_EX_STR);
4175 /* can't know temp key passively */
4176 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
4177 ret = -1;
4178 break;
4179 case encrypted_extensions:
4180 Trace(GOT_ENC_EXT_STR);
4181 ssl->msgsReceived.got_encrypted_extensions = 1;
4182 break;
4183 case certificate:
4184 Trace(GOT_CERT_STR);
4185 if (session->flags.side == WOLFSSL_SERVER_END) {
4186 #ifdef WOLFSSL_SNIFFER_STATS
4187 INC_STAT(SnifferStats.sslClientAuthConns);
4188 #endif
4189 }
4190 #ifdef WOLFSSL_SNIFFER_WATCH
4191 ret = ProcessCertificate(input, sslBytes, session, error);
4192 #endif
4193 break;
4194 case server_hello_done:
4195 Trace(GOT_SERVER_HELLO_DONE_STR);
4196 break;
4197 case finished:
4198 Trace(GOT_FINISHED_STR);
4199 ret = ProcessFinished(input, size, sslBytes, session, error);
4200 break;
4201 case client_hello:
4202 Trace(GOT_CLIENT_HELLO_STR);
4203 ret = ProcessClientHello(input, sslBytes, session, error);
4204 break;
4205 case client_key_exchange:
4206 Trace(GOT_CLIENT_KEY_EX_STR);
4207 #ifdef HAVE_EXTENDED_MASTER
4208 if (session->flags.expectEms && session->hash != NULL) {
4209 if (HashCopy(session->sslServer->hsHashes,
4210 session->hash) == 0 &&
4211 HashCopy(session->sslClient->hsHashes,
4212 session->hash) == 0) {
4213
4214 session->sslServer->options.haveEMS = 1;
4215 session->sslClient->options.haveEMS = 1;
4216 }
4217 else {
4218 SetError(EXTENDED_MASTER_HASH_STR, error,
4219 session, FATAL_ERROR_STATE);
4220 ret = -1;
4221 }
4222 XMEMSET(session->hash, 0, sizeof(HsHashes));
4223 XFREE(session->hash, NULL, DYNAMIC_TYPE_HASHES);
4224 session->hash = NULL;
4225 }
4226 else {
4227 session->sslServer->options.haveEMS = 0;
4228 session->sslClient->options.haveEMS = 0;
4229 }
4230 #endif
4231 if (ret == 0) {
4232 ret = ProcessClientKeyExchange(input, sslBytes, session, error);
4233 if (ret != 0)
4234 SetError(GOT_CLIENT_KEY_EX_STR, error, session, FATAL_ERROR_STATE);
4235 }
4236 break;
4237 case certificate_verify:
4238 Trace(GOT_CERT_VER_STR);
4239 break;
4240 case certificate_status:
4241 Trace(GOT_CERT_STATUS_STR);
4242 break;
4243 default:
4244 SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
4245 ret = -1;
4246 break;
4247 }
4248
4249 #ifdef HAVE_EXTENDED_MASTER
4250 exit:
4251 #endif
4252 #ifdef HAVE_MAX_FRAGMENT
4253 if (session->tlsFragBuf) {
4254 XFREE(session->tlsFragBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4255 session->tlsFragBuf = NULL;
4256 }
4257 #endif
4258
4259 *sslBytes = startBytes - size; /* actual bytes of full process */
4260
4261 return ret;
4262 }
4263
4264
4265 /* Decrypt input into plain output, 0 on success */
4266 static int Decrypt(WOLFSSL* ssl, byte* output, const byte* input, word32 sz)
4267 {
4268 int ret = 0;
4269
4270 (void)output;
4271 (void)input;
4272 (void)sz;
4273
4274 switch (ssl->specs.bulk_cipher_algorithm) {
4275 #ifdef BUILD_ARC4
4276 case wolfssl_rc4:
4277 wc_Arc4Process(ssl->decrypt.arc4, output, input, sz);
4278 break;
4279 #endif
4280
4281 #ifdef BUILD_DES3
4282 case wolfssl_triple_des:
4283 ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz);
4284 break;
4285 #endif
4286
4287 #ifdef BUILD_AES
4288 case wolfssl_aes:
4289 ret = wc_AesCbcDecrypt(ssl->decrypt.aes, output, input, sz);
4290 break;
4291 #endif
4292
4293 #ifdef HAVE_HC128
4294 case wolfssl_hc128:
4295 wc_Hc128_Process(ssl->decrypt.hc128, output, input, sz);
4296 break;
4297 #endif
4298
4299 #ifdef BUILD_RABBIT
4300 case wolfssl_rabbit:
4301 wc_RabbitProcess(ssl->decrypt.rabbit, output, input, sz);
4302 break;
4303 #endif
4304
4305 #ifdef HAVE_CAMELLIA
4306 case wolfssl_camellia:
4307 wc_CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz);
4308 break;
4309 #endif
4310
4311 #ifdef HAVE_IDEA
4312 case wolfssl_idea:
4313 wc_IdeaCbcDecrypt(ssl->decrypt.idea, output, input, sz);
4314 break;
4315 #endif
4316
4317 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
4318 case wolfssl_aes_gcm:
4319 case wolfssl_aes_ccm: /* GCM AEAD macros use same size as CCM */
4320 if (sz >= (word32)(AESGCM_EXP_IV_SZ + ssl->specs.aead_mac_size)) {
4321 /* scratch buffer, sniffer ignores auth tag */
4322 wc_AesAuthEncryptFunc aes_auth_fn;
4323 byte authTag[WOLFSSL_MIN_AUTH_TAG_SZ];
4324 byte nonce[AESGCM_NONCE_SZ];
4325 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ);
4326 XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ);
4327
4328 /* use encrypt because we don't care about authtag */
4329 #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM)
4330 aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
4331 ? wc_AesGcmEncrypt : wc_AesCcmEncrypt;
4332 #elif defined(BUILD_AESGCM)
4333 aes_auth_fn = wc_AesGcmEncrypt;
4334 #else
4335 aes_auth_fn = wc_AesCcmEncrypt;
4336 #endif
4337 if (aes_auth_fn(ssl->decrypt.aes,
4338 output,
4339 input + AESGCM_EXP_IV_SZ,
4340 sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
4341 nonce, AESGCM_NONCE_SZ,
4342 authTag, sizeof(authTag),
4343 NULL, 0) < 0) {
4344 Trace(BAD_DECRYPT);
4345 ret = -1;
4346 }
4347 ForceZero(nonce, AESGCM_NONCE_SZ);
4348 }
4349 else {
4350 Trace(BAD_DECRYPT_SIZE);
4351 ret = -1;
4352 }
4353 break;
4354 #endif
4355
4356 #ifdef HAVE_NULL_CIPHER
4357 case wolfssl_cipher_null:
4358 XMEMCPY(output, input, sz);
4359 break;
4360 #endif
4361
4362 default:
4363 Trace(BAD_DECRYPT_TYPE);
4364 ret = -1;
4365 break;
4366 }
4367
4368 return ret;
4369 }
4370
4371
4372 /* Decrypt input message into output, adjust output steam if needed */
4373 static const byte* DecryptMessage(WOLFSSL* ssl, const byte* input, word32 sz,
4374 byte* output, int* error, int* advance, RecordLayerHeader* rh)
4375 {
4376 int ivExtra = 0;
4377 int ret;
4378
4379 #ifdef WOLFSSL_TLS13
4380 if (IsAtLeastTLSv1_3(ssl->version)) {
4381 ret = DecryptTls13(ssl, output, input, sz, (byte*)rh, RECORD_HEADER_SZ);
4382 }
4383 else
4384 #endif
4385 {
4386 ret = Decrypt(ssl, output, input, sz);
4387 }
4388 if (ret != 0) {
4389 *error = ret;
4390 return NULL;
4391 }
4392
4393 ssl->keys.encryptSz = sz;
4394 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) {
4395 output += ssl->specs.block_size; /* go past TLSv1.1 IV */
4396 ivExtra = ssl->specs.block_size;
4397 *advance = ssl->specs.block_size;
4398 }
4399
4400 if (ssl->specs.cipher_type == aead) {
4401 *advance = ssl->specs.aead_mac_size;
4402 ssl->keys.padSz = ssl->specs.aead_mac_size;
4403 }
4404 else
4405 ssl->keys.padSz = ssl->specs.hash_size;
4406
4407 if (ssl->specs.cipher_type == block) {
4408 /* last pad bytes indicates length */
4409 word32 pad = 0;
4410 if ((int)sz > ivExtra) {
4411 /* get value of last pad byte */
4412 pad = *(output + sz - ivExtra - 1) + 1;
4413 }
4414 ssl->keys.padSz += pad;
4415 }
4416
4417 #ifdef WOLFSSL_TLS13
4418 if (IsAtLeastTLSv1_3(ssl->version)) {
4419 word16 i = (word16)(sz - ssl->keys.padSz);
4420 /* Remove padding from end of plain text. */
4421 for (--i; i > 0; i--) {
4422 if (output[i] != 0)
4423 break;
4424 }
4425 /* Get the real content type from the end of the data. */
4426 rh->type = output[i];
4427 ssl->keys.padSz = sz - i;
4428 }
4429 #endif
4430 (void)rh;
4431
4432 return output;
4433 }
4434
4435
4436 /* remove session from table, use rowHint if no info (means we have a lock) */
4437 static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
4438 TcpInfo* tcpInfo, word32 rowHint)
4439 {
4440 SnifferSession* previous = 0;
4441 SnifferSession* current;
4442 word32 row = rowHint;
4443 int haveLock = 0;
4444
4445 Trace(REMOVE_SESSION_STR);
4446
4447 if (ipInfo && tcpInfo)
4448 row = SessionHash(ipInfo, tcpInfo);
4449 else
4450 haveLock = 1;
4451
4452 if (row >= HASH_SIZE)
4453 return;
4454
4455 if (!haveLock)
4456 wc_LockMutex(&SessionMutex);
4457
4458 current = SessionTable[row];
4459
4460 while (current) {
4461 if (current == session) {
4462 if (previous)
4463 previous->next = current->next;
4464 else
4465 SessionTable[row] = current->next;
4466 FreeSnifferSession(session);
4467 TraceRemovedSession();
4468 break;
4469 }
4470 previous = current;
4471 current = current->next;
4472 }
4473
4474 if (!haveLock)
4475 wc_UnLockMutex(&SessionMutex);
4476 }
4477
4478
4479 /* Remove stale sessions from the Session Table, have a lock */
4480 static void RemoveStaleSessions(void)
4481 {
4482 word32 i;
4483 SnifferSession* session;
4484
4485 for (i = 0; i < HASH_SIZE; i++) {
4486 session = SessionTable[i];
4487 while (session) {
4488 SnifferSession* next = session->next;
4489 if (XTIME(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) {
4490 TraceStaleSession();
4491 RemoveSession(session, NULL, NULL, i);
4492 }
4493 session = next;
4494 }
4495 }
4496 }
4497
4498
4499 /* Create a new Sniffer Session */
4500 static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
4501 char* error)
4502 {
4503 SnifferSession* session = 0;
4504 int row;
4505
4506 Trace(NEW_SESSION_STR);
4507 /* create a new one */
4508 session = (SnifferSession*)XMALLOC(sizeof(SnifferSession),
4509 NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
4510 if (session == NULL) {
4511 SetError(MEMORY_STR, error, NULL, 0);
4512 return 0;
4513 }
4514 InitSession(session);
4515 #ifdef HAVE_EXTENDED_MASTER
4516 {
4517 HsHashes* newHash = (HsHashes*)XMALLOC(sizeof(HsHashes),
4518 NULL, DYNAMIC_TYPE_HASHES);
4519 if (newHash == NULL) {
4520 SetError(MEMORY_STR, error, NULL, 0);
4521 XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
4522 return 0;
4523 }
4524 if (HashInit(newHash) != 0) {
4525 SetError(EXTENDED_MASTER_HASH_STR, error, NULL, 0);
4526 XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
4527 return 0;
4528 }
4529 session->hash = newHash;
4530 }
4531 #endif
4532 session->server = ipInfo->dst;
4533 session->client = ipInfo->src;
4534 session->srvPort = (word16)tcpInfo->dstPort;
4535 session->cliPort = (word16)tcpInfo->srcPort;
4536 session->cliSeqStart = tcpInfo->sequence;
4537 session->cliExpected = 1; /* relative */
4538 session->lastUsed= XTIME(NULL);
4539 session->keySz = 0;
4540 #ifdef HAVE_SNI
4541 session->sni = NULL;
4542 #endif
4543
4544 session->context = GetSnifferServer(ipInfo, tcpInfo);
4545 if (session->context == NULL) {
4546 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
4547 XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
4548 return 0;
4549 }
4550
4551 session->sslServer = wolfSSL_new(session->context->ctx);
4552 if (session->sslServer == NULL) {
4553 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
4554 XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
4555 return 0;
4556 }
4557 session->sslClient = wolfSSL_new(session->context->ctx);
4558 if (session->sslClient == NULL) {
4559 wolfSSL_free(session->sslServer);
4560 session->sslServer = 0;
4561
4562 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
4563 XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
4564 return 0;
4565 }
4566 /* put server back into server mode */
4567 session->sslServer->options.side = WOLFSSL_SERVER_END;
4568
4569 row = SessionHash(ipInfo, tcpInfo);
4570
4571 /* add it to the session table */
4572 wc_LockMutex(&SessionMutex);
4573
4574 session->next = SessionTable[row];
4575 SessionTable[row] = session;
4576
4577 SessionCount++;
4578
4579 if ( (SessionCount % HASH_SIZE) == 0) {
4580 TraceFindingStale();
4581 RemoveStaleSessions();
4582 }
4583
4584 wc_UnLockMutex(&SessionMutex);
4585
4586 /* CreateSession is called in response to a SYN packet, we know this
4587 * is headed to the server. Also we know the server is one we care
4588 * about as we've passed the GetSnifferServer() successfully. */
4589 session->flags.side = WOLFSSL_SERVER_END;
4590
4591 return session;
4592 }
4593
4594
4595 #ifdef OLD_HELLO_ALLOWED
4596
4597 /* Process Old Client Hello Input */
4598 static int DoOldHello(SnifferSession* session, const byte* sslFrame,
4599 int* rhSize, int* sslBytes, char* error)
4600 {
4601 const byte* input = sslFrame;
4602 byte b0, b1;
4603 word32 idx = 0;
4604 int ret;
4605
4606 Trace(GOT_OLD_CLIENT_HELLO_STR);
4607 session->flags.clientHello = 1; /* don't process again */
4608 b0 = *input++;
4609 b1 = *input++;
4610 *sslBytes -= 2;
4611 *rhSize = ((b0 & 0x7f) << 8) | b1;
4612
4613 if (*rhSize > *sslBytes) {
4614 SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
4615 return -1;
4616 }
4617
4618 ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
4619 (word16)*rhSize);
4620 if (ret < 0 && ret != MATCH_SUITE_ERROR) {
4621 SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
4622 return -1;
4623 }
4624
4625 Trace(OLD_CLIENT_OK_STR);
4626 XMEMCPY(session->sslClient->arrays->clientRandom,
4627 session->sslServer->arrays->clientRandom, RAN_LEN);
4628
4629 *sslBytes -= *rhSize;
4630 return 0;
4631 }
4632
4633 #endif /* OLD_HELLO_ALLOWED */
4634
4635
4636 #if 0
4637 /* Calculate the TCP checksum, see RFC 1071 */
4638 /* return 0 for success, -1 on error */
4639 /* can be called from decode() with
4640 TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
4641 could also add a 64bit version if type available and using this
4642 */
4643 int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
4644 const byte* packet)
4645 {
4646 TcpPseudoHdr pseudo;
4647 int count = PSEUDO_HDR_SZ;
4648 const word16* data = (word16*)&pseudo;
4649 word32 sum = 0;
4650 word16 checksum;
4651
4652 pseudo.src = ipInfo->src;
4653 pseudo.dst = ipInfo->dst;
4654 pseudo.rsv = 0;
4655 pseudo.protocol = TCP_PROTO;
4656 pseudo.length = htons(tcpInfo->length + dataLen);
4657
4658 /* pseudo header sum */
4659 while (count >= 2) {
4660 sum += *data++;
4661 count -= 2;
4662 }
4663
4664 count = tcpInfo->length + dataLen;
4665 data = (word16*)packet;
4666
4667 /* main sum */
4668 while (count > 1) {
4669 sum += *data++;
4670 count -=2;
4671 }
4672
4673 /* get left-over, if any */
4674 packet = (byte*)data;
4675 if (count > 0) {
4676 sum += *packet;
4677 }
4678
4679 /* fold 32bit sum into 16 bits */
4680 while (sum >> 16)
4681 sum = (sum & 0xffff) + (sum >> 16);
4682
4683 checksum = (word16)~sum;
4684 /* checksum should now equal 0, since included already calcd checksum */
4685 /* field, but tcp checksum offloading could negate calculation */
4686 if (checksum == 0)
4687 return 0;
4688 return -1;
4689 }
4690 #endif
4691
4692
4693 /* Check IP and TCP headers, set payload */
4694 /* returns 0 on success, -1 on error */
4695 static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
4696 int length, const byte** sslFrame, int* sslBytes, char* error)
4697 {
4698 IpHdr* iphdr = (IpHdr*)packet;
4699 int version;
4700
4701 TraceHeader();
4702 TracePacket();
4703
4704 /* ip header */
4705 if (length < IP_HDR_SZ) {
4706 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
4707 return -1;
4708 }
4709
4710 version = IP_V(iphdr);
4711 if (version != IPV6 && version != IPV4) {
4712 /* Is this VLAN IEEE 802.1Q Frame? TPID = 0x8100 */
4713 if (packet[2] == 0x81 && packet[3] == 0x00) {
4714 /* trim VLAN header and try again */
4715 packet += 8;
4716 length -= 8;
4717 }
4718 }
4719
4720 if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
4721 return -1;
4722
4723 /* tcp header */
4724 if (length < (ipInfo->length + TCP_HDR_SZ)) {
4725 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
4726 return -1;
4727 }
4728 if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0)
4729 return -1;
4730
4731 /* setup */
4732 *sslFrame = packet + ipInfo->length + tcpInfo->length;
4733 if (*sslFrame > packet + length) {
4734 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
4735 return -1;
4736 }
4737
4738 /* We only care about the data in the TCP/IP record. There may be extra
4739 * data after the IP record for the FCS for Ethernet. */
4740 *sslBytes = (int)(packet + ipInfo->total - *sslFrame);
4741
4742 return 0;
4743 }
4744
4745
4746 /* Create or Find existing session */
4747 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
4748 static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes,
4749 SnifferSession** session, char* error)
4750 {
4751 /* create a new SnifferSession on client SYN */
4752 if (tcpInfo->syn && !tcpInfo->ack) {
4753 TraceClientSyn(tcpInfo->sequence);
4754 #ifdef WOLFSSL_SNIFFER_STATS
4755 INC_STAT(SnifferStats.sslEncryptedConns);
4756 #endif
4757 *session = CreateSession(ipInfo, tcpInfo, error);
4758 if (*session == NULL) {
4759 *session = GetSnifferSession(ipInfo, tcpInfo);
4760 /* already had existing, so OK */
4761 if (*session)
4762 return 1;
4763
4764 SetError(MEMORY_STR, error, NULL, 0);
4765 return -1;
4766 }
4767 return 1;
4768 }
4769 /* get existing sniffer session */
4770 else {
4771 *session = GetSnifferSession(ipInfo, tcpInfo);
4772 if (*session == NULL) {
4773 /* don't worry about extraneous RST or duplicate FINs */
4774 if (tcpInfo->fin || tcpInfo->rst)
4775 return 1;
4776 /* don't worry about duplicate ACKs either */
4777 if (sslBytes == 0 && tcpInfo->ack)
4778 return 1;
4779
4780 #ifdef WOLFSSL_SNIFFER_STATS
4781 LOCK_STAT();
4782 NOLOCK_INC_STAT(SnifferStats.sslDecryptedPackets);
4783 NOLOCK_ADD_TO_STAT(SnifferStats.sslDecryptedBytes, sslBytes);
4784 UNLOCK_STAT();
4785 #endif
4786
4787 SetError(BAD_SESSION_STR, error, NULL, 0);
4788 return -1;
4789 }
4790 }
4791 return 0;
4792 }
4793
4794
4795 /* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */
4796 static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data,
4797 int* bytesLeft)
4798 {
4799 PacketBuffer* pb;
4800 int added = (int)(end - *begin + 1);
4801
4802 if (added <= 0) {
4803 return NULL;
4804 }
4805
4806 pb = (PacketBuffer*)XMALLOC(sizeof(PacketBuffer),
4807 NULL, DYNAMIC_TYPE_SNIFFER_PB);
4808 if (pb == NULL) return NULL;
4809
4810 pb->next = 0;
4811 pb->begin = *begin;
4812 pb->end = end;
4813 pb->data = (byte*)XMALLOC(added, NULL, DYNAMIC_TYPE_SNIFFER_PB_BUFFER);
4814
4815 if (pb->data == NULL) {
4816 XFREE(pb, NULL, DYNAMIC_TYPE_SNIFFER_PB);
4817 return NULL;
4818 }
4819 XMEMCPY(pb->data, data, added);
4820
4821 *bytesLeft -= added;
4822 *begin = pb->end + 1;
4823
4824 return pb;
4825 }
4826
4827
4828 /* Add sslFrame to Reassembly List */
4829 /* returns 1 (end) on success, -1, on error */
4830 static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
4831 int sslBytes, SnifferSession* session, char* error)
4832 {
4833 PacketBuffer* add;
4834 PacketBuffer** front = (from == WOLFSSL_SERVER_END) ?
4835 &session->cliReassemblyList: &session->srvReassemblyList;
4836 PacketBuffer* curr = *front;
4837 PacketBuffer* prev = curr;
4838
4839 word32* reassemblyMemory = (from == WOLFSSL_SERVER_END) ?
4840 &session->cliReassemblyMemory : &session->srvReassemblyMemory;
4841 word32 startSeq = seq;
4842 int added;
4843 int bytesLeft = sslBytes; /* could be overlapping fragment */
4844
4845 /* if list is empty add full frame to front */
4846 if (!curr) {
4847 if (MaxRecoveryMemory != -1 &&
4848 (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
4849 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
4850 return -1;
4851 }
4852 add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft);
4853 if (add == NULL) {
4854 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
4855 return -1;
4856 }
4857 *front = add;
4858 *reassemblyMemory += sslBytes;
4859 return 1;
4860 }
4861
4862 /* add to front if before current front, up to next->begin */
4863 if (seq < curr->begin) {
4864 word32 end = seq + sslBytes - 1;
4865
4866 if (end >= curr->begin)
4867 end = curr->begin - 1;
4868
4869 if (MaxRecoveryMemory -1 &&
4870 (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
4871 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
4872 return -1;
4873 }
4874 add = CreateBuffer(&seq, end, sslFrame, &bytesLeft);
4875 if (add == NULL) {
4876 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
4877 return -1;
4878 }
4879 add->next = curr;
4880 *front = add;
4881 *reassemblyMemory += sslBytes;
4882 }
4883
4884 /* while we have bytes left, try to find a gap to fill */
4885 while (bytesLeft > 0) {
4886 /* get previous packet in list */
4887 while (curr && (seq >= curr->begin)) {
4888 prev = curr;
4889 curr = curr->next;
4890 }
4891
4892 /* don't add duplicate data */
4893 if (prev->end >= seq) {
4894 if ( (seq + bytesLeft - 1) <= prev->end)
4895 return 1;
4896 seq = prev->end + 1;
4897 bytesLeft = startSeq + sslBytes - seq;
4898 }
4899
4900 if (!curr)
4901 /* we're at the end */
4902 added = bytesLeft;
4903 else
4904 /* we're in between two frames */
4905 added = min(bytesLeft, (int)(curr->begin - seq));
4906
4907 /* data already there */
4908 if (added <= 0)
4909 continue;
4910
4911 if (MaxRecoveryMemory != -1 &&
4912 (int)(*reassemblyMemory + added) > MaxRecoveryMemory) {
4913 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
4914 return -1;
4915 }
4916 add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq],
4917 &bytesLeft);
4918 if (add == NULL) {
4919 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
4920 return -1;
4921 }
4922 add->next = prev->next;
4923 prev->next = add;
4924 *reassemblyMemory += added;
4925 }
4926 return 1;
4927 }
4928
4929
4930 /* Add out of order FIN capture */
4931 /* returns 1 for success (end) */
4932 static int AddFinCapture(SnifferSession* session, word32 sequence)
4933 {
4934 if (session->flags.side == WOLFSSL_SERVER_END) {
4935 if (session->finCapture.cliCounted == 0)
4936 session->finCapture.cliFinSeq = sequence;
4937 }
4938 else {
4939 if (session->finCapture.srvCounted == 0)
4940 session->finCapture.srvFinSeq = sequence;
4941 }
4942 return 1;
4943 }
4944
4945 static int FindPrevAck(SnifferSession* session, word32 realAck)
4946 {
4947 int i;
4948 word32* acks = (session->flags.side == WOLFSSL_SERVER_END) ?
4949 session->cliAcks : session->srvAcks;
4950 /* if previous ack found return 1, otherwise 0 */
4951 for (i=0; i<WC_SNIFFER_HS_ACK_HIST_MAX; i++) {
4952 if (acks[i] == realAck) {
4953 return 1;
4954 }
4955
4956 }
4957 return 0;
4958 }
4959 static void AddAck(SnifferSession* session, word32 realAck)
4960 {
4961 int i;
4962 word32* acks = (session->flags.side == WOLFSSL_SERVER_END) ?
4963 session->cliAcks : session->srvAcks;
4964 /* find first empty ack slot */
4965 for (i=0; i<WC_SNIFFER_HS_ACK_HIST_MAX; i++) {
4966 if (acks[i] == 0) {
4967 break;
4968 }
4969 }
4970 /* if out of slots, find oldest */
4971 if (i == WC_SNIFFER_HS_ACK_HIST_MAX) {
4972 int idx = 0;
4973 word32 lastAck = realAck;
4974 for (i=0; i<WC_SNIFFER_HS_ACK_HIST_MAX; i++) {
4975 if (acks[i] < lastAck) {
4976 idx = i;
4977 lastAck = acks[i];
4978 }
4979 }
4980 i = idx;
4981 }
4982
4983 acks[i] = realAck;
4984 }
4985
4986 /* Adjust incoming sequence based on side */
4987 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
4988 static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
4989 int* sslBytes, const byte** sslFrame, char* error)
4990 {
4991 int ret = 0;
4992 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
4993 session->cliSeqStart :session->srvSeqStart;
4994 word32 real = tcpInfo->sequence - seqStart;
4995 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
4996 &session->cliExpected : &session->srvExpected;
4997 PacketBuffer* reassemblyList = (session->flags.side == WOLFSSL_SERVER_END) ?
4998 session->cliReassemblyList : session->srvReassemblyList;
4999 byte skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
5000 session->flags.srvSkipPartial :
5001 session->flags.cliSkipPartial;
5002
5003 /* handle rollover of sequence */
5004 if (tcpInfo->sequence < seqStart)
5005 real = 0xffffffffU - seqStart + tcpInfo->sequence + 1;
5006
5007 TraceRelativeSequence(*expected, real);
5008
5009 if (real < *expected) {
5010
5011 if (real + *sslBytes > *expected) {
5012 Trace(OVERLAP_DUPLICATE_STR);
5013
5014 /* The following conditional block is duplicated below. It is the
5015 * same action but for a different setup case. If changing this
5016 * block be sure to also update the block below. */
5017 if (reassemblyList) {
5018 int overlap = *expected - real;
5019 word32 newEnd;
5020
5021 /* adjust to expected, remove duplicate */
5022 *sslFrame += overlap;
5023 *sslBytes = (*sslBytes > overlap) ? *sslBytes - overlap : 0;
5024
5025 newEnd = *expected + *sslBytes;
5026 if (newEnd > reassemblyList->begin) {
5027 int covered_data_len;
5028
5029 Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
5030
5031 /* remove bytes already on reassembly list */
5032 covered_data_len = newEnd - reassemblyList->begin;
5033 *sslFrame += covered_data_len;
5034 *sslBytes = (*sslBytes > covered_data_len) ?
5035 *sslBytes - covered_data_len : 0;
5036 }
5037 if ((*sslBytes > 0) && (newEnd > reassemblyList->end)) {
5038 Trace(OVERLAP_REASSEMBLY_END_STR);
5039
5040 /* may be past reassembly list end (could have more on list)
5041 so try to add what's past the front->end */
5042 AddToReassembly(session->flags.side, reassemblyList->end + 1,
5043 *sslFrame + (reassemblyList->end - *expected + 1),
5044 newEnd - reassemblyList->end, session, error);
5045 }
5046 }
5047 else {
5048 /* DUP overlap, allow */
5049 if (*sslBytes > 0) {
5050 skipPartial = 0; /* do not reset sslBytes */
5051 }
5052 }
5053 ret = 0;
5054 }
5055 else {
5056 /* This can happen with unseen acks, out of order packets, or
5057 * possible spurious retransmission. */
5058 if (*sslBytes > 0) {
5059 /* If packet has data attempt to process packet, if hasn't
5060 * already been ack'd during handshake */
5061 if (FindPrevAck(session, real)) {
5062 Trace(DUPLICATE_STR);
5063 ret = 1;
5064 }
5065 else {
5066 /* DUP: allow */
5067 skipPartial = 0; /* do not reset sslBytes */
5068 ret = 0;
5069 }
5070 }
5071 else {
5072 /* DUP empty, ignore */
5073 ret = 1;
5074 }
5075 }
5076 }
5077 else if (real > *expected) {
5078 Trace(OUT_OF_ORDER_STR);
5079 if (*sslBytes > 0) {
5080 int addResult = AddToReassembly(session->flags.side, real,
5081 *sslFrame, *sslBytes, session, error);
5082 ret = (skipPartial) ? 0 : addResult;
5083 }
5084 else if (tcpInfo->fin) {
5085 ret = AddFinCapture(session, real);
5086 }
5087 }
5088 else if (*sslBytes > 0) {
5089 if (skipPartial) {
5090 AddToReassembly(session->flags.side, real,
5091 *sslFrame, *sslBytes, session, error);
5092 ret = 0;
5093 }
5094 /* The following conditional block is duplicated above. It is the
5095 * same action but for a different setup case. If changing this
5096 * block be sure to also update the block above. */
5097 else if (reassemblyList) {
5098 word32 newEnd = *expected + *sslBytes;
5099
5100 if (newEnd > reassemblyList->begin) {
5101 int covered_data_len;
5102
5103 Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
5104
5105 /* remove bytes already on reassembly list */
5106 covered_data_len = newEnd - reassemblyList->begin;
5107 *sslFrame += covered_data_len;
5108 *sslBytes = (*sslBytes > covered_data_len) ?
5109 *sslBytes - covered_data_len : 0;
5110 }
5111 if ((*sslBytes > 0) && (newEnd > reassemblyList->end)) {
5112 Trace(OVERLAP_REASSEMBLY_END_STR);
5113
5114 /* may be past reassembly list end (could have more on list)
5115 so try to add what's past the front->end */
5116 AddToReassembly(session->flags.side, reassemblyList->end + 1,
5117 *sslFrame + (reassemblyList->end - *expected + 1),
5118 newEnd - reassemblyList->end, session, error);
5119 }
5120 }
5121 }
5122 else {
5123 /* no data present */
5124 }
5125
5126 if (ret == 0) {
5127 /* got expected sequence */
5128 *expected += *sslBytes;
5129 if (tcpInfo->fin)
5130 *expected += 1;
5131 }
5132 if (*sslBytes > 0) {
5133 AddAck(session, real);
5134 }
5135 if (*sslBytes > 0 && skipPartial) {
5136 *sslBytes = 0;
5137 }
5138
5139 return ret;
5140 }
5141
5142
5143 static int FindNextRecordInAssembly(SnifferSession* session,
5144 const byte** sslFrame, int* sslBytes,
5145 const byte** end, char* error)
5146 {
5147 PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ?
5148 &session->cliReassemblyList :
5149 &session->srvReassemblyList;
5150 PacketBuffer* curr = *front;
5151 PacketBuffer* prev = NULL;
5152 byte* skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
5153 &session->flags.srvSkipPartial :
5154 &session->flags.cliSkipPartial;
5155 int* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
5156 (int*)&session->cliReassemblyMemory :
5157 (int*)&session->srvReassemblyMemory;
5158 WOLFSSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
5159 session->sslServer :
5160 session->sslClient;
5161 ProtocolVersion pv = ssl->version;
5162 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
5163 &session->cliExpected :
5164 &session->srvExpected;
5165
5166 while (curr != NULL) {
5167 *expected = curr->end + 1;
5168
5169 if (curr->data[0] == application_data &&
5170 curr->data[1] == pv.major &&
5171 curr->data[2] == pv.minor) {
5172
5173 if (ssl->buffers.inputBuffer.length > 0)
5174 Trace(DROPPING_PARTIAL_RECORD);
5175
5176 *sslBytes = (int)(curr->end - curr->begin + 1);
5177 if ( *sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
5178 if (GrowInputBuffer(ssl, *sslBytes, 0) < 0) {
5179 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
5180 return -1;
5181 }
5182 }
5183
5184 XMEMCPY(ssl->buffers.inputBuffer.buffer, curr->data, *sslBytes);
5185
5186 *front = curr->next;
5187 *reassemblyMemory -= *sslBytes;
5188 FreePacketBuffer(curr);
5189
5190 ssl->buffers.inputBuffer.length = *sslBytes;
5191 *sslFrame = ssl->buffers.inputBuffer.buffer;
5192 *end = *sslFrame + *sslBytes;
5193 *skipPartial = 0;
5194
5195 return 0;
5196 }
5197 else if (ssl->specs.cipher_type == block) {
5198 int ivPos = (int)(curr->end - curr->begin -
5199 ssl->specs.block_size + 1);
5200 if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes) {
5201 #ifdef BUILD_AES
5202 if (ivPos >= 0)
5203 wc_AesSetIV(ssl->decrypt.aes, curr->data + ivPos);
5204 #endif
5205 }
5206 else if (ssl->specs.bulk_cipher_algorithm == wolfssl_triple_des) {
5207 #ifdef BUILD_DES3
5208 if (ivPos >= 0)
5209 wc_Des3_SetIV(ssl->decrypt.des3, curr->data + ivPos);
5210 #endif
5211 }
5212 }
5213
5214 Trace(DROPPING_LOST_FRAG_STR);
5215 #ifdef WOLFSSL_SNIFFER_STATS
5216 INC_STAT(SnifferStats.sslDecodeFails);
5217 #endif
5218 prev = curr;
5219 curr = curr->next;
5220 *reassemblyMemory -= (int)(prev->end - prev->begin + 1);
5221 FreePacketBuffer(prev);
5222 }
5223
5224 *front = curr;
5225
5226 return 0;
5227 }
5228
5229
5230 static int FixSequence(TcpInfo* tcpInfo, SnifferSession* session)
5231 {
5232 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
5233 &session->srvExpected : &session->cliExpected;
5234 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
5235 session->srvSeqStart : session->cliSeqStart;
5236 PacketBuffer* list = (session->flags.side == WOLFSSL_SERVER_END) ?
5237 session->srvReassemblyList :
5238 session->cliReassemblyList;
5239 byte* skipPartial = (session->flags.side != WOLFSSL_SERVER_END) ?
5240 &session->flags.srvSkipPartial :
5241 &session->flags.cliSkipPartial;
5242
5243 *skipPartial = 1;
5244
5245 if (list != NULL)
5246 *expected = list->begin;
5247 else
5248 *expected = tcpInfo->ackNumber - seqStart;
5249
5250 return 1;
5251 }
5252
5253
5254 /* Check latest ack number for missing packets
5255 return 0 ok, <0 on error */
5256 static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session)
5257 {
5258 if (tcpInfo->ack) {
5259 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
5260 session->srvSeqStart :session->cliSeqStart;
5261 word32 real = tcpInfo->ackNumber - seqStart;
5262 word32 expected = (session->flags.side == WOLFSSL_SERVER_END) ?
5263 session->srvExpected : session->cliExpected;
5264
5265 /* handle rollover of sequence */
5266 if (tcpInfo->ackNumber < seqStart)
5267 real = 0xffffffffU - seqStart + tcpInfo->ackNumber + 1;
5268
5269 TraceAck(real, expected);
5270
5271 if (real > expected)
5272 return -1; /* we missed a packet, ACKing data we never saw */
5273 }
5274 return 0;
5275 }
5276
5277
5278 /* Check TCP Sequence status */
5279 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
5280 static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
5281 SnifferSession* session, int* sslBytes,
5282 const byte** sslFrame, char* error)
5283 {
5284 int actualLen;
5285 byte* ackFault = (session->flags.side == WOLFSSL_SERVER_END) ?
5286 &session->flags.cliAckFault :
5287 &session->flags.srvAckFault;
5288
5289 /* init SEQ from server to client - if not ack fault */
5290 if (tcpInfo->syn && tcpInfo->ack && !*ackFault) {
5291 session->srvSeqStart = tcpInfo->sequence;
5292 session->srvExpected = 1;
5293 TraceServerSyn(tcpInfo->sequence);
5294 return 1;
5295 }
5296
5297 /* adjust potential ethernet trailer */
5298 actualLen = ipInfo->total - ipInfo->length - tcpInfo->length;
5299 if (*sslBytes > actualLen) {
5300 *sslBytes = actualLen;
5301 }
5302
5303 TraceSequence(tcpInfo->sequence, *sslBytes);
5304 if (CheckAck(tcpInfo, session) < 0) {
5305 if (!RecoveryEnabled) {
5306 UpdateMissedDataSessions();
5307 SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE);
5308 return -1;
5309 }
5310 else {
5311 SetError(ACK_MISSED_STR, error, session, 0);
5312 if (*ackFault == 0) {
5313 *ackFault = 1;
5314 UpdateMissedDataSessions();
5315 }
5316 return FixSequence(tcpInfo, session);
5317 }
5318 }
5319
5320 if (*ackFault) {
5321 Trace(CLEAR_ACK_FAULT);
5322 *ackFault = 0;
5323 }
5324
5325 return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);
5326 }
5327
5328
5329 /* Check Status before record processing */
5330 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
5331 static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
5332 const byte** sslFrame, SnifferSession** session,
5333 int* sslBytes, const byte** end,
5334 void* vChain, word32 chainSz, char* error)
5335 {
5336 word32 length;
5337 WOLFSSL* ssl = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
5338 (*session)->sslServer : (*session)->sslClient;
5339 byte skipPartial = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
5340 (*session)->flags.srvSkipPartial :
5341 (*session)->flags.cliSkipPartial;
5342 /* remove SnifferSession on 2nd FIN or RST */
5343 if (tcpInfo->fin || tcpInfo->rst) {
5344 /* flag FIN and RST */
5345 if (tcpInfo->fin)
5346 (*session)->flags.finCount += 1;
5347 else if (tcpInfo->rst)
5348 (*session)->flags.finCount += 2;
5349
5350 if ((*session)->flags.finCount >= 2) {
5351 RemoveSession(*session, ipInfo, tcpInfo, 0);
5352 *session = NULL;
5353 return 1;
5354 }
5355 }
5356
5357 if ((*session)->flags.fatalError == FATAL_ERROR_STATE) {
5358 SetError(FATAL_ERROR_STR, error, NULL, 0);
5359 return -1;
5360 }
5361
5362 if (skipPartial) {
5363 if (FindNextRecordInAssembly(*session,
5364 sslFrame, sslBytes, end, error) < 0) {
5365 return -1;
5366 }
5367 }
5368
5369 if (*sslBytes <= 0) {
5370 Trace(NO_DATA_STR);
5371 return 1;
5372 }
5373
5374 /* if current partial data, add to end of partial */
5375 /* if skipping, the data is already at the end of partial */
5376 length = ssl->buffers.inputBuffer.length;
5377 if ( !skipPartial && length ) {
5378 Trace(PARTIAL_ADD_STR);
5379
5380 if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
5381 if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
5382 SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
5383 return -1;
5384 }
5385 }
5386 if (vChain == NULL) {
5387 XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
5388 *sslFrame, *sslBytes);
5389 *sslBytes += length;
5390 ssl->buffers.inputBuffer.length = *sslBytes;
5391 *sslFrame = ssl->buffers.inputBuffer.buffer;
5392 *end = *sslFrame + *sslBytes;
5393 }
5394
5395 if (vChain != NULL) {
5396 #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
5397 struct iovec* chain = (struct iovec*)vChain;
5398 word32 i, offset, headerSz, qty, remainder;
5399
5400 Trace(CHAIN_INPUT_STR);
5401 headerSz = (word32)((const byte*)*sslFrame - (const byte*)chain[0].iov_base);
5402 remainder = *sslBytes;
5403
5404 if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
5405 if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
5406 SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
5407 return -1;
5408 }
5409 }
5410
5411 qty = min(*sslBytes, (word32)chain[0].iov_len - headerSz);
5412 XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
5413 (byte*)chain[0].iov_base + headerSz, qty);
5414 offset = length;
5415 for (i = 1; i < chainSz; i++) {
5416 offset += qty;
5417 remainder -= qty;
5418
5419 if (chain[i].iov_len > remainder)
5420 qty = remainder;
5421 else
5422 qty = (word32)chain[i].iov_len;
5423 XMEMCPY(ssl->buffers.inputBuffer.buffer + offset,
5424 chain[i].iov_base, qty);
5425 }
5426
5427 *sslBytes += length;
5428 ssl->buffers.inputBuffer.length = *sslBytes;
5429 *sslFrame = ssl->buffers.inputBuffer.buffer;
5430 *end = *sslFrame + *sslBytes;
5431 #endif
5432 (void)chainSz;
5433 }
5434 }
5435
5436 if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) {
5437 /* Sanity check the packet for an old style client hello. */
5438 int rhSize = (((*sslFrame)[0] & 0x7f) << 8) | ((*sslFrame)[1]);
5439
5440 if ((rhSize <= (*sslBytes - 2)) &&
5441 (*sslFrame)[2] == OLD_HELLO_ID && (*sslFrame)[3] == SSLv3_MAJOR) {
5442 #ifdef OLD_HELLO_ALLOWED
5443 int ret = DoOldHello(*session, *sslFrame, &rhSize, sslBytes, error);
5444 if (ret < 0)
5445 return -1; /* error already set */
5446 if (*sslBytes <= 0)
5447 return 1;
5448 #endif
5449 }
5450 else {
5451 #ifdef STARTTLS_ALLOWED
5452 if (ssl->buffers.inputBuffer.dynamicFlag) {
5453 ssl->buffers.inputBuffer.length = 0;
5454 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
5455 }
5456 return 1;
5457 #endif
5458 }
5459 }
5460
5461 return 0;
5462 }
5463
5464
5465 /* See if input on the reassembly list is ready for consuming */
5466 /* returns 1 for TRUE, 0 for FALSE */
5467 static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
5468 int* sslBytes, const byte** end, char* error)
5469 {
5470 /* sequence and reassembly based on from, not to */
5471 int moreInput = 0;
5472 PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ?
5473 &session->cliReassemblyList : &session->srvReassemblyList;
5474 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
5475 &session->cliExpected : &session->srvExpected;
5476 /* buffer is on receiving end */
5477 word32* length = (session->flags.side == WOLFSSL_SERVER_END) ?
5478 &session->sslServer->buffers.inputBuffer.length :
5479 &session->sslClient->buffers.inputBuffer.length;
5480 byte** myBuffer = (session->flags.side == WOLFSSL_SERVER_END) ?
5481 &session->sslServer->buffers.inputBuffer.buffer :
5482 &session->sslClient->buffers.inputBuffer.buffer;
5483 word32* bufferSize = (session->flags.side == WOLFSSL_SERVER_END) ?
5484 &session->sslServer->buffers.inputBuffer.bufferSize :
5485 &session->sslClient->buffers.inputBuffer.bufferSize;
5486 WOLFSSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
5487 session->sslServer : session->sslClient;
5488 word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
5489 &session->cliReassemblyMemory : &session->srvReassemblyMemory;
5490
5491 while (*front && ((*front)->begin == *expected) ) {
5492 int room = (int)(*bufferSize - *length);
5493 int packetLen = (int)((*front)->end - (*front)->begin + 1);
5494
5495 if (packetLen > room && *bufferSize < MAX_INPUT_SZ) {
5496 if (GrowInputBuffer(ssl, packetLen, *length) < 0) {
5497 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
5498 return 0;
5499 }
5500 room = *bufferSize - *length; /* bufferSize is now bigger */
5501 }
5502
5503 if (packetLen <= room) {
5504 PacketBuffer* del = *front;
5505 byte* buf = *myBuffer;
5506
5507 XMEMCPY(&buf[*length], (*front)->data, packetLen);
5508 *length += packetLen;
5509 *expected += packetLen;
5510
5511 /* remove used packet */
5512 *front = (*front)->next;
5513
5514 *reassemblyMemory -= packetLen;
5515 FreePacketBuffer(del);
5516
5517 moreInput = 1;
5518 }
5519 else
5520 break;
5521 }
5522 if (moreInput) {
5523 *sslFrame = *myBuffer;
5524 *sslBytes = *length;
5525 *end = *myBuffer + *length;
5526 }
5527 return moreInput;
5528 }
5529
5530
5531
5532 /* Process Message(s) from sslFrame */
5533 /* return Number of bytes on success, 0 for no data yet, and -1 on error */
5534 static int ProcessMessage(const byte* sslFrame, SnifferSession* session,
5535 int sslBytes, byte** data, const byte* end,
5536 void* ctx, char* error)
5537 {
5538 const byte* sslBegin = sslFrame;
5539 const byte* recordEnd; /* end of record indicator */
5540 const byte* inRecordEnd; /* indicator from input stream not decrypt */
5541 RecordLayerHeader rh;
5542 int rhSize = 0;
5543 int ret;
5544 int errCode = 0;
5545 int decoded = 0; /* bytes stored for user in data */
5546 int notEnough; /* notEnough bytes yet flag */
5547 int decrypted = 0; /* was current msg decrypted */
5548 WOLFSSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
5549 session->sslServer : session->sslClient;
5550 doMessage:
5551 notEnough = 0;
5552 if (sslBytes < 0) {
5553 SetError(PACKET_HDR_SHORT_STR, error, session, FATAL_ERROR_STATE);
5554 return -1;
5555 }
5556 if (sslBytes >= RECORD_HEADER_SZ) {
5557 if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) {
5558 /* ignore packet if record header errors */
5559 SetError(BAD_RECORD_HDR_STR, error, session, 0);
5560 return 0;
5561 }
5562 }
5563 else
5564 notEnough = 1;
5565
5566 if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) {
5567 /* don't have enough input yet to process full SSL record */
5568 Trace(PARTIAL_INPUT_STR);
5569
5570 /* store partial if not there already or we advanced */
5571 if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
5572 if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
5573 if (GrowInputBuffer(ssl, sslBytes, 0) < 0) {
5574 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
5575 return -1;
5576 }
5577 }
5578 XMEMMOVE(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
5579 ssl->buffers.inputBuffer.length = sslBytes;
5580 }
5581 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
5582 goto doMessage;
5583 return decoded;
5584 }
5585 sslFrame += RECORD_HEADER_SZ;
5586 sslBytes -= RECORD_HEADER_SZ;
5587 recordEnd = sslFrame + rhSize; /* may have more than one record */
5588 inRecordEnd = recordEnd;
5589
5590 /* Make sure cipher is on for client, if we get an application data packet
5591 * and handhsake is done for server. This workaround is required if client
5592 * handshake packets were missed, retransmitted or sent out of order. */
5593 if ((enum ContentType)rh.type == application_data &&
5594 ssl->options.handShakeDone && session->flags.serverCipherOn) {
5595 session->flags.clientCipherOn = 1;
5596 session->sslClient->options.handShakeState = HANDSHAKE_DONE;
5597 session->sslClient->options.handShakeDone = 1;
5598 }
5599
5600 /* decrypt if needed */
5601 if ((session->flags.side == WOLFSSL_SERVER_END &&
5602 session->flags.serverCipherOn)
5603 || (session->flags.side == WOLFSSL_CLIENT_END &&
5604 session->flags.clientCipherOn)) {
5605 int ivAdvance = 0; /* TLSv1.1 advance amount */
5606
5607 /* change_cipher_spec is not encrypted */
5608 if (rh.type == change_cipher_spec) {
5609 goto doPart;
5610 }
5611 if (ssl->decrypt.setup != 1) {
5612 SetError(DECRYPT_KEYS_NOT_SETUP, error, session, FATAL_ERROR_STATE);
5613 return -1;
5614 }
5615 if (CheckAvailableSize(ssl, rhSize) < 0) {
5616 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
5617 return -1;
5618 }
5619
5620 sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
5621 ssl->buffers.outputBuffer.buffer, &errCode,
5622 &ivAdvance, &rh);
5623 recordEnd = sslFrame - ivAdvance + rhSize; /* sslFrame moved so
5624 should recordEnd */
5625 decrypted = 1;
5626
5627 #ifdef WOLFSSL_SNIFFER_STATS
5628 if (errCode != 0) {
5629 INC_STAT(SnifferStats.sslKeyFails);
5630 }
5631 else {
5632 LOCK_STAT();
5633 NOLOCK_INC_STAT(SnifferStats.sslDecryptedPackets);
5634 NOLOCK_ADD_TO_STAT(SnifferStats.sslDecryptedBytes, sslBytes);
5635 UNLOCK_STAT();
5636 }
5637 #endif
5638 if (errCode != 0) {
5639 if ((enum ContentType)rh.type == application_data) {
5640 SetError(BAD_DECRYPT, error, session, FATAL_ERROR_STATE);
5641 return -1;
5642 }
5643 /* do not end session for failures on handshake packets */
5644 return 0;
5645 }
5646 }
5647
5648 doPart:
5649
5650 switch ((enum ContentType)rh.type) {
5651 case handshake:
5652 {
5653 int startIdx = sslBytes;
5654 int used;
5655
5656 Trace(GOT_HANDSHAKE_STR);
5657 ret = DoHandShake(sslFrame, &sslBytes, session, error, rhSize);
5658 if (ret != 0 || sslBytes > startIdx) {
5659 if (session->flags.fatalError == 0)
5660 SetError(BAD_HANDSHAKE_STR, error, session,
5661 FATAL_ERROR_STATE);
5662 return -1;
5663 }
5664
5665 /* DoHandShake now fully decrements sslBytes to remaining */
5666 used = startIdx - sslBytes;
5667 sslFrame += used;
5668 if (decrypted)
5669 sslFrame += ssl->keys.padSz;
5670 }
5671 break;
5672 case change_cipher_spec:
5673 if (session->flags.side == WOLFSSL_SERVER_END) {
5674 #ifdef WOLFSSL_TLS13
5675 if (IsAtLeastTLSv1_3(session->sslServer->version) && session->srvKs.key_len == 0) {
5676 session->flags.serverCipherOn = 0;
5677 }
5678 else
5679 #endif
5680 {
5681 session->flags.serverCipherOn = 1;
5682 }
5683 }
5684 else
5685 session->flags.clientCipherOn = 1;
5686 Trace(GOT_CHANGE_CIPHER_STR);
5687 ssl->options.handShakeState = HANDSHAKE_DONE;
5688 ssl->options.handShakeDone = 1;
5689
5690 sslFrame += 1;
5691 sslBytes -= 1;
5692
5693 break;
5694 case application_data:
5695 Trace(GOT_APP_DATA_STR);
5696 {
5697 word32 inOutIdx = 0;
5698
5699 ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx, SNIFF);
5700 if (ret == 0) {
5701 ret = ssl->buffers.clearOutputBuffer.length;
5702 TraceGotData(ret);
5703 if (ret) { /* may be blank message */
5704 if (data != NULL) {
5705 byte* tmpData; /* don't leak on realloc free */
5706 /* add an extra byte at end of allocation in case
5707 * user wants to null terminate plaintext */
5708 tmpData = (byte*)XREALLOC(*data, decoded + ret + 1,
5709 NULL, DYNAMIC_TYPE_TMP_BUFFER);
5710 if (tmpData == NULL) {
5711 ForceZero(*data, decoded);
5712 XFREE(*data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5713 *data = NULL;
5714 SetError(MEMORY_STR, error, session,
5715 FATAL_ERROR_STATE);
5716 return -1;
5717 }
5718 *data = tmpData;
5719 XMEMCPY(*data + decoded,
5720 ssl->buffers.clearOutputBuffer.buffer, ret);
5721 }
5722 else {
5723 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
5724 if (StoreDataCb) {
5725 const byte* buf;
5726 word32 offset = 0;
5727 word32 bufSz;
5728 int stored;
5729
5730 buf = ssl->buffers.clearOutputBuffer.buffer;
5731 bufSz = ssl->buffers.clearOutputBuffer.length;
5732 do {
5733 stored = StoreDataCb(buf, bufSz, offset,
5734 ctx);
5735 if (stored <= 0) {
5736 return -1;
5737 }
5738 offset += stored;
5739 } while (offset < bufSz);
5740 }
5741 else {
5742 SetError(STORE_DATA_CB_MISSING_STR, error,
5743 session, FATAL_ERROR_STATE);
5744 return -1;
5745 }
5746 #else
5747 (void)ctx;
5748 SetError(NO_DATA_DEST_STR, error, session,
5749 FATAL_ERROR_STATE);
5750 return -1;
5751 #endif
5752 }
5753 TraceAddedData(ret, decoded);
5754 decoded += ret;
5755 ssl->buffers.clearOutputBuffer.length = 0;
5756 }
5757 }
5758 else {
5759 /* set error, but do not treat fatal */
5760 SetError(BAD_APP_DATA_STR, error,session, 0);
5761 return -1;
5762 }
5763 if (ssl->buffers.outputBuffer.dynamicFlag)
5764 ShrinkOutputBuffer(ssl);
5765
5766 sslFrame += inOutIdx;
5767 sslBytes -= inOutIdx;
5768 }
5769 break;
5770 case alert:
5771 Trace(GOT_ALERT_STR);
5772 #ifdef WOLFSSL_SNIFFER_STATS
5773 INC_STAT(SnifferStats.sslAlerts);
5774 #endif
5775 sslFrame += rhSize;
5776 sslBytes -= rhSize;
5777 break;
5778 case no_type:
5779 default:
5780 SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);
5781 return -1;
5782 }
5783
5784 /* do we have another msg in record ? */
5785 if (sslFrame < recordEnd) {
5786 Trace(ANOTHER_MSG_STR);
5787 goto doPart;
5788 }
5789
5790 /* back to input stream instead of potential decrypt buffer */
5791 recordEnd = inRecordEnd;
5792
5793 /* do we have more records ? */
5794 if (recordEnd < end) {
5795 Trace(ANOTHER_MSG_STR);
5796 sslFrame = recordEnd;
5797 sslBytes = (int)(end - recordEnd);
5798 goto doMessage;
5799 }
5800
5801 /* clear used input */
5802 ssl->buffers.inputBuffer.length = 0;
5803
5804 /* could have more input ready now */
5805 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
5806 goto doMessage;
5807
5808 if (ssl->buffers.inputBuffer.dynamicFlag)
5809 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
5810
5811 return decoded;
5812 }
5813
5814
5815 /* See if we need to process any pending FIN captures */
5816 /* Return 0=normal, else = session removed */
5817 static int CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo,
5818 SnifferSession* session)
5819 {
5820 int ret = 0;
5821 if (session->finCapture.cliFinSeq && session->finCapture.cliFinSeq <=
5822 session->cliExpected) {
5823 if (session->finCapture.cliCounted == 0) {
5824 session->flags.finCount += 1;
5825 session->finCapture.cliCounted = 1;
5826 TraceClientFin(session->finCapture.cliFinSeq, session->cliExpected);
5827 }
5828 }
5829
5830 if (session->finCapture.srvFinSeq && session->finCapture.srvFinSeq <=
5831 session->srvExpected) {
5832 if (session->finCapture.srvCounted == 0) {
5833 session->flags.finCount += 1;
5834 session->finCapture.srvCounted = 1;
5835 TraceServerFin(session->finCapture.srvFinSeq, session->srvExpected);
5836 }
5837 }
5838
5839 if (session->flags.finCount >= 2) {
5840 RemoveSession(session, ipInfo, tcpInfo, 0);
5841 ret = 1;
5842 }
5843 return ret;
5844 }
5845
5846
5847 /* If session is in fatal error state free resources now
5848 return true if removed, 0 otherwise */
5849 static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
5850 SnifferSession* session, char* error)
5851 {
5852 if (session && session->flags.fatalError == FATAL_ERROR_STATE) {
5853 RemoveSession(session, ipInfo, tcpInfo, 0);
5854 SetError(FATAL_ERROR_STR, error, NULL, 0);
5855 return 1;
5856 }
5857 return 0;
5858 }
5859
5860
5861 /* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
5862 /* returns Number of bytes on success, 0 for no data yet, and
5863 * WOLFSSL_SNIFFER_ERROR on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state
5864 * error
5865 */
5866 static int ssl_DecodePacketInternal(const byte* packet, int length,
5867 void* vChain, word32 chainSz,
5868 byte** data, SSLInfo* sslInfo,
5869 void* ctx, char* error)
5870 {
5871 TcpInfo tcpInfo;
5872 IpInfo ipInfo;
5873 const byte* sslFrame;
5874 const byte* end;
5875 int sslBytes; /* ssl bytes unconsumed */
5876 int ret;
5877 SnifferSession* session = 0;
5878
5879 #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
5880 if (packet == NULL && vChain != NULL) {
5881 struct iovec* chain = (struct iovec*)vChain;
5882 word32 i;
5883
5884 length = 0;
5885 for (i = 0; i < chainSz; i++)
5886 length += chain[i].iov_len;
5887 packet = (const byte*)chain[0].iov_base;
5888 }
5889 #endif
5890
5891 if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
5892 error) != 0)
5893 return WOLFSSL_SNIFFER_ERROR;
5894
5895 end = sslFrame + sslBytes;
5896
5897 ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
5898 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
5899 return WOLFSSL_SNIFFER_FATAL_ERROR;
5900 else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
5901 else if (ret == 1) {
5902 #ifdef WOLFSSL_SNIFFER_STATS
5903 if (sslBytes > 0) {
5904 LOCK_STAT();
5905 NOLOCK_INC_STAT(SnifferStats.sslEncryptedPackets);
5906 NOLOCK_ADD_TO_STAT(SnifferStats.sslEncryptedBytes, sslBytes);
5907 UNLOCK_STAT();
5908 }
5909 else
5910 INC_STAT(SnifferStats.sslDecryptedPackets);
5911 #endif
5912 return 0; /* done for now */
5913 }
5914
5915 ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
5916 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
5917 return WOLFSSL_SNIFFER_FATAL_ERROR;
5918 else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
5919 else if (ret == 1) {
5920 #ifdef WOLFSSL_SNIFFER_STATS
5921 INC_STAT(SnifferStats.sslDecryptedPackets);
5922 #endif
5923 return 0; /* done for now */
5924 }
5925
5926 ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
5927 &end, vChain, chainSz, error);
5928 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
5929 return WOLFSSL_SNIFFER_FATAL_ERROR;
5930 else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
5931 else if (ret == 1) {
5932 #ifdef WOLFSSL_SNIFFER_STATS
5933 INC_STAT(SnifferStats.sslDecryptedPackets);
5934 #endif
5935 return 0; /* done for now */
5936 }
5937
5938 #ifdef WOLFSSL_SNIFFER_STATS
5939 if (sslBytes > 0) {
5940 LOCK_STAT();
5941 NOLOCK_INC_STAT(SnifferStats.sslEncryptedPackets);
5942 NOLOCK_ADD_TO_STAT(SnifferStats.sslEncryptedBytes, sslBytes);
5943 UNLOCK_STAT();
5944 }
5945 else
5946 INC_STAT(SnifferStats.sslDecryptedPackets);
5947 #endif
5948
5949 ret = ProcessMessage(sslFrame, session, sslBytes, data, end, ctx, error);
5950 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
5951 return WOLFSSL_SNIFFER_FATAL_ERROR;
5952 if (CheckFinCapture(&ipInfo, &tcpInfo, session) == 0) {
5953 CopySessionInfo(session, sslInfo);
5954 }
5955
5956 return ret;
5957 }
5958
5959
5960 /* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
5961 /* returns Number of bytes on success, 0 for no data yet, WOLFSSL_SNIFFER_ERROR.
5962 * on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state error */
5963 /* Also returns Session Info if available */
5964 int ssl_DecodePacketWithSessionInfo(const unsigned char* packet, int length,
5965 unsigned char** data, SSLInfo* sslInfo, char* error)
5966 {
5967 return ssl_DecodePacketInternal(packet, length, NULL, 0, data, sslInfo,
5968 NULL, error);
5969 }
5970
5971
5972 /* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
5973 /* returns Number of bytes on success, 0 for no data yet, WOLFSSL_SNIFFER_ERROR.
5974 * on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state error */
5975 int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
5976 {
5977 return ssl_DecodePacketInternal(packet, length, NULL, 0, data, NULL, NULL,
5978 error);
5979 }
5980
5981
5982 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
5983
5984 /* returns Number of bytes on success, 0 for no data yet, WOLFSSL_SNIFFER_ERROR.
5985 * on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state error */
5986 int ssl_DecodePacketWithSessionInfoStoreData(const unsigned char* packet,
5987 int length, void* ctx, SSLInfo* sslInfo, char* error)
5988 {
5989 return ssl_DecodePacketInternal(packet, length, NULL, 0, NULL, sslInfo,
5990 ctx, error);
5991 }
5992
5993 #endif
5994
5995
5996 #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
5997
5998 /* returns Number of bytes on success, 0 for no data yet, WOLFSSL_SNIFFER_ERROR.
5999 * on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state error */
6000 int ssl_DecodePacketWithChain(void* vChain, word32 chainSz, byte** data,
6001 char* error)
6002 {
6003 return ssl_DecodePacketInternal(NULL, 0, vChain, chainSz, data, NULL, NULL,
6004 error);
6005 }
6006
6007 #endif
6008
6009
6010 #if defined(WOLFSSL_SNIFFER_CHAIN_INPUT) && \
6011 defined(WOLFSSL_SNIFFER_STORE_DATA_CB)
6012
6013 /*
6014 * returns WOLFSSL_SNIFFER_ERROR on error and WOLFSSL_SNIFFER_FATAL_ERROR on
6015 * fatal state error
6016 */
6017 int ssl_DecodePacketWithChainSessionInfoStoreData(void* vChain, word32 chainSz,
6018 void* ctx, SSLInfo* sslInfo, char* error)
6019 {
6020 return ssl_DecodePacketInternal(NULL, 0, vChain, chainSz, NULL, sslInfo,
6021 ctx, error);
6022 }
6023
6024 #endif
6025
6026
6027 /* Deallocator for the decoded data buffer. */
6028 /* returns 0 on success, -1 on error */
6029 int ssl_FreeDecodeBuffer(byte** data, char* error)
6030 {
6031 return ssl_FreeZeroDecodeBuffer(data, 0, error);
6032 }
6033
6034
6035 /* Deallocator for the decoded data buffer, zeros out buffer. */
6036 /* returns 0 on success, -1 on error */
6037 int ssl_FreeZeroDecodeBuffer(byte** data, int sz, char* error)
6038 {
6039 (void)error;
6040
6041 if (sz < 0) {
6042 return -1;
6043 }
6044
6045 if (data != NULL) {
6046 ForceZero(*data, (word32)sz);
6047 XFREE(*data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6048 *data = NULL;
6049 }
6050
6051 return 0;
6052 }
6053
6054
6055 /* Enables (if traceFile)/ Disables debug tracing */
6056 /* returns 0 on success, -1 on error */
6057 int ssl_Trace(const char* traceFile, char* error)
6058 {
6059 if (traceFile) {
6060 /* Don't try to reopen the file */
6061 if (TraceFile == NULL) {
6062 TraceFile = XFOPEN(traceFile, "a");
6063 if (!TraceFile) {
6064 SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
6065 return -1;
6066 }
6067 TraceOn = 1;
6068 }
6069 }
6070 else
6071 TraceOn = 0;
6072
6073 return 0;
6074 }
6075
6076
6077 /* Enables/Disables Recovery of missed data if later packets allow
6078 * maxMemory is number of bytes to use for reassembly buffering per session,
6079 * -1 means unlimited
6080 * returns 0 on success, -1 on error */
6081 int ssl_EnableRecovery(int onOff, int maxMemory, char* error)
6082 {
6083 (void)error;
6084
6085 RecoveryEnabled = onOff;
6086 if (onOff)
6087 MaxRecoveryMemory = maxMemory;
6088
6089 return 0;
6090 }
6091
6092
6093
6094 #if defined(WOLFSSL_SESSION_STATS) && !defined(NO_SESSION_CACHE)
6095
6096 int ssl_GetSessionStats(unsigned int* active, unsigned int* total,
6097 unsigned int* peak, unsigned int* maxSessions,
6098 unsigned int* missedData, unsigned int* reassemblyMem,
6099 char* error)
6100 {
6101 int ret;
6102
6103 if (missedData) {
6104 wc_LockMutex(&RecoveryMutex);
6105 *missedData = MissedDataSessions;
6106 wc_UnLockMutex(&RecoveryMutex);
6107 }
6108
6109 if (reassemblyMem) {
6110 SnifferSession* session;
6111 int i;
6112
6113 *reassemblyMem = 0;
6114 wc_LockMutex(&SessionMutex);
6115 for (i = 0; i < HASH_SIZE; i++) {
6116 session = SessionTable[i];
6117 while (session) {
6118 *reassemblyMem += session->cliReassemblyMemory;
6119 *reassemblyMem += session->srvReassemblyMemory;
6120 session = session->next;
6121 }
6122 }
6123 wc_UnLockMutex(&SessionMutex);
6124 }
6125
6126 ret = wolfSSL_get_session_stats(active, total, peak, maxSessions);
6127
6128 if (ret == WOLFSSL_SUCCESS)
6129 return 0;
6130 else {
6131 SetError(BAD_SESSION_STATS, error, NULL, 0);
6132 return -1;
6133 }
6134 }
6135
6136 #endif
6137
6138
6139
6140 int ssl_SetConnectionCb(SSLConnCb cb)
6141 {
6142 ConnectionCb = cb;
6143 return 0;
6144 }
6145
6146
6147
6148 int ssl_SetConnectionCtx(void* ctx)
6149 {
6150 ConnectionCbCtx = ctx;
6151 return 0;
6152 }
6153
6154
6155 #ifdef WOLFSSL_SNIFFER_STATS
6156
6157 /* Resets the statistics tracking global structure.
6158 * returns 0 on success, -1 on error */
6159 int ssl_ResetStatistics(void)
6160 {
6161 wc_LockMutex(&StatsMutex);
6162 XMEMSET(&SnifferStats, 0, sizeof(SSLStats));
6163 wc_UnLockMutex(&StatsMutex);
6164 return 0;
6165 }
6166
6167
6168 /* Copies the SSL statistics into the provided stats record.
6169 * returns 0 on success, -1 on error */
6170 int ssl_ReadStatistics(SSLStats* stats)
6171 {
6172 if (stats == NULL)
6173 return -1;
6174
6175 LOCK_STAT();
6176 XMEMCPY(stats, &SnifferStats, sizeof(SSLStats));
6177 UNLOCK_STAT();
6178 return 0;
6179 }
6180
6181 /* Copies the SSL statistics into the provided stats record then
6182 * resets the statistics tracking global structure.
6183 * returns 0 on success, -1 on error */
6184 int ssl_ReadResetStatistics(SSLStats* stats)
6185 {
6186 if (stats == NULL)
6187 return -1;
6188
6189 LOCK_STAT();
6190 XMEMCPY(stats, &SnifferStats, sizeof(SSLStats));
6191 XMEMSET(&SnifferStats, 0, sizeof(SSLStats));
6192 UNLOCK_STAT();
6193 return 0;
6194 }
6195
6196 #endif /* WOLFSSL_SNIFFER_STATS */
6197
6198
6199 #ifdef WOLFSSL_SNIFFER_WATCH
6200
6201 int ssl_SetWatchKeyCallback_ex(SSLWatchCb cb, int devId, char* error)
6202 {
6203 #ifdef WOLF_CRYPTO_CB
6204 if (CryptoDeviceId == INVALID_DEVID)
6205 CryptoDeviceId = devId;
6206 #else
6207 (void)devId;
6208 #endif
6209 WatchCb = cb;
6210 return CreateWatchSnifferServer(error);
6211 }
6212
6213 int ssl_SetWatchKeyCallback(SSLWatchCb cb, char* error)
6214 {
6215 WatchCb = cb;
6216 return CreateWatchSnifferServer(error);
6217 }
6218
6219 int ssl_SetWatchKeyCtx(void* ctx, char* error)
6220 {
6221 (void)error;
6222 WatchCbCtx = ctx;
6223 return 0;
6224 }
6225
6226 int ssl_SetWatchKey_buffer(void* vSniffer, const byte* key, word32 keySz,
6227 int keyType, char* error)
6228 {
6229 SnifferSession* sniffer;
6230 int ret;
6231
6232 if (vSniffer == NULL) {
6233 return -1;
6234 }
6235 if (key == NULL || keySz == 0) {
6236 return -1;
6237 }
6238
6239 sniffer = (SnifferSession*)vSniffer;
6240 /* Remap the keyType from what the user can use to
6241 * what wolfSSL_use_PrivateKey_buffer expects. */
6242 keyType = (keyType == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
6243 WOLFSSL_FILETYPE_ASN1;
6244
6245 #ifdef WOLFSSL_STATIC_EPHEMERAL
6246 /* try setting static ephemeral first */
6247 /* auto detect key type with WC_PK_TYPE_NONE */
6248 ret = wolfSSL_set_ephemeral_key(sniffer->sslServer,
6249 WC_PK_TYPE_NONE, (const char*)key, keySz,
6250 WOLFSSL_FILETYPE_ASN1);
6251 if (ret != 0) {
6252 #ifdef DEBUG_SNIFFER
6253 /* print warnings */
6254 printf("key watch set ephemeral failed %d\n", ret);
6255 #endif
6256 }
6257 #endif
6258
6259 /* always try and load private key */
6260 ret = wolfSSL_use_PrivateKey_buffer(sniffer->sslServer,
6261 key, keySz, keyType);
6262
6263 if (ret != WOLFSSL_SUCCESS) {
6264 SetError(KEY_FILE_STR, error, sniffer, FATAL_ERROR_STATE);
6265 return -1;
6266 }
6267
6268 return 0;
6269 }
6270
6271 int ssl_SetWatchKey_file(void* vSniffer, const char* keyFile, int keyType,
6272 const char* password, char* error)
6273 {
6274 byte* keyBuf = NULL;
6275 word32 keyBufSz = 0;
6276 int ret;
6277
6278 if (vSniffer == NULL) {
6279 return -1;
6280 }
6281 if (keyFile == NULL) {
6282 return -1;
6283 }
6284
6285 /* Remap the keyType from what the user can use to
6286 * what LoadKeyFile expects. */
6287 keyType = (keyType == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
6288 WOLFSSL_FILETYPE_ASN1;
6289
6290 ret = LoadKeyFile(&keyBuf, &keyBufSz, keyFile, 0, keyType, password);
6291 if (ret < 0) {
6292 SetError(KEY_FILE_STR, error, NULL, 0);
6293 XFREE(keyBuf, NULL, DYNAMIC_TYPE_X509);
6294 return -1;
6295 }
6296
6297 ret = ssl_SetWatchKey_buffer(vSniffer, keyBuf, keyBufSz, FILETYPE_DER,
6298 error);
6299 XFREE(keyBuf, NULL, DYNAMIC_TYPE_X509);
6300
6301 return ret;
6302 }
6303
6304 #endif /* WOLFSSL_SNIFFER_WATCH */
6305
6306
6307 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
6308
6309 int ssl_SetStoreDataCallback(SSLStoreDataCb cb)
6310 {
6311 StoreDataCb = cb;
6312 return 0;
6313 }
6314
6315 #endif /* WOLFSSL_SNIFFER_STORE_DATA_CB */
6316
6317 #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
6318 int ssl_SetKeyCallback(SSLKeyCb cb, void* cbCtx)
6319 {
6320 KeyCb = cb;
6321 KeyCbCtx = cbCtx;
6322 return 0;
6323 }
6324 #endif
6325
6326 #endif /* WOLFSSL_SNIFFER */
6327 #endif /* WOLFCRYPT_ONLY */
6328