source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/sniffer.c

Last change on this file was 464, checked in by coas-nagasima, 3 years ago

WolfSSLとAzure IoT SDKを更新

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