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