Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
sniffer.c
00001 /* sniffer.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 #ifndef WOLFCRYPT_ONLY 00030 #ifdef WOLFSSL_SNIFFER 00031 00032 #include <assert.h> 00033 #include <time.h> 00034 00035 #ifndef _WIN32 00036 #include <arpa/inet.h> 00037 #endif 00038 00039 #ifdef _WIN32 00040 #define SNPRINTF _snprintf 00041 #else 00042 #define SNPRINTF snprintf 00043 #endif 00044 00045 #include <wolfssl/openssl/ssl.h> 00046 #include <wolfssl/internal.h> 00047 #include <wolfssl/error-ssl.h> 00048 #include <wolfssl/sniffer.h> 00049 #include <wolfssl/sniffer_error.h> 00050 #ifdef NO_INLINE 00051 #include <wolfssl/wolfcrypt/misc.h> 00052 #else 00053 #define WOLFSSL_MISC_INCLUDED 00054 #include <wolfcrypt/src/misc.c> 00055 #endif 00056 00057 00058 #ifndef WOLFSSL_SNIFFER_TIMEOUT 00059 #define WOLFSSL_SNIFFER_TIMEOUT 900 00060 /* Cache unclosed Sessions for 15 minutes since last used */ 00061 #endif 00062 00063 /* Misc constants */ 00064 enum { 00065 MAX_SERVER_ADDRESS = 128, /* maximum server address length */ 00066 MAX_SERVER_NAME = 128, /* maximum server name length */ 00067 MAX_ERROR_LEN = 80, /* maximum error length */ 00068 ETHER_IF_ADDR_LEN = 6, /* ethernet interface address length */ 00069 LOCAL_IF_ADDR_LEN = 4, /* localhost interface address length, !windows */ 00070 TCP_PROTO = 6, /* TCP_PROTOCOL */ 00071 IP_HDR_SZ = 20, /* IP header length, min */ 00072 TCP_HDR_SZ = 20, /* TCP header length, min */ 00073 IPV4 = 4, /* IP version 4 */ 00074 TCP_PROTOCOL = 6, /* TCP Protocol id */ 00075 TRACE_MSG_SZ = 80, /* Trace Message buffer size */ 00076 HASH_SIZE = 499, /* Session Hash Table Rows */ 00077 PSEUDO_HDR_SZ = 12, /* TCP Pseudo Header size in bytes */ 00078 FATAL_ERROR_STATE = 1, /* SnifferSession fatal error state */ 00079 TICKET_HINT_LEN = 4, /* Session Ticket Hint length */ 00080 EXT_TYPE_SZ = 2, /* Extension length */ 00081 MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA + 00082 MTU_EXTRA, /* Max input sz of reassembly */ 00083 EXT_MASTER_SECRET = 0x17, /* Extended Master Secret Extension ID */ 00084 TICKET_EXT_ID = 0x23 /* Session Ticket Extension ID */ 00085 }; 00086 00087 00088 #ifdef _WIN32 00089 00090 static HMODULE dllModule; /* for error string resources */ 00091 00092 BOOL APIENTRY DllMain( HMODULE hModule, 00093 DWORD ul_reason_for_call, 00094 LPVOID lpReserved 00095 ) 00096 { 00097 static int didInit = 0; 00098 00099 switch (ul_reason_for_call) 00100 { 00101 case DLL_PROCESS_ATTACH: 00102 if (didInit == 0) { 00103 dllModule = hModule; 00104 ssl_InitSniffer(); 00105 didInit = 1; 00106 } 00107 break; 00108 case DLL_THREAD_ATTACH: 00109 break; 00110 case DLL_THREAD_DETACH: 00111 break; 00112 case DLL_PROCESS_DETACH: 00113 if (didInit) { 00114 ssl_FreeSniffer(); 00115 didInit = 0; 00116 } 00117 break; 00118 } 00119 return TRUE; 00120 } 00121 00122 #endif /* _WIN32 */ 00123 00124 00125 static int TraceOn = 0; /* Trace is off by default */ 00126 static FILE* TraceFile = 0; 00127 00128 00129 /* windows uses .rc table for this */ 00130 #ifndef _WIN32 00131 00132 static const char* const msgTable[] = 00133 { 00134 /* 1 */ 00135 "Out of Memory", 00136 "New SSL Sniffer Server Registered", 00137 "Checking IP Header", 00138 "SSL Sniffer Server Not Registered", 00139 "Checking TCP Header", 00140 00141 /* 6 */ 00142 "SSL Sniffer Server Port Not Registered", 00143 "RSA Private Decrypt Error", 00144 "RSA Private Decode Error", 00145 "Set Cipher Spec Error", 00146 "Server Hello Input Malformed", 00147 00148 /* 11 */ 00149 "Couldn't Resume Session Error", 00150 "Server Did Resumption", 00151 "Client Hello Input Malformed", 00152 "Client Trying to Resume", 00153 "Handshake Input Malformed", 00154 00155 /* 16 */ 00156 "Got Hello Verify msg", 00157 "Got Server Hello msg", 00158 "Got Cert Request msg", 00159 "Got Server Key Exchange msg", 00160 "Got Cert msg", 00161 00162 /* 21 */ 00163 "Got Server Hello Done msg", 00164 "Got Finished msg", 00165 "Got Client Hello msg", 00166 "Got Client Key Exchange msg", 00167 "Got Cert Verify msg", 00168 00169 /* 26 */ 00170 "Got Unknown Handshake msg", 00171 "New SSL Sniffer Session created", 00172 "Couldn't create new SSL", 00173 "Got a Packet to decode", 00174 "No data present", 00175 00176 /* 31 */ 00177 "Session Not Found", 00178 "Got an Old Client Hello msg", 00179 "Old Client Hello Input Malformed", 00180 "Old Client Hello OK", 00181 "Bad Old Client Hello", 00182 00183 /* 36 */ 00184 "Bad Record Header", 00185 "Record Header Input Malformed", 00186 "Got a HandShake msg", 00187 "Bad HandShake msg", 00188 "Got a Change Cipher Spec msg", 00189 00190 /* 41 */ 00191 "Got Application Data msg", 00192 "Bad Application Data", 00193 "Got an Alert msg", 00194 "Another msg to Process", 00195 "Removing Session From Table", 00196 00197 /* 46 */ 00198 "Bad Key File", 00199 "Wrong IP Version", 00200 "Wrong Protocol type", 00201 "Packet Short for header processing", 00202 "Got Unknown Record Type", 00203 00204 /* 51 */ 00205 "Can't Open Trace File", 00206 "Session in Fatal Error State", 00207 "Partial SSL record received", 00208 "Buffer Error, malformed input", 00209 "Added to Partial Input", 00210 00211 /* 56 */ 00212 "Received a Duplicate Packet", 00213 "Received an Out of Order Packet", 00214 "Received an Overlap Duplicate Packet", 00215 "Received an Overlap Reassembly Begin Duplicate Packet", 00216 "Received an Overlap Reassembly End Duplicate Packet", 00217 00218 /* 61 */ 00219 "Missed the Client Hello Entirely", 00220 "Got Hello Request msg", 00221 "Got Session Ticket msg", 00222 "Bad Input", 00223 "Bad Decrypt Type", 00224 00225 /* 66 */ 00226 "Bad Finished Message Processing", 00227 "Bad Compression Type", 00228 "Bad DeriveKeys Error", 00229 "Saw ACK for Missing Packet Error", 00230 "Bad Decrypt Operation", 00231 00232 /* 71 */ 00233 "Decrypt Keys Not Set Up", 00234 "Late Key Load Error", 00235 "Got Certificate Status msg", 00236 "RSA Key Missing Error", 00237 "Secure Renegotiation Not Supported", 00238 00239 /* 76 */ 00240 "Get Session Stats Failure", 00241 "Reassembly Buffer Size Exceeded", 00242 "Dropping Lost Fragment", 00243 "Dropping Partial Record", 00244 "Clear ACK Fault", 00245 00246 /* 81 */ 00247 "Bad Decrypt Size", 00248 "Extended Master Secret Hash Error" 00249 }; 00250 00251 00252 /* *nix version uses table above */ 00253 static void GetError(int idx, char* str) 00254 { 00255 XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN); 00256 } 00257 00258 00259 #else /* _WIN32 */ 00260 00261 00262 /* Windows version uses .rc table */ 00263 static void GetError(int idx, char* buffer) 00264 { 00265 if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN)) 00266 buffer[0] = 0; 00267 } 00268 00269 00270 #endif /* _WIN32 */ 00271 00272 00273 /* Packet Buffer for reassembly list and ready list */ 00274 typedef struct PacketBuffer { 00275 word32 begin; /* relative sequence begin */ 00276 word32 end; /* relative sequence end */ 00277 byte* data; /* actual data */ 00278 struct PacketBuffer* next; /* next on reassembly list or ready list */ 00279 } PacketBuffer; 00280 00281 00282 #ifdef HAVE_SNI 00283 00284 /* NamedKey maps a SNI name to a specific private key */ 00285 typedef struct NamedKey { 00286 char name[MAX_SERVER_NAME]; /* server DNS name */ 00287 word32 nameSz; /* size of server DNS name */ 00288 byte* key; /* DER private key */ 00289 word32 keySz; /* size of DER private key */ 00290 struct NamedKey* next; /* for list */ 00291 } NamedKey; 00292 00293 #endif 00294 00295 00296 /* Sniffer Server holds info for each server/port monitored */ 00297 typedef struct SnifferServer { 00298 SSL_CTX* ctx; /* SSL context */ 00299 char address[MAX_SERVER_ADDRESS]; /* passed in server address */ 00300 word32 server; /* netowrk order address */ 00301 int port; /* server port */ 00302 #ifdef HAVE_SNI 00303 NamedKey* namedKeys; /* mapping of names and keys */ 00304 wolfSSL_Mutex namedKeysMutex; /* mutex for namedKey list */ 00305 #endif 00306 struct SnifferServer* next; /* for list */ 00307 } SnifferServer; 00308 00309 00310 /* Session Flags */ 00311 typedef struct Flags { 00312 byte side; /* which end is current packet headed */ 00313 byte serverCipherOn; /* indicates whether cipher is active */ 00314 byte clientCipherOn; /* indicates whether cipher is active */ 00315 byte resuming; /* did this session come from resumption */ 00316 byte cached; /* have we cached this session yet */ 00317 byte clientHello; /* processed client hello yet, for SSLv2 */ 00318 byte finCount; /* get both FINs before removing */ 00319 byte fatalError; /* fatal error state */ 00320 byte cliAckFault; /* client acked unseen data from server */ 00321 byte srvAckFault; /* server acked unseen data from client */ 00322 byte cliSkipPartial; /* client skips partial data to catch up */ 00323 byte srvSkipPartial; /* server skips partial data to catch up */ 00324 #ifdef HAVE_EXTENDED_MASTER 00325 byte expectEms; /* expect extended master secret */ 00326 #endif 00327 } Flags; 00328 00329 00330 /* Out of Order FIN caputre */ 00331 typedef struct FinCaputre { 00332 word32 cliFinSeq; /* client relative sequence FIN 0 is no */ 00333 word32 srvFinSeq; /* server relative sequence FIN, 0 is no */ 00334 byte cliCounted; /* did we count yet, detects duplicates */ 00335 byte srvCounted; /* did we count yet, detects duplicates */ 00336 } FinCaputre; 00337 00338 00339 typedef struct HsHashes { 00340 #ifndef NO_OLD_TLS 00341 #ifndef NO_SHA 00342 Sha hashSha; 00343 #endif 00344 #ifndef NO_MD5 00345 Md5 hashMd5; 00346 #endif 00347 #endif 00348 #ifndef NO_SHA256 00349 Sha256 hashSha256; 00350 #endif 00351 #ifdef WOLFSSL_SHA384 00352 Sha384 hashSha384; 00353 #endif 00354 } HsHashes; 00355 00356 00357 /* Sniffer Session holds info for each client/server SSL/TLS session */ 00358 typedef struct SnifferSession { 00359 SnifferServer* context; /* server context */ 00360 SSL* sslServer; /* SSL server side decode */ 00361 SSL* sslClient; /* SSL client side decode */ 00362 word32 server; /* server address in network byte order */ 00363 word32 client; /* client address in network byte order */ 00364 word16 srvPort; /* server port */ 00365 word16 cliPort; /* client port */ 00366 word32 cliSeqStart; /* client start sequence */ 00367 word32 srvSeqStart; /* server start sequence */ 00368 word32 cliExpected; /* client expected sequence (relative) */ 00369 word32 srvExpected; /* server expected sequence (relative) */ 00370 FinCaputre finCaputre; /* retain out of order FIN s */ 00371 Flags flags; /* session flags */ 00372 time_t lastUsed; /* last used ticks */ 00373 PacketBuffer* cliReassemblyList; /* client out of order packets */ 00374 PacketBuffer* srvReassemblyList; /* server out of order packets */ 00375 word32 cliReassemblyMemory; /* client packet memory used */ 00376 word32 srvReassemblyMemory; /* server packet memory used */ 00377 struct SnifferSession* next; /* for hash table list */ 00378 byte* ticketID; /* mac ID of session ticket */ 00379 #ifdef HAVE_EXTENDED_MASTER 00380 HsHashes* hash; 00381 #endif 00382 } SnifferSession; 00383 00384 00385 /* Sniffer Server List and mutex */ 00386 static SnifferServer* ServerList = 0; 00387 static wolfSSL_Mutex ServerListMutex; 00388 00389 00390 /* Session Hash Table, mutex, and count */ 00391 static SnifferSession* SessionTable[HASH_SIZE]; 00392 static wolfSSL_Mutex SessionMutex; 00393 static int SessionCount = 0; 00394 00395 /* Recovery of missed data switches and stats */ 00396 static wolfSSL_Mutex RecoveryMutex; /* for stats */ 00397 static int RecoveryEnabled = 0; /* global switch */ 00398 static int MaxRecoveryMemory = -1; /* per session max recovery memory */ 00399 static word32 MissedDataSessions = 0; /* # of sessions with missed data */ 00400 00401 00402 static void UpdateMissedDataSessions(void) 00403 { 00404 wc_LockMutex(&RecoveryMutex); 00405 MissedDataSessions += 1; 00406 wc_UnLockMutex(&RecoveryMutex); 00407 } 00408 00409 00410 /* Initialize overall Sniffer */ 00411 void ssl_InitSniffer(void) 00412 { 00413 wolfSSL_Init(); 00414 wc_InitMutex(&ServerListMutex); 00415 wc_InitMutex(&SessionMutex); 00416 wc_InitMutex(&RecoveryMutex); 00417 } 00418 00419 00420 #ifdef HAVE_SNI 00421 00422 /* Free Named Key and the zero out the private key it holds */ 00423 static void FreeNamedKey(NamedKey* in) 00424 { 00425 if (in) { 00426 if (in->key) { 00427 ForceZero(in->key, in->keySz); 00428 free(in->key); 00429 } 00430 free(in); 00431 } 00432 } 00433 00434 00435 static void FreeNamedKeyList(NamedKey* in) 00436 { 00437 NamedKey* next; 00438 00439 while (in) { 00440 next = in->next; 00441 FreeNamedKey(in); 00442 in = next; 00443 } 00444 } 00445 00446 #endif 00447 00448 00449 /* Free Sniffer Server's resources/self */ 00450 static void FreeSnifferServer(SnifferServer* srv) 00451 { 00452 if (srv) { 00453 #ifdef HAVE_SNI 00454 wc_LockMutex(&srv->namedKeysMutex); 00455 FreeNamedKeyList(srv->namedKeys); 00456 wc_UnLockMutex(&srv->namedKeysMutex); 00457 wc_FreeMutex(&srv->namedKeysMutex); 00458 #endif 00459 SSL_CTX_free(srv->ctx); 00460 } 00461 free(srv); 00462 } 00463 00464 00465 /* free PacketBuffer's resources/self */ 00466 static void FreePacketBuffer(PacketBuffer* del) 00467 { 00468 if (del) { 00469 free(del->data); 00470 free(del); 00471 } 00472 } 00473 00474 00475 /* remove PacketBuffer List */ 00476 static void FreePacketList(PacketBuffer* in) 00477 { 00478 if (in) { 00479 PacketBuffer* del; 00480 PacketBuffer* packet = in; 00481 00482 while (packet) { 00483 del = packet; 00484 packet = packet->next; 00485 FreePacketBuffer(del); 00486 } 00487 } 00488 } 00489 00490 00491 /* Free Sniffer Session's resources/self */ 00492 static void FreeSnifferSession(SnifferSession* session) 00493 { 00494 if (session) { 00495 SSL_free(session->sslClient); 00496 SSL_free(session->sslServer); 00497 00498 FreePacketList(session->cliReassemblyList); 00499 FreePacketList(session->srvReassemblyList); 00500 00501 free(session->ticketID); 00502 #ifdef HAVE_EXTENDED_MASTER 00503 free(session->hash); 00504 #endif 00505 } 00506 free(session); 00507 } 00508 00509 00510 /* Free overall Sniffer */ 00511 void ssl_FreeSniffer(void) 00512 { 00513 SnifferServer* srv; 00514 SnifferServer* removeServer; 00515 SnifferSession* session; 00516 SnifferSession* removeSession; 00517 int i; 00518 00519 wc_LockMutex(&ServerListMutex); 00520 wc_LockMutex(&SessionMutex); 00521 00522 srv = ServerList; 00523 while (srv) { 00524 removeServer = srv; 00525 srv = srv->next; 00526 FreeSnifferServer(removeServer); 00527 } 00528 00529 for (i = 0; i < HASH_SIZE; i++) { 00530 session = SessionTable[i]; 00531 while (session) { 00532 removeSession = session; 00533 session = session->next; 00534 FreeSnifferSession(removeSession); 00535 } 00536 } 00537 00538 wc_UnLockMutex(&SessionMutex); 00539 wc_UnLockMutex(&ServerListMutex); 00540 00541 wc_FreeMutex(&RecoveryMutex); 00542 wc_FreeMutex(&SessionMutex); 00543 wc_FreeMutex(&ServerListMutex); 00544 00545 if (TraceFile) { 00546 TraceOn = 0; 00547 fclose(TraceFile); 00548 TraceFile = NULL; 00549 } 00550 00551 wolfSSL_Cleanup(); 00552 } 00553 00554 00555 #ifdef HAVE_EXTENDED_MASTER 00556 00557 static int HashInit(HsHashes* hash) 00558 { 00559 int ret = 0; 00560 00561 XMEMSET(hash, 0, sizeof(HsHashes)); 00562 00563 #ifndef NO_OLD_TLS 00564 #ifndef NO_SHA 00565 if (ret == 0) 00566 ret = wc_InitSha(&hash->hashSha); 00567 #endif 00568 #ifndef NO_MD5 00569 if (ret == 0) 00570 wc_InitMd5(&hash->hashMd5); 00571 #endif 00572 #endif 00573 #ifndef NO_SHA256 00574 if (ret == 0) 00575 ret = wc_InitSha256(&hash->hashSha256); 00576 #endif 00577 #ifdef WOLFSSL_SHA384 00578 if (ret == 0) 00579 ret = wc_InitSha384(&hash->hashSha384); 00580 #endif 00581 00582 return ret; 00583 } 00584 00585 00586 static int HashUpdate(HsHashes* hash, const byte* input, int sz) 00587 { 00588 int ret = 0; 00589 00590 input -= HANDSHAKE_HEADER_SZ; 00591 sz += HANDSHAKE_HEADER_SZ; 00592 00593 #ifndef NO_OLD_TLS 00594 #ifndef NO_SHA 00595 if (ret == 0) 00596 ret = wc_ShaUpdate(&hash->hashSha, input, sz); 00597 #endif 00598 #ifndef NO_MD5 00599 if (ret == 0) 00600 wc_Md5Update(&hash->hashMd5, input, sz); 00601 #endif 00602 #endif 00603 #ifndef NO_SHA256 00604 if (ret == 0) 00605 ret = wc_Sha256Update(&hash->hashSha256, input, sz); 00606 #endif 00607 #ifdef WOLFSSL_SHA384 00608 if (ret == 0) 00609 ret = wc_Sha384Update(&hash->hashSha384, input, sz); 00610 #endif 00611 00612 return ret; 00613 } 00614 00615 00616 static int HashCopy(HS_Hashes* d, HsHashes* s) 00617 { 00618 #ifndef NO_OLD_TLS 00619 #ifndef NO_SHA 00620 XMEMCPY(&d->hashSha, &s->hashSha, sizeof(Sha)); 00621 #endif 00622 #ifndef NO_MD5 00623 XMEMCPY(&d->hashMd5, &s->hashMd5, sizeof(Md5)); 00624 #endif 00625 #endif 00626 00627 #ifndef NO_SHA256 00628 XMEMCPY(&d->hashSha256, &s->hashSha256, sizeof(Sha256)); 00629 #endif 00630 #ifdef WOLFSSL_SHA384 00631 XMEMCPY(&d->hashSha384, &s->hashSha384, sizeof(Sha384)); 00632 #endif 00633 00634 return 0; 00635 } 00636 00637 #endif 00638 00639 00640 /* Initialize a SnifferServer */ 00641 static void InitSnifferServer(SnifferServer* sniffer) 00642 { 00643 sniffer->ctx = 0; 00644 XMEMSET(sniffer->address, 0, MAX_SERVER_ADDRESS); 00645 sniffer->server = 0; 00646 sniffer->port = 0; 00647 #ifdef HAVE_SNI 00648 sniffer->namedKeys = 0; 00649 wc_InitMutex(&sniffer->namedKeysMutex); 00650 #endif 00651 sniffer->next = 0; 00652 } 00653 00654 00655 /* Initialize session flags */ 00656 static void InitFlags(Flags* flags) 00657 { 00658 flags->side = 0; 00659 flags->serverCipherOn = 0; 00660 flags->clientCipherOn = 0; 00661 flags->resuming = 0; 00662 flags->cached = 0; 00663 flags->clientHello = 0; 00664 flags->finCount = 0; 00665 flags->fatalError = 0; 00666 flags->cliAckFault = 0; 00667 flags->srvAckFault = 0; 00668 flags->cliSkipPartial = 0; 00669 flags->srvSkipPartial = 0; 00670 #ifdef HAVE_EXTENDED_MASTER 00671 flags->expectEms = 0; 00672 #endif 00673 } 00674 00675 00676 /* Initialize FIN Capture */ 00677 static void InitFinCapture(FinCaputre* cap) 00678 { 00679 cap->cliFinSeq = 0; 00680 cap->srvFinSeq = 0; 00681 cap->cliCounted = 0; 00682 cap->srvCounted = 0; 00683 } 00684 00685 00686 /* Initialize a Sniffer Session */ 00687 static void InitSession(SnifferSession* session) 00688 { 00689 session->context = 0; 00690 session->sslServer = 0; 00691 session->sslClient = 0; 00692 session->server = 0; 00693 session->client = 0; 00694 session->srvPort = 0; 00695 session->cliPort = 0; 00696 session->cliSeqStart = 0; 00697 session->srvSeqStart = 0; 00698 session->cliExpected = 0; 00699 session->srvExpected = 0; 00700 session->lastUsed = 0; 00701 session->cliReassemblyList = 0; 00702 session->srvReassemblyList = 0; 00703 session->cliReassemblyMemory = 0; 00704 session->srvReassemblyMemory = 0; 00705 session->next = 0; 00706 session->ticketID = 0; 00707 00708 InitFlags(&session->flags); 00709 InitFinCapture(&session->finCaputre); 00710 #ifdef HAVE_EXTENDED_MASTER 00711 session->hash = 0; 00712 #endif 00713 } 00714 00715 00716 /* IP Info from IP Header */ 00717 typedef struct IpInfo { 00718 int length; /* length of this header */ 00719 int total; /* total length of fragment */ 00720 word32 src; /* network order source address */ 00721 word32 dst; /* network order destination address */ 00722 } IpInfo; 00723 00724 00725 /* TCP Info from TCP Header */ 00726 typedef struct TcpInfo { 00727 int srcPort; /* source port */ 00728 int dstPort; /* source port */ 00729 int length; /* length of this header */ 00730 word32 sequence; /* sequence number */ 00731 word32 ackNumber; /* ack number */ 00732 byte fin; /* FIN set */ 00733 byte rst; /* RST set */ 00734 byte syn; /* SYN set */ 00735 byte ack; /* ACK set */ 00736 } TcpInfo; 00737 00738 00739 /* Tcp Pseudo Header for Checksum calculation */ 00740 typedef struct TcpPseudoHdr { 00741 word32 src; /* source address */ 00742 word32 dst; /* destination address */ 00743 byte rsv; /* reserved, always 0 */ 00744 byte protocol; /* IP protocol */ 00745 word16 length; /* tcp header length + data length (doesn't include */ 00746 /* pseudo header length) network order */ 00747 } TcpPseudoHdr; 00748 00749 00750 /* Password Setting Callback */ 00751 static int SetPassword(char* passwd, int sz, int rw, void* userdata) 00752 { 00753 (void)rw; 00754 XSTRNCPY(passwd, (const char*)userdata, sz); 00755 return (int)XSTRLEN((const char*)userdata); 00756 } 00757 00758 00759 /* Ethernet Header */ 00760 typedef struct EthernetHdr { 00761 byte dst[ETHER_IF_ADDR_LEN]; /* destination host address */ 00762 byte src[ETHER_IF_ADDR_LEN]; /* source host address */ 00763 word16 type; /* IP, ARP, etc */ 00764 } EthernetHdr; 00765 00766 00767 /* IP Header */ 00768 typedef struct IpHdr { 00769 byte ver_hl; /* version/header length */ 00770 byte tos; /* type of service */ 00771 word16 length; /* total length */ 00772 word16 id; /* identification */ 00773 word16 offset; /* fragment offset field */ 00774 byte ttl; /* time to live */ 00775 byte protocol; /* protocol */ 00776 word16 sum; /* checksum */ 00777 word32 src; /* source address */ 00778 word32 dst; /* destination address */ 00779 } IpHdr; 00780 00781 00782 #define IP_HL(ip) ( (((ip)->ver_hl) & 0x0f) * 4) 00783 #define IP_V(ip) ( ((ip)->ver_hl) >> 4) 00784 00785 /* TCP Header */ 00786 typedef struct TcpHdr { 00787 word16 srcPort; /* source port */ 00788 word16 dstPort; /* destination port */ 00789 word32 sequence; /* sequence number */ 00790 word32 ack; /* acknoledgment number */ 00791 byte offset; /* data offset, reserved */ 00792 byte flags; /* option flags */ 00793 word16 window; /* window */ 00794 word16 sum; /* checksum */ 00795 word16 urgent; /* urgent pointer */ 00796 } TcpHdr; 00797 00798 #define TCP_LEN(tcp) ( (((tcp)->offset & 0xf0) >> 4) * 4) 00799 #define TCP_FIN 0x01 00800 #define TCP_SYN 0x02 00801 #define TCP_RST 0x04 00802 #define TCP_ACK 0x10 00803 00804 00805 00806 00807 00808 /* Use platform specific GetError to write to tracfile if tracing */ 00809 static void Trace(int idx) 00810 { 00811 if (TraceOn) { 00812 char myBuffer[MAX_ERROR_LEN]; 00813 GetError(idx, myBuffer); 00814 fprintf(TraceFile, "\t%s\n", myBuffer); 00815 #ifdef DEBUG_SNIFFER 00816 fprintf(stderr, "\t%s\n", myBuffer); 00817 #endif 00818 } 00819 } 00820 00821 00822 /* Show TimeStamp for beginning of packet Trace */ 00823 static void TraceHeader(void) 00824 { 00825 if (TraceOn) { 00826 time_t ticks = time(NULL); 00827 fprintf(TraceFile, "\n%s", ctime(&ticks)); 00828 } 00829 } 00830 00831 00832 /* Show Set Server info for Trace */ 00833 static void TraceSetServer(const char* srv, int port, const char* keyFile) 00834 { 00835 if (TraceOn) { 00836 fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n"); 00837 fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port, 00838 keyFile); 00839 } 00840 } 00841 00842 00843 #ifdef HAVE_SNI 00844 00845 /* Show Set Named Server info for Trace */ 00846 static void TraceSetNamedServer(const char* name, 00847 const char* srv, int port, const char* keyFile) 00848 { 00849 if (TraceOn) { 00850 fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n"); 00851 fprintf(TraceFile, "\tname: %s, server: %s, port: %d, keyFile: %s\n", 00852 name, srv, port, keyFile); 00853 } 00854 } 00855 00856 #endif 00857 00858 00859 /* Trace got packet number */ 00860 static void TracePacket(void) 00861 { 00862 if (TraceOn) { 00863 static word32 packetNumber = 0; 00864 fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n", 00865 ++packetNumber); 00866 } 00867 } 00868 00869 00870 /* Convert network byte order address into human readable */ 00871 static char* IpToS(word32 addr, char* str) 00872 { 00873 byte* p = (byte*)&addr; 00874 00875 SNPRINTF(str, TRACE_MSG_SZ, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 00876 00877 return str; 00878 } 00879 00880 00881 /* Show destination and source address from Ip Hdr for packet Trace */ 00882 static void TraceIP(IpHdr* iphdr) 00883 { 00884 if (TraceOn) { 00885 char src[TRACE_MSG_SZ]; 00886 char dst[TRACE_MSG_SZ]; 00887 fprintf(TraceFile, "\tdst:%s src:%s\n", IpToS(iphdr->dst, dst), 00888 IpToS(iphdr->src, src)); 00889 } 00890 } 00891 00892 00893 /* Show destination and source port from Tcp Hdr for packet Trace */ 00894 static void TraceTcp(TcpHdr* tcphdr) 00895 { 00896 if (TraceOn) { 00897 fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort), 00898 ntohs(tcphdr->srcPort)); 00899 } 00900 } 00901 00902 00903 /* Show sequence and payload length for Trace */ 00904 static void TraceSequence(word32 seq, int len) 00905 { 00906 if (TraceOn) { 00907 fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len); 00908 } 00909 } 00910 00911 00912 /* Show sequence and payload length for Trace */ 00913 static void TraceAck(word32 ack, word32 expected) 00914 { 00915 if (TraceOn) { 00916 fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected); 00917 } 00918 } 00919 00920 00921 /* Show relative expected and relative received sequences */ 00922 static void TraceRelativeSequence(word32 expected, word32 got) 00923 { 00924 if (TraceOn) { 00925 fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n", 00926 expected, got); 00927 } 00928 } 00929 00930 00931 /* Show server sequence startup from SYN */ 00932 static void TraceServerSyn(word32 seq) 00933 { 00934 if (TraceOn) { 00935 fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq); 00936 } 00937 } 00938 00939 00940 /* Show client sequence startup from SYN */ 00941 static void TraceClientSyn(word32 seq) 00942 { 00943 if (TraceOn) { 00944 fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq); 00945 } 00946 } 00947 00948 00949 /* Show client FIN capture */ 00950 static void TraceClientFin(word32 finSeq, word32 relSeq) 00951 { 00952 if (TraceOn) { 00953 fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n", 00954 finSeq, relSeq); 00955 } 00956 } 00957 00958 00959 /* Show server FIN capture */ 00960 static void TraceServerFin(word32 finSeq, word32 relSeq) 00961 { 00962 if (TraceOn) { 00963 fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n", 00964 finSeq, relSeq); 00965 } 00966 } 00967 00968 00969 /* Show number of SSL data bytes decoded, could be 0 (ok) */ 00970 static void TraceGotData(int bytes) 00971 { 00972 if (TraceOn) { 00973 fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes); 00974 } 00975 } 00976 00977 00978 /* Show bytes added to old SSL App data */ 00979 static void TraceAddedData(int newBytes, int existingBytes) 00980 { 00981 if (TraceOn) { 00982 fprintf(TraceFile, 00983 "\t%d bytes added to %d existing bytes in User Buffer\n", 00984 newBytes, existingBytes); 00985 } 00986 } 00987 00988 00989 /* Show Stale Session */ 00990 static void TraceStaleSession(void) 00991 { 00992 if (TraceOn) { 00993 fprintf(TraceFile, "\tFound a stale session\n"); 00994 } 00995 } 00996 00997 00998 /* Show Finding Stale Sessions */ 00999 static void TraceFindingStale(void) 01000 { 01001 if (TraceOn) { 01002 fprintf(TraceFile, "\tTrying to find Stale Sessions\n"); 01003 } 01004 } 01005 01006 01007 /* Show Removed Session */ 01008 static void TraceRemovedSession(void) 01009 { 01010 if (TraceOn) { 01011 fprintf(TraceFile, "\tRemoved it\n"); 01012 } 01013 } 01014 01015 01016 /* Set user error string */ 01017 static void SetError(int idx, char* error, SnifferSession* session, int fatal) 01018 { 01019 GetError(idx, error); 01020 Trace(idx); 01021 if (session && fatal == FATAL_ERROR_STATE) 01022 session->flags.fatalError = 1; 01023 } 01024 01025 01026 /* See if this IPV4 network order address has been registered */ 01027 /* return 1 is true, 0 is false */ 01028 static int IsServerRegistered(word32 addr) 01029 { 01030 int ret = 0; /* false */ 01031 SnifferServer* sniffer; 01032 01033 wc_LockMutex(&ServerListMutex); 01034 01035 sniffer = ServerList; 01036 while (sniffer) { 01037 if (sniffer->server == addr) { 01038 ret = 1; 01039 break; 01040 } 01041 sniffer = sniffer->next; 01042 } 01043 01044 wc_UnLockMutex(&ServerListMutex); 01045 01046 return ret; 01047 } 01048 01049 01050 /* See if this port has been registered to watch */ 01051 /* return 1 is true, 0 is false */ 01052 static int IsPortRegistered(word32 port) 01053 { 01054 int ret = 0; /* false */ 01055 SnifferServer* sniffer; 01056 01057 wc_LockMutex(&ServerListMutex); 01058 01059 sniffer = ServerList; 01060 while (sniffer) { 01061 if (sniffer->port == (int)port) { 01062 ret = 1; 01063 break; 01064 } 01065 sniffer = sniffer->next; 01066 } 01067 01068 wc_UnLockMutex(&ServerListMutex); 01069 01070 return ret; 01071 } 01072 01073 01074 /* Get SnifferServer from IP and Port */ 01075 static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo) 01076 { 01077 SnifferServer* sniffer; 01078 01079 wc_LockMutex(&ServerListMutex); 01080 01081 sniffer = ServerList; 01082 while (sniffer) { 01083 if (sniffer->port == tcpInfo->srcPort && sniffer->server == ipInfo->src) 01084 break; 01085 if (sniffer->port == tcpInfo->dstPort && sniffer->server == ipInfo->dst) 01086 break; 01087 sniffer = sniffer->next; 01088 } 01089 01090 wc_UnLockMutex(&ServerListMutex); 01091 01092 return sniffer; 01093 } 01094 01095 01096 /* Hash the Session Info, return hash row */ 01097 static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo) 01098 { 01099 word32 hash = ipInfo->src * ipInfo->dst; 01100 hash *= tcpInfo->srcPort * tcpInfo->dstPort; 01101 01102 return hash % HASH_SIZE; 01103 } 01104 01105 01106 /* Get Exisiting SnifferSession from IP and Port */ 01107 static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo) 01108 { 01109 SnifferSession* session; 01110 time_t currTime = time(NULL); 01111 word32 row = SessionHash(ipInfo, tcpInfo); 01112 01113 assert(row <= HASH_SIZE); 01114 01115 wc_LockMutex(&SessionMutex); 01116 01117 session = SessionTable[row]; 01118 while (session) { 01119 if (session->server == ipInfo->src && session->client == ipInfo->dst && 01120 session->srvPort == tcpInfo->srcPort && 01121 session->cliPort == tcpInfo->dstPort) 01122 break; 01123 if (session->client == ipInfo->src && session->server == ipInfo->dst && 01124 session->cliPort == tcpInfo->srcPort && 01125 session->srvPort == tcpInfo->dstPort) 01126 break; 01127 01128 session = session->next; 01129 } 01130 01131 if (session) 01132 session->lastUsed= currTime; /* keep session alive, remove stale will */ 01133 /* leave alone */ 01134 wc_UnLockMutex(&SessionMutex); 01135 01136 /* determine side */ 01137 if (session) { 01138 if (ipInfo->dst == session->context->server && 01139 tcpInfo->dstPort == session->context->port) 01140 session->flags.side = WOLFSSL_SERVER_END; 01141 else 01142 session->flags.side = WOLFSSL_CLIENT_END; 01143 } 01144 01145 return session; 01146 } 01147 01148 01149 #ifdef HAVE_SNI 01150 01151 static int LoadKeyFile(byte** keyBuf, word32* keyBufSz, 01152 const char* keyFile, int typeKey, 01153 const char* password) 01154 { 01155 byte* loadBuf; 01156 long fileSz = 0; 01157 XFILE file; 01158 int ret; 01159 01160 if (keyBuf == NULL || keyBufSz == NULL || keyFile == NULL) { 01161 return -1; 01162 } 01163 01164 file = XFOPEN(keyFile, "rb"); 01165 if (file == XBADFILE) return -1; 01166 XFSEEK(file, 0, XSEEK_END); 01167 fileSz = XFTELL(file); 01168 XREWIND(file); 01169 01170 loadBuf = (byte*)malloc(fileSz); 01171 if (loadBuf == NULL) { 01172 XFCLOSE(file); 01173 return -1; 01174 } 01175 01176 ret = (int)XFREAD(loadBuf, 1, fileSz, file); 01177 XFCLOSE(file); 01178 01179 if (ret != fileSz) { 01180 free(loadBuf); 01181 return -1; 01182 } 01183 01184 if (typeKey == SSL_FILETYPE_PEM) { 01185 byte* saveBuf = (byte*)malloc(fileSz); 01186 int saveBufSz = 0; 01187 01188 ret = -1; 01189 if (saveBuf != NULL) { 01190 saveBufSz = wolfSSL_KeyPemToDer(loadBuf, (int)fileSz, 01191 saveBuf, (int)fileSz, password); 01192 if (saveBufSz < 0) { 01193 saveBufSz = 0; 01194 free(saveBuf); 01195 saveBuf = NULL; 01196 } 01197 else 01198 ret = 0; 01199 } 01200 01201 ForceZero(loadBuf, (word32)fileSz); 01202 free(loadBuf); 01203 01204 if (saveBuf) { 01205 *keyBuf = saveBuf; 01206 *keyBufSz = (word32)saveBufSz; 01207 } 01208 } 01209 else { 01210 *keyBuf = loadBuf; 01211 *keyBufSz = (word32)fileSz; 01212 } 01213 01214 if (ret < 0) { 01215 return -1; 01216 } 01217 01218 return ret; 01219 } 01220 01221 #endif 01222 01223 01224 static int SetNamedPrivateKey(const char* name, const char* address, int port, 01225 const char* keyFile, int typeKey, const char* password, char* error) 01226 { 01227 SnifferServer* sniffer; 01228 int ret; 01229 int type = (typeKey == FILETYPE_PEM) ? SSL_FILETYPE_PEM : 01230 SSL_FILETYPE_ASN1; 01231 int isNew = 0; 01232 word32 serverIp; 01233 01234 #ifdef HAVE_SNI 01235 NamedKey* namedKey = NULL; 01236 #endif 01237 01238 (void)name; 01239 #ifdef HAVE_SNI 01240 if (name != NULL) { 01241 namedKey = (NamedKey*)malloc(sizeof(NamedKey)); 01242 if (namedKey == NULL) { 01243 SetError(MEMORY_STR, error, NULL, 0); 01244 return -1; 01245 } 01246 XMEMSET(namedKey, 0, sizeof(NamedKey)); 01247 01248 namedKey->nameSz = (word32)XSTRLEN(name); 01249 XSTRNCPY(namedKey->name, name, sizeof(namedKey->name)); 01250 if (namedKey->nameSz >= sizeof(namedKey->name)) { 01251 namedKey->nameSz = sizeof(namedKey->name) - 1; 01252 namedKey->name[namedKey->nameSz] = '\0'; 01253 } 01254 01255 ret = LoadKeyFile(&namedKey->key, &namedKey->keySz, 01256 keyFile, type, password); 01257 if (ret < 0) { 01258 SetError(KEY_FILE_STR, error, NULL, 0); 01259 FreeNamedKey(namedKey); 01260 return -1; 01261 } 01262 } 01263 #endif 01264 01265 serverIp = inet_addr(address); 01266 sniffer = ServerList; 01267 while (sniffer != NULL && 01268 (sniffer->server != serverIp || sniffer->port != port)) { 01269 sniffer = sniffer->next; 01270 } 01271 01272 if (sniffer == NULL) { 01273 isNew = 1; 01274 sniffer = (SnifferServer*)malloc(sizeof(SnifferServer)); 01275 if (sniffer == NULL) { 01276 SetError(MEMORY_STR, error, NULL, 0); 01277 #ifdef HAVE_SNI 01278 FreeNamedKey(namedKey); 01279 #endif 01280 return -1; 01281 } 01282 InitSnifferServer(sniffer); 01283 01284 XSTRNCPY(sniffer->address, address, MAX_SERVER_ADDRESS-1); 01285 sniffer->address[MAX_SERVER_ADDRESS-1] = '\0'; 01286 sniffer->server = serverIp; 01287 sniffer->port = port; 01288 01289 sniffer->ctx = SSL_CTX_new(TLSv1_client_method()); 01290 if (!sniffer->ctx) { 01291 SetError(MEMORY_STR, error, NULL, 0); 01292 #ifdef HAVE_SNI 01293 FreeNamedKey(namedKey); 01294 #endif 01295 FreeSnifferServer(sniffer); 01296 return -1; 01297 } 01298 } 01299 01300 if (name == NULL) { 01301 if (password) { 01302 SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword); 01303 SSL_CTX_set_default_passwd_cb_userdata( 01304 sniffer->ctx, (void*)password); 01305 } 01306 ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type); 01307 if (ret != SSL_SUCCESS) { 01308 SetError(KEY_FILE_STR, error, NULL, 0); 01309 if (isNew) 01310 FreeSnifferServer(sniffer); 01311 return -1; 01312 } 01313 } 01314 #ifdef HAVE_SNI 01315 else { 01316 wc_LockMutex(&sniffer->namedKeysMutex); 01317 namedKey->next = sniffer->namedKeys; 01318 sniffer->namedKeys = namedKey; 01319 wc_UnLockMutex(&sniffer->namedKeysMutex); 01320 } 01321 #endif 01322 01323 if (isNew) { 01324 sniffer->next = ServerList; 01325 ServerList = sniffer; 01326 } 01327 01328 return 0; 01329 } 01330 01331 01332 #ifdef HAVE_SNI 01333 01334 /* Sets the private key for a specific name, server and port */ 01335 /* returns 0 on success, -1 on error */ 01336 int ssl_SetNamedPrivateKey(const char* name, 01337 const char* address, int port, 01338 const char* keyFile, int typeKey, 01339 const char* password, char* error) 01340 { 01341 int ret; 01342 01343 TraceHeader(); 01344 TraceSetNamedServer(name, address, port, keyFile); 01345 01346 wc_LockMutex(&ServerListMutex); 01347 ret = SetNamedPrivateKey(name, address, port, keyFile, 01348 typeKey, password, error); 01349 wc_UnLockMutex(&ServerListMutex); 01350 01351 if (ret == 0) 01352 Trace(NEW_SERVER_STR); 01353 01354 return ret; 01355 } 01356 01357 #endif 01358 01359 01360 /* Sets the private key for a specific server and port */ 01361 /* returns 0 on success, -1 on error */ 01362 int ssl_SetPrivateKey(const char* address, int port, const char* keyFile, 01363 int typeKey, const char* password, char* error) 01364 { 01365 int ret; 01366 01367 TraceHeader(); 01368 TraceSetServer(address, port, keyFile); 01369 01370 wc_LockMutex(&ServerListMutex); 01371 ret = SetNamedPrivateKey(NULL, address, port, keyFile, 01372 typeKey, password, error); 01373 wc_UnLockMutex(&ServerListMutex); 01374 01375 if (ret == 0) 01376 Trace(NEW_SERVER_STR); 01377 01378 return ret; 01379 } 01380 01381 01382 /* Check IP Header for IPV4, TCP, and a registered server address */ 01383 /* returns 0 on success, -1 on error */ 01384 static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error) 01385 { 01386 int version = IP_V(iphdr); 01387 01388 TraceIP(iphdr); 01389 Trace(IP_CHECK_STR); 01390 01391 if (version != IPV4) { 01392 SetError(BAD_IPVER_STR, error, NULL, 0); 01393 return -1; 01394 } 01395 01396 if (iphdr->protocol != TCP_PROTOCOL) { 01397 SetError(BAD_PROTO_STR, error, NULL, 0); 01398 return -1; 01399 } 01400 01401 if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) { 01402 SetError(SERVER_NOT_REG_STR, error, NULL, 0); 01403 return -1; 01404 } 01405 01406 info->length = IP_HL(iphdr); 01407 info->total = ntohs(iphdr->length); 01408 info->src = iphdr->src; 01409 info->dst = iphdr->dst; 01410 01411 if (info->total == 0) 01412 info->total = length; /* reassembled may be off */ 01413 01414 return 0; 01415 } 01416 01417 01418 /* Check TCP Header for a registered port */ 01419 /* returns 0 on success, -1 on error */ 01420 static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error) 01421 { 01422 TraceTcp(tcphdr); 01423 Trace(TCP_CHECK_STR); 01424 info->srcPort = ntohs(tcphdr->srcPort); 01425 info->dstPort = ntohs(tcphdr->dstPort); 01426 info->length = TCP_LEN(tcphdr); 01427 info->sequence = ntohl(tcphdr->sequence); 01428 info->fin = tcphdr->flags & TCP_FIN; 01429 info->rst = tcphdr->flags & TCP_RST; 01430 info->syn = tcphdr->flags & TCP_SYN; 01431 info->ack = tcphdr->flags & TCP_ACK; 01432 if (info->ack) 01433 info->ackNumber = ntohl(tcphdr->ack); 01434 01435 if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) { 01436 SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0); 01437 return -1; 01438 } 01439 01440 return 0; 01441 } 01442 01443 01444 /* Decode Record Layer Header */ 01445 static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size) 01446 { 01447 XMEMCPY(rh, input, RECORD_HEADER_SZ); 01448 *size = (rh->length[0] << 8) | rh->length[1]; 01449 01450 if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA)) 01451 return LENGTH_ERROR; 01452 01453 return 0; 01454 } 01455 01456 01457 /* Process Client Key Exchange, RSA only */ 01458 static int ProcessClientKeyExchange(const byte* input, int* sslBytes, 01459 SnifferSession* session, char* error) 01460 { 01461 word32 idx = 0; 01462 RsaKey key; 01463 int ret; 01464 01465 if (session->sslServer->buffers.key == NULL || 01466 session->sslServer->buffers.key->buffer == NULL || 01467 session->sslServer->buffers.key->length == 0) { 01468 01469 SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE); 01470 return -1; 01471 } 01472 ret = wc_InitRsaKey(&key, 0); 01473 if (ret == 0) 01474 ret = wc_RsaPrivateKeyDecode(session->sslServer->buffers.key->buffer, 01475 &idx, &key, session->sslServer->buffers.key->length); 01476 if (ret == 0) { 01477 int length = wc_RsaEncryptSize(&key); 01478 01479 if (IsTLS(session->sslServer)) 01480 input += 2; /* tls pre length */ 01481 01482 if (length > *sslBytes) { 01483 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); 01484 wc_FreeRsaKey(&key); 01485 return -1; 01486 } 01487 #ifdef WC_RSA_BLINDING 01488 ret = wc_RsaSetRNG(&key, session->sslServer->rng); 01489 if (ret != 0) { 01490 SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); 01491 return -1; 01492 } 01493 #endif 01494 ret = wc_RsaPrivateDecrypt(input, length, 01495 session->sslServer->arrays->preMasterSecret,SECRET_LEN, &key); 01496 01497 if (ret != SECRET_LEN) { 01498 SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); 01499 wc_FreeRsaKey(&key); 01500 return -1; 01501 } 01502 session->sslServer->arrays->preMasterSz = SECRET_LEN; 01503 01504 /* store for client side as well */ 01505 XMEMCPY(session->sslClient->arrays->preMasterSecret, 01506 session->sslServer->arrays->preMasterSecret, SECRET_LEN); 01507 session->sslClient->arrays->preMasterSz = SECRET_LEN; 01508 01509 #ifdef SHOW_SECRETS 01510 { 01511 int i; 01512 printf("pre master secret: "); 01513 for (i = 0; i < SECRET_LEN; i++) 01514 printf("%02x", session->sslServer->arrays->preMasterSecret[i]); 01515 printf("\n"); 01516 } 01517 #endif 01518 } 01519 else { 01520 SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE); 01521 wc_FreeRsaKey(&key); 01522 return -1; 01523 } 01524 01525 if (SetCipherSpecs(session->sslServer) != 0) { 01526 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); 01527 wc_FreeRsaKey(&key); 01528 return -1; 01529 } 01530 01531 if (SetCipherSpecs(session->sslClient) != 0) { 01532 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); 01533 wc_FreeRsaKey(&key); 01534 return -1; 01535 } 01536 01537 ret = MakeMasterSecret(session->sslServer); 01538 ret += MakeMasterSecret(session->sslClient); 01539 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE); 01540 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE); 01541 01542 if (ret != 0) { 01543 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE); 01544 return -1; 01545 } 01546 01547 #ifdef SHOW_SECRETS 01548 { 01549 int i; 01550 printf("server master secret: "); 01551 for (i = 0; i < SECRET_LEN; i++) 01552 printf("%02x", session->sslServer->arrays->masterSecret[i]); 01553 printf("\n"); 01554 01555 printf("client master secret: "); 01556 for (i = 0; i < SECRET_LEN; i++) 01557 printf("%02x", session->sslClient->arrays->masterSecret[i]); 01558 printf("\n"); 01559 01560 printf("server suite = %d\n", session->sslServer->options.cipherSuite); 01561 printf("client suite = %d\n", session->sslClient->options.cipherSuite); 01562 } 01563 #endif 01564 01565 wc_FreeRsaKey(&key); 01566 return ret; 01567 } 01568 01569 01570 /* Process Session Ticket */ 01571 static int ProcessSessionTicket(const byte* input, int* sslBytes, 01572 SnifferSession* session, char* error) 01573 { 01574 word16 len; 01575 01576 /* make sure can read through hint and len */ 01577 if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) { 01578 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE); 01579 return -1; 01580 } 01581 01582 input += TICKET_HINT_LEN; /* skip over hint */ 01583 *sslBytes -= TICKET_HINT_LEN; 01584 01585 len = (word16)((input[0] << 8) | input[1]); 01586 input += LENGTH_SZ; 01587 *sslBytes -= LENGTH_SZ; 01588 01589 /* make sure can read through ticket */ 01590 if (len > *sslBytes || len < ID_LEN) { 01591 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE); 01592 return -1; 01593 } 01594 01595 /* store session with macID as sessionID */ 01596 session->sslServer->options.haveSessionId = 1; 01597 XMEMCPY(session->sslServer->arrays->sessionID, input + len - ID_LEN,ID_LEN); 01598 01599 return 0; 01600 } 01601 01602 01603 /* Process Server Hello */ 01604 static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, 01605 SnifferSession* session, char* error) 01606 { 01607 ProtocolVersion pv; 01608 byte b; 01609 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN; 01610 int doResume = 0; 01611 int initialBytes = *sslBytes; 01612 01613 (void)msgSz; 01614 (void)initialBytes; 01615 01616 /* make sure we didn't miss ClientHello */ 01617 if (session->flags.clientHello == 0) { 01618 SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE); 01619 return -1; 01620 } 01621 01622 /* make sure can read through session len */ 01623 if (toRead > *sslBytes) { 01624 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01625 return -1; 01626 } 01627 01628 XMEMCPY(&pv, input, VERSION_SZ); 01629 input += VERSION_SZ; 01630 *sslBytes -= VERSION_SZ; 01631 01632 session->sslServer->version = pv; 01633 session->sslClient->version = pv; 01634 01635 XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN); 01636 XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN); 01637 input += RAN_LEN; 01638 *sslBytes -= RAN_LEN; 01639 01640 b = *input++; 01641 *sslBytes -= 1; 01642 01643 /* make sure can read through compression */ 01644 if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) { 01645 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01646 return -1; 01647 } 01648 if (b) { 01649 XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN); 01650 session->sslServer->options.haveSessionId = 1; 01651 } 01652 input += b; 01653 *sslBytes -= b; 01654 01655 /* cipher suite */ 01656 b = *input++; /* first byte, ECC or not */ 01657 session->sslServer->options.cipherSuite0 = b; 01658 session->sslClient->options.cipherSuite0 = b; 01659 b = *input++; 01660 session->sslServer->options.cipherSuite = b; 01661 session->sslClient->options.cipherSuite = b; 01662 *sslBytes -= SUITE_LEN; 01663 01664 /* compression */ 01665 b = *input++; 01666 *sslBytes -= ENUM_LEN; 01667 01668 if (b) { 01669 SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE); 01670 return -1; 01671 } 01672 01673 #ifdef HAVE_EXTENDED_MASTER 01674 /* extensions */ 01675 if ((initialBytes - *sslBytes) < msgSz) { 01676 word16 len; 01677 01678 /* skip extensions until extended master secret */ 01679 /* make sure can read len */ 01680 if (SUITE_LEN > *sslBytes) { 01681 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01682 return -1; 01683 } 01684 len = (word16)((input[0] << 8) | input[1]); 01685 input += SUITE_LEN; 01686 *sslBytes -= SUITE_LEN; 01687 /* make sure can read through all extensions */ 01688 if (len > *sslBytes) { 01689 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01690 return -1; 01691 } 01692 01693 while (len >= EXT_TYPE_SZ + LENGTH_SZ) { 01694 byte extType[EXT_TYPE_SZ]; 01695 word16 extLen; 01696 01697 extType[0] = input[0]; 01698 extType[1] = input[1]; 01699 input += EXT_TYPE_SZ; 01700 *sslBytes -= EXT_TYPE_SZ; 01701 01702 extLen = (word16)((input[0] << 8) | input[1]); 01703 input += LENGTH_SZ; 01704 *sslBytes -= LENGTH_SZ; 01705 01706 /* make sure can read through individual extension */ 01707 if (extLen > *sslBytes) { 01708 SetError(SERVER_HELLO_INPUT_STR, error, session, 01709 FATAL_ERROR_STATE); 01710 return -1; 01711 } 01712 01713 if (extType[0] == 0x00 && extType[1] == EXT_MASTER_SECRET) { 01714 session->flags.expectEms = 1; 01715 } 01716 01717 input += extLen; 01718 *sslBytes -= extLen; 01719 len -= extLen + EXT_TYPE_SZ + LENGTH_SZ; 01720 } 01721 } 01722 01723 if (!session->flags.expectEms) { 01724 free(session->hash); 01725 session->hash = NULL; 01726 } 01727 #endif 01728 01729 if (session->sslServer->options.haveSessionId && 01730 XMEMCMP(session->sslServer->arrays->sessionID, 01731 session->sslClient->arrays->sessionID, ID_LEN) == 0) 01732 doResume = 1; 01733 else if (session->sslClient->options.haveSessionId == 0 && 01734 session->sslServer->options.haveSessionId == 0 && 01735 session->ticketID) 01736 doResume = 1; 01737 01738 if (session->ticketID && doResume) { 01739 /* use ticketID to retrieve from session, prefer over sessionID */ 01740 XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN); 01741 session->sslServer->options.haveSessionId = 1; /* may not have 01742 actual sessionID */ 01743 } 01744 01745 if (doResume ) { 01746 int ret = 0; 01747 SSL_SESSION* resume = GetSession(session->sslServer, 01748 session->sslServer->arrays->masterSecret, 0); 01749 if (resume == NULL) { 01750 SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE); 01751 return -1; 01752 } 01753 /* make sure client has master secret too */ 01754 XMEMCPY(session->sslClient->arrays->masterSecret, 01755 session->sslServer->arrays->masterSecret, SECRET_LEN); 01756 session->flags.resuming = 1; 01757 01758 Trace(SERVER_DID_RESUMPTION_STR); 01759 if (SetCipherSpecs(session->sslServer) != 0) { 01760 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); 01761 return -1; 01762 } 01763 01764 if (SetCipherSpecs(session->sslClient) != 0) { 01765 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); 01766 return -1; 01767 } 01768 01769 if (session->sslServer->options.tls) { 01770 ret = DeriveTlsKeys(session->sslServer); 01771 ret += DeriveTlsKeys(session->sslClient); 01772 } 01773 else { 01774 ret = DeriveKeys(session->sslServer); 01775 ret += DeriveKeys(session->sslClient); 01776 } 01777 ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE); 01778 ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE); 01779 01780 if (ret != 0) { 01781 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE); 01782 return -1; 01783 } 01784 } 01785 #ifdef SHOW_SECRETS 01786 { 01787 int i; 01788 printf("cipher suite = 0x%02x\n", 01789 session->sslServer->options.cipherSuite); 01790 printf("server random: "); 01791 for (i = 0; i < RAN_LEN; i++) 01792 printf("%02x", session->sslServer->arrays->serverRandom[i]); 01793 printf("\n"); 01794 } 01795 #endif 01796 return 0; 01797 } 01798 01799 01800 /* Process normal Client Hello */ 01801 static int ProcessClientHello(const byte* input, int* sslBytes, 01802 SnifferSession* session, char* error) 01803 { 01804 byte bLen; 01805 word16 len; 01806 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN; 01807 01808 #ifdef HAVE_SNI 01809 { 01810 byte name[MAX_SERVER_NAME]; 01811 word32 nameSz = sizeof(name); 01812 int ret; 01813 01814 ret = wolfSSL_SNI_GetFromBuffer( 01815 input - HANDSHAKE_HEADER_SZ - RECORD_HEADER_SZ, 01816 *sslBytes + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ, 01817 WOLFSSL_SNI_HOST_NAME, name, &nameSz); 01818 01819 if (ret == SSL_SUCCESS) { 01820 NamedKey* namedKey; 01821 01822 if (nameSz >= sizeof(name)) 01823 nameSz = sizeof(name) - 1; 01824 name[nameSz] = 0; 01825 wc_LockMutex(&session->context->namedKeysMutex); 01826 namedKey = session->context->namedKeys; 01827 while (namedKey != NULL) { 01828 if (nameSz == namedKey->nameSz && 01829 XSTRNCMP((char*)name, namedKey->name, nameSz) == 0) { 01830 if (wolfSSL_use_PrivateKey_buffer(session->sslServer, 01831 namedKey->key, namedKey->keySz, 01832 SSL_FILETYPE_ASN1) != SSL_SUCCESS) { 01833 wc_UnLockMutex(&session->context->namedKeysMutex); 01834 SetError(CLIENT_HELLO_LATE_KEY_STR, error, session, 01835 FATAL_ERROR_STATE); 01836 return -1; 01837 } 01838 break; 01839 } 01840 else 01841 namedKey = namedKey->next; 01842 } 01843 wc_UnLockMutex(&session->context->namedKeysMutex); 01844 } 01845 } 01846 #endif 01847 01848 session->flags.clientHello = 1; /* don't process again */ 01849 01850 /* make sure can read up to session len */ 01851 if (toRead > *sslBytes) { 01852 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01853 return -1; 01854 } 01855 01856 /* skip, get negotiated one from server hello */ 01857 input += VERSION_SZ; 01858 *sslBytes -= VERSION_SZ; 01859 01860 XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN); 01861 XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN); 01862 01863 input += RAN_LEN; 01864 *sslBytes -= RAN_LEN; 01865 01866 /* store session in case trying to resume */ 01867 bLen = *input++; 01868 *sslBytes -= ENUM_LEN; 01869 if (bLen) { 01870 if (ID_LEN > *sslBytes) { 01871 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01872 return -1; 01873 } 01874 Trace(CLIENT_RESUME_TRY_STR); 01875 XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN); 01876 session->sslClient->options.haveSessionId = 1; 01877 } 01878 #ifdef SHOW_SECRETS 01879 { 01880 int i; 01881 printf("client random: "); 01882 for (i = 0; i < RAN_LEN; i++) 01883 printf("%02x", session->sslServer->arrays->clientRandom[i]); 01884 printf("\n"); 01885 } 01886 #endif 01887 01888 input += bLen; 01889 *sslBytes -= bLen; 01890 01891 /* skip cipher suites */ 01892 /* make sure can read len */ 01893 if (SUITE_LEN > *sslBytes) { 01894 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01895 return -1; 01896 } 01897 len = (word16)((input[0] << 8) | input[1]); 01898 input += SUITE_LEN; 01899 *sslBytes -= SUITE_LEN; 01900 /* make sure can read suites + comp len */ 01901 if (len + ENUM_LEN > *sslBytes) { 01902 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01903 return -1; 01904 } 01905 input += len; 01906 *sslBytes -= len; 01907 01908 /* skip compression */ 01909 bLen = *input++; 01910 *sslBytes -= ENUM_LEN; 01911 /* make sure can read len */ 01912 if (bLen > *sslBytes) { 01913 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01914 return -1; 01915 } 01916 input += bLen; 01917 *sslBytes -= bLen; 01918 01919 if (*sslBytes == 0) { 01920 /* no extensions */ 01921 return 0; 01922 } 01923 01924 /* skip extensions until session ticket */ 01925 /* make sure can read len */ 01926 if (SUITE_LEN > *sslBytes) { 01927 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01928 return -1; 01929 } 01930 len = (word16)((input[0] << 8) | input[1]); 01931 input += SUITE_LEN; 01932 *sslBytes -= SUITE_LEN; 01933 /* make sure can read through all extensions */ 01934 if (len > *sslBytes) { 01935 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01936 return -1; 01937 } 01938 01939 while (len >= EXT_TYPE_SZ + LENGTH_SZ) { 01940 byte extType[EXT_TYPE_SZ]; 01941 word16 extLen; 01942 01943 extType[0] = input[0]; 01944 extType[1] = input[1]; 01945 input += EXT_TYPE_SZ; 01946 *sslBytes -= EXT_TYPE_SZ; 01947 01948 extLen = (word16)((input[0] << 8) | input[1]); 01949 input += LENGTH_SZ; 01950 *sslBytes -= LENGTH_SZ; 01951 01952 /* make sure can read through individual extension */ 01953 if (extLen > *sslBytes) { 01954 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); 01955 return -1; 01956 } 01957 01958 if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) { 01959 01960 /* make sure can read through ticket if there is a non blank one */ 01961 if (extLen && extLen < ID_LEN) { 01962 SetError(CLIENT_HELLO_INPUT_STR, error, session, 01963 FATAL_ERROR_STATE); 01964 return -1; 01965 } 01966 01967 if (extLen) { 01968 if (session->ticketID == 0) { 01969 session->ticketID = (byte*)malloc(ID_LEN); 01970 if (session->ticketID == 0) { 01971 SetError(MEMORY_STR, error, session, 01972 FATAL_ERROR_STATE); 01973 return -1; 01974 } 01975 } 01976 XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN); 01977 } 01978 } 01979 01980 input += extLen; 01981 *sslBytes -= extLen; 01982 len -= extLen + EXT_TYPE_SZ + LENGTH_SZ; 01983 } 01984 01985 return 0; 01986 } 01987 01988 01989 /* Process Finished */ 01990 static int ProcessFinished(const byte* input, int size, int* sslBytes, 01991 SnifferSession* session, char* error) 01992 { 01993 SSL* ssl; 01994 word32 inOutIdx = 0; 01995 int ret; 01996 01997 if (session->flags.side == WOLFSSL_SERVER_END) 01998 ssl = session->sslServer; 01999 else 02000 ssl = session->sslClient; 02001 02002 ret = DoFinished(ssl, input, &inOutIdx, (word32) size, (word32) *sslBytes, 02003 SNIFF); 02004 *sslBytes -= (int)inOutIdx; 02005 02006 if (ret < 0) { 02007 SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE); 02008 return ret; 02009 } 02010 02011 if (ret == 0 && session->flags.cached == 0) { 02012 if (session->sslServer->options.haveSessionId) { 02013 WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL, 0); 02014 if (sess == NULL) 02015 AddSession(session->sslServer); /* don't re add */ 02016 session->flags.cached = 1; 02017 } 02018 } 02019 02020 /* If receiving a finished message from one side, free the resources 02021 * from the other side's tracker. */ 02022 if (session->flags.side == WOLFSSL_SERVER_END) 02023 FreeHandshakeResources(session->sslClient); 02024 else 02025 FreeHandshakeResources(session->sslServer); 02026 02027 return ret; 02028 } 02029 02030 02031 /* Process HandShake input */ 02032 static int DoHandShake(const byte* input, int* sslBytes, 02033 SnifferSession* session, char* error) 02034 { 02035 byte type; 02036 int size; 02037 int ret = 0; 02038 int startBytes; 02039 02040 if (*sslBytes < HANDSHAKE_HEADER_SZ) { 02041 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE); 02042 return -1; 02043 } 02044 type = input[0]; 02045 size = (input[1] << 16) | (input[2] << 8) | input[3]; 02046 02047 input += HANDSHAKE_HEADER_SZ; 02048 *sslBytes -= HANDSHAKE_HEADER_SZ; 02049 startBytes = *sslBytes; 02050 02051 if (*sslBytes < size) { 02052 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE); 02053 return -1; 02054 } 02055 02056 /* A session's arrays are released when the handshake is completed. */ 02057 if (session->sslServer->arrays == NULL && 02058 session->sslClient->arrays == NULL) { 02059 02060 SetError(NO_SECURE_RENEGOTIATION, error, session, FATAL_ERROR_STATE); 02061 return -1; 02062 } 02063 02064 #ifdef HAVE_EXTENDED_MASTER 02065 if (session->hash) { 02066 if (HashUpdate(session->hash, input, size) != 0) { 02067 SetError(EXTENDED_MASTER_HASH_STR, error, 02068 session, FATAL_ERROR_STATE); 02069 return -1; 02070 } 02071 } 02072 #endif 02073 02074 switch (type) { 02075 case hello_verify_request: 02076 Trace(GOT_HELLO_VERIFY_STR); 02077 break; 02078 case hello_request: 02079 Trace(GOT_HELLO_REQUEST_STR); 02080 break; 02081 case session_ticket: 02082 Trace(GOT_SESSION_TICKET_STR); 02083 ret = ProcessSessionTicket(input, sslBytes, session, error); 02084 break; 02085 case server_hello: 02086 Trace(GOT_SERVER_HELLO_STR); 02087 ret = ProcessServerHello(size, input, sslBytes, session, error); 02088 break; 02089 case certificate_request: 02090 Trace(GOT_CERT_REQ_STR); 02091 break; 02092 case server_key_exchange: 02093 Trace(GOT_SERVER_KEY_EX_STR); 02094 /* can't know temp key passively */ 02095 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); 02096 ret = -1; 02097 break; 02098 case certificate: 02099 Trace(GOT_CERT_STR); 02100 break; 02101 case server_hello_done: 02102 Trace(GOT_SERVER_HELLO_DONE_STR); 02103 break; 02104 case finished: 02105 Trace(GOT_FINISHED_STR); 02106 ret = ProcessFinished(input, size, sslBytes, session, error); 02107 break; 02108 case client_hello: 02109 Trace(GOT_CLIENT_HELLO_STR); 02110 ret = ProcessClientHello(input, sslBytes, session, error); 02111 break; 02112 case client_key_exchange: 02113 Trace(GOT_CLIENT_KEY_EX_STR); 02114 #ifdef HAVE_EXTENDED_MASTER 02115 if (session->flags.expectEms && session->hash != NULL) { 02116 if (HashCopy(session->sslServer->hsHashes, 02117 session->hash) == 0 && 02118 HashCopy(session->sslClient->hsHashes, 02119 session->hash) == 0) { 02120 02121 session->sslServer->options.haveEMS = 1; 02122 session->sslClient->options.haveEMS = 1; 02123 } 02124 else { 02125 SetError(EXTENDED_MASTER_HASH_STR, error, 02126 session, FATAL_ERROR_STATE); 02127 ret = -1; 02128 } 02129 XMEMSET(session->hash, 0, sizeof(HsHashes)); 02130 free(session->hash); 02131 session->hash = NULL; 02132 } 02133 else { 02134 session->sslServer->options.haveEMS = 0; 02135 session->sslClient->options.haveEMS = 0; 02136 } 02137 #endif 02138 if (ret == 0) 02139 ret = ProcessClientKeyExchange(input, sslBytes, session, error); 02140 break; 02141 case certificate_verify: 02142 Trace(GOT_CERT_VER_STR); 02143 break; 02144 case certificate_status: 02145 Trace(GOT_CERT_STATUS_STR); 02146 break; 02147 default: 02148 SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0); 02149 return -1; 02150 } 02151 02152 *sslBytes = startBytes - size; /* actual bytes of full process */ 02153 02154 return ret; 02155 } 02156 02157 02158 /* Decrypt input into plain output, 0 on success */ 02159 static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz) 02160 { 02161 int ret = 0; 02162 02163 (void)output; 02164 (void)input; 02165 (void)sz; 02166 02167 switch (ssl->specs.bulk_cipher_algorithm) { 02168 #ifdef BUILD_ARC4 02169 case wolfssl_rc4: 02170 wc_Arc4Process(ssl->decrypt.arc4, output, input, sz); 02171 break; 02172 #endif 02173 02174 #ifdef BUILD_DES3 02175 case wolfssl_triple_des: 02176 ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz); 02177 break; 02178 #endif 02179 02180 #ifdef BUILD_AES 02181 case wolfssl_aes: 02182 ret = wc_AesCbcDecrypt(ssl->decrypt.aes, output, input, sz); 02183 break; 02184 #endif 02185 02186 #ifdef HAVE_HC128 02187 case wolfssl_hc128: 02188 wc_Hc128_Process(ssl->decrypt.hc128, output, input, sz); 02189 break; 02190 #endif 02191 02192 #ifdef BUILD_RABBIT 02193 case wolfssl_rabbit: 02194 wc_RabbitProcess(ssl->decrypt.rabbit, output, input, sz); 02195 break; 02196 #endif 02197 02198 #ifdef HAVE_CAMELLIA 02199 case wolfssl_camellia: 02200 wc_CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz); 02201 break; 02202 #endif 02203 02204 #ifdef HAVE_IDEA 02205 case wolfssl_idea: 02206 wc_IdeaCbcDecrypt(ssl->decrypt.idea, output, input, sz); 02207 break; 02208 #endif 02209 02210 #ifdef HAVE_AESGCM 02211 case wolfssl_aes_gcm: 02212 if (sz >= (word32)(AESGCM_EXP_IV_SZ + ssl->specs.aead_mac_size)) 02213 { 02214 /* scratch buffer, sniffer ignores auth tag*/ 02215 byte authTag[WOLFSSL_MIN_AUTH_TAG_SZ]; 02216 02217 byte nonce[AESGCM_NONCE_SZ]; 02218 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ); 02219 XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); 02220 02221 if (wc_AesGcmEncrypt(ssl->decrypt.aes, 02222 output, 02223 input + AESGCM_EXP_IV_SZ, 02224 sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, 02225 nonce, AESGCM_NONCE_SZ, 02226 authTag, sizeof(authTag), 02227 NULL, 0) < 0) { 02228 Trace(BAD_DECRYPT); 02229 ret = -1; 02230 } 02231 ForceZero(nonce, AESGCM_NONCE_SZ); 02232 } 02233 else { 02234 Trace(BAD_DECRYPT_SIZE); 02235 ret = -1; 02236 } 02237 break; 02238 #endif 02239 02240 default: 02241 Trace(BAD_DECRYPT_TYPE); 02242 ret = -1; 02243 break; 02244 } 02245 02246 return ret; 02247 } 02248 02249 02250 /* Decrypt input message into output, adjust output steam if needed */ 02251 static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz, 02252 byte* output, int* error, int* advance) 02253 { 02254 int ivExtra = 0; 02255 02256 int ret = Decrypt(ssl, output, input, sz); 02257 if (ret != 0) { 02258 *error = ret; 02259 return NULL; 02260 } 02261 ssl->keys.encryptSz = sz; 02262 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) { 02263 output += ssl->specs.block_size; /* go past TLSv1.1 IV */ 02264 ivExtra = ssl->specs.block_size; 02265 *advance = ssl->specs.block_size; 02266 } 02267 02268 if (ssl->specs.cipher_type == aead) { 02269 *advance = ssl->specs.aead_mac_size; 02270 ssl->keys.padSz = ssl->specs.aead_mac_size; 02271 } 02272 else 02273 ssl->keys.padSz = ssl->specs.hash_size; 02274 02275 if (ssl->specs.cipher_type == block) 02276 ssl->keys.padSz += *(output + sz - ivExtra - 1) + 1; 02277 02278 return output; 02279 } 02280 02281 02282 /* remove session from table, use rowHint if no info (means we have a lock) */ 02283 static void RemoveSession(SnifferSession* session, IpInfo* ipInfo, 02284 TcpInfo* tcpInfo, word32 rowHint) 02285 { 02286 SnifferSession* previous = 0; 02287 SnifferSession* current; 02288 word32 row = rowHint; 02289 int haveLock = 0; 02290 02291 if (ipInfo && tcpInfo) 02292 row = SessionHash(ipInfo, tcpInfo); 02293 else 02294 haveLock = 1; 02295 02296 assert(row <= HASH_SIZE); 02297 Trace(REMOVE_SESSION_STR); 02298 02299 if (!haveLock) 02300 wc_LockMutex(&SessionMutex); 02301 02302 current = SessionTable[row]; 02303 02304 while (current) { 02305 if (current == session) { 02306 if (previous) 02307 previous->next = current->next; 02308 else 02309 SessionTable[row] = current->next; 02310 FreeSnifferSession(session); 02311 TraceRemovedSession(); 02312 break; 02313 } 02314 previous = current; 02315 current = current->next; 02316 } 02317 02318 if (!haveLock) 02319 wc_UnLockMutex(&SessionMutex); 02320 } 02321 02322 02323 /* Remove stale sessions from the Session Table, have a lock */ 02324 static void RemoveStaleSessions(void) 02325 { 02326 word32 i; 02327 SnifferSession* session; 02328 02329 for (i = 0; i < HASH_SIZE; i++) { 02330 session = SessionTable[i]; 02331 while (session) { 02332 SnifferSession* next = session->next; 02333 if (time(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) { 02334 TraceStaleSession(); 02335 RemoveSession(session, NULL, NULL, i); 02336 } 02337 session = next; 02338 } 02339 } 02340 } 02341 02342 02343 /* Create a new Sniffer Session */ 02344 static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, 02345 char* error) 02346 { 02347 SnifferSession* session = 0; 02348 int row; 02349 02350 Trace(NEW_SESSION_STR); 02351 /* create a new one */ 02352 session = (SnifferSession*)malloc(sizeof(SnifferSession)); 02353 if (session == NULL) { 02354 SetError(MEMORY_STR, error, NULL, 0); 02355 return 0; 02356 } 02357 InitSession(session); 02358 #ifdef HAVE_EXTENDED_MASTER 02359 { 02360 HsHashes* newHash = (HsHashes*)malloc(sizeof(HsHashes)); 02361 if (newHash == NULL) { 02362 SetError(MEMORY_STR, error, NULL, 0); 02363 free(session); 02364 return 0; 02365 } 02366 if (HashInit(newHash) != 0) { 02367 SetError(EXTENDED_MASTER_HASH_STR, error, NULL, 0); 02368 free(session); 02369 return 0; 02370 } 02371 session->hash = newHash; 02372 } 02373 #endif 02374 session->server = ipInfo->dst; 02375 session->client = ipInfo->src; 02376 session->srvPort = (word16)tcpInfo->dstPort; 02377 session->cliPort = (word16)tcpInfo->srcPort; 02378 session->cliSeqStart = tcpInfo->sequence; 02379 session->cliExpected = 1; /* relative */ 02380 session->lastUsed= time(NULL); 02381 02382 session->context = GetSnifferServer(ipInfo, tcpInfo); 02383 if (session->context == NULL) { 02384 SetError(SERVER_NOT_REG_STR, error, NULL, 0); 02385 free(session); 02386 return 0; 02387 } 02388 02389 session->sslServer = SSL_new(session->context->ctx); 02390 if (session->sslServer == NULL) { 02391 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE); 02392 free(session); 02393 return 0; 02394 } 02395 session->sslClient = SSL_new(session->context->ctx); 02396 if (session->sslClient == NULL) { 02397 SSL_free(session->sslServer); 02398 session->sslServer = 0; 02399 02400 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE); 02401 free(session); 02402 return 0; 02403 } 02404 /* put server back into server mode */ 02405 session->sslServer->options.side = WOLFSSL_SERVER_END; 02406 02407 row = SessionHash(ipInfo, tcpInfo); 02408 02409 /* add it to the session table */ 02410 wc_LockMutex(&SessionMutex); 02411 02412 session->next = SessionTable[row]; 02413 SessionTable[row] = session; 02414 02415 SessionCount++; 02416 02417 if ( (SessionCount % HASH_SIZE) == 0) { 02418 TraceFindingStale(); 02419 RemoveStaleSessions(); 02420 } 02421 02422 wc_UnLockMutex(&SessionMutex); 02423 02424 /* determine headed side */ 02425 if (ipInfo->dst == session->context->server && 02426 tcpInfo->dstPort == session->context->port) 02427 session->flags.side = WOLFSSL_SERVER_END; 02428 else 02429 session->flags.side = WOLFSSL_CLIENT_END; 02430 02431 return session; 02432 } 02433 02434 02435 #ifdef OLD_HELLO_ALLOWED 02436 02437 /* Process Old Client Hello Input */ 02438 static int DoOldHello(SnifferSession* session, const byte* sslFrame, 02439 int* rhSize, int* sslBytes, char* error) 02440 { 02441 const byte* input = sslFrame; 02442 byte b0, b1; 02443 word32 idx = 0; 02444 int ret; 02445 02446 Trace(GOT_OLD_CLIENT_HELLO_STR); 02447 session->flags.clientHello = 1; /* don't process again */ 02448 b0 = *input++; 02449 b1 = *input++; 02450 *sslBytes -= 2; 02451 *rhSize = ((b0 & 0x7f) << 8) | b1; 02452 02453 if (*rhSize > *sslBytes) { 02454 SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE); 02455 return -1; 02456 } 02457 02458 ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes, 02459 (word16)*rhSize); 02460 if (ret < 0 && ret != MATCH_SUITE_ERROR) { 02461 SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE); 02462 return -1; 02463 } 02464 02465 Trace(OLD_CLIENT_OK_STR); 02466 XMEMCPY(session->sslClient->arrays->clientRandom, 02467 session->sslServer->arrays->clientRandom, RAN_LEN); 02468 02469 *sslBytes -= *rhSize; 02470 return 0; 02471 } 02472 02473 #endif /* OLD_HELLO_ALLOWED */ 02474 02475 02476 #if 0 02477 /* Calculate the TCP checksum, see RFC 1071 */ 02478 /* return 0 for success, -1 on error */ 02479 /* can be called from decode() with 02480 TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length); 02481 could also add a 64bit version if type available and using this 02482 */ 02483 int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen, 02484 const byte* packet) 02485 { 02486 TcpPseudoHdr pseudo; 02487 int count = PSEUDO_HDR_SZ; 02488 const word16* data = (word16*)&pseudo; 02489 word32 sum = 0; 02490 word16 checksum; 02491 02492 pseudo.src = ipInfo->src; 02493 pseudo.dst = ipInfo->dst; 02494 pseudo.rsv = 0; 02495 pseudo.protocol = TCP_PROTO; 02496 pseudo.length = htons(tcpInfo->length + dataLen); 02497 02498 /* pseudo header sum */ 02499 while (count >= 2) { 02500 sum += *data++; 02501 count -= 2; 02502 } 02503 02504 count = tcpInfo->length + dataLen; 02505 data = (word16*)packet; 02506 02507 /* main sum */ 02508 while (count > 1) { 02509 sum += *data++; 02510 count -=2; 02511 } 02512 02513 /* get left-over, if any */ 02514 packet = (byte*)data; 02515 if (count > 0) { 02516 sum += *packet; 02517 } 02518 02519 /* fold 32bit sum into 16 bits */ 02520 while (sum >> 16) 02521 sum = (sum & 0xffff) + (sum >> 16); 02522 02523 checksum = (word16)~sum; 02524 /* checksum should now equal 0, since included already calcd checksum */ 02525 /* field, but tcp checksum offloading could negate calculation */ 02526 if (checksum == 0) 02527 return 0; 02528 return -1; 02529 } 02530 #endif 02531 02532 02533 /* Check IP and TCP headers, set payload */ 02534 /* returns 0 on success, -1 on error */ 02535 static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet, 02536 int length, const byte** sslFrame, int* sslBytes, char* error) 02537 { 02538 TraceHeader(); 02539 TracePacket(); 02540 02541 /* ip header */ 02542 if (length < IP_HDR_SZ) { 02543 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0); 02544 return -1; 02545 } 02546 if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0) 02547 return -1; 02548 02549 /* tcp header */ 02550 if (length < (ipInfo->length + TCP_HDR_SZ)) { 02551 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0); 02552 return -1; 02553 } 02554 if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0) 02555 return -1; 02556 02557 /* setup */ 02558 *sslFrame = packet + ipInfo->length + tcpInfo->length; 02559 if (*sslFrame > packet + length) { 02560 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0); 02561 return -1; 02562 } 02563 *sslBytes = (int)(packet + length - *sslFrame); 02564 02565 return 0; 02566 } 02567 02568 02569 /* Create or Find existing session */ 02570 /* returns 0 on success (continue), -1 on error, 1 on success (end) */ 02571 static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes, 02572 SnifferSession** session, char* error) 02573 { 02574 /* create a new SnifferSession on client SYN */ 02575 if (tcpInfo->syn && !tcpInfo->ack) { 02576 TraceClientSyn(tcpInfo->sequence); 02577 *session = CreateSession(ipInfo, tcpInfo, error); 02578 if (*session == NULL) { 02579 *session = GetSnifferSession(ipInfo, tcpInfo); 02580 /* already had existing, so OK */ 02581 if (*session) 02582 return 1; 02583 02584 SetError(MEMORY_STR, error, NULL, 0); 02585 return -1; 02586 } 02587 return 1; 02588 } 02589 /* get existing sniffer session */ 02590 else { 02591 *session = GetSnifferSession(ipInfo, tcpInfo); 02592 if (*session == NULL) { 02593 /* don't worry about extraneous RST or duplicate FINs */ 02594 if (tcpInfo->fin || tcpInfo->rst) 02595 return 1; 02596 /* don't worry about duplicate ACKs either */ 02597 if (sslBytes == 0 && tcpInfo->ack) 02598 return 1; 02599 02600 SetError(BAD_SESSION_STR, error, NULL, 0); 02601 return -1; 02602 } 02603 } 02604 return 0; 02605 } 02606 02607 02608 /* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */ 02609 static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data, 02610 int* bytesLeft) 02611 { 02612 PacketBuffer* pb; 02613 02614 int added = end - *begin + 1; 02615 assert(*begin <= end); 02616 02617 pb = (PacketBuffer*)malloc(sizeof(PacketBuffer)); 02618 if (pb == NULL) return NULL; 02619 02620 pb->next = 0; 02621 pb->begin = *begin; 02622 pb->end = end; 02623 pb->data = (byte*)malloc(added); 02624 02625 if (pb->data == NULL) { 02626 free(pb); 02627 return NULL; 02628 } 02629 XMEMCPY(pb->data, data, added); 02630 02631 *bytesLeft -= added; 02632 *begin = pb->end + 1; 02633 02634 return pb; 02635 } 02636 02637 02638 /* Add sslFrame to Reassembly List */ 02639 /* returns 1 (end) on success, -1, on error */ 02640 static int AddToReassembly(byte from, word32 seq, const byte* sslFrame, 02641 int sslBytes, SnifferSession* session, char* error) 02642 { 02643 PacketBuffer* add; 02644 PacketBuffer** front = (from == WOLFSSL_SERVER_END) ? 02645 &session->cliReassemblyList: &session->srvReassemblyList; 02646 PacketBuffer* curr = *front; 02647 PacketBuffer* prev = curr; 02648 02649 word32* reassemblyMemory = (from == WOLFSSL_SERVER_END) ? 02650 &session->cliReassemblyMemory : &session->srvReassemblyMemory; 02651 word32 startSeq = seq; 02652 word32 added; 02653 int bytesLeft = sslBytes; /* could be overlapping fragment */ 02654 02655 /* if list is empty add full frame to front */ 02656 if (!curr) { 02657 if (MaxRecoveryMemory != -1 && 02658 (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) { 02659 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE); 02660 return -1; 02661 } 02662 add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft); 02663 if (add == NULL) { 02664 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 02665 return -1; 02666 } 02667 *front = add; 02668 *reassemblyMemory += sslBytes; 02669 return 1; 02670 } 02671 02672 /* add to front if before current front, up to next->begin */ 02673 if (seq < curr->begin) { 02674 word32 end = seq + sslBytes - 1; 02675 02676 if (end >= curr->begin) 02677 end = curr->begin - 1; 02678 02679 if (MaxRecoveryMemory -1 && 02680 (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) { 02681 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE); 02682 return -1; 02683 } 02684 add = CreateBuffer(&seq, end, sslFrame, &bytesLeft); 02685 if (add == NULL) { 02686 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 02687 return -1; 02688 } 02689 add->next = curr; 02690 *front = add; 02691 *reassemblyMemory += sslBytes; 02692 } 02693 02694 /* while we have bytes left, try to find a gap to fill */ 02695 while (bytesLeft > 0) { 02696 /* get previous packet in list */ 02697 while (curr && (seq >= curr->begin)) { 02698 prev = curr; 02699 curr = curr->next; 02700 } 02701 02702 /* don't add duplicate data */ 02703 if (prev->end >= seq) { 02704 if ( (seq + bytesLeft - 1) <= prev->end) 02705 return 1; 02706 seq = prev->end + 1; 02707 bytesLeft = startSeq + sslBytes - seq; 02708 } 02709 02710 if (!curr) 02711 /* we're at the end */ 02712 added = bytesLeft; 02713 else 02714 /* we're in between two frames */ 02715 added = min((word32)bytesLeft, curr->begin - seq); 02716 02717 /* data already there */ 02718 if (added == 0) 02719 continue; 02720 02721 if (MaxRecoveryMemory != -1 && 02722 (int)(*reassemblyMemory + added) > MaxRecoveryMemory) { 02723 SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE); 02724 return -1; 02725 } 02726 add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq], 02727 &bytesLeft); 02728 if (add == NULL) { 02729 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 02730 return -1; 02731 } 02732 add->next = prev->next; 02733 prev->next = add; 02734 *reassemblyMemory += added; 02735 } 02736 return 1; 02737 } 02738 02739 02740 /* Add out of order FIN capture */ 02741 /* returns 1 for success (end) */ 02742 static int AddFinCapture(SnifferSession* session, word32 sequence) 02743 { 02744 if (session->flags.side == WOLFSSL_SERVER_END) { 02745 if (session->finCaputre.cliCounted == 0) 02746 session->finCaputre.cliFinSeq = sequence; 02747 } 02748 else { 02749 if (session->finCaputre.srvCounted == 0) 02750 session->finCaputre.srvFinSeq = sequence; 02751 } 02752 return 1; 02753 } 02754 02755 02756 /* Adjust incoming sequence based on side */ 02757 /* returns 0 on success (continue), -1 on error, 1 on success (end) */ 02758 static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session, 02759 int* sslBytes, const byte** sslFrame, char* error) 02760 { 02761 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ? 02762 session->cliSeqStart :session->srvSeqStart; 02763 word32 real = tcpInfo->sequence - seqStart; 02764 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ? 02765 &session->cliExpected : &session->srvExpected; 02766 PacketBuffer* reassemblyList = (session->flags.side == WOLFSSL_SERVER_END) ? 02767 session->cliReassemblyList : session->srvReassemblyList; 02768 byte skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ? 02769 session->flags.srvSkipPartial : 02770 session->flags.cliSkipPartial; 02771 02772 /* handle rollover of sequence */ 02773 if (tcpInfo->sequence < seqStart) 02774 real = 0xffffffffU - seqStart + tcpInfo->sequence; 02775 02776 TraceRelativeSequence(*expected, real); 02777 02778 if (real < *expected) { 02779 Trace(DUPLICATE_STR); 02780 if (real + *sslBytes > *expected) { 02781 int overlap = *expected - real; 02782 Trace(OVERLAP_DUPLICATE_STR); 02783 02784 /* adjust to expected, remove duplicate */ 02785 *sslFrame += overlap; 02786 *sslBytes -= overlap; 02787 02788 /* The following conditional block is duplicated below. It is the 02789 * same action but for a different setup case. If changing this 02790 * block be sure to also update the block below. */ 02791 if (reassemblyList) { 02792 word32 newEnd = *expected + *sslBytes; 02793 02794 if (newEnd > reassemblyList->begin) { 02795 Trace(OVERLAP_REASSEMBLY_BEGIN_STR); 02796 02797 /* remove bytes already on reassembly list */ 02798 *sslBytes -= newEnd - reassemblyList->begin; 02799 } 02800 if (newEnd > reassemblyList->end) { 02801 Trace(OVERLAP_REASSEMBLY_END_STR); 02802 02803 /* may be past reassembly list end (could have more on list) 02804 so try to add what's past the front->end */ 02805 AddToReassembly(session->flags.side, reassemblyList->end +1, 02806 *sslFrame + reassemblyList->end - *expected + 1, 02807 newEnd - reassemblyList->end, session, error); 02808 } 02809 } 02810 } 02811 else 02812 return 1; 02813 } 02814 else if (real > *expected) { 02815 Trace(OUT_OF_ORDER_STR); 02816 if (*sslBytes > 0) { 02817 int addResult = AddToReassembly(session->flags.side, real, 02818 *sslFrame, *sslBytes, session, error); 02819 if (skipPartial) { 02820 *sslBytes = 0; 02821 return 0; 02822 } 02823 else 02824 return addResult; 02825 } 02826 else if (tcpInfo->fin) 02827 return AddFinCapture(session, real); 02828 } 02829 else if (*sslBytes > 0) { 02830 if (skipPartial) { 02831 AddToReassembly(session->flags.side, real, 02832 *sslFrame, *sslBytes, session, error); 02833 *expected += *sslBytes; 02834 *sslBytes = 0; 02835 if (tcpInfo->fin) 02836 *expected += 1; 02837 return 0; 02838 } 02839 /* The following conditional block is duplicated above. It is the 02840 * same action but for a different setup case. If changing this 02841 * block be sure to also update the block above. */ 02842 else if (reassemblyList) { 02843 word32 newEnd = *expected + *sslBytes; 02844 02845 if (newEnd > reassemblyList->begin) { 02846 Trace(OVERLAP_REASSEMBLY_BEGIN_STR); 02847 02848 /* remove bytes already on reassembly list */ 02849 *sslBytes -= newEnd - reassemblyList->begin; 02850 } 02851 if (newEnd > reassemblyList->end) { 02852 Trace(OVERLAP_REASSEMBLY_END_STR); 02853 02854 /* may be past reassembly list end (could have more on list) 02855 so try to add what's past the front->end */ 02856 AddToReassembly(session->flags.side, reassemblyList->end +1, 02857 *sslFrame + reassemblyList->end - *expected + 1, 02858 newEnd - reassemblyList->end, session, error); 02859 } 02860 } 02861 } 02862 /* got expected sequence */ 02863 *expected += *sslBytes; 02864 if (tcpInfo->fin) 02865 *expected += 1; 02866 02867 return 0; 02868 } 02869 02870 02871 static int FindNextRecordInAssembly(SnifferSession* session, 02872 const byte** sslFrame, int* sslBytes, 02873 const byte** end, char* error) 02874 { 02875 PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ? 02876 &session->cliReassemblyList : 02877 &session->srvReassemblyList; 02878 PacketBuffer* curr = *front; 02879 PacketBuffer* prev = NULL; 02880 byte* skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ? 02881 &session->flags.srvSkipPartial : 02882 &session->flags.cliSkipPartial; 02883 word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ? 02884 &session->cliReassemblyMemory : 02885 &session->srvReassemblyMemory; 02886 SSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ? 02887 session->sslServer : 02888 session->sslClient; 02889 ProtocolVersion pv = ssl->version; 02890 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ? 02891 &session->cliExpected : 02892 &session->srvExpected; 02893 02894 while (curr != NULL) { 02895 *expected = curr->end + 1; 02896 02897 if (curr->data[0] == application_data && 02898 curr->data[1] == pv.major && 02899 curr->data[2] == pv.minor) { 02900 02901 if (ssl->buffers.inputBuffer.length > 0) 02902 Trace(DROPPING_PARTIAL_RECORD); 02903 02904 *sslBytes = curr->end - curr->begin + 1; 02905 if ( (word32)*sslBytes > ssl->buffers.inputBuffer.bufferSize) { 02906 if (GrowInputBuffer(ssl, *sslBytes, 0) < 0) { 02907 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 02908 return -1; 02909 } 02910 } 02911 02912 XMEMCPY(ssl->buffers.inputBuffer.buffer, curr->data, *sslBytes); 02913 02914 *front = curr->next; 02915 *reassemblyMemory -= *sslBytes; 02916 FreePacketBuffer(curr); 02917 02918 ssl->buffers.inputBuffer.length = *sslBytes; 02919 *sslFrame = ssl->buffers.inputBuffer.buffer; 02920 *end = *sslFrame + *sslBytes; 02921 *skipPartial = 0; 02922 02923 return 0; 02924 } 02925 else if (ssl->specs.cipher_type == block) { 02926 if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes) { 02927 #ifdef BUILD_AES 02928 wc_AesSetIV(ssl->decrypt.aes, 02929 curr->data + curr->end - curr->begin 02930 - ssl->specs.block_size + 1); 02931 #endif 02932 } 02933 else if (ssl->specs.bulk_cipher_algorithm == wolfssl_triple_des) { 02934 #ifdef BUILD_DES3 02935 wc_Des3_SetIV(ssl->decrypt.des3, 02936 curr->data + curr->end - curr->begin 02937 - ssl->specs.block_size + 1); 02938 #endif 02939 } 02940 } 02941 02942 Trace(DROPPING_LOST_FRAG_STR); 02943 prev = curr; 02944 curr = curr->next; 02945 *reassemblyMemory -= (prev->end - prev->begin + 1); 02946 FreePacketBuffer(prev); 02947 } 02948 02949 *front = curr; 02950 02951 return 0; 02952 } 02953 02954 02955 static int FixSequence(TcpInfo* tcpInfo, SnifferSession* session) 02956 { 02957 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ? 02958 &session->srvExpected : &session->cliExpected; 02959 PacketBuffer* list = (session->flags.side == WOLFSSL_SERVER_END) ? 02960 session->srvReassemblyList : 02961 session->cliReassemblyList; 02962 byte* skipPartial = (session->flags.side != WOLFSSL_SERVER_END) ? 02963 &session->flags.srvSkipPartial : 02964 &session->flags.cliSkipPartial; 02965 02966 *skipPartial = 1; 02967 if (list != NULL) 02968 *expected = list->begin; 02969 else { 02970 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ? 02971 session->srvSeqStart : session->cliSeqStart; 02972 word32 real = tcpInfo->ackNumber - seqStart; 02973 02974 *expected = real; 02975 } 02976 02977 return 1; 02978 } 02979 02980 02981 /* Check latest ack number for missing packets 02982 return 0 ok, <0 on error */ 02983 static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session) 02984 { 02985 if (tcpInfo->ack) { 02986 word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ? 02987 session->srvSeqStart :session->cliSeqStart; 02988 word32 real = tcpInfo->ackNumber - seqStart; 02989 word32 expected = (session->flags.side == WOLFSSL_SERVER_END) ? 02990 session->srvExpected : session->cliExpected; 02991 02992 /* handle rollover of sequence */ 02993 if (tcpInfo->ackNumber < seqStart) 02994 real = 0xffffffffU - seqStart + tcpInfo->ackNumber; 02995 02996 TraceAck(real, expected); 02997 02998 if (real > expected) 02999 return -1; /* we missed a packet, ACKing data we never saw */ 03000 } 03001 return 0; 03002 } 03003 03004 03005 /* Check TCP Sequence status */ 03006 /* returns 0 on success (continue), -1 on error, 1 on success (end) */ 03007 static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo, 03008 SnifferSession* session, int* sslBytes, 03009 const byte** sslFrame, char* error) 03010 { 03011 int actualLen; 03012 byte* ackFault = (session->flags.side == WOLFSSL_SERVER_END) ? 03013 &session->flags.cliAckFault : 03014 &session->flags.srvAckFault; 03015 03016 /* init SEQ from server to client */ 03017 if (tcpInfo->syn && tcpInfo->ack) { 03018 session->srvSeqStart = tcpInfo->sequence; 03019 session->srvExpected = 1; 03020 TraceServerSyn(tcpInfo->sequence); 03021 return 1; 03022 } 03023 03024 /* adjust potential ethernet trailer */ 03025 actualLen = ipInfo->total - ipInfo->length - tcpInfo->length; 03026 if (*sslBytes > actualLen) { 03027 *sslBytes = actualLen; 03028 } 03029 03030 TraceSequence(tcpInfo->sequence, *sslBytes); 03031 if (CheckAck(tcpInfo, session) < 0) { 03032 if (!RecoveryEnabled) { 03033 UpdateMissedDataSessions(); 03034 SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE); 03035 return -1; 03036 } 03037 else { 03038 SetError(ACK_MISSED_STR, error, session, 0); 03039 if (*ackFault == 0) { 03040 *ackFault = 1; 03041 UpdateMissedDataSessions(); 03042 } 03043 return FixSequence(tcpInfo, session); 03044 } 03045 } 03046 03047 if (*ackFault) { 03048 Trace(CLEAR_ACK_FAULT); 03049 *ackFault = 0; 03050 } 03051 03052 return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error); 03053 } 03054 03055 03056 /* Check Status before record processing */ 03057 /* returns 0 on success (continue), -1 on error, 1 on success (end) */ 03058 static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo, 03059 const byte** sslFrame, SnifferSession** session, 03060 int* sslBytes, const byte** end, char* error) 03061 { 03062 word32 length; 03063 SSL* ssl = ((*session)->flags.side == WOLFSSL_SERVER_END) ? 03064 (*session)->sslServer : (*session)->sslClient; 03065 byte skipPartial = ((*session)->flags.side == WOLFSSL_SERVER_END) ? 03066 (*session)->flags.srvSkipPartial : 03067 (*session)->flags.cliSkipPartial; 03068 /* remove SnifferSession on 2nd FIN or RST */ 03069 if (tcpInfo->fin || tcpInfo->rst) { 03070 /* flag FIN and RST */ 03071 if (tcpInfo->fin) 03072 (*session)->flags.finCount += 1; 03073 else if (tcpInfo->rst) 03074 (*session)->flags.finCount += 2; 03075 03076 if ((*session)->flags.finCount >= 2) { 03077 RemoveSession(*session, ipInfo, tcpInfo, 0); 03078 *session = NULL; 03079 return 1; 03080 } 03081 } 03082 03083 if ((*session)->flags.fatalError == FATAL_ERROR_STATE) { 03084 SetError(FATAL_ERROR_STR, error, NULL, 0); 03085 return -1; 03086 } 03087 03088 if (skipPartial) { 03089 if (FindNextRecordInAssembly(*session, 03090 sslFrame, sslBytes, end, error) < 0) { 03091 return -1; 03092 } 03093 } 03094 03095 if (*sslBytes == 0) { 03096 Trace(NO_DATA_STR); 03097 return 1; 03098 } 03099 03100 /* if current partial data, add to end of partial */ 03101 /* if skipping, the data is already at the end of partial */ 03102 if ( !skipPartial && 03103 (length = ssl->buffers.inputBuffer.length) ) { 03104 Trace(PARTIAL_ADD_STR); 03105 03106 if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) { 03107 if (GrowInputBuffer(ssl, *sslBytes, length) < 0) { 03108 SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE); 03109 return -1; 03110 } 03111 } 03112 XMEMCPY(&ssl->buffers.inputBuffer.buffer[length], *sslFrame, *sslBytes); 03113 *sslBytes += length; 03114 ssl->buffers.inputBuffer.length = *sslBytes; 03115 *sslFrame = ssl->buffers.inputBuffer.buffer; 03116 *end = *sslFrame + *sslBytes; 03117 } 03118 03119 if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) { 03120 /* Sanity check the packet for an old style client hello. */ 03121 int rhSize = (((*sslFrame)[0] & 0x7f) << 8) | ((*sslFrame)[1]); 03122 03123 if ((rhSize <= (*sslBytes - 2)) && 03124 (*sslFrame)[2] == OLD_HELLO_ID && (*sslFrame)[3] == SSLv3_MAJOR) { 03125 #ifdef OLD_HELLO_ALLOWED 03126 int ret = DoOldHello(*session, *sslFrame, &rhSize, sslBytes, error); 03127 if (ret < 0) 03128 return -1; /* error already set */ 03129 if (*sslBytes <= 0) 03130 return 1; 03131 #endif 03132 } 03133 else { 03134 #ifdef STARTTLS_ALLOWED 03135 return 1; 03136 #endif 03137 } 03138 } 03139 03140 return 0; 03141 } 03142 03143 03144 /* See if input on the reassembly list is ready for consuming */ 03145 /* returns 1 for TRUE, 0 for FALSE */ 03146 static int HaveMoreInput(SnifferSession* session, const byte** sslFrame, 03147 int* sslBytes, const byte** end, char* error) 03148 { 03149 /* sequence and reassembly based on from, not to */ 03150 int moreInput = 0; 03151 PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ? 03152 &session->cliReassemblyList : &session->srvReassemblyList; 03153 word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ? 03154 &session->cliExpected : &session->srvExpected; 03155 /* buffer is on receiving end */ 03156 word32* length = (session->flags.side == WOLFSSL_SERVER_END) ? 03157 &session->sslServer->buffers.inputBuffer.length : 03158 &session->sslClient->buffers.inputBuffer.length; 03159 byte** myBuffer = (session->flags.side == WOLFSSL_SERVER_END) ? 03160 &session->sslServer->buffers.inputBuffer.buffer : 03161 &session->sslClient->buffers.inputBuffer.buffer; 03162 word32* bufferSize = (session->flags.side == WOLFSSL_SERVER_END) ? 03163 &session->sslServer->buffers.inputBuffer.bufferSize : 03164 &session->sslClient->buffers.inputBuffer.bufferSize; 03165 SSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ? 03166 session->sslServer : session->sslClient; 03167 word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ? 03168 &session->cliReassemblyMemory : &session->srvReassemblyMemory; 03169 03170 while (*front && ((*front)->begin == *expected) ) { 03171 word32 room = *bufferSize - *length; 03172 word32 packetLen = (*front)->end - (*front)->begin + 1; 03173 03174 if (packetLen > room && *bufferSize < MAX_INPUT_SZ) { 03175 if (GrowInputBuffer(ssl, packetLen, *length) < 0) { 03176 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 03177 return 0; 03178 } 03179 room = *bufferSize - *length; /* bufferSize is now bigger */ 03180 } 03181 03182 if (packetLen <= room) { 03183 PacketBuffer* del = *front; 03184 byte* buf = *myBuffer; 03185 03186 XMEMCPY(&buf[*length], (*front)->data, packetLen); 03187 *length += packetLen; 03188 *expected += packetLen; 03189 03190 /* remove used packet */ 03191 *front = (*front)->next; 03192 03193 *reassemblyMemory -= packetLen; 03194 FreePacketBuffer(del); 03195 03196 moreInput = 1; 03197 } 03198 else 03199 break; 03200 } 03201 if (moreInput) { 03202 *sslFrame = *myBuffer; 03203 *sslBytes = *length; 03204 *end = *myBuffer + *length; 03205 } 03206 return moreInput; 03207 } 03208 03209 03210 03211 /* Process Message(s) from sslFrame */ 03212 /* return Number of bytes on success, 0 for no data yet, and -1 on error */ 03213 static int ProcessMessage(const byte* sslFrame, SnifferSession* session, 03214 int sslBytes, byte** data, const byte* end, 03215 char* error) 03216 { 03217 const byte* sslBegin = sslFrame; 03218 const byte* recordEnd; /* end of record indicator */ 03219 const byte* inRecordEnd; /* indicator from input stream not decrypt */ 03220 RecordLayerHeader rh; 03221 int rhSize = 0; 03222 int ret; 03223 int errCode = 0; 03224 int decoded = 0; /* bytes stored for user in data */ 03225 int notEnough; /* notEnough bytes yet flag */ 03226 int decrypted = 0; /* was current msg decrypted */ 03227 SSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ? 03228 session->sslServer : session->sslClient; 03229 doMessage: 03230 notEnough = 0; 03231 if (sslBytes < 0) { 03232 SetError(PACKET_HDR_SHORT_STR, error, session, FATAL_ERROR_STATE); 03233 return -1; 03234 } 03235 if (sslBytes >= RECORD_HEADER_SZ) { 03236 if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) { 03237 SetError(BAD_RECORD_HDR_STR, error, session, FATAL_ERROR_STATE); 03238 return -1; 03239 } 03240 } 03241 else 03242 notEnough = 1; 03243 03244 if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) { 03245 /* don't have enough input yet to process full SSL record */ 03246 Trace(PARTIAL_INPUT_STR); 03247 03248 /* store partial if not there already or we advanced */ 03249 if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) { 03250 if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) { 03251 if (GrowInputBuffer(ssl, sslBytes, 0) < 0) { 03252 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 03253 return -1; 03254 } 03255 } 03256 XMEMMOVE(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes); 03257 ssl->buffers.inputBuffer.length = sslBytes; 03258 } 03259 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error)) 03260 goto doMessage; 03261 return decoded; 03262 } 03263 sslFrame += RECORD_HEADER_SZ; 03264 sslBytes -= RECORD_HEADER_SZ; 03265 recordEnd = sslFrame + rhSize; /* may have more than one record */ 03266 inRecordEnd = recordEnd; 03267 03268 /* decrypt if needed */ 03269 if ((session->flags.side == WOLFSSL_SERVER_END && 03270 session->flags.serverCipherOn) 03271 || (session->flags.side == WOLFSSL_CLIENT_END && 03272 session->flags.clientCipherOn)) { 03273 int ivAdvance = 0; /* TLSv1.1 advance amount */ 03274 if (ssl->decrypt.setup != 1) { 03275 SetError(DECRYPT_KEYS_NOT_SETUP, error, session, FATAL_ERROR_STATE); 03276 return -1; 03277 } 03278 if (CheckAvailableSize(ssl, rhSize) < 0) { 03279 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE); 03280 return -1; 03281 } 03282 sslFrame = DecryptMessage(ssl, sslFrame, rhSize, 03283 ssl->buffers.outputBuffer.buffer, &errCode, 03284 &ivAdvance); 03285 recordEnd = sslFrame - ivAdvance + rhSize; /* sslFrame moved so 03286 should recordEnd */ 03287 decrypted = 1; 03288 if (errCode != 0) { 03289 SetError(BAD_DECRYPT, error, session, FATAL_ERROR_STATE); 03290 return -1; 03291 } 03292 } 03293 03294 doPart: 03295 03296 switch ((enum ContentType)rh.type) { 03297 case handshake: 03298 { 03299 int startIdx = sslBytes; 03300 int used; 03301 03302 Trace(GOT_HANDSHAKE_STR); 03303 ret = DoHandShake(sslFrame, &sslBytes, session, error); 03304 if (ret != 0) { 03305 if (session->flags.fatalError == 0) 03306 SetError(BAD_HANDSHAKE_STR, error, session, 03307 FATAL_ERROR_STATE); 03308 return -1; 03309 } 03310 03311 /* DoHandShake now fully decrements sslBytes to remaining */ 03312 used = startIdx - sslBytes; 03313 sslFrame += used; 03314 if (decrypted) 03315 sslFrame += ssl->keys.padSz; 03316 } 03317 break; 03318 case change_cipher_spec: 03319 if (session->flags.side == WOLFSSL_SERVER_END) 03320 session->flags.serverCipherOn = 1; 03321 else 03322 session->flags.clientCipherOn = 1; 03323 Trace(GOT_CHANGE_CIPHER_STR); 03324 ssl->options.handShakeState = HANDSHAKE_DONE; 03325 ssl->options.handShakeDone = 1; 03326 03327 sslFrame += 1; 03328 sslBytes -= 1; 03329 03330 break; 03331 case application_data: 03332 Trace(GOT_APP_DATA_STR); 03333 { 03334 word32 inOutIdx = 0; 03335 03336 ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx); 03337 if (ret == 0) { 03338 ret = ssl->buffers.clearOutputBuffer.length; 03339 TraceGotData(ret); 03340 if (ret) { /* may be blank message */ 03341 byte* tmpData; /* don't leak on realloc free */ 03342 /* add an extra byte at end of allocation in case user 03343 * wants to null terminate plaintext */ 03344 tmpData = (byte*)realloc(*data, decoded + ret + 1); 03345 if (tmpData == NULL) { 03346 ForceZero(*data, decoded); 03347 free(*data); 03348 *data = NULL; 03349 SetError(MEMORY_STR, error, session, 03350 FATAL_ERROR_STATE); 03351 return -1; 03352 } 03353 *data = tmpData; 03354 XMEMCPY(*data + decoded, 03355 ssl->buffers.clearOutputBuffer.buffer, ret); 03356 TraceAddedData(ret, decoded); 03357 decoded += ret; 03358 ssl->buffers.clearOutputBuffer.length = 0; 03359 } 03360 } 03361 else { 03362 SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE); 03363 return -1; 03364 } 03365 if (ssl->buffers.outputBuffer.dynamicFlag) 03366 ShrinkOutputBuffer(ssl); 03367 03368 sslFrame += inOutIdx; 03369 sslBytes -= inOutIdx; 03370 } 03371 break; 03372 case alert: 03373 Trace(GOT_ALERT_STR); 03374 sslFrame += rhSize; 03375 sslBytes -= rhSize; 03376 break; 03377 case no_type: 03378 default: 03379 SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE); 03380 return -1; 03381 } 03382 03383 /* do we have another msg in record ? */ 03384 if (sslFrame < recordEnd) { 03385 Trace(ANOTHER_MSG_STR); 03386 goto doPart; 03387 } 03388 03389 /* back to input stream instead of potential decrypt buffer */ 03390 recordEnd = inRecordEnd; 03391 03392 /* do we have more records ? */ 03393 if (recordEnd < end) { 03394 Trace(ANOTHER_MSG_STR); 03395 sslFrame = recordEnd; 03396 sslBytes = (int)(end - recordEnd); 03397 goto doMessage; 03398 } 03399 03400 /* clear used input */ 03401 ssl->buffers.inputBuffer.length = 0; 03402 03403 /* could have more input ready now */ 03404 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error)) 03405 goto doMessage; 03406 03407 if (ssl->buffers.inputBuffer.dynamicFlag) 03408 ShrinkInputBuffer(ssl, NO_FORCED_FREE); 03409 03410 return decoded; 03411 } 03412 03413 03414 /* See if we need to process any pending FIN captures */ 03415 static void CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo, 03416 SnifferSession* session) 03417 { 03418 if (session->finCaputre.cliFinSeq && session->finCaputre.cliFinSeq <= 03419 session->cliExpected) { 03420 if (session->finCaputre.cliCounted == 0) { 03421 session->flags.finCount += 1; 03422 session->finCaputre.cliCounted = 1; 03423 TraceClientFin(session->finCaputre.cliFinSeq, session->cliExpected); 03424 } 03425 } 03426 03427 if (session->finCaputre.srvFinSeq && session->finCaputre.srvFinSeq <= 03428 session->srvExpected) { 03429 if (session->finCaputre.srvCounted == 0) { 03430 session->flags.finCount += 1; 03431 session->finCaputre.srvCounted = 1; 03432 TraceServerFin(session->finCaputre.srvFinSeq, session->srvExpected); 03433 } 03434 } 03435 03436 if (session->flags.finCount >= 2) 03437 RemoveSession(session, ipInfo, tcpInfo, 0); 03438 } 03439 03440 03441 /* If session is in fatal error state free resources now 03442 return true if removed, 0 otherwise */ 03443 static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo, 03444 SnifferSession* session, char* error) 03445 { 03446 if (session && session->flags.fatalError == FATAL_ERROR_STATE) { 03447 RemoveSession(session, ipInfo, tcpInfo, 0); 03448 SetError(FATAL_ERROR_STR, error, NULL, 0); 03449 return 1; 03450 } 03451 return 0; 03452 } 03453 03454 03455 /* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */ 03456 /* returns Number of bytes on success, 0 for no data yet, and -1 on error */ 03457 int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error) 03458 { 03459 TcpInfo tcpInfo; 03460 IpInfo ipInfo; 03461 const byte* sslFrame; 03462 const byte* end = packet + length; 03463 int sslBytes; /* ssl bytes unconsumed */ 03464 int ret; 03465 SnifferSession* session = 0; 03466 03467 if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes, 03468 error) != 0) 03469 return -1; 03470 03471 ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error); 03472 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1; 03473 else if (ret == -1) return -1; 03474 else if (ret == 1) return 0; /* done for now */ 03475 03476 ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error); 03477 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1; 03478 else if (ret == -1) return -1; 03479 else if (ret == 1) return 0; /* done for now */ 03480 03481 ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes, 03482 &end, error); 03483 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1; 03484 else if (ret == -1) return -1; 03485 else if (ret == 1) return 0; /* done for now */ 03486 03487 ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error); 03488 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1; 03489 CheckFinCapture(&ipInfo, &tcpInfo, session); 03490 return ret; 03491 } 03492 03493 03494 /* Deallocator for the decoded data buffer. */ 03495 /* returns 0 on success, -1 on error */ 03496 int ssl_FreeDecodeBuffer(byte** data, char* error) 03497 { 03498 return ssl_FreeZeroDecodeBuffer(data, 0, error); 03499 } 03500 03501 03502 /* Deallocator for the decoded data buffer, zeros out buffer. */ 03503 /* returns 0 on success, -1 on error */ 03504 int ssl_FreeZeroDecodeBuffer(byte** data, int sz, char* error) 03505 { 03506 (void)error; 03507 03508 if (sz < 0) { 03509 return -1; 03510 } 03511 03512 if (data != NULL) { 03513 ForceZero(*data, (word32)sz); 03514 free(*data); 03515 *data = NULL; 03516 } 03517 03518 return 0; 03519 } 03520 03521 03522 /* Enables (if traceFile)/ Disables debug tracing */ 03523 /* returns 0 on success, -1 on error */ 03524 int ssl_Trace(const char* traceFile, char* error) 03525 { 03526 if (traceFile) { 03527 TraceFile = fopen(traceFile, "a"); 03528 if (!TraceFile) { 03529 SetError(BAD_TRACE_FILE_STR, error, NULL, 0); 03530 return -1; 03531 } 03532 TraceOn = 1; 03533 } 03534 else 03535 TraceOn = 0; 03536 03537 return 0; 03538 } 03539 03540 03541 /* Enables/Disables Recovery of missed data if later packets allow 03542 * maxMemory is number of bytes to use for reassembly buffering per session, 03543 * -1 means unlimited 03544 * returns 0 on success, -1 on error */ 03545 int ssl_EnableRecovery(int onOff, int maxMemory, char* error) 03546 { 03547 (void)error; 03548 03549 RecoveryEnabled = onOff; 03550 if (onOff) 03551 MaxRecoveryMemory = maxMemory; 03552 03553 return 0; 03554 } 03555 03556 03557 03558 int ssl_GetSessionStats(unsigned int* active, unsigned int* total, 03559 unsigned int* peak, unsigned int* maxSessions, 03560 unsigned int* missedData, unsigned int* reassemblyMem, 03561 char* error) 03562 { 03563 int ret; 03564 03565 if (missedData) { 03566 wc_LockMutex(&RecoveryMutex); 03567 *missedData = MissedDataSessions; 03568 wc_UnLockMutex(&RecoveryMutex); 03569 } 03570 03571 if (reassemblyMem) { 03572 SnifferSession* session; 03573 int i; 03574 03575 *reassemblyMem = 0; 03576 wc_LockMutex(&SessionMutex); 03577 for (i = 0; i < HASH_SIZE; i++) { 03578 session = SessionTable[i]; 03579 while (session) { 03580 *reassemblyMem += session->cliReassemblyMemory; 03581 *reassemblyMem += session->srvReassemblyMemory; 03582 session = session->next; 03583 } 03584 } 03585 wc_UnLockMutex(&SessionMutex); 03586 } 03587 03588 ret = wolfSSL_get_session_stats(active, total, peak, maxSessions); 03589 03590 if (ret == SSL_SUCCESS) 03591 return 0; 03592 else { 03593 SetError(BAD_SESSION_STATS, error, NULL, 0); 03594 return -1; 03595 } 03596 } 03597 03598 03599 03600 #endif /* WOLFSSL_SNIFFER */ 03601 #endif /* WOLFCRYPT_ONLY */ 03602
Generated on Tue Jul 12 2022 23:30:59 by
1.7.2
