source: UsbWattMeter/trunk/wolfssl-3.7.0/src/sniffer.c@ 167

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

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 99.0 KB
RevLine 
[164]1/* sniffer.c
2 *
3 * Copyright (C) 2006-2015 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
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-1301, USA
20 */
21
22#ifdef HAVE_CONFIG_H
23 #include <config.h>
24#endif
25
26#include <wolfssl/wolfcrypt/settings.h>
27
28#ifndef WOLFCRYPT_ONLY
29#ifdef WOLFSSL_SNIFFER
30
31#include <assert.h>
32#include <time.h>
33
34#ifndef _WIN32
35 #include <arpa/inet.h>
36#endif
37
38#ifdef _WIN32
39 #define SNPRINTF _snprintf
40#else
41 #define SNPRINTF snprintf
42#endif
43
44#include <wolfssl/openssl/ssl.h>
45#include <wolfssl/internal.h>
46#include <wolfssl/error-ssl.h>
47#include <wolfssl/sniffer.h>
48#include <wolfssl/sniffer_error.h>
49#ifdef NO_INLINE
50 #include <wolfssl/wolfcrypt/misc.h>
51#else
52 #include <wolfcrypt/src/misc.c>
53#endif
54
55
56#ifndef WOLFSSL_HAVE_MIN
57#define WOLFSSL_HAVE_MIN
58
59static INLINE word32 min(word32 a, word32 b)
60{
61 return a > b ? b : a;
62}
63
64#endif /* WOLFSSL_HAVE_MIN */
65
66#ifndef WOLFSSL_SNIFFER_TIMEOUT
67 #define WOLFSSL_SNIFFER_TIMEOUT 900
68 /* Cache unclosed Sessions for 15 minutes since last used */
69#endif
70
71/* Misc constants */
72enum {
73 MAX_SERVER_ADDRESS = 128, /* maximum server address length */
74 MAX_SERVER_NAME = 128, /* maximum server name length */
75 MAX_ERROR_LEN = 80, /* maximum error length */
76 ETHER_IF_ADDR_LEN = 6, /* ethernet interface address length */
77 LOCAL_IF_ADDR_LEN = 4, /* localhost interface address length, !windows */
78 TCP_PROTO = 6, /* TCP_PROTOCOL */
79 IP_HDR_SZ = 20, /* IP header legnth, min */
80 TCP_HDR_SZ = 20, /* TCP header legnth, min */
81 IPV4 = 4, /* IP version 4 */
82 TCP_PROTOCOL = 6, /* TCP Protocol id */
83 TRACE_MSG_SZ = 80, /* Trace Message buffer size */
84 HASH_SIZE = 499, /* Session Hash Table Rows */
85 PSEUDO_HDR_SZ = 12, /* TCP Pseudo Header size in bytes */
86 FATAL_ERROR_STATE = 1, /* SnifferSession fatal error state */
87 TICKET_HINT_LEN = 4, /* Session Ticket Hint length */
88 EXT_TYPE_SZ = 2, /* Extension length */
89 MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
90 MTU_EXTRA, /* Max input sz of reassembly */
91 TICKET_EXT_ID = 0x23 /* Session Ticket Extension ID */
92};
93
94
95#ifdef _WIN32
96
97static HMODULE dllModule; /* for error string resources */
98
99BOOL APIENTRY DllMain( HMODULE hModule,
100 DWORD ul_reason_for_call,
101 LPVOID lpReserved
102 )
103{
104 static int didInit = 0;
105
106 switch (ul_reason_for_call)
107 {
108 case DLL_PROCESS_ATTACH:
109 if (didInit == 0) {
110 dllModule = hModule;
111 ssl_InitSniffer();
112 didInit = 1;
113 }
114 break;
115 case DLL_THREAD_ATTACH:
116 break;
117 case DLL_THREAD_DETACH:
118 break;
119 case DLL_PROCESS_DETACH:
120 if (didInit) {
121 ssl_FreeSniffer();
122 didInit = 0;
123 }
124 break;
125 }
126 return TRUE;
127}
128
129#endif /* _WIN32 */
130
131
132static int TraceOn = 0; /* Trace is off by default */
133static FILE* TraceFile = 0;
134
135
136/* windows uses .rc table for this */
137#ifndef _WIN32
138
139static const char* const msgTable[] =
140{
141 /* 1 */
142 "Out of Memory",
143 "New SSL Sniffer Server Registered",
144 "Checking IP Header",
145 "SSL Sniffer Server Not Registered",
146 "Checking TCP Header",
147
148 /* 6 */
149 "SSL Sniffer Server Port Not Registered",
150 "RSA Private Decrypt Error",
151 "RSA Private Decode Error",
152 "Set Cipher Spec Error",
153 "Server Hello Input Malformed",
154
155 /* 11 */
156 "Couldn't Resume Session Error",
157 "Server Did Resumption",
158 "Client Hello Input Malformed",
159 "Client Trying to Resume",
160 "Handshake Input Malformed",
161
162 /* 16 */
163 "Got Hello Verify msg",
164 "Got Server Hello msg",
165 "Got Cert Request msg",
166 "Got Server Key Exchange msg",
167 "Got Cert msg",
168
169 /* 21 */
170 "Got Server Hello Done msg",
171 "Got Finished msg",
172 "Got Client Hello msg",
173 "Got Client Key Exchange msg",
174 "Got Cert Verify msg",
175
176 /* 26 */
177 "Got Unknown Handshake msg",
178 "New SSL Sniffer Session created",
179 "Couldn't create new SSL",
180 "Got a Packet to decode",
181 "No data present",
182
183 /* 31 */
184 "Session Not Found",
185 "Got an Old Client Hello msg",
186 "Old Client Hello Input Malformed",
187 "Old Client Hello OK",
188 "Bad Old Client Hello",
189
190 /* 36 */
191 "Bad Record Header",
192 "Record Header Input Malformed",
193 "Got a HandShake msg",
194 "Bad HandShake msg",
195 "Got a Change Cipher Spec msg",
196
197 /* 41 */
198 "Got Application Data msg",
199 "Bad Application Data",
200 "Got an Alert msg",
201 "Another msg to Process",
202 "Removing Session From Table",
203
204 /* 46 */
205 "Bad Key File",
206 "Wrong IP Version",
207 "Wrong Protocol type",
208 "Packet Short for header processing",
209 "Got Unknown Record Type",
210
211 /* 51 */
212 "Can't Open Trace File",
213 "Session in Fatal Error State",
214 "Partial SSL record received",
215 "Buffer Error, malformed input",
216 "Added to Partial Input",
217
218 /* 56 */
219 "Received a Duplicate Packet",
220 "Received an Out of Order Packet",
221 "Received an Overlap Duplicate Packet",
222 "Received an Overlap Reassembly Begin Duplicate Packet",
223 "Received an Overlap Reassembly End Duplicate Packet",
224
225 /* 61 */
226 "Missed the Client Hello Entirely",
227 "Got Hello Request msg",
228 "Got Session Ticket msg",
229 "Bad Input",
230 "Bad Decrypt Type",
231
232 /* 66 */
233 "Bad Finished Message Processing",
234 "Bad Compression Type",
235 "Bad DeriveKeys Error",
236 "Saw ACK for Missing Packet Error",
237 "Bad Decrypt Operation",
238
239 /* 71 */
240 "Decrypt Keys Not Set Up",
241 "Late Key Load Error",
242 "Got Certificate Status msg",
243 "RSA Key Missing Error",
244 "Secure Renegotiation Not Supported",
245
246 /* 76 */
247 "Get Session Stats Failure",
248 "Reassembly Buffer Size Exceeded",
249 "Dropping Lost Fragment",
250 "Dropping Partial Record",
251 "Clear ACK Fault",
252
253 /* 81 */
254 "Bad Decrypt Size"
255};
256
257
258/* *nix version uses table above */
259static void GetError(int idx, char* str)
260{
261 XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN);
262}
263
264
265#else /* _WIN32 */
266
267
268/* Windows version uses .rc table */
269static void GetError(int idx, char* buffer)
270{
271 if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
272 buffer[0] = 0;
273}
274
275
276#endif /* _WIN32 */
277
278
279/* Packet Buffer for reassembly list and ready list */
280typedef struct PacketBuffer {
281 word32 begin; /* relative sequence begin */
282 word32 end; /* relative sequence end */
283 byte* data; /* actual data */
284 struct PacketBuffer* next; /* next on reassembly list or ready list */
285} PacketBuffer;
286
287
288#ifdef HAVE_SNI
289
290/* NamedKey maps a SNI name to a specific private key */
291typedef struct NamedKey {
292 char name[MAX_SERVER_NAME]; /* server DNS name */
293 word32 nameSz; /* size of server DNS name */
294 byte* key; /* DER private key */
295 word32 keySz; /* size of DER private key */
296 struct NamedKey* next; /* for list */
297} NamedKey;
298
299#endif
300
301
302/* Sniffer Server holds info for each server/port monitored */
303typedef struct SnifferServer {
304 SSL_CTX* ctx; /* SSL context */
305 char address[MAX_SERVER_ADDRESS]; /* passed in server address */
306 word32 server; /* netowrk order address */
307 int port; /* server port */
308#ifdef HAVE_SNI
309 NamedKey* namedKeys; /* mapping of names and keys */
310 wolfSSL_Mutex namedKeysMutex; /* mutex for namedKey list */
311#endif
312 struct SnifferServer* next; /* for list */
313} SnifferServer;
314
315
316/* Session Flags */
317typedef struct Flags {
318 byte side; /* which end is current packet headed */
319 byte serverCipherOn; /* indicates whether cipher is active */
320 byte clientCipherOn; /* indicates whether cipher is active */
321 byte resuming; /* did this session come from resumption */
322 byte cached; /* have we cached this session yet */
323 byte clientHello; /* processed client hello yet, for SSLv2 */
324 byte finCount; /* get both FINs before removing */
325 byte fatalError; /* fatal error state */
326 byte cliAckFault; /* client acked unseen data from server */
327 byte srvAckFault; /* server acked unseen data from client */
328 byte cliSkipPartial; /* client skips partial data to catch up */
329 byte srvSkipPartial; /* server skips partial data to catch up */
330} Flags;
331
332
333/* Out of Order FIN caputre */
334typedef struct FinCaputre {
335 word32 cliFinSeq; /* client relative sequence FIN 0 is no */
336 word32 srvFinSeq; /* server relative sequence FIN, 0 is no */
337 byte cliCounted; /* did we count yet, detects duplicates */
338 byte srvCounted; /* did we count yet, detects duplicates */
339} FinCaputre;
340
341
342/* Sniffer Session holds info for each client/server SSL/TLS session */
343typedef struct SnifferSession {
344 SnifferServer* context; /* server context */
345 SSL* sslServer; /* SSL server side decode */
346 SSL* sslClient; /* SSL client side decode */
347 word32 server; /* server address in network byte order */
348 word32 client; /* client address in network byte order */
349 word16 srvPort; /* server port */
350 word16 cliPort; /* client port */
351 word32 cliSeqStart; /* client start sequence */
352 word32 srvSeqStart; /* server start sequence */
353 word32 cliExpected; /* client expected sequence (relative) */
354 word32 srvExpected; /* server expected sequence (relative) */
355 FinCaputre finCaputre; /* retain out of order FIN s */
356 Flags flags; /* session flags */
357 time_t lastUsed; /* last used ticks */
358 PacketBuffer* cliReassemblyList; /* client out of order packets */
359 PacketBuffer* srvReassemblyList; /* server out of order packets */
360 word32 cliReassemblyMemory; /* client packet memory used */
361 word32 srvReassemblyMemory; /* server packet memory used */
362 struct SnifferSession* next; /* for hash table list */
363 byte* ticketID; /* mac ID of session ticket */
364} SnifferSession;
365
366
367/* Sniffer Server List and mutex */
368static SnifferServer* ServerList = 0;
369static wolfSSL_Mutex ServerListMutex;
370
371
372/* Session Hash Table, mutex, and count */
373static SnifferSession* SessionTable[HASH_SIZE];
374static wolfSSL_Mutex SessionMutex;
375static int SessionCount = 0;
376
377/* Recovery of missed data switches and stats */
378static wolfSSL_Mutex RecoveryMutex; /* for stats */
379static int RecoveryEnabled = 0; /* global switch */
380static int MaxRecoveryMemory = -1; /* per session max recovery memory */
381static word32 MissedDataSessions = 0; /* # of sessions with missed data */
382
383
384static void UpdateMissedDataSessions(void)
385{
386 LockMutex(&RecoveryMutex);
387 MissedDataSessions += 1;
388 UnLockMutex(&RecoveryMutex);
389}
390
391
392/* Initialize overall Sniffer */
393void ssl_InitSniffer(void)
394{
395 wolfSSL_Init();
396 InitMutex(&ServerListMutex);
397 InitMutex(&SessionMutex);
398 InitMutex(&RecoveryMutex);
399}
400
401
402#ifdef HAVE_SNI
403
404/* Free Named Key and the zero out the private key it holds */
405static void FreeNamedKey(NamedKey* in)
406{
407 if (in) {
408 if (in->key) {
409 ForceZero(in->key, in->keySz);
410 free(in->key);
411 }
412 free(in);
413 }
414}
415
416
417static void FreeNamedKeyList(NamedKey* in)
418{
419 NamedKey* next;
420
421 while (in) {
422 next = in->next;
423 FreeNamedKey(in);
424 in = next;
425 }
426}
427
428#endif
429
430
431/* Free Sniffer Server's resources/self */
432static void FreeSnifferServer(SnifferServer* srv)
433{
434 if (srv) {
435#ifdef HAVE_SNI
436 LockMutex(&srv->namedKeysMutex);
437 FreeNamedKeyList(srv->namedKeys);
438 UnLockMutex(&srv->namedKeysMutex);
439 FreeMutex(&srv->namedKeysMutex);
440#endif
441 SSL_CTX_free(srv->ctx);
442 }
443 free(srv);
444}
445
446
447/* free PacketBuffer's resources/self */
448static void FreePacketBuffer(PacketBuffer* del)
449{
450 if (del) {
451 free(del->data);
452 free(del);
453 }
454}
455
456
457/* remove PacketBuffer List */
458static void FreePacketList(PacketBuffer* in)
459{
460 if (in) {
461 PacketBuffer* del;
462 PacketBuffer* packet = in;
463
464 while (packet) {
465 del = packet;
466 packet = packet->next;
467 FreePacketBuffer(del);
468 }
469 }
470}
471
472
473/* Free Sniffer Session's resources/self */
474static void FreeSnifferSession(SnifferSession* session)
475{
476 if (session) {
477 SSL_free(session->sslClient);
478 SSL_free(session->sslServer);
479
480 FreePacketList(session->cliReassemblyList);
481 FreePacketList(session->srvReassemblyList);
482
483 free(session->ticketID);
484 }
485 free(session);
486}
487
488
489/* Free overall Sniffer */
490void ssl_FreeSniffer(void)
491{
492 SnifferServer* srv;
493 SnifferServer* removeServer;
494 SnifferSession* session;
495 SnifferSession* removeSession;
496 int i;
497
498 LockMutex(&ServerListMutex);
499 LockMutex(&SessionMutex);
500
501 srv = ServerList;
502 while (srv) {
503 removeServer = srv;
504 srv = srv->next;
505 FreeSnifferServer(removeServer);
506 }
507
508 for (i = 0; i < HASH_SIZE; i++) {
509 session = SessionTable[i];
510 while (session) {
511 removeSession = session;
512 session = session->next;
513 FreeSnifferSession(removeSession);
514 }
515 }
516
517 UnLockMutex(&SessionMutex);
518 UnLockMutex(&ServerListMutex);
519
520 FreeMutex(&RecoveryMutex);
521 FreeMutex(&SessionMutex);
522 FreeMutex(&ServerListMutex);
523
524 if (TraceFile) {
525 TraceOn = 0;
526 fclose(TraceFile);
527 TraceFile = NULL;
528 }
529
530 wolfSSL_Cleanup();
531}
532
533
534/* Initialize a SnifferServer */
535static void InitSnifferServer(SnifferServer* sniffer)
536{
537 sniffer->ctx = 0;
538 XMEMSET(sniffer->address, 0, MAX_SERVER_ADDRESS);
539 sniffer->server = 0;
540 sniffer->port = 0;
541#ifdef HAVE_SNI
542 sniffer->namedKeys = 0;
543 InitMutex(&sniffer->namedKeysMutex);
544#endif
545 sniffer->next = 0;
546}
547
548
549/* Initialize session flags */
550static void InitFlags(Flags* flags)
551{
552 flags->side = 0;
553 flags->serverCipherOn = 0;
554 flags->clientCipherOn = 0;
555 flags->resuming = 0;
556 flags->cached = 0;
557 flags->clientHello = 0;
558 flags->finCount = 0;
559 flags->fatalError = 0;
560 flags->cliAckFault = 0;
561 flags->srvAckFault = 0;
562 flags->cliSkipPartial = 0;
563 flags->srvSkipPartial = 0;
564}
565
566
567/* Initialize FIN Capture */
568static void InitFinCapture(FinCaputre* cap)
569{
570 cap->cliFinSeq = 0;
571 cap->srvFinSeq = 0;
572 cap->cliCounted = 0;
573 cap->srvCounted = 0;
574}
575
576
577/* Initialize a Sniffer Session */
578static void InitSession(SnifferSession* session)
579{
580 session->context = 0;
581 session->sslServer = 0;
582 session->sslClient = 0;
583 session->server = 0;
584 session->client = 0;
585 session->srvPort = 0;
586 session->cliPort = 0;
587 session->cliSeqStart = 0;
588 session->srvSeqStart = 0;
589 session->cliExpected = 0;
590 session->srvExpected = 0;
591 session->lastUsed = 0;
592 session->cliReassemblyList = 0;
593 session->srvReassemblyList = 0;
594 session->cliReassemblyMemory = 0;
595 session->srvReassemblyMemory = 0;
596 session->next = 0;
597 session->ticketID = 0;
598
599 InitFlags(&session->flags);
600 InitFinCapture(&session->finCaputre);
601}
602
603
604/* IP Info from IP Header */
605typedef struct IpInfo {
606 int length; /* length of this header */
607 int total; /* total length of fragment */
608 word32 src; /* network order source address */
609 word32 dst; /* network order destination address */
610} IpInfo;
611
612
613/* TCP Info from TCP Header */
614typedef struct TcpInfo {
615 int srcPort; /* source port */
616 int dstPort; /* source port */
617 int length; /* length of this header */
618 word32 sequence; /* sequence number */
619 word32 ackNumber; /* ack number */
620 byte fin; /* FIN set */
621 byte rst; /* RST set */
622 byte syn; /* SYN set */
623 byte ack; /* ACK set */
624} TcpInfo;
625
626
627/* Tcp Pseudo Header for Checksum calculation */
628typedef struct TcpPseudoHdr {
629 word32 src; /* source address */
630 word32 dst; /* destination address */
631 byte rsv; /* reserved, always 0 */
632 byte protocol; /* IP protocol */
633 word16 legnth; /* tcp header length + data length (doesn't include */
634 /* pseudo header length) network order */
635} TcpPseudoHdr;
636
637
638/* Password Setting Callback */
639static int SetPassword(char* passwd, int sz, int rw, void* userdata)
640{
641 (void)rw;
642 XSTRNCPY(passwd, (const char*)userdata, sz);
643 return (int)XSTRLEN((const char*)userdata);
644}
645
646
647/* Ethernet Header */
648typedef struct EthernetHdr {
649 byte dst[ETHER_IF_ADDR_LEN]; /* destination host address */
650 byte src[ETHER_IF_ADDR_LEN]; /* source host address */
651 word16 type; /* IP, ARP, etc */
652} EthernetHdr;
653
654
655/* IP Header */
656typedef struct IpHdr {
657 byte ver_hl; /* version/header length */
658 byte tos; /* type of service */
659 word16 length; /* total length */
660 word16 id; /* identification */
661 word16 offset; /* fragment offset field */
662 byte ttl; /* time to live */
663 byte protocol; /* protocol */
664 word16 sum; /* checksum */
665 word32 src; /* source address */
666 word32 dst; /* destination address */
667} IpHdr;
668
669
670#define IP_HL(ip) ( (((ip)->ver_hl) & 0x0f) * 4)
671#define IP_V(ip) ( ((ip)->ver_hl) >> 4)
672
673/* TCP Header */
674typedef struct TcpHdr {
675 word16 srcPort; /* source port */
676 word16 dstPort; /* destination port */
677 word32 sequence; /* sequence number */
678 word32 ack; /* acknoledgment number */
679 byte offset; /* data offset, reserved */
680 byte flags; /* option flags */
681 word16 window; /* window */
682 word16 sum; /* checksum */
683 word16 urgent; /* urgent pointer */
684} TcpHdr;
685
686#define TCP_LEN(tcp) ( (((tcp)->offset & 0xf0) >> 4) * 4)
687#define TCP_FIN 0x01
688#define TCP_SYN 0x02
689#define TCP_RST 0x04
690#define TCP_ACK 0x10
691
692
693
694
695
696/* Use platform specific GetError to write to tracfile if tracing */
697static void Trace(int idx)
698{
699 if (TraceOn) {
700 char myBuffer[MAX_ERROR_LEN];
701 GetError(idx, myBuffer);
702 fprintf(TraceFile, "\t%s\n", myBuffer);
703#ifdef DEBUG_SNIFFER
704 fprintf(stderr, "\t%s\n", myBuffer);
705#endif
706 }
707}
708
709
710/* Show TimeStamp for beginning of packet Trace */
711static void TraceHeader(void)
712{
713 if (TraceOn) {
714 time_t ticks = time(NULL);
715 fprintf(TraceFile, "\n%s", ctime(&ticks));
716 }
717}
718
719
720/* Show Set Server info for Trace */
721static void TraceSetServer(const char* srv, int port, const char* keyFile)
722{
723 if (TraceOn) {
724 fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
725 fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
726 keyFile);
727 }
728}
729
730
731#ifdef HAVE_SNI
732
733/* Show Set Named Server info for Trace */
734static void TraceSetNamedServer(const char* name,
735 const char* srv, int port, const char* keyFile)
736{
737 if (TraceOn) {
738 fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
739 fprintf(TraceFile, "\tname: %s, server: %s, port: %d, keyFile: %s\n",
740 name, srv, port, keyFile);
741 }
742}
743
744#endif
745
746
747/* Trace got packet number */
748static void TracePacket(void)
749{
750 if (TraceOn) {
751 static word32 packetNumber = 0;
752 fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n",
753 ++packetNumber);
754 }
755}
756
757
758/* Convert network byte order address into human readable */
759static char* IpToS(word32 addr, char* str)
760{
761 byte* p = (byte*)&addr;
762
763 SNPRINTF(str, TRACE_MSG_SZ, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
764
765 return str;
766}
767
768
769/* Show destination and source address from Ip Hdr for packet Trace */
770static void TraceIP(IpHdr* iphdr)
771{
772 if (TraceOn) {
773 char src[TRACE_MSG_SZ];
774 char dst[TRACE_MSG_SZ];
775 fprintf(TraceFile, "\tdst:%s src:%s\n", IpToS(iphdr->dst, dst),
776 IpToS(iphdr->src, src));
777 }
778}
779
780
781/* Show destination and source port from Tcp Hdr for packet Trace */
782static void TraceTcp(TcpHdr* tcphdr)
783{
784 if (TraceOn) {
785 fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort),
786 ntohs(tcphdr->srcPort));
787 }
788}
789
790
791/* Show sequence and payload length for Trace */
792static void TraceSequence(word32 seq, int len)
793{
794 if (TraceOn) {
795 fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
796 }
797}
798
799
800/* Show sequence and payload length for Trace */
801static void TraceAck(word32 ack, word32 expected)
802{
803 if (TraceOn) {
804 fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected);
805 }
806}
807
808
809/* Show relative expected and relative received sequences */
810static void TraceRelativeSequence(word32 expected, word32 got)
811{
812 if (TraceOn) {
813 fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
814 expected, got);
815 }
816}
817
818
819/* Show server sequence startup from SYN */
820static void TraceServerSyn(word32 seq)
821{
822 if (TraceOn) {
823 fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
824 }
825}
826
827
828/* Show client sequence startup from SYN */
829static void TraceClientSyn(word32 seq)
830{
831 if (TraceOn) {
832 fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
833 }
834}
835
836
837/* Show client FIN capture */
838static void TraceClientFin(word32 finSeq, word32 relSeq)
839{
840 if (TraceOn) {
841 fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
842 finSeq, relSeq);
843 }
844}
845
846
847/* Show server FIN capture */
848static void TraceServerFin(word32 finSeq, word32 relSeq)
849{
850 if (TraceOn) {
851 fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
852 finSeq, relSeq);
853 }
854}
855
856
857/* Show number of SSL data bytes decoded, could be 0 (ok) */
858static void TraceGotData(int bytes)
859{
860 if (TraceOn) {
861 fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
862 }
863}
864
865
866/* Show bytes added to old SSL App data */
867static void TraceAddedData(int newBytes, int existingBytes)
868{
869 if (TraceOn) {
870 fprintf(TraceFile,
871 "\t%d bytes added to %d exisiting bytes in User Buffer\n",
872 newBytes, existingBytes);
873 }
874}
875
876
877/* Show Stale Session */
878static void TraceStaleSession(void)
879{
880 if (TraceOn) {
881 fprintf(TraceFile, "\tFound a stale session\n");
882 }
883}
884
885
886/* Show Finding Stale Sessions */
887static void TraceFindingStale(void)
888{
889 if (TraceOn) {
890 fprintf(TraceFile, "\tTrying to find Stale Sessions\n");
891 }
892}
893
894
895/* Show Removed Session */
896static void TraceRemovedSession(void)
897{
898 if (TraceOn) {
899 fprintf(TraceFile, "\tRemoved it\n");
900 }
901}
902
903
904/* Set user error string */
905static void SetError(int idx, char* error, SnifferSession* session, int fatal)
906{
907 GetError(idx, error);
908 Trace(idx);
909 if (session && fatal == FATAL_ERROR_STATE)
910 session->flags.fatalError = 1;
911}
912
913
914/* See if this IPV4 network order address has been registered */
915/* return 1 is true, 0 is false */
916static int IsServerRegistered(word32 addr)
917{
918 int ret = 0; /* false */
919 SnifferServer* sniffer;
920
921 LockMutex(&ServerListMutex);
922
923 sniffer = ServerList;
924 while (sniffer) {
925 if (sniffer->server == addr) {
926 ret = 1;
927 break;
928 }
929 sniffer = sniffer->next;
930 }
931
932 UnLockMutex(&ServerListMutex);
933
934 return ret;
935}
936
937
938/* See if this port has been registered to watch */
939/* return 1 is true, 0 is false */
940static int IsPortRegistered(word32 port)
941{
942 int ret = 0; /* false */
943 SnifferServer* sniffer;
944
945 LockMutex(&ServerListMutex);
946
947 sniffer = ServerList;
948 while (sniffer) {
949 if (sniffer->port == (int)port) {
950 ret = 1;
951 break;
952 }
953 sniffer = sniffer->next;
954 }
955
956 UnLockMutex(&ServerListMutex);
957
958 return ret;
959}
960
961
962/* Get SnifferServer from IP and Port */
963static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
964{
965 SnifferServer* sniffer;
966
967 LockMutex(&ServerListMutex);
968
969 sniffer = ServerList;
970 while (sniffer) {
971 if (sniffer->port == tcpInfo->srcPort && sniffer->server == ipInfo->src)
972 break;
973 if (sniffer->port == tcpInfo->dstPort && sniffer->server == ipInfo->dst)
974 break;
975 sniffer = sniffer->next;
976 }
977
978 UnLockMutex(&ServerListMutex);
979
980 return sniffer;
981}
982
983
984/* Hash the Session Info, return hash row */
985static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
986{
987 word32 hash = ipInfo->src * ipInfo->dst;
988 hash *= tcpInfo->srcPort * tcpInfo->dstPort;
989
990 return hash % HASH_SIZE;
991}
992
993
994/* Get Exisiting SnifferSession from IP and Port */
995static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
996{
997 SnifferSession* session;
998 time_t currTime = time(NULL);
999 word32 row = SessionHash(ipInfo, tcpInfo);
1000
1001 assert(row <= HASH_SIZE);
1002
1003 LockMutex(&SessionMutex);
1004
1005 session = SessionTable[row];
1006 while (session) {
1007 if (session->server == ipInfo->src && session->client == ipInfo->dst &&
1008 session->srvPort == tcpInfo->srcPort &&
1009 session->cliPort == tcpInfo->dstPort)
1010 break;
1011 if (session->client == ipInfo->src && session->server == ipInfo->dst &&
1012 session->cliPort == tcpInfo->srcPort &&
1013 session->srvPort == tcpInfo->dstPort)
1014 break;
1015
1016 session = session->next;
1017 }
1018
1019 if (session)
1020 session->lastUsed= currTime; /* keep session alive, remove stale will */
1021 /* leave alone */
1022 UnLockMutex(&SessionMutex);
1023
1024 /* determine side */
1025 if (session) {
1026 if (ipInfo->dst == session->context->server &&
1027 tcpInfo->dstPort == session->context->port)
1028 session->flags.side = WOLFSSL_SERVER_END;
1029 else
1030 session->flags.side = WOLFSSL_CLIENT_END;
1031 }
1032
1033 return session;
1034}
1035
1036
1037#ifdef HAVE_SNI
1038
1039static int LoadKeyFile(byte** keyBuf, word32* keyBufSz,
1040 const char* keyFile, int typeKey,
1041 const char* password)
1042{
1043 byte* loadBuf;
1044 byte* saveBuf;
1045 long fileSz = 0;
1046 int saveBufSz;
1047 XFILE file;
1048 int ret;
1049
1050 if (keyBuf == NULL || keyBufSz == NULL || keyFile == NULL) {
1051 return -1;
1052 }
1053
1054 file = XFOPEN(keyFile, "rb");
1055 if (file == XBADFILE) return -1;
1056 XFSEEK(file, 0, XSEEK_END);
1057 fileSz = XFTELL(file);
1058 XREWIND(file);
1059
1060 loadBuf = (byte*)malloc(fileSz);
1061 if (loadBuf == NULL) {
1062 XFCLOSE(file);
1063 return -1;
1064 }
1065
1066 ret = (int)XFREAD(loadBuf, fileSz, 1, file);
1067 XFCLOSE(file);
1068
1069 if (typeKey == SSL_FILETYPE_PEM) {
1070 saveBuf = (byte*)malloc(fileSz);
1071
1072 saveBufSz = wolfSSL_KeyPemToDer(loadBuf, (int)fileSz,
1073 saveBuf, (int)fileSz, password);
1074 free(loadBuf);
1075
1076 *keyBuf = saveBuf;
1077 *keyBufSz = (word32)saveBufSz;
1078 }
1079 else {
1080 *keyBuf = loadBuf;
1081 *keyBufSz = (word32)fileSz;
1082 }
1083
1084
1085 if (ret < 0) {
1086 return -1;
1087 }
1088
1089 return ret;
1090}
1091
1092#endif
1093
1094
1095static int SetNamedPrivateKey(const char* name, const char* address, int port,
1096 const char* keyFile, int typeKey, const char* password, char* error)
1097{
1098 SnifferServer* sniffer;
1099 int ret;
1100 int type = (typeKey == FILETYPE_PEM) ? SSL_FILETYPE_PEM :
1101 SSL_FILETYPE_ASN1;
1102 int isNew = 0;
1103 word32 serverIp;
1104
1105#ifdef HAVE_SNI
1106 NamedKey* namedKey = NULL;
1107#endif
1108
1109 (void)name;
1110#ifdef HAVE_SNI
1111 if (name != NULL) {
1112 namedKey = (NamedKey*)malloc(sizeof(NamedKey));
1113 if (namedKey == NULL) {
1114 SetError(MEMORY_STR, error, NULL, 0);
1115 return -1;
1116 }
1117 XMEMSET(namedKey, 0, sizeof(NamedKey));
1118
1119 namedKey->nameSz = (word32)XSTRLEN(name);
1120 XSTRNCPY(namedKey->name, name, sizeof(namedKey->name));
1121 if (namedKey->nameSz >= sizeof(namedKey->name)) {
1122 namedKey->nameSz = sizeof(namedKey->name) - 1;
1123 namedKey->name[namedKey->nameSz] = '\0';
1124 }
1125
1126 ret = LoadKeyFile(&namedKey->key, &namedKey->keySz,
1127 keyFile, type, password);
1128 if (ret < 0) {
1129 SetError(KEY_FILE_STR, error, NULL, 0);
1130 FreeNamedKey(namedKey);
1131 return -1;
1132 }
1133 }
1134#endif
1135
1136 serverIp = inet_addr(address);
1137 sniffer = ServerList;
1138 while (sniffer != NULL &&
1139 (sniffer->server != serverIp || sniffer->port != port)) {
1140 sniffer = sniffer->next;
1141 }
1142
1143 if (sniffer == NULL) {
1144 isNew = 1;
1145 sniffer = (SnifferServer*)malloc(sizeof(SnifferServer));
1146 if (sniffer == NULL) {
1147 SetError(MEMORY_STR, error, NULL, 0);
1148#ifdef HAVE_SNI
1149 FreeNamedKey(namedKey);
1150#endif
1151 return -1;
1152 }
1153 InitSnifferServer(sniffer);
1154
1155 XSTRNCPY(sniffer->address, address, MAX_SERVER_ADDRESS-1);
1156 sniffer->address[MAX_SERVER_ADDRESS-1] = '\0';
1157 sniffer->server = serverIp;
1158 sniffer->port = port;
1159
1160 sniffer->ctx = SSL_CTX_new(TLSv1_client_method());
1161 if (!sniffer->ctx) {
1162 SetError(MEMORY_STR, error, NULL, 0);
1163#ifdef HAVE_SNI
1164 FreeNamedKey(namedKey);
1165#endif
1166 FreeSnifferServer(sniffer);
1167 return -1;
1168 }
1169 }
1170
1171 if (name == NULL) {
1172 if (password) {
1173 SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
1174 SSL_CTX_set_default_passwd_cb_userdata(
1175 sniffer->ctx, (void*)password);
1176 }
1177 ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
1178 if (ret != SSL_SUCCESS) {
1179 SetError(KEY_FILE_STR, error, NULL, 0);
1180 if (isNew)
1181 FreeSnifferServer(sniffer);
1182 return -1;
1183 }
1184 }
1185#ifdef HAVE_SNI
1186 else {
1187 LockMutex(&sniffer->namedKeysMutex);
1188 namedKey->next = sniffer->namedKeys;
1189 sniffer->namedKeys = namedKey;
1190 UnLockMutex(&sniffer->namedKeysMutex);
1191 }
1192#endif
1193
1194 if (isNew) {
1195 sniffer->next = ServerList;
1196 ServerList = sniffer;
1197 }
1198
1199 return 0;
1200}
1201
1202
1203#ifdef HAVE_SNI
1204
1205/* Sets the private key for a specific name, server and port */
1206/* returns 0 on success, -1 on error */
1207int ssl_SetNamedPrivateKey(const char* name,
1208 const char* address, int port,
1209 const char* keyFile, int typeKey,
1210 const char* password, char* error)
1211{
1212 int ret;
1213
1214 TraceHeader();
1215 TraceSetNamedServer(name, address, port, keyFile);
1216
1217 LockMutex(&ServerListMutex);
1218 ret = SetNamedPrivateKey(name, address, port, keyFile,
1219 typeKey, password, error);
1220 UnLockMutex(&ServerListMutex);
1221
1222 if (ret == 0)
1223 Trace(NEW_SERVER_STR);
1224
1225 return ret;
1226}
1227
1228#endif
1229
1230
1231/* Sets the private key for a specific server and port */
1232/* returns 0 on success, -1 on error */
1233int ssl_SetPrivateKey(const char* address, int port, const char* keyFile,
1234 int typeKey, const char* password, char* error)
1235{
1236 int ret;
1237
1238 TraceHeader();
1239 TraceSetServer(address, port, keyFile);
1240
1241 LockMutex(&ServerListMutex);
1242 ret = SetNamedPrivateKey(NULL, address, port, keyFile,
1243 typeKey, password, error);
1244 UnLockMutex(&ServerListMutex);
1245
1246 if (ret == 0)
1247 Trace(NEW_SERVER_STR);
1248
1249 return ret;
1250}
1251
1252
1253/* Check IP Header for IPV4, TCP, and a registered server address */
1254/* returns 0 on success, -1 on error */
1255static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
1256{
1257 int version = IP_V(iphdr);
1258
1259 TraceIP(iphdr);
1260 Trace(IP_CHECK_STR);
1261
1262 if (version != IPV4) {
1263 SetError(BAD_IPVER_STR, error, NULL, 0);
1264 return -1;
1265 }
1266
1267 if (iphdr->protocol != TCP_PROTOCOL) {
1268 SetError(BAD_PROTO_STR, error, NULL, 0);
1269 return -1;
1270 }
1271
1272 if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
1273 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
1274 return -1;
1275 }
1276
1277 info->length = IP_HL(iphdr);
1278 info->total = ntohs(iphdr->length);
1279 info->src = iphdr->src;
1280 info->dst = iphdr->dst;
1281
1282 if (info->total == 0)
1283 info->total = length; /* reassembled may be off */
1284
1285 return 0;
1286}
1287
1288
1289/* Check TCP Header for a registered port */
1290/* returns 0 on success, -1 on error */
1291static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
1292{
1293 TraceTcp(tcphdr);
1294 Trace(TCP_CHECK_STR);
1295 info->srcPort = ntohs(tcphdr->srcPort);
1296 info->dstPort = ntohs(tcphdr->dstPort);
1297 info->length = TCP_LEN(tcphdr);
1298 info->sequence = ntohl(tcphdr->sequence);
1299 info->fin = tcphdr->flags & TCP_FIN;
1300 info->rst = tcphdr->flags & TCP_RST;
1301 info->syn = tcphdr->flags & TCP_SYN;
1302 info->ack = tcphdr->flags & TCP_ACK;
1303 if (info->ack)
1304 info->ackNumber = ntohl(tcphdr->ack);
1305
1306 if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
1307 SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
1308 return -1;
1309 }
1310
1311 return 0;
1312}
1313
1314
1315/* Decode Record Layer Header */
1316static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
1317{
1318 XMEMCPY(rh, input, RECORD_HEADER_SZ);
1319 *size = (rh->length[0] << 8) | rh->length[1];
1320
1321 if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
1322 return LENGTH_ERROR;
1323
1324 return 0;
1325}
1326
1327
1328/* Process Client Key Exchange, RSA only */
1329static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
1330 SnifferSession* session, char* error)
1331{
1332 word32 idx = 0;
1333 RsaKey key;
1334 int ret;
1335
1336 if (session->sslServer->buffers.key.buffer == NULL ||
1337 session->sslServer->buffers.key.length == 0) {
1338
1339 SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
1340 return -1;
1341 }
1342 ret = wc_InitRsaKey(&key, 0);
1343 if (ret == 0)
1344 ret = wc_RsaPrivateKeyDecode(session->sslServer->buffers.key.buffer,
1345 &idx, &key, session->sslServer->buffers.key.length);
1346 if (ret == 0) {
1347 int length = wc_RsaEncryptSize(&key);
1348
1349 if (IsTLS(session->sslServer))
1350 input += 2; /* tls pre length */
1351
1352 if (length > *sslBytes) {
1353 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
1354 wc_FreeRsaKey(&key);
1355 return -1;
1356 }
1357 ret = wc_RsaPrivateDecrypt(input, length,
1358 session->sslServer->arrays->preMasterSecret,SECRET_LEN, &key);
1359
1360 if (ret != SECRET_LEN) {
1361 SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
1362 wc_FreeRsaKey(&key);
1363 return -1;
1364 }
1365 session->sslServer->arrays->preMasterSz = SECRET_LEN;
1366
1367 /* store for client side as well */
1368 XMEMCPY(session->sslClient->arrays->preMasterSecret,
1369 session->sslServer->arrays->preMasterSecret, SECRET_LEN);
1370 session->sslClient->arrays->preMasterSz = SECRET_LEN;
1371
1372 #ifdef SHOW_SECRETS
1373 {
1374 int i;
1375 printf("pre master secret: ");
1376 for (i = 0; i < SECRET_LEN; i++)
1377 printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
1378 printf("\n");
1379 }
1380 #endif
1381 }
1382 else {
1383 SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
1384 wc_FreeRsaKey(&key);
1385 return -1;
1386 }
1387
1388 if (SetCipherSpecs(session->sslServer) != 0) {
1389 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
1390 wc_FreeRsaKey(&key);
1391 return -1;
1392 }
1393
1394 if (SetCipherSpecs(session->sslClient) != 0) {
1395 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
1396 wc_FreeRsaKey(&key);
1397 return -1;
1398 }
1399
1400 ret = MakeMasterSecret(session->sslServer);
1401 ret += MakeMasterSecret(session->sslClient);
1402 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
1403 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
1404
1405 if (ret != 0) {
1406 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
1407 return -1;
1408 }
1409
1410#ifdef SHOW_SECRETS
1411 {
1412 int i;
1413 printf("server master secret: ");
1414 for (i = 0; i < SECRET_LEN; i++)
1415 printf("%02x", session->sslServer->arrays->masterSecret[i]);
1416 printf("\n");
1417
1418 printf("client master secret: ");
1419 for (i = 0; i < SECRET_LEN; i++)
1420 printf("%02x", session->sslClient->arrays->masterSecret[i]);
1421 printf("\n");
1422
1423 printf("server suite = %d\n", session->sslServer->options.cipherSuite);
1424 printf("client suite = %d\n", session->sslClient->options.cipherSuite);
1425 }
1426#endif
1427
1428 wc_FreeRsaKey(&key);
1429 return ret;
1430}
1431
1432
1433/* Process Session Ticket */
1434static int ProcessSessionTicket(const byte* input, int* sslBytes,
1435 SnifferSession* session, char* error)
1436{
1437 word16 len;
1438
1439 /* make sure can read through hint and len */
1440 if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) {
1441 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
1442 return -1;
1443 }
1444
1445 input += TICKET_HINT_LEN; /* skip over hint */
1446 *sslBytes -= TICKET_HINT_LEN;
1447
1448 len = (word16)((input[0] << 8) | input[1]);
1449 input += LENGTH_SZ;
1450 *sslBytes -= LENGTH_SZ;
1451
1452 /* make sure can read through ticket */
1453 if (len > *sslBytes || len < ID_LEN) {
1454 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
1455 return -1;
1456 }
1457
1458 /* store session with macID as sessionID */
1459 session->sslServer->options.haveSessionId = 1;
1460 XMEMCPY(session->sslServer->arrays->sessionID, input + len - ID_LEN,ID_LEN);
1461
1462 return 0;
1463}
1464
1465
1466/* Process Server Hello */
1467static int ProcessServerHello(const byte* input, int* sslBytes,
1468 SnifferSession* session, char* error)
1469{
1470 ProtocolVersion pv;
1471 byte b;
1472 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
1473 int doResume = 0;
1474
1475 /* make sure we didn't miss ClientHello */
1476 if (session->flags.clientHello == 0) {
1477 SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE);
1478 return -1;
1479 }
1480
1481 /* make sure can read through session len */
1482 if (toRead > *sslBytes) {
1483 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1484 return -1;
1485 }
1486
1487 XMEMCPY(&pv, input, VERSION_SZ);
1488 input += VERSION_SZ;
1489 *sslBytes -= VERSION_SZ;
1490
1491 session->sslServer->version = pv;
1492 session->sslClient->version = pv;
1493
1494 XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN);
1495 XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN);
1496 input += RAN_LEN;
1497 *sslBytes -= RAN_LEN;
1498
1499 b = *input++;
1500 *sslBytes -= 1;
1501
1502 /* make sure can read through compression */
1503 if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
1504 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1505 return -1;
1506 }
1507 if (b) {
1508 XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN);
1509 session->sslServer->options.haveSessionId = 1;
1510 }
1511 input += b;
1512 *sslBytes -= b;
1513
1514 /* cipher suite */
1515 b = *input++; /* first byte, ECC or not */
1516 session->sslServer->options.cipherSuite0 = b;
1517 session->sslClient->options.cipherSuite0 = b;
1518 b = *input++;
1519 session->sslServer->options.cipherSuite = b;
1520 session->sslClient->options.cipherSuite = b;
1521 *sslBytes -= SUITE_LEN;
1522
1523 /* compression */
1524 b = *input++;
1525 *sslBytes -= ENUM_LEN;
1526
1527 if (b) {
1528 SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
1529 return -1;
1530 }
1531
1532 if (session->sslServer->options.haveSessionId &&
1533 XMEMCMP(session->sslServer->arrays->sessionID,
1534 session->sslClient->arrays->sessionID, ID_LEN) == 0)
1535 doResume = 1;
1536 else if (session->sslClient->options.haveSessionId == 0 &&
1537 session->sslServer->options.haveSessionId == 0 &&
1538 session->ticketID)
1539 doResume = 1;
1540
1541 if (session->ticketID && doResume) {
1542 /* use ticketID to retrieve from session, prefer over sessionID */
1543 XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN);
1544 session->sslServer->options.haveSessionId = 1; /* may not have
1545 actual sessionID */
1546 }
1547
1548 if (doResume ) {
1549 int ret = 0;
1550 SSL_SESSION* resume = GetSession(session->sslServer,
1551 session->sslServer->arrays->masterSecret);
1552 if (resume == NULL) {
1553 SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
1554 return -1;
1555 }
1556 /* make sure client has master secret too */
1557 XMEMCPY(session->sslClient->arrays->masterSecret,
1558 session->sslServer->arrays->masterSecret, SECRET_LEN);
1559 session->flags.resuming = 1;
1560
1561 Trace(SERVER_DID_RESUMPTION_STR);
1562 if (SetCipherSpecs(session->sslServer) != 0) {
1563 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
1564 return -1;
1565 }
1566
1567 if (SetCipherSpecs(session->sslClient) != 0) {
1568 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
1569 return -1;
1570 }
1571
1572 if (session->sslServer->options.tls) {
1573 ret = DeriveTlsKeys(session->sslServer);
1574 ret += DeriveTlsKeys(session->sslClient);
1575 }
1576 else {
1577 ret = DeriveKeys(session->sslServer);
1578 ret += DeriveKeys(session->sslClient);
1579 }
1580 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
1581 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
1582
1583 if (ret != 0) {
1584 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
1585 return -1;
1586 }
1587 }
1588#ifdef SHOW_SECRETS
1589 {
1590 int i;
1591 printf("cipher suite = 0x%02x\n",
1592 session->sslServer->options.cipherSuite);
1593 printf("server random: ");
1594 for (i = 0; i < RAN_LEN; i++)
1595 printf("%02x", session->sslServer->arrays->serverRandom[i]);
1596 printf("\n");
1597 }
1598#endif
1599 return 0;
1600}
1601
1602
1603/* Process normal Client Hello */
1604static int ProcessClientHello(const byte* input, int* sslBytes,
1605 SnifferSession* session, char* error)
1606{
1607 byte bLen;
1608 word16 len;
1609 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
1610
1611#ifdef HAVE_SNI
1612 {
1613 byte name[MAX_SERVER_NAME];
1614 word32 nameSz = sizeof(name);
1615 int ret;
1616
1617 ret = wolfSSL_SNI_GetFromBuffer(
1618 input - HANDSHAKE_HEADER_SZ - RECORD_HEADER_SZ,
1619 *sslBytes + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ,
1620 WOLFSSL_SNI_HOST_NAME, name, &nameSz);
1621
1622 if (ret == SSL_SUCCESS) {
1623 NamedKey* namedKey;
1624
1625 if (nameSz >= sizeof(name))
1626 nameSz = sizeof(name) - 1;
1627 name[nameSz] = 0;
1628 LockMutex(&session->context->namedKeysMutex);
1629 namedKey = session->context->namedKeys;
1630 while (namedKey != NULL) {
1631 if (nameSz == namedKey->nameSz &&
1632 XSTRNCMP((char*)name, namedKey->name, nameSz) == 0) {
1633 if (wolfSSL_use_PrivateKey_buffer(session->sslServer,
1634 namedKey->key, namedKey->keySz,
1635 SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
1636 UnLockMutex(&session->context->namedKeysMutex);
1637 SetError(CLIENT_HELLO_LATE_KEY_STR, error, session,
1638 FATAL_ERROR_STATE);
1639 return -1;
1640 }
1641 break;
1642 }
1643 else
1644 namedKey = namedKey->next;
1645 }
1646 UnLockMutex(&session->context->namedKeysMutex);
1647 }
1648 }
1649#endif
1650
1651 session->flags.clientHello = 1; /* don't process again */
1652
1653 /* make sure can read up to session len */
1654 if (toRead > *sslBytes) {
1655 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1656 return -1;
1657 }
1658
1659 /* skip, get negotiated one from server hello */
1660 input += VERSION_SZ;
1661 *sslBytes -= VERSION_SZ;
1662
1663 XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN);
1664 XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN);
1665
1666 input += RAN_LEN;
1667 *sslBytes -= RAN_LEN;
1668
1669 /* store session in case trying to resume */
1670 bLen = *input++;
1671 *sslBytes -= ENUM_LEN;
1672 if (bLen) {
1673 if (ID_LEN > *sslBytes) {
1674 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1675 return -1;
1676 }
1677 Trace(CLIENT_RESUME_TRY_STR);
1678 XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN);
1679 session->sslClient->options.haveSessionId = 1;
1680 }
1681#ifdef SHOW_SECRETS
1682 {
1683 int i;
1684 printf("client random: ");
1685 for (i = 0; i < RAN_LEN; i++)
1686 printf("%02x", session->sslServer->arrays->clientRandom[i]);
1687 printf("\n");
1688 }
1689#endif
1690
1691 input += bLen;
1692 *sslBytes -= bLen;
1693
1694 /* skip cipher suites */
1695 /* make sure can read len */
1696 if (SUITE_LEN > *sslBytes) {
1697 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1698 return -1;
1699 }
1700 len = (word16)((input[0] << 8) | input[1]);
1701 input += SUITE_LEN;
1702 *sslBytes -= SUITE_LEN;
1703 /* make sure can read suites + comp len */
1704 if (len + ENUM_LEN > *sslBytes) {
1705 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1706 return -1;
1707 }
1708 input += len;
1709 *sslBytes -= len;
1710
1711 /* skip compression */
1712 bLen = *input++;
1713 *sslBytes -= ENUM_LEN;
1714 /* make sure can read len */
1715 if (bLen > *sslBytes) {
1716 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1717 return -1;
1718 }
1719 input += bLen;
1720 *sslBytes -= bLen;
1721
1722 if (*sslBytes == 0) {
1723 /* no extensions */
1724 return 0;
1725 }
1726
1727 /* skip extensions until session ticket */
1728 /* make sure can read len */
1729 if (SUITE_LEN > *sslBytes) {
1730 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1731 return -1;
1732 }
1733 len = (word16)((input[0] << 8) | input[1]);
1734 input += SUITE_LEN;
1735 *sslBytes -= SUITE_LEN;
1736 /* make sure can read through all extensions */
1737 if (len > *sslBytes) {
1738 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1739 return -1;
1740 }
1741
1742 while (len > EXT_TYPE_SZ + LENGTH_SZ) {
1743 byte extType[EXT_TYPE_SZ];
1744 word16 extLen;
1745
1746 extType[0] = input[0];
1747 extType[1] = input[1];
1748 input += EXT_TYPE_SZ;
1749 *sslBytes -= EXT_TYPE_SZ;
1750
1751 extLen = (word16)((input[0] << 8) | input[1]);
1752 input += LENGTH_SZ;
1753 *sslBytes -= LENGTH_SZ;
1754
1755 /* make sure can read through individual extension */
1756 if (extLen > *sslBytes) {
1757 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
1758 return -1;
1759 }
1760
1761 if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) {
1762
1763 /* make sure can read through ticket if there is a non blank one */
1764 if (extLen && extLen < ID_LEN) {
1765 SetError(CLIENT_HELLO_INPUT_STR, error, session,
1766 FATAL_ERROR_STATE);
1767 return -1;
1768 }
1769
1770 if (extLen) {
1771 if (session->ticketID == 0) {
1772 session->ticketID = (byte*)malloc(ID_LEN);
1773 if (session->ticketID == 0) {
1774 SetError(MEMORY_STR, error, session,
1775 FATAL_ERROR_STATE);
1776 return -1;
1777 }
1778 }
1779 XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
1780 }
1781 }
1782
1783 input += extLen;
1784 *sslBytes -= extLen;
1785 len -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
1786 }
1787
1788 return 0;
1789}
1790
1791
1792/* Process Finished */
1793static int ProcessFinished(const byte* input, int size, int* sslBytes,
1794 SnifferSession* session, char* error)
1795{
1796 SSL* ssl;
1797 word32 inOutIdx = 0;
1798 int ret;
1799
1800 if (session->flags.side == WOLFSSL_SERVER_END)
1801 ssl = session->sslServer;
1802 else
1803 ssl = session->sslClient;
1804
1805 ret = DoFinished(ssl, input, &inOutIdx, (word32) size, (word32) *sslBytes,
1806 SNIFF);
1807 *sslBytes -= (int)inOutIdx;
1808
1809 if (ret < 0) {
1810 SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
1811 return ret;
1812 }
1813
1814 if (ret == 0 && session->flags.cached == 0) {
1815 if (session->sslServer->options.haveSessionId) {
1816 WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL);
1817 if (sess == NULL)
1818 AddSession(session->sslServer); /* don't re add */
1819 session->flags.cached = 1;
1820 }
1821 }
1822
1823 /* If receiving a finished message from one side, free the resources
1824 * from the other side's tracker. */
1825 if (session->flags.side == WOLFSSL_SERVER_END)
1826 FreeHandshakeResources(session->sslClient);
1827 else
1828 FreeHandshakeResources(session->sslServer);
1829
1830 return ret;
1831}
1832
1833
1834/* Process HandShake input */
1835static int DoHandShake(const byte* input, int* sslBytes,
1836 SnifferSession* session, char* error)
1837{
1838 byte type;
1839 int size;
1840 int ret = 0;
1841 int startBytes;
1842
1843 if (*sslBytes < HANDSHAKE_HEADER_SZ) {
1844 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
1845 return -1;
1846 }
1847 type = input[0];
1848 size = (input[1] << 16) | (input[2] << 8) | input[3];
1849
1850 input += HANDSHAKE_HEADER_SZ;
1851 *sslBytes -= HANDSHAKE_HEADER_SZ;
1852 startBytes = *sslBytes;
1853
1854 if (*sslBytes < size) {
1855 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
1856 return -1;
1857 }
1858
1859 /* A session's arrays are released when the handshake is completed. */
1860 if (session->sslServer->arrays == NULL &&
1861 session->sslClient->arrays == NULL) {
1862
1863 SetError(NO_SECURE_RENEGOTIATION, error, session, FATAL_ERROR_STATE);
1864 return -1;
1865 }
1866
1867 switch (type) {
1868 case hello_verify_request:
1869 Trace(GOT_HELLO_VERIFY_STR);
1870 break;
1871 case hello_request:
1872 Trace(GOT_HELLO_REQUEST_STR);
1873 break;
1874 case session_ticket:
1875 Trace(GOT_SESSION_TICKET_STR);
1876 ret = ProcessSessionTicket(input, sslBytes, session, error);
1877 break;
1878 case server_hello:
1879 Trace(GOT_SERVER_HELLO_STR);
1880 ret = ProcessServerHello(input, sslBytes, session, error);
1881 break;
1882 case certificate_request:
1883 Trace(GOT_CERT_REQ_STR);
1884 break;
1885 case server_key_exchange:
1886 Trace(GOT_SERVER_KEY_EX_STR);
1887 /* can't know temp key passively */
1888 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
1889 ret = -1;
1890 break;
1891 case certificate:
1892 Trace(GOT_CERT_STR);
1893 break;
1894 case server_hello_done:
1895 Trace(GOT_SERVER_HELLO_DONE_STR);
1896 break;
1897 case finished:
1898 Trace(GOT_FINISHED_STR);
1899 ret = ProcessFinished(input, size, sslBytes, session, error);
1900 break;
1901 case client_hello:
1902 Trace(GOT_CLIENT_HELLO_STR);
1903 ret = ProcessClientHello(input, sslBytes, session, error);
1904 break;
1905 case client_key_exchange:
1906 Trace(GOT_CLIENT_KEY_EX_STR);
1907 ret = ProcessClientKeyExchange(input, sslBytes, session, error);
1908 break;
1909 case certificate_verify:
1910 Trace(GOT_CERT_VER_STR);
1911 break;
1912 case certificate_status:
1913 Trace(GOT_CERT_STATUS_STR);
1914 break;
1915 default:
1916 SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
1917 return -1;
1918 }
1919
1920 *sslBytes = startBytes - size; /* actual bytes of full process */
1921
1922 return ret;
1923}
1924
1925
1926/* Decrypt input into plain output, 0 on success */
1927static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
1928{
1929 int ret = 0;
1930
1931 switch (ssl->specs.bulk_cipher_algorithm) {
1932 #ifdef BUILD_ARC4
1933 case wolfssl_rc4:
1934 wc_Arc4Process(ssl->decrypt.arc4, output, input, sz);
1935 break;
1936 #endif
1937
1938 #ifdef BUILD_DES3
1939 case wolfssl_triple_des:
1940 ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz);
1941 break;
1942 #endif
1943
1944 #ifdef BUILD_AES
1945 case wolfssl_aes:
1946 ret = wc_AesCbcDecrypt(ssl->decrypt.aes, output, input, sz);
1947 break;
1948 #endif
1949
1950 #ifdef HAVE_HC128
1951 case wolfssl_hc128:
1952 wc_Hc128_Process(ssl->decrypt.hc128, output, input, sz);
1953 break;
1954 #endif
1955
1956 #ifdef BUILD_RABBIT
1957 case wolfssl_rabbit:
1958 wc_RabbitProcess(ssl->decrypt.rabbit, output, input, sz);
1959 break;
1960 #endif
1961
1962 #ifdef HAVE_CAMELLIA
1963 case wolfssl_camellia:
1964 wc_CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz);
1965 break;
1966 #endif
1967
1968 #ifdef HAVE_IDEA
1969 case wolfssl_idea:
1970 wc_IdeaCbcDecrypt(ssl->decrypt.idea, output, input, sz);
1971 break;
1972 #endif
1973
1974 #ifdef HAVE_AESGCM
1975 case wolfssl_aes_gcm:
1976 if (sz >= (word32)(AEAD_EXP_IV_SZ + ssl->specs.aead_mac_size))
1977 {
1978 byte nonce[AEAD_NONCE_SZ];
1979 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
1980 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
1981
1982 if (wc_AesGcmEncrypt(ssl->decrypt.aes,
1983 output,
1984 input + AEAD_EXP_IV_SZ,
1985 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
1986 nonce, AEAD_NONCE_SZ,
1987 NULL, 0,
1988 NULL, 0) < 0) {
1989 Trace(BAD_DECRYPT);
1990 ret = -1;
1991 }
1992 ForceZero(nonce, AEAD_NONCE_SZ);
1993 }
1994 else {
1995 Trace(BAD_DECRYPT_SIZE);
1996 ret = -1;
1997 }
1998 break;
1999 #endif
2000
2001 default:
2002 Trace(BAD_DECRYPT_TYPE);
2003 ret = -1;
2004 break;
2005 }
2006
2007 return ret;
2008}
2009
2010
2011/* Decrypt input message into output, adjust output steam if needed */
2012static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz,
2013 byte* output, int* error, int* advance)
2014{
2015 int ivExtra = 0;
2016
2017 int ret = Decrypt(ssl, output, input, sz);
2018 if (ret != 0) {
2019 *error = ret;
2020 return NULL;
2021 }
2022 ssl->keys.encryptSz = sz;
2023 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) {
2024 output += ssl->specs.block_size; /* go past TLSv1.1 IV */
2025 ivExtra = ssl->specs.block_size;
2026 *advance = ssl->specs.block_size;
2027 }
2028
2029 if (ssl->specs.cipher_type == aead) {
2030 *advance = ssl->specs.aead_mac_size;
2031 ssl->keys.padSz = ssl->specs.aead_mac_size;
2032 }
2033 else
2034 ssl->keys.padSz = ssl->specs.hash_size;
2035
2036 if (ssl->specs.cipher_type == block)
2037 ssl->keys.padSz += *(output + sz - ivExtra - 1) + 1;
2038
2039 return output;
2040}
2041
2042
2043/* remove session from table, use rowHint if no info (means we have a lock) */
2044static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
2045 TcpInfo* tcpInfo, word32 rowHint)
2046{
2047 SnifferSession* previous = 0;
2048 SnifferSession* current;
2049 word32 row = rowHint;
2050 int haveLock = 0;
2051
2052 if (ipInfo && tcpInfo)
2053 row = SessionHash(ipInfo, tcpInfo);
2054 else
2055 haveLock = 1;
2056
2057 assert(row <= HASH_SIZE);
2058 Trace(REMOVE_SESSION_STR);
2059
2060 if (!haveLock)
2061 LockMutex(&SessionMutex);
2062
2063 current = SessionTable[row];
2064
2065 while (current) {
2066 if (current == session) {
2067 if (previous)
2068 previous->next = current->next;
2069 else
2070 SessionTable[row] = current->next;
2071 FreeSnifferSession(session);
2072 TraceRemovedSession();
2073 break;
2074 }
2075 previous = current;
2076 current = current->next;
2077 }
2078
2079 if (!haveLock)
2080 UnLockMutex(&SessionMutex);
2081}
2082
2083
2084/* Remove stale sessions from the Session Table, have a lock */
2085static void RemoveStaleSessions(void)
2086{
2087 word32 i;
2088 SnifferSession* session;
2089
2090 for (i = 0; i < HASH_SIZE; i++) {
2091 session = SessionTable[i];
2092 while (session) {
2093 SnifferSession* next = session->next;
2094 if (time(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) {
2095 TraceStaleSession();
2096 RemoveSession(session, NULL, NULL, i);
2097 }
2098 session = next;
2099 }
2100 }
2101}
2102
2103
2104/* Create a new Sniffer Session */
2105static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
2106 char* error)
2107{
2108 SnifferSession* session = 0;
2109 int row;
2110
2111 Trace(NEW_SESSION_STR);
2112 /* create a new one */
2113 session = (SnifferSession*)malloc(sizeof(SnifferSession));
2114 if (session == NULL) {
2115 SetError(MEMORY_STR, error, NULL, 0);
2116 return 0;
2117 }
2118 InitSession(session);
2119 session->server = ipInfo->dst;
2120 session->client = ipInfo->src;
2121 session->srvPort = (word16)tcpInfo->dstPort;
2122 session->cliPort = (word16)tcpInfo->srcPort;
2123 session->cliSeqStart = tcpInfo->sequence;
2124 session->cliExpected = 1; /* relative */
2125 session->lastUsed= time(NULL);
2126
2127 session->context = GetSnifferServer(ipInfo, tcpInfo);
2128 if (session->context == NULL) {
2129 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
2130 free(session);
2131 return 0;
2132 }
2133
2134 session->sslServer = SSL_new(session->context->ctx);
2135 if (session->sslServer == NULL) {
2136 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
2137 free(session);
2138 return 0;
2139 }
2140 session->sslClient = SSL_new(session->context->ctx);
2141 if (session->sslClient == NULL) {
2142 SSL_free(session->sslServer);
2143 session->sslServer = 0;
2144
2145 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
2146 free(session);
2147 return 0;
2148 }
2149 /* put server back into server mode */
2150 session->sslServer->options.side = WOLFSSL_SERVER_END;
2151
2152 row = SessionHash(ipInfo, tcpInfo);
2153
2154 /* add it to the session table */
2155 LockMutex(&SessionMutex);
2156
2157 session->next = SessionTable[row];
2158 SessionTable[row] = session;
2159
2160 SessionCount++;
2161
2162 if ( (SessionCount % HASH_SIZE) == 0) {
2163 TraceFindingStale();
2164 RemoveStaleSessions();
2165 }
2166
2167 UnLockMutex(&SessionMutex);
2168
2169 /* determine headed side */
2170 if (ipInfo->dst == session->context->server &&
2171 tcpInfo->dstPort == session->context->port)
2172 session->flags.side = WOLFSSL_SERVER_END;
2173 else
2174 session->flags.side = WOLFSSL_CLIENT_END;
2175
2176 return session;
2177}
2178
2179
2180#ifdef OLD_HELLO_ALLOWED
2181
2182/* Process Old Client Hello Input */
2183static int DoOldHello(SnifferSession* session, const byte* sslFrame,
2184 int* rhSize, int* sslBytes, char* error)
2185{
2186 const byte* input = sslFrame;
2187 byte b0, b1;
2188 word32 idx = 0;
2189 int ret;
2190
2191 Trace(GOT_OLD_CLIENT_HELLO_STR);
2192 session->flags.clientHello = 1; /* don't process again */
2193 b0 = *input++;
2194 b1 = *input++;
2195 *sslBytes -= 2;
2196 *rhSize = ((b0 & 0x7f) << 8) | b1;
2197
2198 if (*rhSize > *sslBytes) {
2199 SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
2200 return -1;
2201 }
2202
2203 ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
2204 (word16)*rhSize);
2205 if (ret < 0 && ret != MATCH_SUITE_ERROR) {
2206 SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
2207 return -1;
2208 }
2209
2210 Trace(OLD_CLIENT_OK_STR);
2211 XMEMCPY(session->sslClient->arrays->clientRandom,
2212 session->sslServer->arrays->clientRandom, RAN_LEN);
2213
2214 *sslBytes -= *rhSize;
2215 return 0;
2216}
2217
2218#endif /* OLD_HELLO_ALLOWED */
2219
2220
2221#if 0
2222/* Calculate the TCP checksum, see RFC 1071 */
2223/* return 0 for success, -1 on error */
2224/* can be called from decode() with
2225 TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
2226 could also add a 64bit version if type available and using this
2227*/
2228int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
2229 const byte* packet)
2230{
2231 TcpPseudoHdr pseudo;
2232 int count = PSEUDO_HDR_SZ;
2233 const word16* data = (word16*)&pseudo;
2234 word32 sum = 0;
2235 word16 checksum;
2236
2237 pseudo.src = ipInfo->src;
2238 pseudo.dst = ipInfo->dst;
2239 pseudo.rsv = 0;
2240 pseudo.protocol = TCP_PROTO;
2241 pseudo.legnth = htons(tcpInfo->length + dataLen);
2242
2243 /* pseudo header sum */
2244 while (count >= 2) {
2245 sum += *data++;
2246 count -= 2;
2247 }
2248
2249 count = tcpInfo->length + dataLen;
2250 data = (word16*)packet;
2251
2252 /* main sum */
2253 while (count > 1) {
2254 sum += *data++;
2255 count -=2;
2256 }
2257
2258 /* get left-over, if any */
2259 packet = (byte*)data;
2260 if (count > 0) {
2261 sum += *packet;
2262 }
2263
2264 /* fold 32bit sum into 16 bits */
2265 while (sum >> 16)
2266 sum = (sum & 0xffff) + (sum >> 16);
2267
2268 checksum = (word16)~sum;
2269 /* checksum should now equal 0, since included already calcd checksum */
2270 /* field, but tcp checksum offloading could negate calculation */
2271 if (checksum == 0)
2272 return 0;
2273 return -1;
2274}
2275#endif
2276
2277
2278/* Check IP and TCP headers, set payload */
2279/* returns 0 on success, -1 on error */
2280static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
2281 int length, const byte** sslFrame, int* sslBytes, char* error)
2282{
2283 TraceHeader();
2284 TracePacket();
2285
2286 /* ip header */
2287 if (length < IP_HDR_SZ) {
2288 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
2289 return -1;
2290 }
2291 if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
2292 return -1;
2293
2294 /* tcp header */
2295 if (length < (ipInfo->length + TCP_HDR_SZ)) {
2296 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
2297 return -1;
2298 }
2299 if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0)
2300 return -1;
2301
2302 /* setup */
2303 *sslFrame = packet + ipInfo->length + tcpInfo->length;
2304 if (*sslFrame > packet + length) {
2305 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
2306 return -1;
2307 }
2308 *sslBytes = (int)(packet + length - *sslFrame);
2309
2310 return 0;
2311}
2312
2313
2314/* Create or Find existing session */
2315/* returns 0 on success (continue), -1 on error, 1 on success (end) */
2316static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes,
2317 SnifferSession** session, char* error)
2318{
2319 /* create a new SnifferSession on client SYN */
2320 if (tcpInfo->syn && !tcpInfo->ack) {
2321 TraceClientSyn(tcpInfo->sequence);
2322 *session = CreateSession(ipInfo, tcpInfo, error);
2323 if (*session == NULL) {
2324 *session = GetSnifferSession(ipInfo, tcpInfo);
2325 /* already had exisiting, so OK */
2326 if (*session)
2327 return 1;
2328
2329 SetError(MEMORY_STR, error, NULL, 0);
2330 return -1;
2331 }
2332 return 1;
2333 }
2334 /* get existing sniffer session */
2335 else {
2336 *session = GetSnifferSession(ipInfo, tcpInfo);
2337 if (*session == NULL) {
2338 /* don't worry about extraneous RST or duplicate FINs */
2339 if (tcpInfo->fin || tcpInfo->rst)
2340 return 1;
2341 /* don't worry about duplicate ACKs either */
2342 if (sslBytes == 0 && tcpInfo->ack)
2343 return 1;
2344
2345 SetError(BAD_SESSION_STR, error, NULL, 0);
2346 return -1;
2347 }
2348 }
2349 return 0;
2350}
2351
2352
2353/* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */
2354static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data,
2355 int* bytesLeft)
2356{
2357 PacketBuffer* pb;
2358
2359 int added = end - *begin + 1;
2360 assert(*begin <= end);
2361
2362 pb = (PacketBuffer*)malloc(sizeof(PacketBuffer));
2363 if (pb == NULL) return NULL;
2364
2365 pb->next = 0;
2366 pb->begin = *begin;
2367 pb->end = end;
2368 pb->data = (byte*)malloc(added);
2369
2370 if (pb->data == NULL) {
2371 free(pb);
2372 return NULL;
2373 }
2374 XMEMCPY(pb->data, data, added);
2375
2376 *bytesLeft -= added;
2377 *begin = pb->end + 1;
2378
2379 return pb;
2380}
2381
2382
2383/* Add sslFrame to Reassembly List */
2384/* returns 1 (end) on success, -1, on error */
2385static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
2386 int sslBytes, SnifferSession* session, char* error)
2387{
2388 PacketBuffer* add;
2389 PacketBuffer** front = (from == WOLFSSL_SERVER_END) ?
2390 &session->cliReassemblyList: &session->srvReassemblyList;
2391 PacketBuffer* curr = *front;
2392 PacketBuffer* prev = curr;
2393
2394 word32* reassemblyMemory = (from == WOLFSSL_SERVER_END) ?
2395 &session->cliReassemblyMemory : &session->srvReassemblyMemory;
2396 word32 startSeq = seq;
2397 word32 added;
2398 int bytesLeft = sslBytes; /* could be overlapping fragment */
2399
2400 /* if list is empty add full frame to front */
2401 if (!curr) {
2402 if (MaxRecoveryMemory != -1 &&
2403 (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
2404 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
2405 return -1;
2406 }
2407 add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft);
2408 if (add == NULL) {
2409 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
2410 return -1;
2411 }
2412 *front = add;
2413 *reassemblyMemory += sslBytes;
2414 return 1;
2415 }
2416
2417 /* add to front if before current front, up to next->begin */
2418 if (seq < curr->begin) {
2419 word32 end = seq + sslBytes - 1;
2420
2421 if (end >= curr->begin)
2422 end = curr->begin - 1;
2423
2424 if (MaxRecoveryMemory -1 &&
2425 (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
2426 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
2427 return -1;
2428 }
2429 add = CreateBuffer(&seq, end, sslFrame, &bytesLeft);
2430 if (add == NULL) {
2431 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
2432 return -1;
2433 }
2434 add->next = curr;
2435 *front = add;
2436 *reassemblyMemory += sslBytes;
2437 }
2438
2439 /* while we have bytes left, try to find a gap to fill */
2440 while (bytesLeft > 0) {
2441 /* get previous packet in list */
2442 while (curr && (seq >= curr->begin)) {
2443 prev = curr;
2444 curr = curr->next;
2445 }
2446
2447 /* don't add duplicate data */
2448 if (prev->end >= seq) {
2449 if ( (seq + bytesLeft - 1) <= prev->end)
2450 return 1;
2451 seq = prev->end + 1;
2452 bytesLeft = startSeq + sslBytes - seq;
2453 }
2454
2455 if (!curr)
2456 /* we're at the end */
2457 added = bytesLeft;
2458 else
2459 /* we're in between two frames */
2460 added = min((word32)bytesLeft, curr->begin - seq);
2461
2462 /* data already there */
2463 if (added == 0)
2464 continue;
2465
2466 if (MaxRecoveryMemory != -1 &&
2467 (int)(*reassemblyMemory + added) > MaxRecoveryMemory) {
2468 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
2469 return -1;
2470 }
2471 add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq],
2472 &bytesLeft);
2473 if (add == NULL) {
2474 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
2475 return -1;
2476 }
2477 add->next = prev->next;
2478 prev->next = add;
2479 *reassemblyMemory += added;
2480 }
2481 return 1;
2482}
2483
2484
2485/* Add out of order FIN capture */
2486/* returns 1 for success (end) */
2487static int AddFinCapture(SnifferSession* session, word32 sequence)
2488{
2489 if (session->flags.side == WOLFSSL_SERVER_END) {
2490 if (session->finCaputre.cliCounted == 0)
2491 session->finCaputre.cliFinSeq = sequence;
2492 }
2493 else {
2494 if (session->finCaputre.srvCounted == 0)
2495 session->finCaputre.srvFinSeq = sequence;
2496 }
2497 return 1;
2498}
2499
2500
2501/* Adjust incoming sequence based on side */
2502/* returns 0 on success (continue), -1 on error, 1 on success (end) */
2503static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
2504 int* sslBytes, const byte** sslFrame, char* error)
2505{
2506 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
2507 session->cliSeqStart :session->srvSeqStart;
2508 word32 real = tcpInfo->sequence - seqStart;
2509 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
2510 &session->cliExpected : &session->srvExpected;
2511 PacketBuffer* reassemblyList = (session->flags.side == WOLFSSL_SERVER_END) ?
2512 session->cliReassemblyList : session->srvReassemblyList;
2513 byte skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
2514 session->flags.srvSkipPartial :
2515 session->flags.cliSkipPartial;
2516
2517 /* handle rollover of sequence */
2518 if (tcpInfo->sequence < seqStart)
2519 real = 0xffffffffU - seqStart + tcpInfo->sequence;
2520
2521 TraceRelativeSequence(*expected, real);
2522
2523 if (real < *expected) {
2524 Trace(DUPLICATE_STR);
2525 if (real + *sslBytes > *expected) {
2526 int overlap = *expected - real;
2527 Trace(OVERLAP_DUPLICATE_STR);
2528
2529 /* adjust to expected, remove duplicate */
2530 *sslFrame += overlap;
2531 *sslBytes -= overlap;
2532
2533 /* The following conditional block is duplicated below. It is the
2534 * same action but for a different setup case. If changing this
2535 * block be sure to also update the block below. */
2536 if (reassemblyList) {
2537 word32 newEnd = *expected + *sslBytes;
2538
2539 if (newEnd > reassemblyList->begin) {
2540 Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
2541
2542 /* remove bytes already on reassembly list */
2543 *sslBytes -= newEnd - reassemblyList->begin;
2544 }
2545 if (newEnd > reassemblyList->end) {
2546 Trace(OVERLAP_REASSEMBLY_END_STR);
2547
2548 /* may be past reassembly list end (could have more on list)
2549 so try to add what's past the front->end */
2550 AddToReassembly(session->flags.side, reassemblyList->end +1,
2551 *sslFrame + reassemblyList->end - *expected + 1,
2552 newEnd - reassemblyList->end, session, error);
2553 }
2554 }
2555 }
2556 else
2557 return 1;
2558 }
2559 else if (real > *expected) {
2560 Trace(OUT_OF_ORDER_STR);
2561 if (*sslBytes > 0) {
2562 int addResult = AddToReassembly(session->flags.side, real,
2563 *sslFrame, *sslBytes, session, error);
2564 if (skipPartial) {
2565 *sslBytes = 0;
2566 return 0;
2567 }
2568 else
2569 return addResult;
2570 }
2571 else if (tcpInfo->fin)
2572 return AddFinCapture(session, real);
2573 }
2574 else if (*sslBytes > 0) {
2575 if (skipPartial) {
2576 AddToReassembly(session->flags.side, real,
2577 *sslFrame, *sslBytes, session, error);
2578 *expected += *sslBytes;
2579 *sslBytes = 0;
2580 if (tcpInfo->fin)
2581 *expected += 1;
2582 return 0;
2583 }
2584 /* The following conditional block is duplicated above. It is the
2585 * same action but for a different setup case. If changing this
2586 * block be sure to also update the block above. */
2587 else if (reassemblyList) {
2588 word32 newEnd = *expected + *sslBytes;
2589
2590 if (newEnd > reassemblyList->begin) {
2591 Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
2592
2593 /* remove bytes already on reassembly list */
2594 *sslBytes -= newEnd - reassemblyList->begin;
2595 }
2596 if (newEnd > reassemblyList->end) {
2597 Trace(OVERLAP_REASSEMBLY_END_STR);
2598
2599 /* may be past reassembly list end (could have more on list)
2600 so try to add what's past the front->end */
2601 AddToReassembly(session->flags.side, reassemblyList->end +1,
2602 *sslFrame + reassemblyList->end - *expected + 1,
2603 newEnd - reassemblyList->end, session, error);
2604 }
2605 }
2606 }
2607 /* got expected sequence */
2608 *expected += *sslBytes;
2609 if (tcpInfo->fin)
2610 *expected += 1;
2611
2612 return 0;
2613}
2614
2615
2616static int FindNextRecordInAssembly(SnifferSession* session,
2617 const byte** sslFrame, int* sslBytes,
2618 const byte** end, char* error)
2619{
2620 PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ?
2621 &session->cliReassemblyList :
2622 &session->srvReassemblyList;
2623 PacketBuffer* curr = *front;
2624 PacketBuffer* prev = NULL;
2625 byte* skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
2626 &session->flags.srvSkipPartial :
2627 &session->flags.cliSkipPartial;
2628 word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
2629 &session->cliReassemblyMemory :
2630 &session->srvReassemblyMemory;
2631 SSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
2632 session->sslServer :
2633 session->sslClient;
2634 ProtocolVersion pv = ssl->version;
2635 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
2636 &session->cliExpected :
2637 &session->srvExpected;
2638
2639 while (curr != NULL) {
2640 *expected = curr->end + 1;
2641
2642 if (curr->data[0] == application_data &&
2643 curr->data[1] == pv.major &&
2644 curr->data[2] == pv.minor) {
2645
2646 if (ssl->buffers.inputBuffer.length > 0)
2647 Trace(DROPPING_PARTIAL_RECORD);
2648
2649 *sslBytes = curr->end - curr->begin + 1;
2650 if ( (word32)*sslBytes > ssl->buffers.inputBuffer.bufferSize) {
2651 if (GrowInputBuffer(ssl, *sslBytes, 0) < 0) {
2652 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
2653 return -1;
2654 }
2655 }
2656
2657 XMEMCPY(ssl->buffers.inputBuffer.buffer, curr->data, *sslBytes);
2658
2659 *front = curr->next;
2660 *reassemblyMemory -= *sslBytes;
2661 FreePacketBuffer(curr);
2662
2663 ssl->buffers.inputBuffer.length = *sslBytes;
2664 *sslFrame = ssl->buffers.inputBuffer.buffer;
2665 *end = *sslFrame + *sslBytes;
2666 *skipPartial = 0;
2667
2668 return 0;
2669 }
2670 else if (ssl->specs.cipher_type == block) {
2671 if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes)
2672 wc_AesSetIV(ssl->decrypt.aes,
2673 curr->data + curr->end - curr->begin
2674 - ssl->specs.block_size + 1);
2675 else if (ssl->specs.bulk_cipher_algorithm == wolfssl_triple_des)
2676 wc_Des3_SetIV(ssl->decrypt.des3,
2677 curr->data + curr->end - curr->begin
2678 - ssl->specs.block_size + 1);
2679 }
2680
2681 Trace(DROPPING_LOST_FRAG_STR);
2682 prev = curr;
2683 curr = curr->next;
2684 *reassemblyMemory -= (prev->end - prev->begin + 1);
2685 FreePacketBuffer(prev);
2686 }
2687
2688 *front = curr;
2689
2690 return 0;
2691}
2692
2693
2694static int FixSequence(TcpInfo* tcpInfo, SnifferSession* session)
2695{
2696 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
2697 &session->srvExpected : &session->cliExpected;
2698 PacketBuffer* list = (session->flags.side == WOLFSSL_SERVER_END) ?
2699 session->srvReassemblyList :
2700 session->cliReassemblyList;
2701 byte* skipPartial = (session->flags.side != WOLFSSL_SERVER_END) ?
2702 &session->flags.srvSkipPartial :
2703 &session->flags.cliSkipPartial;
2704
2705 *skipPartial = 1;
2706 if (list != NULL)
2707 *expected = list->begin;
2708 else {
2709 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
2710 session->srvSeqStart : session->cliSeqStart;
2711 word32 real = tcpInfo->ackNumber - seqStart;
2712
2713 *expected = real;
2714 }
2715
2716 return 1;
2717}
2718
2719
2720/* Check latest ack number for missing packets
2721 return 0 ok, <0 on error */
2722static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session)
2723{
2724 if (tcpInfo->ack) {
2725 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
2726 session->srvSeqStart :session->cliSeqStart;
2727 word32 real = tcpInfo->ackNumber - seqStart;
2728 word32 expected = (session->flags.side == WOLFSSL_SERVER_END) ?
2729 session->srvExpected : session->cliExpected;
2730
2731 /* handle rollover of sequence */
2732 if (tcpInfo->ackNumber < seqStart)
2733 real = 0xffffffffU - seqStart + tcpInfo->ackNumber;
2734
2735 TraceAck(real, expected);
2736
2737 if (real > expected)
2738 return -1; /* we missed a packet, ACKing data we never saw */
2739 }
2740 return 0;
2741}
2742
2743
2744/* Check TCP Sequence status */
2745/* returns 0 on success (continue), -1 on error, 1 on success (end) */
2746static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
2747 SnifferSession* session, int* sslBytes,
2748 const byte** sslFrame, char* error)
2749{
2750 int actualLen;
2751 byte* ackFault = (session->flags.side == WOLFSSL_SERVER_END) ?
2752 &session->flags.cliAckFault :
2753 &session->flags.srvAckFault;
2754
2755 /* init SEQ from server to client */
2756 if (tcpInfo->syn && tcpInfo->ack) {
2757 session->srvSeqStart = tcpInfo->sequence;
2758 session->srvExpected = 1;
2759 TraceServerSyn(tcpInfo->sequence);
2760 return 1;
2761 }
2762
2763 /* adjust potential ethernet trailer */
2764 actualLen = ipInfo->total - ipInfo->length - tcpInfo->length;
2765 if (*sslBytes > actualLen) {
2766 *sslBytes = actualLen;
2767 }
2768
2769 TraceSequence(tcpInfo->sequence, *sslBytes);
2770 if (CheckAck(tcpInfo, session) < 0) {
2771 if (!RecoveryEnabled) {
2772 UpdateMissedDataSessions();
2773 SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE);
2774 return -1;
2775 }
2776 else {
2777 SetError(ACK_MISSED_STR, error, session, 0);
2778 if (*ackFault == 0) {
2779 *ackFault = 1;
2780 UpdateMissedDataSessions();
2781 }
2782 return FixSequence(tcpInfo, session);
2783 }
2784 }
2785
2786 if (*ackFault) {
2787 Trace(CLEAR_ACK_FAULT);
2788 *ackFault = 0;
2789 }
2790
2791 return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);
2792}
2793
2794
2795/* Check Status before record processing */
2796/* returns 0 on success (continue), -1 on error, 1 on success (end) */
2797static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
2798 const byte** sslFrame, SnifferSession** session,
2799 int* sslBytes, const byte** end, char* error)
2800{
2801 word32 length;
2802 SSL* ssl = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
2803 (*session)->sslServer : (*session)->sslClient;
2804 byte skipPartial = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
2805 (*session)->flags.srvSkipPartial :
2806 (*session)->flags.cliSkipPartial;
2807 /* remove SnifferSession on 2nd FIN or RST */
2808 if (tcpInfo->fin || tcpInfo->rst) {
2809 /* flag FIN and RST */
2810 if (tcpInfo->fin)
2811 (*session)->flags.finCount += 1;
2812 else if (tcpInfo->rst)
2813 (*session)->flags.finCount += 2;
2814
2815 if ((*session)->flags.finCount >= 2) {
2816 RemoveSession(*session, ipInfo, tcpInfo, 0);
2817 *session = NULL;
2818 return 1;
2819 }
2820 }
2821
2822 if ((*session)->flags.fatalError == FATAL_ERROR_STATE) {
2823 SetError(FATAL_ERROR_STR, error, NULL, 0);
2824 return -1;
2825 }
2826
2827 if (skipPartial) {
2828 if (FindNextRecordInAssembly(*session,
2829 sslFrame, sslBytes, end, error) < 0) {
2830 return -1;
2831 }
2832 }
2833
2834 if (*sslBytes == 0) {
2835 Trace(NO_DATA_STR);
2836 return 1;
2837 }
2838
2839 /* if current partial data, add to end of partial */
2840 /* if skipping, the data is alread at the end of partial */
2841 if ( !skipPartial &&
2842 (length = ssl->buffers.inputBuffer.length) ) {
2843 Trace(PARTIAL_ADD_STR);
2844
2845 if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
2846 if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
2847 SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
2848 return -1;
2849 }
2850 }
2851 XMEMCPY(&ssl->buffers.inputBuffer.buffer[length], *sslFrame, *sslBytes);
2852 *sslBytes += length;
2853 ssl->buffers.inputBuffer.length = *sslBytes;
2854 *sslFrame = ssl->buffers.inputBuffer.buffer;
2855 *end = *sslFrame + *sslBytes;
2856 }
2857
2858 if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) {
2859 /* Sanity check the packet for an old style client hello. */
2860 int rhSize = (((*sslFrame)[0] & 0x7f) << 8) | ((*sslFrame)[1]);
2861
2862 if ((rhSize <= (*sslBytes - 2)) &&
2863 (*sslFrame)[2] == OLD_HELLO_ID && (*sslFrame)[3] == SSLv3_MAJOR) {
2864#ifdef OLD_HELLO_ALLOWED
2865 int ret = DoOldHello(*session, *sslFrame, &rhSize, sslBytes, error);
2866 if (ret < 0)
2867 return -1; /* error already set */
2868 if (*sslBytes <= 0)
2869 return 1;
2870#endif
2871 }
2872 else {
2873#ifdef STARTTLS_ALLOWED
2874 return 1;
2875#endif
2876 }
2877 }
2878
2879 return 0;
2880}
2881
2882
2883/* See if input on the reassembly list is ready for consuming */
2884/* returns 1 for TRUE, 0 for FALSE */
2885static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
2886 int* sslBytes, const byte** end, char* error)
2887{
2888 /* sequence and reassembly based on from, not to */
2889 int moreInput = 0;
2890 PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ?
2891 &session->cliReassemblyList : &session->srvReassemblyList;
2892 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
2893 &session->cliExpected : &session->srvExpected;
2894 /* buffer is on receiving end */
2895 word32* length = (session->flags.side == WOLFSSL_SERVER_END) ?
2896 &session->sslServer->buffers.inputBuffer.length :
2897 &session->sslClient->buffers.inputBuffer.length;
2898 byte** myBuffer = (session->flags.side == WOLFSSL_SERVER_END) ?
2899 &session->sslServer->buffers.inputBuffer.buffer :
2900 &session->sslClient->buffers.inputBuffer.buffer;
2901 word32* bufferSize = (session->flags.side == WOLFSSL_SERVER_END) ?
2902 &session->sslServer->buffers.inputBuffer.bufferSize :
2903 &session->sslClient->buffers.inputBuffer.bufferSize;
2904 SSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
2905 session->sslServer : session->sslClient;
2906 word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
2907 &session->cliReassemblyMemory : &session->srvReassemblyMemory;
2908
2909 while (*front && ((*front)->begin == *expected) ) {
2910 word32 room = *bufferSize - *length;
2911 word32 packetLen = (*front)->end - (*front)->begin + 1;
2912
2913 if (packetLen > room && *bufferSize < MAX_INPUT_SZ) {
2914 if (GrowInputBuffer(ssl, packetLen, *length) < 0) {
2915 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
2916 return 0;
2917 }
2918 room = *bufferSize - *length; /* bufferSize is now bigger */
2919 }
2920
2921 if (packetLen <= room) {
2922 PacketBuffer* del = *front;
2923 byte* buf = *myBuffer;
2924
2925 XMEMCPY(&buf[*length], (*front)->data, packetLen);
2926 *length += packetLen;
2927 *expected += packetLen;
2928
2929 /* remove used packet */
2930 *front = (*front)->next;
2931
2932 *reassemblyMemory -= packetLen;
2933 FreePacketBuffer(del);
2934
2935 moreInput = 1;
2936 }
2937 else
2938 break;
2939 }
2940 if (moreInput) {
2941 *sslFrame = *myBuffer;
2942 *sslBytes = *length;
2943 *end = *myBuffer + *length;
2944 }
2945 return moreInput;
2946}
2947
2948
2949
2950/* Process Message(s) from sslFrame */
2951/* return Number of bytes on success, 0 for no data yet, and -1 on error */
2952static int ProcessMessage(const byte* sslFrame, SnifferSession* session,
2953 int sslBytes, byte** data, const byte* end,
2954 char* error)
2955{
2956 const byte* sslBegin = sslFrame;
2957 const byte* recordEnd; /* end of record indicator */
2958 const byte* inRecordEnd; /* indictor from input stream not decrypt */
2959 RecordLayerHeader rh;
2960 int rhSize = 0;
2961 int ret;
2962 int errCode = 0;
2963 int decoded = 0; /* bytes stored for user in data */
2964 int notEnough; /* notEnough bytes yet flag */
2965 int decrypted = 0; /* was current msg decrypted */
2966 SSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
2967 session->sslServer : session->sslClient;
2968doMessage:
2969 notEnough = 0;
2970 if (sslBytes < 0) {
2971 SetError(PACKET_HDR_SHORT_STR, error, session, FATAL_ERROR_STATE);
2972 return -1;
2973 }
2974 if (sslBytes >= RECORD_HEADER_SZ) {
2975 if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) {
2976 SetError(BAD_RECORD_HDR_STR, error, session, FATAL_ERROR_STATE);
2977 return -1;
2978 }
2979 }
2980 else
2981 notEnough = 1;
2982
2983 if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) {
2984 /* don't have enough input yet to process full SSL record */
2985 Trace(PARTIAL_INPUT_STR);
2986
2987 /* store partial if not there already or we advanced */
2988 if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
2989 if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
2990 if (GrowInputBuffer(ssl, sslBytes, 0) < 0) {
2991 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
2992 return -1;
2993 }
2994 }
2995 XMEMMOVE(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
2996 ssl->buffers.inputBuffer.length = sslBytes;
2997 }
2998 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
2999 goto doMessage;
3000 return decoded;
3001 }
3002 sslFrame += RECORD_HEADER_SZ;
3003 sslBytes -= RECORD_HEADER_SZ;
3004 recordEnd = sslFrame + rhSize; /* may have more than one record */
3005 inRecordEnd = recordEnd;
3006
3007 /* decrypt if needed */
3008 if ((session->flags.side == WOLFSSL_SERVER_END &&
3009 session->flags.serverCipherOn)
3010 || (session->flags.side == WOLFSSL_CLIENT_END &&
3011 session->flags.clientCipherOn)) {
3012 int ivAdvance = 0; /* TLSv1.1 advance amount */
3013 if (ssl->decrypt.setup != 1) {
3014 SetError(DECRYPT_KEYS_NOT_SETUP, error, session, FATAL_ERROR_STATE);
3015 return -1;
3016 }
3017 if (CheckAvailableSize(ssl, rhSize) < 0) {
3018 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
3019 return -1;
3020 }
3021 sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
3022 ssl->buffers.outputBuffer.buffer, &errCode,
3023 &ivAdvance);
3024 recordEnd = sslFrame - ivAdvance + rhSize; /* sslFrame moved so
3025 should recordEnd */
3026 decrypted = 1;
3027 if (errCode != 0) {
3028 SetError(BAD_DECRYPT, error, session, FATAL_ERROR_STATE);
3029 return -1;
3030 }
3031 }
3032
3033doPart:
3034
3035 switch ((enum ContentType)rh.type) {
3036 case handshake:
3037 {
3038 int startIdx = sslBytes;
3039 int used;
3040
3041 Trace(GOT_HANDSHAKE_STR);
3042 ret = DoHandShake(sslFrame, &sslBytes, session, error);
3043 if (ret != 0) {
3044 if (session->flags.fatalError == 0)
3045 SetError(BAD_HANDSHAKE_STR, error, session,
3046 FATAL_ERROR_STATE);
3047 return -1;
3048 }
3049
3050 /* DoHandShake now fully decrements sslBytes to remaining */
3051 used = startIdx - sslBytes;
3052 sslFrame += used;
3053 if (decrypted)
3054 sslFrame += ssl->keys.padSz;
3055 }
3056 break;
3057 case change_cipher_spec:
3058 if (session->flags.side == WOLFSSL_SERVER_END)
3059 session->flags.serverCipherOn = 1;
3060 else
3061 session->flags.clientCipherOn = 1;
3062 Trace(GOT_CHANGE_CIPHER_STR);
3063 ssl->options.handShakeState = HANDSHAKE_DONE;
3064 ssl->options.handShakeDone = 1;
3065
3066 sslFrame += 1;
3067 sslBytes -= 1;
3068
3069 break;
3070 case application_data:
3071 Trace(GOT_APP_DATA_STR);
3072 {
3073 word32 inOutIdx = 0;
3074
3075 ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx);
3076 if (ret == 0) {
3077 ret = ssl->buffers.clearOutputBuffer.length;
3078 TraceGotData(ret);
3079 if (ret) { /* may be blank message */
3080 byte* tmpData; /* don't leak on realloc free */
3081 /* add an extra byte at end of allocation in case user
3082 * wants to null terminate plaintext */
3083 tmpData = (byte*)realloc(*data, decoded + ret + 1);
3084 if (tmpData == NULL) {
3085 free(*data);
3086 *data = NULL;
3087 SetError(MEMORY_STR, error, session,
3088 FATAL_ERROR_STATE);
3089 return -1;
3090 }
3091 *data = tmpData;
3092 XMEMCPY(*data + decoded,
3093 ssl->buffers.clearOutputBuffer.buffer, ret);
3094 TraceAddedData(ret, decoded);
3095 decoded += ret;
3096 ssl->buffers.clearOutputBuffer.length = 0;
3097 }
3098 }
3099 else {
3100 SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE);
3101 return -1;
3102 }
3103 if (ssl->buffers.outputBuffer.dynamicFlag)
3104 ShrinkOutputBuffer(ssl);
3105
3106 sslFrame += inOutIdx;
3107 sslBytes -= inOutIdx;
3108 }
3109 break;
3110 case alert:
3111 Trace(GOT_ALERT_STR);
3112 sslFrame += rhSize;
3113 sslBytes -= rhSize;
3114 break;
3115 case no_type:
3116 default:
3117 SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);
3118 return -1;
3119 }
3120
3121 /* do we have another msg in record ? */
3122 if (sslFrame < recordEnd) {
3123 Trace(ANOTHER_MSG_STR);
3124 goto doPart;
3125 }
3126
3127 /* back to input stream instead of potential decrypt buffer */
3128 recordEnd = inRecordEnd;
3129
3130 /* do we have more records ? */
3131 if (recordEnd < end) {
3132 Trace(ANOTHER_MSG_STR);
3133 sslFrame = recordEnd;
3134 sslBytes = (int)(end - recordEnd);
3135 goto doMessage;
3136 }
3137
3138 /* clear used input */
3139 ssl->buffers.inputBuffer.length = 0;
3140
3141 /* could have more input ready now */
3142 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
3143 goto doMessage;
3144
3145 if (ssl->buffers.inputBuffer.dynamicFlag)
3146 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
3147
3148 return decoded;
3149}
3150
3151
3152/* See if we need to process any pending FIN captures */
3153static void CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo,
3154 SnifferSession* session)
3155{
3156 if (session->finCaputre.cliFinSeq && session->finCaputre.cliFinSeq <=
3157 session->cliExpected) {
3158 if (session->finCaputre.cliCounted == 0) {
3159 session->flags.finCount += 1;
3160 session->finCaputre.cliCounted = 1;
3161 TraceClientFin(session->finCaputre.cliFinSeq, session->cliExpected);
3162 }
3163 }
3164
3165 if (session->finCaputre.srvFinSeq && session->finCaputre.srvFinSeq <=
3166 session->srvExpected) {
3167 if (session->finCaputre.srvCounted == 0) {
3168 session->flags.finCount += 1;
3169 session->finCaputre.srvCounted = 1;
3170 TraceServerFin(session->finCaputre.srvFinSeq, session->srvExpected);
3171 }
3172 }
3173
3174 if (session->flags.finCount >= 2)
3175 RemoveSession(session, ipInfo, tcpInfo, 0);
3176}
3177
3178
3179/* If session is in fatal error state free resources now
3180 return true if removed, 0 otherwise */
3181static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
3182 SnifferSession* session, char* error)
3183{
3184 if (session && session->flags.fatalError == FATAL_ERROR_STATE) {
3185 RemoveSession(session, ipInfo, tcpInfo, 0);
3186 SetError(FATAL_ERROR_STR, error, NULL, 0);
3187 return 1;
3188 }
3189 return 0;
3190}
3191
3192
3193/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
3194/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
3195int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
3196{
3197 TcpInfo tcpInfo;
3198 IpInfo ipInfo;
3199 const byte* sslFrame;
3200 const byte* end = packet + length;
3201 int sslBytes; /* ssl bytes unconsumed */
3202 int ret;
3203 SnifferSession* session = 0;
3204
3205 if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
3206 error) != 0)
3207 return -1;
3208
3209 ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
3210 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
3211 else if (ret == -1) return -1;
3212 else if (ret == 1) return 0; /* done for now */
3213
3214 ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
3215 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
3216 else if (ret == -1) return -1;
3217 else if (ret == 1) return 0; /* done for now */
3218
3219 ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
3220 &end, error);
3221 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
3222 else if (ret == -1) return -1;
3223 else if (ret == 1) return 0; /* done for now */
3224
3225 ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error);
3226 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
3227 CheckFinCapture(&ipInfo, &tcpInfo, session);
3228 return ret;
3229}
3230
3231
3232/* Deallocator for the decoded data buffer. */
3233/* returns 0 on success, -1 on error */
3234int ssl_FreeDecodeBuffer(byte** data, char* error)
3235{
3236 (void)error;
3237
3238 if (data != NULL) {
3239 free(*data);
3240 *data = NULL;
3241 }
3242
3243 return 0;
3244}
3245
3246
3247/* Enables (if traceFile)/ Disables debug tracing */
3248/* returns 0 on success, -1 on error */
3249int ssl_Trace(const char* traceFile, char* error)
3250{
3251 if (traceFile) {
3252 TraceFile = fopen(traceFile, "a");
3253 if (!TraceFile) {
3254 SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
3255 return -1;
3256 }
3257 TraceOn = 1;
3258 }
3259 else
3260 TraceOn = 0;
3261
3262 return 0;
3263}
3264
3265
3266/* Enables/Disables Recovery of missed data if later packets allow
3267 * maxMemory is number of bytes to use for reassembly buffering per session,
3268 * -1 means unlimited
3269 * returns 0 on success, -1 on error */
3270int ssl_EnableRecovery(int onOff, int maxMemory, char* error)
3271{
3272 (void)error;
3273
3274 RecoveryEnabled = onOff;
3275 if (onOff)
3276 MaxRecoveryMemory = maxMemory;
3277
3278 return 0;
3279}
3280
3281
3282
3283int ssl_GetSessionStats(unsigned int* active, unsigned int* total,
3284 unsigned int* peak, unsigned int* maxSessions,
3285 unsigned int* missedData, unsigned int* reassemblyMem,
3286 char* error)
3287{
3288 int ret;
3289
3290 if (missedData) {
3291 LockMutex(&RecoveryMutex);
3292 *missedData = MissedDataSessions;
3293 UnLockMutex(&RecoveryMutex);
3294 }
3295
3296 if (reassemblyMem) {
3297 SnifferSession* session;
3298 int i;
3299
3300 *reassemblyMem = 0;
3301 LockMutex(&SessionMutex);
3302 for (i = 0; i < HASH_SIZE; i++) {
3303 session = SessionTable[i];
3304 while (session) {
3305 *reassemblyMem += session->cliReassemblyMemory;
3306 *reassemblyMem += session->srvReassemblyMemory;
3307 session = session->next;
3308 }
3309 }
3310 UnLockMutex(&SessionMutex);
3311 }
3312
3313 ret = wolfSSL_get_session_stats(active, total, peak, maxSessions);
3314
3315 if (ret == SSL_SUCCESS)
3316 return 0;
3317 else {
3318 SetError(BAD_SESSION_STATS, error, NULL, 0);
3319 return -1;
3320 }
3321}
3322
3323
3324
3325#endif /* WOLFSSL_SNIFFER */
3326#endif /* WOLFCRYPT_ONLY */
Note: See TracBrowser for help on using the repository browser.