SSL/TLS Library

Dependents:  

CyaSSL is SSL/TLS library for embedded systems.

wolfssl.com

Committer:
wolfSSL
Date:
Sun Apr 20 12:40:57 2014 +0000
Revision:
0:9d17e4342598
CyaSSL SSL/TLS Library 2.9.4;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:9d17e4342598 1 /* sniffer.c
wolfSSL 0:9d17e4342598 2 *
wolfSSL 0:9d17e4342598 3 * Copyright (C) 2006-2013 wolfSSL Inc.
wolfSSL 0:9d17e4342598 4 *
wolfSSL 0:9d17e4342598 5 * This file is part of CyaSSL.
wolfSSL 0:9d17e4342598 6 *
wolfSSL 0:9d17e4342598 7 * CyaSSL is free software; you can redistribute it and/or modify
wolfSSL 0:9d17e4342598 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:9d17e4342598 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:9d17e4342598 10 * (at your option) any later version.
wolfSSL 0:9d17e4342598 11 *
wolfSSL 0:9d17e4342598 12 * CyaSSL is distributed in the hope that it will be useful,
wolfSSL 0:9d17e4342598 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:9d17e4342598 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:9d17e4342598 15 * GNU General Public License for more details.
wolfSSL 0:9d17e4342598 16 *
wolfSSL 0:9d17e4342598 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:9d17e4342598 18 * along with this program; if not, write to the Free Software
wolfSSL 0:9d17e4342598 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
wolfSSL 0:9d17e4342598 20 */
wolfSSL 0:9d17e4342598 21
wolfSSL 0:9d17e4342598 22
wolfSSL 0:9d17e4342598 23
wolfSSL 0:9d17e4342598 24 #ifdef HAVE_CONFIG_H
wolfSSL 0:9d17e4342598 25 #include <config.h>
wolfSSL 0:9d17e4342598 26 #endif
wolfSSL 0:9d17e4342598 27
wolfSSL 0:9d17e4342598 28 #include <cyassl/ctaocrypt/settings.h>
wolfSSL 0:9d17e4342598 29
wolfSSL 0:9d17e4342598 30 #ifdef CYASSL_SNIFFER
wolfSSL 0:9d17e4342598 31
wolfSSL 0:9d17e4342598 32 #include <assert.h>
wolfSSL 0:9d17e4342598 33 #include <time.h>
wolfSSL 0:9d17e4342598 34
wolfSSL 0:9d17e4342598 35 #ifndef _WIN32
wolfSSL 0:9d17e4342598 36 #include <arpa/inet.h>
wolfSSL 0:9d17e4342598 37 #endif
wolfSSL 0:9d17e4342598 38
wolfSSL 0:9d17e4342598 39 #ifdef _WIN32
wolfSSL 0:9d17e4342598 40 #define SNPRINTF _snprintf
wolfSSL 0:9d17e4342598 41 #else
wolfSSL 0:9d17e4342598 42 #define SNPRINTF snprintf
wolfSSL 0:9d17e4342598 43 #endif
wolfSSL 0:9d17e4342598 44
wolfSSL 0:9d17e4342598 45 #include <cyassl/openssl/ssl.h>
wolfSSL 0:9d17e4342598 46 #include <cyassl/internal.h>
wolfSSL 0:9d17e4342598 47 #include <cyassl/error-ssl.h>
wolfSSL 0:9d17e4342598 48 #include <cyassl/sniffer.h>
wolfSSL 0:9d17e4342598 49 #include <cyassl/sniffer_error.h>
wolfSSL 0:9d17e4342598 50
wolfSSL 0:9d17e4342598 51
wolfSSL 0:9d17e4342598 52 #ifndef min
wolfSSL 0:9d17e4342598 53
wolfSSL 0:9d17e4342598 54 static INLINE word32 min(word32 a, word32 b)
wolfSSL 0:9d17e4342598 55 {
wolfSSL 0:9d17e4342598 56 return a > b ? b : a;
wolfSSL 0:9d17e4342598 57 }
wolfSSL 0:9d17e4342598 58
wolfSSL 0:9d17e4342598 59 #endif
wolfSSL 0:9d17e4342598 60
wolfSSL 0:9d17e4342598 61
wolfSSL 0:9d17e4342598 62 /* Misc constants */
wolfSSL 0:9d17e4342598 63 enum {
wolfSSL 0:9d17e4342598 64 MAX_SERVER_ADDRESS = 128, /* maximum server address length */
wolfSSL 0:9d17e4342598 65 MAX_ERROR_LEN = 80, /* maximum error length */
wolfSSL 0:9d17e4342598 66 ETHER_IF_ADDR_LEN = 6, /* ethernet interface address length */
wolfSSL 0:9d17e4342598 67 LOCAL_IF_ADDR_LEN = 4, /* localhost interface address length, !windows */
wolfSSL 0:9d17e4342598 68 TCP_PROTO = 6, /* TCP_PROTOCOL */
wolfSSL 0:9d17e4342598 69 IP_HDR_SZ = 20, /* IP header legnth, min */
wolfSSL 0:9d17e4342598 70 TCP_HDR_SZ = 20, /* TCP header legnth, min */
wolfSSL 0:9d17e4342598 71 IPV4 = 4, /* IP version 4 */
wolfSSL 0:9d17e4342598 72 TCP_PROTOCOL = 6, /* TCP Protocol id */
wolfSSL 0:9d17e4342598 73 TRACE_MSG_SZ = 80, /* Trace Message buffer size */
wolfSSL 0:9d17e4342598 74 HASH_SIZE = 499, /* Session Hash Table Rows */
wolfSSL 0:9d17e4342598 75 PSEUDO_HDR_SZ = 12, /* TCP Pseudo Header size in bytes */
wolfSSL 0:9d17e4342598 76 FATAL_ERROR_STATE = 1, /* SnifferSession fatal error state */
wolfSSL 0:9d17e4342598 77 SNIFFER_TIMEOUT = 900, /* Cache unclosed Sessions for 15 minutes */
wolfSSL 0:9d17e4342598 78 TICKET_HINT_LEN = 4, /* Session Ticket Hint length */
wolfSSL 0:9d17e4342598 79 EXT_TYPE_SZ = 2, /* Extension length */
wolfSSL 0:9d17e4342598 80 MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
wolfSSL 0:9d17e4342598 81 MTU_EXTRA, /* Max input sz of reassembly */
wolfSSL 0:9d17e4342598 82 TICKET_EXT_ID = 0x23 /* Session Ticket Extension ID */
wolfSSL 0:9d17e4342598 83 };
wolfSSL 0:9d17e4342598 84
wolfSSL 0:9d17e4342598 85
wolfSSL 0:9d17e4342598 86 #ifdef _WIN32
wolfSSL 0:9d17e4342598 87
wolfSSL 0:9d17e4342598 88 static HMODULE dllModule; /* for error string resources */
wolfSSL 0:9d17e4342598 89
wolfSSL 0:9d17e4342598 90 BOOL APIENTRY DllMain( HMODULE hModule,
wolfSSL 0:9d17e4342598 91 DWORD ul_reason_for_call,
wolfSSL 0:9d17e4342598 92 LPVOID lpReserved
wolfSSL 0:9d17e4342598 93 )
wolfSSL 0:9d17e4342598 94 {
wolfSSL 0:9d17e4342598 95 static int didInit = 0;
wolfSSL 0:9d17e4342598 96
wolfSSL 0:9d17e4342598 97 switch (ul_reason_for_call)
wolfSSL 0:9d17e4342598 98 {
wolfSSL 0:9d17e4342598 99 case DLL_PROCESS_ATTACH:
wolfSSL 0:9d17e4342598 100 if (didInit == 0) {
wolfSSL 0:9d17e4342598 101 dllModule = hModule;
wolfSSL 0:9d17e4342598 102 ssl_InitSniffer();
wolfSSL 0:9d17e4342598 103 didInit = 1;
wolfSSL 0:9d17e4342598 104 }
wolfSSL 0:9d17e4342598 105 break;
wolfSSL 0:9d17e4342598 106 case DLL_THREAD_ATTACH:
wolfSSL 0:9d17e4342598 107 break;
wolfSSL 0:9d17e4342598 108 case DLL_THREAD_DETACH:
wolfSSL 0:9d17e4342598 109 break;
wolfSSL 0:9d17e4342598 110 case DLL_PROCESS_DETACH:
wolfSSL 0:9d17e4342598 111 if (didInit) {
wolfSSL 0:9d17e4342598 112 ssl_FreeSniffer();
wolfSSL 0:9d17e4342598 113 didInit = 0;
wolfSSL 0:9d17e4342598 114 }
wolfSSL 0:9d17e4342598 115 break;
wolfSSL 0:9d17e4342598 116 }
wolfSSL 0:9d17e4342598 117 return TRUE;
wolfSSL 0:9d17e4342598 118 }
wolfSSL 0:9d17e4342598 119
wolfSSL 0:9d17e4342598 120 #endif /* _WIN32 */
wolfSSL 0:9d17e4342598 121
wolfSSL 0:9d17e4342598 122
wolfSSL 0:9d17e4342598 123 static int TraceOn = 0; /* Trace is off by default */
wolfSSL 0:9d17e4342598 124 static FILE* TraceFile = 0;
wolfSSL 0:9d17e4342598 125
wolfSSL 0:9d17e4342598 126
wolfSSL 0:9d17e4342598 127 /* windows uses .rc table for this */
wolfSSL 0:9d17e4342598 128 #ifndef _WIN32
wolfSSL 0:9d17e4342598 129
wolfSSL 0:9d17e4342598 130 static const char* const msgTable[] =
wolfSSL 0:9d17e4342598 131 {
wolfSSL 0:9d17e4342598 132 /* 1 */
wolfSSL 0:9d17e4342598 133 "Out of Memory",
wolfSSL 0:9d17e4342598 134 "New SSL Sniffer Server Registered",
wolfSSL 0:9d17e4342598 135 "Checking IP Header",
wolfSSL 0:9d17e4342598 136 "SSL Sniffer Server Not Registered",
wolfSSL 0:9d17e4342598 137 "Checking TCP Header",
wolfSSL 0:9d17e4342598 138
wolfSSL 0:9d17e4342598 139 /* 6 */
wolfSSL 0:9d17e4342598 140 "SSL Sniffer Server Port Not Registered",
wolfSSL 0:9d17e4342598 141 "RSA Private Decrypt Error",
wolfSSL 0:9d17e4342598 142 "RSA Private Decode Error",
wolfSSL 0:9d17e4342598 143 "Set Cipher Spec Error",
wolfSSL 0:9d17e4342598 144 "Server Hello Input Malformed",
wolfSSL 0:9d17e4342598 145
wolfSSL 0:9d17e4342598 146 /* 11 */
wolfSSL 0:9d17e4342598 147 "Couldn't Resume Session Error",
wolfSSL 0:9d17e4342598 148 "Server Did Resumption",
wolfSSL 0:9d17e4342598 149 "Client Hello Input Malformed",
wolfSSL 0:9d17e4342598 150 "Client Trying to Resume",
wolfSSL 0:9d17e4342598 151 "Handshake Input Malformed",
wolfSSL 0:9d17e4342598 152
wolfSSL 0:9d17e4342598 153 /* 16 */
wolfSSL 0:9d17e4342598 154 "Got Hello Verify msg",
wolfSSL 0:9d17e4342598 155 "Got Server Hello msg",
wolfSSL 0:9d17e4342598 156 "Got Cert Request msg",
wolfSSL 0:9d17e4342598 157 "Got Server Key Exchange msg",
wolfSSL 0:9d17e4342598 158 "Got Cert msg",
wolfSSL 0:9d17e4342598 159
wolfSSL 0:9d17e4342598 160 /* 21 */
wolfSSL 0:9d17e4342598 161 "Got Server Hello Done msg",
wolfSSL 0:9d17e4342598 162 "Got Finished msg",
wolfSSL 0:9d17e4342598 163 "Got Client Hello msg",
wolfSSL 0:9d17e4342598 164 "Got Client Key Exchange msg",
wolfSSL 0:9d17e4342598 165 "Got Cert Verify msg",
wolfSSL 0:9d17e4342598 166
wolfSSL 0:9d17e4342598 167 /* 26 */
wolfSSL 0:9d17e4342598 168 "Got Unknown Handshake msg",
wolfSSL 0:9d17e4342598 169 "New SSL Sniffer Session created",
wolfSSL 0:9d17e4342598 170 "Couldn't create new SSL",
wolfSSL 0:9d17e4342598 171 "Got a Packet to decode",
wolfSSL 0:9d17e4342598 172 "No data present",
wolfSSL 0:9d17e4342598 173
wolfSSL 0:9d17e4342598 174 /* 31 */
wolfSSL 0:9d17e4342598 175 "Session Not Found",
wolfSSL 0:9d17e4342598 176 "Got an Old Client Hello msg",
wolfSSL 0:9d17e4342598 177 "Old Client Hello Input Malformed",
wolfSSL 0:9d17e4342598 178 "Old Client Hello OK",
wolfSSL 0:9d17e4342598 179 "Bad Old Client Hello",
wolfSSL 0:9d17e4342598 180
wolfSSL 0:9d17e4342598 181 /* 36 */
wolfSSL 0:9d17e4342598 182 "Bad Record Header",
wolfSSL 0:9d17e4342598 183 "Record Header Input Malformed",
wolfSSL 0:9d17e4342598 184 "Got a HandShake msg",
wolfSSL 0:9d17e4342598 185 "Bad HandShake msg",
wolfSSL 0:9d17e4342598 186 "Got a Change Cipher Spec msg",
wolfSSL 0:9d17e4342598 187
wolfSSL 0:9d17e4342598 188 /* 41 */
wolfSSL 0:9d17e4342598 189 "Got Application Data msg",
wolfSSL 0:9d17e4342598 190 "Bad Application Data",
wolfSSL 0:9d17e4342598 191 "Got an Alert msg",
wolfSSL 0:9d17e4342598 192 "Another msg to Process",
wolfSSL 0:9d17e4342598 193 "Removing Session From Table",
wolfSSL 0:9d17e4342598 194
wolfSSL 0:9d17e4342598 195 /* 46 */
wolfSSL 0:9d17e4342598 196 "Bad Key File",
wolfSSL 0:9d17e4342598 197 "Wrong IP Version",
wolfSSL 0:9d17e4342598 198 "Wrong Protocol type",
wolfSSL 0:9d17e4342598 199 "Packet Short for header processing",
wolfSSL 0:9d17e4342598 200 "Got Unknown Record Type",
wolfSSL 0:9d17e4342598 201
wolfSSL 0:9d17e4342598 202 /* 51 */
wolfSSL 0:9d17e4342598 203 "Can't Open Trace File",
wolfSSL 0:9d17e4342598 204 "Session in Fatal Error State",
wolfSSL 0:9d17e4342598 205 "Partial SSL record received",
wolfSSL 0:9d17e4342598 206 "Buffer Error, malformed input",
wolfSSL 0:9d17e4342598 207 "Added to Partial Input",
wolfSSL 0:9d17e4342598 208
wolfSSL 0:9d17e4342598 209 /* 56 */
wolfSSL 0:9d17e4342598 210 "Received a Duplicate Packet",
wolfSSL 0:9d17e4342598 211 "Received an Out of Order Packet",
wolfSSL 0:9d17e4342598 212 "Received an Overlap Duplicate Packet",
wolfSSL 0:9d17e4342598 213 "Received an Overlap Reassembly Begin Duplicate Packet",
wolfSSL 0:9d17e4342598 214 "Received an Overlap Reassembly End Duplicate Packet",
wolfSSL 0:9d17e4342598 215
wolfSSL 0:9d17e4342598 216 /* 61 */
wolfSSL 0:9d17e4342598 217 "Missed the Client Hello Entirely",
wolfSSL 0:9d17e4342598 218 "Got Hello Request msg",
wolfSSL 0:9d17e4342598 219 "Got Session Ticket msg",
wolfSSL 0:9d17e4342598 220 "Bad Input",
wolfSSL 0:9d17e4342598 221 "Bad Decrypt Type",
wolfSSL 0:9d17e4342598 222
wolfSSL 0:9d17e4342598 223 /* 66 */
wolfSSL 0:9d17e4342598 224 "Bad Finished Message Processing",
wolfSSL 0:9d17e4342598 225 "Bad Compression Type",
wolfSSL 0:9d17e4342598 226 "Bad DeriveKeys Error",
wolfSSL 0:9d17e4342598 227 "Saw ACK for Missing Packet Error",
wolfSSL 0:9d17e4342598 228 "Bad Decrypt Operation"
wolfSSL 0:9d17e4342598 229 };
wolfSSL 0:9d17e4342598 230
wolfSSL 0:9d17e4342598 231
wolfSSL 0:9d17e4342598 232 /* *nix version uses table above */
wolfSSL 0:9d17e4342598 233 static void GetError(int idx, char* str)
wolfSSL 0:9d17e4342598 234 {
wolfSSL 0:9d17e4342598 235 XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN);
wolfSSL 0:9d17e4342598 236 }
wolfSSL 0:9d17e4342598 237
wolfSSL 0:9d17e4342598 238
wolfSSL 0:9d17e4342598 239 #else /* _WIN32 */
wolfSSL 0:9d17e4342598 240
wolfSSL 0:9d17e4342598 241
wolfSSL 0:9d17e4342598 242 /* Windows version uses .rc table */
wolfSSL 0:9d17e4342598 243 static void GetError(int idx, char* buffer)
wolfSSL 0:9d17e4342598 244 {
wolfSSL 0:9d17e4342598 245 if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
wolfSSL 0:9d17e4342598 246 buffer[0] = 0;
wolfSSL 0:9d17e4342598 247 }
wolfSSL 0:9d17e4342598 248
wolfSSL 0:9d17e4342598 249
wolfSSL 0:9d17e4342598 250 #endif /* _WIN32 */
wolfSSL 0:9d17e4342598 251
wolfSSL 0:9d17e4342598 252
wolfSSL 0:9d17e4342598 253 /* Packet Buffer for reassembly list and ready list */
wolfSSL 0:9d17e4342598 254 typedef struct PacketBuffer {
wolfSSL 0:9d17e4342598 255 word32 begin; /* relative sequence begin */
wolfSSL 0:9d17e4342598 256 word32 end; /* relative sequence end */
wolfSSL 0:9d17e4342598 257 byte* data; /* actual data */
wolfSSL 0:9d17e4342598 258 struct PacketBuffer* next; /* next on reassembly list or ready list */
wolfSSL 0:9d17e4342598 259 } PacketBuffer;
wolfSSL 0:9d17e4342598 260
wolfSSL 0:9d17e4342598 261
wolfSSL 0:9d17e4342598 262 /* Sniffer Server holds info for each server/port monitored */
wolfSSL 0:9d17e4342598 263 typedef struct SnifferServer {
wolfSSL 0:9d17e4342598 264 SSL_CTX* ctx; /* SSL context */
wolfSSL 0:9d17e4342598 265 char address[MAX_SERVER_ADDRESS]; /* passed in server address */
wolfSSL 0:9d17e4342598 266 word32 server; /* netowrk order address */
wolfSSL 0:9d17e4342598 267 int port; /* server port */
wolfSSL 0:9d17e4342598 268 struct SnifferServer* next; /* for list */
wolfSSL 0:9d17e4342598 269 } SnifferServer;
wolfSSL 0:9d17e4342598 270
wolfSSL 0:9d17e4342598 271
wolfSSL 0:9d17e4342598 272 /* Session Flags */
wolfSSL 0:9d17e4342598 273 typedef struct Flags {
wolfSSL 0:9d17e4342598 274 byte side; /* which end is current packet headed */
wolfSSL 0:9d17e4342598 275 byte serverCipherOn; /* indicates whether cipher is active */
wolfSSL 0:9d17e4342598 276 byte clientCipherOn; /* indicates whether cipher is active */
wolfSSL 0:9d17e4342598 277 byte resuming; /* did this session come from resumption */
wolfSSL 0:9d17e4342598 278 byte cached; /* have we cached this session yet */
wolfSSL 0:9d17e4342598 279 byte clientHello; /* processed client hello yet, for SSLv2 */
wolfSSL 0:9d17e4342598 280 byte finCount; /* get both FINs before removing */
wolfSSL 0:9d17e4342598 281 byte fatalError; /* fatal error state */
wolfSSL 0:9d17e4342598 282 } Flags;
wolfSSL 0:9d17e4342598 283
wolfSSL 0:9d17e4342598 284
wolfSSL 0:9d17e4342598 285 /* Out of Order FIN caputre */
wolfSSL 0:9d17e4342598 286 typedef struct FinCaputre {
wolfSSL 0:9d17e4342598 287 word32 cliFinSeq; /* client relative sequence FIN 0 is no */
wolfSSL 0:9d17e4342598 288 word32 srvFinSeq; /* server relative sequence FIN, 0 is no */
wolfSSL 0:9d17e4342598 289 byte cliCounted; /* did we count yet, detects duplicates */
wolfSSL 0:9d17e4342598 290 byte srvCounted; /* did we count yet, detects duplicates */
wolfSSL 0:9d17e4342598 291 } FinCaputre;
wolfSSL 0:9d17e4342598 292
wolfSSL 0:9d17e4342598 293
wolfSSL 0:9d17e4342598 294 /* Sniffer Session holds info for each client/server SSL/TLS session */
wolfSSL 0:9d17e4342598 295 typedef struct SnifferSession {
wolfSSL 0:9d17e4342598 296 SnifferServer* context; /* server context */
wolfSSL 0:9d17e4342598 297 SSL* sslServer; /* SSL server side decode */
wolfSSL 0:9d17e4342598 298 SSL* sslClient; /* SSL client side decode */
wolfSSL 0:9d17e4342598 299 word32 server; /* server address in network byte order */
wolfSSL 0:9d17e4342598 300 word32 client; /* client address in network byte order */
wolfSSL 0:9d17e4342598 301 word16 srvPort; /* server port */
wolfSSL 0:9d17e4342598 302 word16 cliPort; /* client port */
wolfSSL 0:9d17e4342598 303 word32 cliSeqStart; /* client start sequence */
wolfSSL 0:9d17e4342598 304 word32 srvSeqStart; /* server start sequence */
wolfSSL 0:9d17e4342598 305 word32 cliExpected; /* client expected sequence (relative) */
wolfSSL 0:9d17e4342598 306 word32 srvExpected; /* server expected sequence (relative) */
wolfSSL 0:9d17e4342598 307 FinCaputre finCaputre; /* retain out of order FIN s */
wolfSSL 0:9d17e4342598 308 Flags flags; /* session flags */
wolfSSL 0:9d17e4342598 309 time_t lastUsed; /* last used ticks */
wolfSSL 0:9d17e4342598 310 PacketBuffer* cliReassemblyList; /* client out of order packets */
wolfSSL 0:9d17e4342598 311 PacketBuffer* srvReassemblyList; /* server out of order packets */
wolfSSL 0:9d17e4342598 312 struct SnifferSession* next; /* for hash table list */
wolfSSL 0:9d17e4342598 313 byte* ticketID; /* mac ID of session ticket */
wolfSSL 0:9d17e4342598 314 } SnifferSession;
wolfSSL 0:9d17e4342598 315
wolfSSL 0:9d17e4342598 316
wolfSSL 0:9d17e4342598 317 /* Sniffer Server List and mutex */
wolfSSL 0:9d17e4342598 318 static SnifferServer* ServerList = 0;
wolfSSL 0:9d17e4342598 319 static CyaSSL_Mutex ServerListMutex;
wolfSSL 0:9d17e4342598 320
wolfSSL 0:9d17e4342598 321
wolfSSL 0:9d17e4342598 322 /* Session Hash Table, mutex, and count */
wolfSSL 0:9d17e4342598 323 static SnifferSession* SessionTable[HASH_SIZE];
wolfSSL 0:9d17e4342598 324 static CyaSSL_Mutex SessionMutex;
wolfSSL 0:9d17e4342598 325 static int SessionCount = 0;
wolfSSL 0:9d17e4342598 326
wolfSSL 0:9d17e4342598 327
wolfSSL 0:9d17e4342598 328 /* Initialize overall Sniffer */
wolfSSL 0:9d17e4342598 329 void ssl_InitSniffer(void)
wolfSSL 0:9d17e4342598 330 {
wolfSSL 0:9d17e4342598 331 CyaSSL_Init();
wolfSSL 0:9d17e4342598 332 InitMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 333 InitMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 334 }
wolfSSL 0:9d17e4342598 335
wolfSSL 0:9d17e4342598 336
wolfSSL 0:9d17e4342598 337 /* Free Sniffer Server's resources/self */
wolfSSL 0:9d17e4342598 338 static void FreeSnifferServer(SnifferServer* srv)
wolfSSL 0:9d17e4342598 339 {
wolfSSL 0:9d17e4342598 340 if (srv)
wolfSSL 0:9d17e4342598 341 SSL_CTX_free(srv->ctx);
wolfSSL 0:9d17e4342598 342 free(srv);
wolfSSL 0:9d17e4342598 343 }
wolfSSL 0:9d17e4342598 344
wolfSSL 0:9d17e4342598 345
wolfSSL 0:9d17e4342598 346 /* free PacketBuffer's resources/self */
wolfSSL 0:9d17e4342598 347 static void FreePacketBuffer(PacketBuffer* del)
wolfSSL 0:9d17e4342598 348 {
wolfSSL 0:9d17e4342598 349 if (del) {
wolfSSL 0:9d17e4342598 350 free(del->data);
wolfSSL 0:9d17e4342598 351 free(del);
wolfSSL 0:9d17e4342598 352 }
wolfSSL 0:9d17e4342598 353 }
wolfSSL 0:9d17e4342598 354
wolfSSL 0:9d17e4342598 355
wolfSSL 0:9d17e4342598 356 /* remove PacketBuffer List */
wolfSSL 0:9d17e4342598 357 static void FreePacketList(PacketBuffer* in)
wolfSSL 0:9d17e4342598 358 {
wolfSSL 0:9d17e4342598 359 if (in) {
wolfSSL 0:9d17e4342598 360 PacketBuffer* del;
wolfSSL 0:9d17e4342598 361 PacketBuffer* packet = in;
wolfSSL 0:9d17e4342598 362
wolfSSL 0:9d17e4342598 363 while (packet) {
wolfSSL 0:9d17e4342598 364 del = packet;
wolfSSL 0:9d17e4342598 365 packet = packet->next;
wolfSSL 0:9d17e4342598 366 FreePacketBuffer(del);
wolfSSL 0:9d17e4342598 367 }
wolfSSL 0:9d17e4342598 368 }
wolfSSL 0:9d17e4342598 369 }
wolfSSL 0:9d17e4342598 370
wolfSSL 0:9d17e4342598 371
wolfSSL 0:9d17e4342598 372 /* Free Sniffer Session's resources/self */
wolfSSL 0:9d17e4342598 373 static void FreeSnifferSession(SnifferSession* session)
wolfSSL 0:9d17e4342598 374 {
wolfSSL 0:9d17e4342598 375 if (session) {
wolfSSL 0:9d17e4342598 376 SSL_free(session->sslClient);
wolfSSL 0:9d17e4342598 377 SSL_free(session->sslServer);
wolfSSL 0:9d17e4342598 378
wolfSSL 0:9d17e4342598 379 FreePacketList(session->cliReassemblyList);
wolfSSL 0:9d17e4342598 380 FreePacketList(session->srvReassemblyList);
wolfSSL 0:9d17e4342598 381
wolfSSL 0:9d17e4342598 382 free(session->ticketID);
wolfSSL 0:9d17e4342598 383 }
wolfSSL 0:9d17e4342598 384 free(session);
wolfSSL 0:9d17e4342598 385 }
wolfSSL 0:9d17e4342598 386
wolfSSL 0:9d17e4342598 387
wolfSSL 0:9d17e4342598 388 /* Free overall Sniffer */
wolfSSL 0:9d17e4342598 389 void ssl_FreeSniffer(void)
wolfSSL 0:9d17e4342598 390 {
wolfSSL 0:9d17e4342598 391 SnifferServer* srv;
wolfSSL 0:9d17e4342598 392 SnifferServer* removeServer;
wolfSSL 0:9d17e4342598 393 SnifferSession* session;
wolfSSL 0:9d17e4342598 394 SnifferSession* removeSession;
wolfSSL 0:9d17e4342598 395 int i;
wolfSSL 0:9d17e4342598 396
wolfSSL 0:9d17e4342598 397 LockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 398 LockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 399
wolfSSL 0:9d17e4342598 400 srv = ServerList;
wolfSSL 0:9d17e4342598 401 while (srv) {
wolfSSL 0:9d17e4342598 402 removeServer = srv;
wolfSSL 0:9d17e4342598 403 srv = srv->next;
wolfSSL 0:9d17e4342598 404 FreeSnifferServer(removeServer);
wolfSSL 0:9d17e4342598 405 }
wolfSSL 0:9d17e4342598 406
wolfSSL 0:9d17e4342598 407 for (i = 0; i < HASH_SIZE; i++) {
wolfSSL 0:9d17e4342598 408 session = SessionTable[i];
wolfSSL 0:9d17e4342598 409 while (session) {
wolfSSL 0:9d17e4342598 410 removeSession = session;
wolfSSL 0:9d17e4342598 411 session = session->next;
wolfSSL 0:9d17e4342598 412 FreeSnifferSession(removeSession);
wolfSSL 0:9d17e4342598 413 }
wolfSSL 0:9d17e4342598 414 }
wolfSSL 0:9d17e4342598 415
wolfSSL 0:9d17e4342598 416 UnLockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 417 UnLockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 418
wolfSSL 0:9d17e4342598 419 FreeMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 420 FreeMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 421
wolfSSL 0:9d17e4342598 422 if (TraceFile) {
wolfSSL 0:9d17e4342598 423 TraceOn = 0;
wolfSSL 0:9d17e4342598 424 fclose(TraceFile);
wolfSSL 0:9d17e4342598 425 TraceFile = NULL;
wolfSSL 0:9d17e4342598 426 }
wolfSSL 0:9d17e4342598 427
wolfSSL 0:9d17e4342598 428 CyaSSL_Cleanup();
wolfSSL 0:9d17e4342598 429 }
wolfSSL 0:9d17e4342598 430
wolfSSL 0:9d17e4342598 431
wolfSSL 0:9d17e4342598 432 /* Initialize a SnifferServer */
wolfSSL 0:9d17e4342598 433 static void InitSnifferServer(SnifferServer* sniffer)
wolfSSL 0:9d17e4342598 434 {
wolfSSL 0:9d17e4342598 435 sniffer->ctx = 0;
wolfSSL 0:9d17e4342598 436 XMEMSET(sniffer->address, 0, MAX_SERVER_ADDRESS);
wolfSSL 0:9d17e4342598 437 sniffer->server = 0;
wolfSSL 0:9d17e4342598 438 sniffer->port = 0;
wolfSSL 0:9d17e4342598 439 sniffer->next = 0;
wolfSSL 0:9d17e4342598 440 }
wolfSSL 0:9d17e4342598 441
wolfSSL 0:9d17e4342598 442
wolfSSL 0:9d17e4342598 443 /* Initialize session flags */
wolfSSL 0:9d17e4342598 444 static void InitFlags(Flags* flags)
wolfSSL 0:9d17e4342598 445 {
wolfSSL 0:9d17e4342598 446 flags->side = 0;
wolfSSL 0:9d17e4342598 447 flags->serverCipherOn = 0;
wolfSSL 0:9d17e4342598 448 flags->clientCipherOn = 0;
wolfSSL 0:9d17e4342598 449 flags->resuming = 0;
wolfSSL 0:9d17e4342598 450 flags->cached = 0;
wolfSSL 0:9d17e4342598 451 flags->clientHello = 0;
wolfSSL 0:9d17e4342598 452 flags->finCount = 0;
wolfSSL 0:9d17e4342598 453 flags->fatalError = 0;
wolfSSL 0:9d17e4342598 454 }
wolfSSL 0:9d17e4342598 455
wolfSSL 0:9d17e4342598 456
wolfSSL 0:9d17e4342598 457 /* Initialize FIN Capture */
wolfSSL 0:9d17e4342598 458 static void InitFinCapture(FinCaputre* cap)
wolfSSL 0:9d17e4342598 459 {
wolfSSL 0:9d17e4342598 460 cap->cliFinSeq = 0;
wolfSSL 0:9d17e4342598 461 cap->srvFinSeq = 0;
wolfSSL 0:9d17e4342598 462 cap->cliCounted = 0;
wolfSSL 0:9d17e4342598 463 cap->srvCounted = 0;
wolfSSL 0:9d17e4342598 464 }
wolfSSL 0:9d17e4342598 465
wolfSSL 0:9d17e4342598 466
wolfSSL 0:9d17e4342598 467 /* Initialize a Sniffer Session */
wolfSSL 0:9d17e4342598 468 static void InitSession(SnifferSession* session)
wolfSSL 0:9d17e4342598 469 {
wolfSSL 0:9d17e4342598 470 session->context = 0;
wolfSSL 0:9d17e4342598 471 session->sslServer = 0;
wolfSSL 0:9d17e4342598 472 session->sslClient = 0;
wolfSSL 0:9d17e4342598 473 session->server = 0;
wolfSSL 0:9d17e4342598 474 session->client = 0;
wolfSSL 0:9d17e4342598 475 session->srvPort = 0;
wolfSSL 0:9d17e4342598 476 session->cliPort = 0;
wolfSSL 0:9d17e4342598 477 session->cliSeqStart = 0;
wolfSSL 0:9d17e4342598 478 session->srvSeqStart = 0;
wolfSSL 0:9d17e4342598 479 session->cliExpected = 0;
wolfSSL 0:9d17e4342598 480 session->srvExpected = 0;
wolfSSL 0:9d17e4342598 481 session->lastUsed = 0;
wolfSSL 0:9d17e4342598 482 session->cliReassemblyList = 0;
wolfSSL 0:9d17e4342598 483 session->srvReassemblyList = 0;
wolfSSL 0:9d17e4342598 484 session->next = 0;
wolfSSL 0:9d17e4342598 485 session->ticketID = 0;
wolfSSL 0:9d17e4342598 486
wolfSSL 0:9d17e4342598 487 InitFlags(&session->flags);
wolfSSL 0:9d17e4342598 488 InitFinCapture(&session->finCaputre);
wolfSSL 0:9d17e4342598 489 }
wolfSSL 0:9d17e4342598 490
wolfSSL 0:9d17e4342598 491
wolfSSL 0:9d17e4342598 492 /* IP Info from IP Header */
wolfSSL 0:9d17e4342598 493 typedef struct IpInfo {
wolfSSL 0:9d17e4342598 494 int length; /* length of this header */
wolfSSL 0:9d17e4342598 495 int total; /* total length of fragment */
wolfSSL 0:9d17e4342598 496 word32 src; /* network order source address */
wolfSSL 0:9d17e4342598 497 word32 dst; /* network order destination address */
wolfSSL 0:9d17e4342598 498 } IpInfo;
wolfSSL 0:9d17e4342598 499
wolfSSL 0:9d17e4342598 500
wolfSSL 0:9d17e4342598 501 /* TCP Info from TCP Header */
wolfSSL 0:9d17e4342598 502 typedef struct TcpInfo {
wolfSSL 0:9d17e4342598 503 int srcPort; /* source port */
wolfSSL 0:9d17e4342598 504 int dstPort; /* source port */
wolfSSL 0:9d17e4342598 505 int length; /* length of this header */
wolfSSL 0:9d17e4342598 506 word32 sequence; /* sequence number */
wolfSSL 0:9d17e4342598 507 word32 ackNumber; /* ack number */
wolfSSL 0:9d17e4342598 508 byte fin; /* FIN set */
wolfSSL 0:9d17e4342598 509 byte rst; /* RST set */
wolfSSL 0:9d17e4342598 510 byte syn; /* SYN set */
wolfSSL 0:9d17e4342598 511 byte ack; /* ACK set */
wolfSSL 0:9d17e4342598 512 } TcpInfo;
wolfSSL 0:9d17e4342598 513
wolfSSL 0:9d17e4342598 514
wolfSSL 0:9d17e4342598 515 /* Tcp Pseudo Header for Checksum calculation */
wolfSSL 0:9d17e4342598 516 typedef struct TcpPseudoHdr {
wolfSSL 0:9d17e4342598 517 word32 src; /* source address */
wolfSSL 0:9d17e4342598 518 word32 dst; /* destination address */
wolfSSL 0:9d17e4342598 519 byte rsv; /* reserved, always 0 */
wolfSSL 0:9d17e4342598 520 byte protocol; /* IP protocol */
wolfSSL 0:9d17e4342598 521 word16 legnth; /* tcp header length + data length (doesn't include */
wolfSSL 0:9d17e4342598 522 /* pseudo header length) network order */
wolfSSL 0:9d17e4342598 523 } TcpPseudoHdr;
wolfSSL 0:9d17e4342598 524
wolfSSL 0:9d17e4342598 525
wolfSSL 0:9d17e4342598 526 /* Password Setting Callback */
wolfSSL 0:9d17e4342598 527 static int SetPassword(char* passwd, int sz, int rw, void* userdata)
wolfSSL 0:9d17e4342598 528 {
wolfSSL 0:9d17e4342598 529 (void)rw;
wolfSSL 0:9d17e4342598 530 XSTRNCPY(passwd, userdata, sz);
wolfSSL 0:9d17e4342598 531 return (int)XSTRLEN(userdata);
wolfSSL 0:9d17e4342598 532 }
wolfSSL 0:9d17e4342598 533
wolfSSL 0:9d17e4342598 534
wolfSSL 0:9d17e4342598 535 /* Ethernet Header */
wolfSSL 0:9d17e4342598 536 typedef struct EthernetHdr {
wolfSSL 0:9d17e4342598 537 byte dst[ETHER_IF_ADDR_LEN]; /* destination host address */
wolfSSL 0:9d17e4342598 538 byte src[ETHER_IF_ADDR_LEN]; /* source host address */
wolfSSL 0:9d17e4342598 539 word16 type; /* IP, ARP, etc */
wolfSSL 0:9d17e4342598 540 } EthernetHdr;
wolfSSL 0:9d17e4342598 541
wolfSSL 0:9d17e4342598 542
wolfSSL 0:9d17e4342598 543 /* IP Header */
wolfSSL 0:9d17e4342598 544 typedef struct IpHdr {
wolfSSL 0:9d17e4342598 545 byte ver_hl; /* version/header length */
wolfSSL 0:9d17e4342598 546 byte tos; /* type of service */
wolfSSL 0:9d17e4342598 547 word16 length; /* total length */
wolfSSL 0:9d17e4342598 548 word16 id; /* identification */
wolfSSL 0:9d17e4342598 549 word16 offset; /* fragment offset field */
wolfSSL 0:9d17e4342598 550 byte ttl; /* time to live */
wolfSSL 0:9d17e4342598 551 byte protocol; /* protocol */
wolfSSL 0:9d17e4342598 552 word16 sum; /* checksum */
wolfSSL 0:9d17e4342598 553 word32 src; /* source address */
wolfSSL 0:9d17e4342598 554 word32 dst; /* destination address */
wolfSSL 0:9d17e4342598 555 } IpHdr;
wolfSSL 0:9d17e4342598 556
wolfSSL 0:9d17e4342598 557
wolfSSL 0:9d17e4342598 558 #define IP_HL(ip) ( (((ip)->ver_hl) & 0x0f) * 4)
wolfSSL 0:9d17e4342598 559 #define IP_V(ip) ( ((ip)->ver_hl) >> 4)
wolfSSL 0:9d17e4342598 560
wolfSSL 0:9d17e4342598 561 /* TCP Header */
wolfSSL 0:9d17e4342598 562 typedef struct TcpHdr {
wolfSSL 0:9d17e4342598 563 word16 srcPort; /* source port */
wolfSSL 0:9d17e4342598 564 word16 dstPort; /* destination port */
wolfSSL 0:9d17e4342598 565 word32 sequence; /* sequence number */
wolfSSL 0:9d17e4342598 566 word32 ack; /* acknoledgment number */
wolfSSL 0:9d17e4342598 567 byte offset; /* data offset, reserved */
wolfSSL 0:9d17e4342598 568 byte flags; /* option flags */
wolfSSL 0:9d17e4342598 569 word16 window; /* window */
wolfSSL 0:9d17e4342598 570 word16 sum; /* checksum */
wolfSSL 0:9d17e4342598 571 word16 urgent; /* urgent pointer */
wolfSSL 0:9d17e4342598 572 } TcpHdr;
wolfSSL 0:9d17e4342598 573
wolfSSL 0:9d17e4342598 574 #define TCP_LEN(tcp) ( (((tcp)->offset & 0xf0) >> 4) * 4)
wolfSSL 0:9d17e4342598 575 #define TCP_FIN 0x01
wolfSSL 0:9d17e4342598 576 #define TCP_SYN 0x02
wolfSSL 0:9d17e4342598 577 #define TCP_RST 0x04
wolfSSL 0:9d17e4342598 578 #define TCP_ACK 0x10
wolfSSL 0:9d17e4342598 579
wolfSSL 0:9d17e4342598 580
wolfSSL 0:9d17e4342598 581
wolfSSL 0:9d17e4342598 582
wolfSSL 0:9d17e4342598 583
wolfSSL 0:9d17e4342598 584 /* Use platform specific GetError to write to tracfile if tracing */
wolfSSL 0:9d17e4342598 585 static void Trace(int idx)
wolfSSL 0:9d17e4342598 586 {
wolfSSL 0:9d17e4342598 587 if (TraceOn) {
wolfSSL 0:9d17e4342598 588 char myBuffer[MAX_ERROR_LEN];
wolfSSL 0:9d17e4342598 589 GetError(idx, myBuffer);
wolfSSL 0:9d17e4342598 590 fprintf(TraceFile, "\t%s\n", myBuffer);
wolfSSL 0:9d17e4342598 591 #ifdef DEBUG_SNIFFER
wolfSSL 0:9d17e4342598 592 fprintf(stderr, "\t%s\n", myBuffer);
wolfSSL 0:9d17e4342598 593 #endif
wolfSSL 0:9d17e4342598 594 }
wolfSSL 0:9d17e4342598 595 }
wolfSSL 0:9d17e4342598 596
wolfSSL 0:9d17e4342598 597
wolfSSL 0:9d17e4342598 598 /* Show TimeStamp for beginning of packet Trace */
wolfSSL 0:9d17e4342598 599 static void TraceHeader(void)
wolfSSL 0:9d17e4342598 600 {
wolfSSL 0:9d17e4342598 601 if (TraceOn) {
wolfSSL 0:9d17e4342598 602 time_t ticks = time(NULL);
wolfSSL 0:9d17e4342598 603 fprintf(TraceFile, "\n%s", ctime(&ticks));
wolfSSL 0:9d17e4342598 604 }
wolfSSL 0:9d17e4342598 605 }
wolfSSL 0:9d17e4342598 606
wolfSSL 0:9d17e4342598 607
wolfSSL 0:9d17e4342598 608 /* Show Set Server info for Trace */
wolfSSL 0:9d17e4342598 609 static void TraceSetServer(const char* srv, int port, const char* keyFile)
wolfSSL 0:9d17e4342598 610 {
wolfSSL 0:9d17e4342598 611 if (TraceOn) {
wolfSSL 0:9d17e4342598 612 fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
wolfSSL 0:9d17e4342598 613 fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
wolfSSL 0:9d17e4342598 614 keyFile);
wolfSSL 0:9d17e4342598 615 }
wolfSSL 0:9d17e4342598 616 }
wolfSSL 0:9d17e4342598 617
wolfSSL 0:9d17e4342598 618
wolfSSL 0:9d17e4342598 619 /* Trace got packet number */
wolfSSL 0:9d17e4342598 620 static void TracePacket(void)
wolfSSL 0:9d17e4342598 621 {
wolfSSL 0:9d17e4342598 622 if (TraceOn) {
wolfSSL 0:9d17e4342598 623 static word32 packetNumber = 0;
wolfSSL 0:9d17e4342598 624 fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n",
wolfSSL 0:9d17e4342598 625 ++packetNumber);
wolfSSL 0:9d17e4342598 626 }
wolfSSL 0:9d17e4342598 627 }
wolfSSL 0:9d17e4342598 628
wolfSSL 0:9d17e4342598 629
wolfSSL 0:9d17e4342598 630 /* Convert network byte order address into human readable */
wolfSSL 0:9d17e4342598 631 static char* IpToS(word32 addr, char* str)
wolfSSL 0:9d17e4342598 632 {
wolfSSL 0:9d17e4342598 633 byte* p = (byte*)&addr;
wolfSSL 0:9d17e4342598 634
wolfSSL 0:9d17e4342598 635 SNPRINTF(str, TRACE_MSG_SZ, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
wolfSSL 0:9d17e4342598 636
wolfSSL 0:9d17e4342598 637 return str;
wolfSSL 0:9d17e4342598 638 }
wolfSSL 0:9d17e4342598 639
wolfSSL 0:9d17e4342598 640
wolfSSL 0:9d17e4342598 641 /* Show destination and source address from Ip Hdr for packet Trace */
wolfSSL 0:9d17e4342598 642 static void TraceIP(IpHdr* iphdr)
wolfSSL 0:9d17e4342598 643 {
wolfSSL 0:9d17e4342598 644 if (TraceOn) {
wolfSSL 0:9d17e4342598 645 char src[TRACE_MSG_SZ];
wolfSSL 0:9d17e4342598 646 char dst[TRACE_MSG_SZ];
wolfSSL 0:9d17e4342598 647 fprintf(TraceFile, "\tdst:%s src:%s\n", IpToS(iphdr->dst, dst),
wolfSSL 0:9d17e4342598 648 IpToS(iphdr->src, src));
wolfSSL 0:9d17e4342598 649 }
wolfSSL 0:9d17e4342598 650 }
wolfSSL 0:9d17e4342598 651
wolfSSL 0:9d17e4342598 652
wolfSSL 0:9d17e4342598 653 /* Show destination and source port from Tcp Hdr for packet Trace */
wolfSSL 0:9d17e4342598 654 static void TraceTcp(TcpHdr* tcphdr)
wolfSSL 0:9d17e4342598 655 {
wolfSSL 0:9d17e4342598 656 if (TraceOn) {
wolfSSL 0:9d17e4342598 657 fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort),
wolfSSL 0:9d17e4342598 658 ntohs(tcphdr->srcPort));
wolfSSL 0:9d17e4342598 659 }
wolfSSL 0:9d17e4342598 660 }
wolfSSL 0:9d17e4342598 661
wolfSSL 0:9d17e4342598 662
wolfSSL 0:9d17e4342598 663 /* Show sequence and payload length for Trace */
wolfSSL 0:9d17e4342598 664 static void TraceSequence(word32 seq, int len)
wolfSSL 0:9d17e4342598 665 {
wolfSSL 0:9d17e4342598 666 if (TraceOn) {
wolfSSL 0:9d17e4342598 667 fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
wolfSSL 0:9d17e4342598 668 }
wolfSSL 0:9d17e4342598 669 }
wolfSSL 0:9d17e4342598 670
wolfSSL 0:9d17e4342598 671
wolfSSL 0:9d17e4342598 672 /* Show sequence and payload length for Trace */
wolfSSL 0:9d17e4342598 673 static void TraceAck(word32 ack, word32 expected)
wolfSSL 0:9d17e4342598 674 {
wolfSSL 0:9d17e4342598 675 if (TraceOn) {
wolfSSL 0:9d17e4342598 676 fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected);
wolfSSL 0:9d17e4342598 677 }
wolfSSL 0:9d17e4342598 678 }
wolfSSL 0:9d17e4342598 679
wolfSSL 0:9d17e4342598 680
wolfSSL 0:9d17e4342598 681 /* Show relative expected and relative received sequences */
wolfSSL 0:9d17e4342598 682 static void TraceRelativeSequence(word32 expected, word32 got)
wolfSSL 0:9d17e4342598 683 {
wolfSSL 0:9d17e4342598 684 if (TraceOn) {
wolfSSL 0:9d17e4342598 685 fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
wolfSSL 0:9d17e4342598 686 expected, got);
wolfSSL 0:9d17e4342598 687 }
wolfSSL 0:9d17e4342598 688 }
wolfSSL 0:9d17e4342598 689
wolfSSL 0:9d17e4342598 690
wolfSSL 0:9d17e4342598 691 /* Show server sequence startup from SYN */
wolfSSL 0:9d17e4342598 692 static void TraceServerSyn(word32 seq)
wolfSSL 0:9d17e4342598 693 {
wolfSSL 0:9d17e4342598 694 if (TraceOn) {
wolfSSL 0:9d17e4342598 695 fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
wolfSSL 0:9d17e4342598 696 }
wolfSSL 0:9d17e4342598 697 }
wolfSSL 0:9d17e4342598 698
wolfSSL 0:9d17e4342598 699
wolfSSL 0:9d17e4342598 700 /* Show client sequence startup from SYN */
wolfSSL 0:9d17e4342598 701 static void TraceClientSyn(word32 seq)
wolfSSL 0:9d17e4342598 702 {
wolfSSL 0:9d17e4342598 703 if (TraceOn) {
wolfSSL 0:9d17e4342598 704 fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
wolfSSL 0:9d17e4342598 705 }
wolfSSL 0:9d17e4342598 706 }
wolfSSL 0:9d17e4342598 707
wolfSSL 0:9d17e4342598 708
wolfSSL 0:9d17e4342598 709 /* Show client FIN capture */
wolfSSL 0:9d17e4342598 710 static void TraceClientFin(word32 finSeq, word32 relSeq)
wolfSSL 0:9d17e4342598 711 {
wolfSSL 0:9d17e4342598 712 if (TraceOn) {
wolfSSL 0:9d17e4342598 713 fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
wolfSSL 0:9d17e4342598 714 finSeq, relSeq);
wolfSSL 0:9d17e4342598 715 }
wolfSSL 0:9d17e4342598 716 }
wolfSSL 0:9d17e4342598 717
wolfSSL 0:9d17e4342598 718
wolfSSL 0:9d17e4342598 719 /* Show server FIN capture */
wolfSSL 0:9d17e4342598 720 static void TraceServerFin(word32 finSeq, word32 relSeq)
wolfSSL 0:9d17e4342598 721 {
wolfSSL 0:9d17e4342598 722 if (TraceOn) {
wolfSSL 0:9d17e4342598 723 fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
wolfSSL 0:9d17e4342598 724 finSeq, relSeq);
wolfSSL 0:9d17e4342598 725 }
wolfSSL 0:9d17e4342598 726 }
wolfSSL 0:9d17e4342598 727
wolfSSL 0:9d17e4342598 728
wolfSSL 0:9d17e4342598 729 /* Show number of SSL data bytes decoded, could be 0 (ok) */
wolfSSL 0:9d17e4342598 730 static void TraceGotData(int bytes)
wolfSSL 0:9d17e4342598 731 {
wolfSSL 0:9d17e4342598 732 if (TraceOn) {
wolfSSL 0:9d17e4342598 733 fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
wolfSSL 0:9d17e4342598 734 }
wolfSSL 0:9d17e4342598 735 }
wolfSSL 0:9d17e4342598 736
wolfSSL 0:9d17e4342598 737
wolfSSL 0:9d17e4342598 738 /* Show bytes added to old SSL App data */
wolfSSL 0:9d17e4342598 739 static void TraceAddedData(int newBytes, int existingBytes)
wolfSSL 0:9d17e4342598 740 {
wolfSSL 0:9d17e4342598 741 if (TraceOn) {
wolfSSL 0:9d17e4342598 742 fprintf(TraceFile,
wolfSSL 0:9d17e4342598 743 "\t%d bytes added to %d exisiting bytes in User Buffer\n",
wolfSSL 0:9d17e4342598 744 newBytes, existingBytes);
wolfSSL 0:9d17e4342598 745 }
wolfSSL 0:9d17e4342598 746 }
wolfSSL 0:9d17e4342598 747
wolfSSL 0:9d17e4342598 748
wolfSSL 0:9d17e4342598 749 /* Show Stale Session */
wolfSSL 0:9d17e4342598 750 static void TraceStaleSession(void)
wolfSSL 0:9d17e4342598 751 {
wolfSSL 0:9d17e4342598 752 if (TraceOn) {
wolfSSL 0:9d17e4342598 753 fprintf(TraceFile, "\tFound a stale session\n");
wolfSSL 0:9d17e4342598 754 }
wolfSSL 0:9d17e4342598 755 }
wolfSSL 0:9d17e4342598 756
wolfSSL 0:9d17e4342598 757
wolfSSL 0:9d17e4342598 758 /* Show Finding Stale Sessions */
wolfSSL 0:9d17e4342598 759 static void TraceFindingStale(void)
wolfSSL 0:9d17e4342598 760 {
wolfSSL 0:9d17e4342598 761 if (TraceOn) {
wolfSSL 0:9d17e4342598 762 fprintf(TraceFile, "\tTrying to find Stale Sessions\n");
wolfSSL 0:9d17e4342598 763 }
wolfSSL 0:9d17e4342598 764 }
wolfSSL 0:9d17e4342598 765
wolfSSL 0:9d17e4342598 766
wolfSSL 0:9d17e4342598 767 /* Show Removed Session */
wolfSSL 0:9d17e4342598 768 static void TraceRemovedSession(void)
wolfSSL 0:9d17e4342598 769 {
wolfSSL 0:9d17e4342598 770 if (TraceOn) {
wolfSSL 0:9d17e4342598 771 fprintf(TraceFile, "\tRemoved it\n");
wolfSSL 0:9d17e4342598 772 }
wolfSSL 0:9d17e4342598 773 }
wolfSSL 0:9d17e4342598 774
wolfSSL 0:9d17e4342598 775
wolfSSL 0:9d17e4342598 776 /* Set user error string */
wolfSSL 0:9d17e4342598 777 static void SetError(int idx, char* error, SnifferSession* session, int fatal)
wolfSSL 0:9d17e4342598 778 {
wolfSSL 0:9d17e4342598 779 GetError(idx, error);
wolfSSL 0:9d17e4342598 780 Trace(idx);
wolfSSL 0:9d17e4342598 781 if (session && fatal == FATAL_ERROR_STATE)
wolfSSL 0:9d17e4342598 782 session->flags.fatalError = 1;
wolfSSL 0:9d17e4342598 783 }
wolfSSL 0:9d17e4342598 784
wolfSSL 0:9d17e4342598 785
wolfSSL 0:9d17e4342598 786 /* See if this IPV4 network order address has been registered */
wolfSSL 0:9d17e4342598 787 /* return 1 is true, 0 is false */
wolfSSL 0:9d17e4342598 788 static int IsServerRegistered(word32 addr)
wolfSSL 0:9d17e4342598 789 {
wolfSSL 0:9d17e4342598 790 int ret = 0; /* false */
wolfSSL 0:9d17e4342598 791 SnifferServer* sniffer;
wolfSSL 0:9d17e4342598 792
wolfSSL 0:9d17e4342598 793 LockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 794
wolfSSL 0:9d17e4342598 795 sniffer = ServerList;
wolfSSL 0:9d17e4342598 796 while (sniffer) {
wolfSSL 0:9d17e4342598 797 if (sniffer->server == addr) {
wolfSSL 0:9d17e4342598 798 ret = 1;
wolfSSL 0:9d17e4342598 799 break;
wolfSSL 0:9d17e4342598 800 }
wolfSSL 0:9d17e4342598 801 sniffer = sniffer->next;
wolfSSL 0:9d17e4342598 802 }
wolfSSL 0:9d17e4342598 803
wolfSSL 0:9d17e4342598 804 UnLockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 805
wolfSSL 0:9d17e4342598 806 return ret;
wolfSSL 0:9d17e4342598 807 }
wolfSSL 0:9d17e4342598 808
wolfSSL 0:9d17e4342598 809
wolfSSL 0:9d17e4342598 810 /* See if this port has been registered to watch */
wolfSSL 0:9d17e4342598 811 /* return 1 is true, 0 is false */
wolfSSL 0:9d17e4342598 812 static int IsPortRegistered(word32 port)
wolfSSL 0:9d17e4342598 813 {
wolfSSL 0:9d17e4342598 814 int ret = 0; /* false */
wolfSSL 0:9d17e4342598 815 SnifferServer* sniffer;
wolfSSL 0:9d17e4342598 816
wolfSSL 0:9d17e4342598 817 LockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 818
wolfSSL 0:9d17e4342598 819 sniffer = ServerList;
wolfSSL 0:9d17e4342598 820 while (sniffer) {
wolfSSL 0:9d17e4342598 821 if (sniffer->port == (int)port) {
wolfSSL 0:9d17e4342598 822 ret = 1;
wolfSSL 0:9d17e4342598 823 break;
wolfSSL 0:9d17e4342598 824 }
wolfSSL 0:9d17e4342598 825 sniffer = sniffer->next;
wolfSSL 0:9d17e4342598 826 }
wolfSSL 0:9d17e4342598 827
wolfSSL 0:9d17e4342598 828 UnLockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 829
wolfSSL 0:9d17e4342598 830 return ret;
wolfSSL 0:9d17e4342598 831 }
wolfSSL 0:9d17e4342598 832
wolfSSL 0:9d17e4342598 833
wolfSSL 0:9d17e4342598 834 /* Get SnifferServer from IP and Port */
wolfSSL 0:9d17e4342598 835 static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
wolfSSL 0:9d17e4342598 836 {
wolfSSL 0:9d17e4342598 837 SnifferServer* sniffer;
wolfSSL 0:9d17e4342598 838
wolfSSL 0:9d17e4342598 839 LockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 840
wolfSSL 0:9d17e4342598 841 sniffer = ServerList;
wolfSSL 0:9d17e4342598 842 while (sniffer) {
wolfSSL 0:9d17e4342598 843 if (sniffer->port == tcpInfo->srcPort && sniffer->server == ipInfo->src)
wolfSSL 0:9d17e4342598 844 break;
wolfSSL 0:9d17e4342598 845 if (sniffer->port == tcpInfo->dstPort && sniffer->server == ipInfo->dst)
wolfSSL 0:9d17e4342598 846 break;
wolfSSL 0:9d17e4342598 847 sniffer = sniffer->next;
wolfSSL 0:9d17e4342598 848 }
wolfSSL 0:9d17e4342598 849
wolfSSL 0:9d17e4342598 850 UnLockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 851
wolfSSL 0:9d17e4342598 852 return sniffer;
wolfSSL 0:9d17e4342598 853 }
wolfSSL 0:9d17e4342598 854
wolfSSL 0:9d17e4342598 855
wolfSSL 0:9d17e4342598 856 /* Hash the Session Info, return hash row */
wolfSSL 0:9d17e4342598 857 static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
wolfSSL 0:9d17e4342598 858 {
wolfSSL 0:9d17e4342598 859 word32 hash = ipInfo->src * ipInfo->dst;
wolfSSL 0:9d17e4342598 860 hash *= tcpInfo->srcPort * tcpInfo->dstPort;
wolfSSL 0:9d17e4342598 861
wolfSSL 0:9d17e4342598 862 return hash % HASH_SIZE;
wolfSSL 0:9d17e4342598 863 }
wolfSSL 0:9d17e4342598 864
wolfSSL 0:9d17e4342598 865
wolfSSL 0:9d17e4342598 866 /* Get Exisiting SnifferSession from IP and Port */
wolfSSL 0:9d17e4342598 867 static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
wolfSSL 0:9d17e4342598 868 {
wolfSSL 0:9d17e4342598 869 SnifferSession* session;
wolfSSL 0:9d17e4342598 870 time_t currTime = time(NULL);
wolfSSL 0:9d17e4342598 871 word32 row = SessionHash(ipInfo, tcpInfo);
wolfSSL 0:9d17e4342598 872
wolfSSL 0:9d17e4342598 873 assert(row <= HASH_SIZE);
wolfSSL 0:9d17e4342598 874
wolfSSL 0:9d17e4342598 875 LockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 876
wolfSSL 0:9d17e4342598 877 session = SessionTable[row];
wolfSSL 0:9d17e4342598 878 while (session) {
wolfSSL 0:9d17e4342598 879 if (session->server == ipInfo->src && session->client == ipInfo->dst &&
wolfSSL 0:9d17e4342598 880 session->srvPort == tcpInfo->srcPort &&
wolfSSL 0:9d17e4342598 881 session->cliPort == tcpInfo->dstPort)
wolfSSL 0:9d17e4342598 882 break;
wolfSSL 0:9d17e4342598 883 if (session->client == ipInfo->src && session->server == ipInfo->dst &&
wolfSSL 0:9d17e4342598 884 session->cliPort == tcpInfo->srcPort &&
wolfSSL 0:9d17e4342598 885 session->srvPort == tcpInfo->dstPort)
wolfSSL 0:9d17e4342598 886 break;
wolfSSL 0:9d17e4342598 887
wolfSSL 0:9d17e4342598 888 session = session->next;
wolfSSL 0:9d17e4342598 889 }
wolfSSL 0:9d17e4342598 890
wolfSSL 0:9d17e4342598 891 if (session)
wolfSSL 0:9d17e4342598 892 session->lastUsed= currTime; /* keep session alive, remove stale will */
wolfSSL 0:9d17e4342598 893 /* leave alone */
wolfSSL 0:9d17e4342598 894 UnLockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 895
wolfSSL 0:9d17e4342598 896 /* determine side */
wolfSSL 0:9d17e4342598 897 if (session) {
wolfSSL 0:9d17e4342598 898 if (ipInfo->dst == session->context->server &&
wolfSSL 0:9d17e4342598 899 tcpInfo->dstPort == session->context->port)
wolfSSL 0:9d17e4342598 900 session->flags.side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 901 else
wolfSSL 0:9d17e4342598 902 session->flags.side = CYASSL_CLIENT_END;
wolfSSL 0:9d17e4342598 903 }
wolfSSL 0:9d17e4342598 904
wolfSSL 0:9d17e4342598 905 return session;
wolfSSL 0:9d17e4342598 906 }
wolfSSL 0:9d17e4342598 907
wolfSSL 0:9d17e4342598 908
wolfSSL 0:9d17e4342598 909 /* Sets the private key for a specific server and port */
wolfSSL 0:9d17e4342598 910 /* returns 0 on success, -1 on error */
wolfSSL 0:9d17e4342598 911 int ssl_SetPrivateKey(const char* serverAddress, int port, const char* keyFile,
wolfSSL 0:9d17e4342598 912 int typeKey, const char* password, char* error)
wolfSSL 0:9d17e4342598 913 {
wolfSSL 0:9d17e4342598 914 int ret;
wolfSSL 0:9d17e4342598 915 int type = (typeKey == FILETYPE_PEM) ? SSL_FILETYPE_PEM :
wolfSSL 0:9d17e4342598 916 SSL_FILETYPE_ASN1;
wolfSSL 0:9d17e4342598 917 SnifferServer* sniffer;
wolfSSL 0:9d17e4342598 918
wolfSSL 0:9d17e4342598 919 TraceHeader();
wolfSSL 0:9d17e4342598 920 TraceSetServer(serverAddress, port, keyFile);
wolfSSL 0:9d17e4342598 921
wolfSSL 0:9d17e4342598 922 sniffer = (SnifferServer*)malloc(sizeof(SnifferServer));
wolfSSL 0:9d17e4342598 923 if (sniffer == NULL) {
wolfSSL 0:9d17e4342598 924 SetError(MEMORY_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 925 return -1;
wolfSSL 0:9d17e4342598 926 }
wolfSSL 0:9d17e4342598 927 InitSnifferServer(sniffer);
wolfSSL 0:9d17e4342598 928
wolfSSL 0:9d17e4342598 929 XSTRNCPY(sniffer->address, serverAddress, MAX_SERVER_ADDRESS);
wolfSSL 0:9d17e4342598 930 sniffer->server = inet_addr(sniffer->address);
wolfSSL 0:9d17e4342598 931 sniffer->port = port;
wolfSSL 0:9d17e4342598 932
wolfSSL 0:9d17e4342598 933 /* start in client mode since SSL_new needs a cert for server */
wolfSSL 0:9d17e4342598 934 sniffer->ctx = SSL_CTX_new(SSLv3_client_method());
wolfSSL 0:9d17e4342598 935 if (!sniffer->ctx) {
wolfSSL 0:9d17e4342598 936 SetError(MEMORY_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 937 FreeSnifferServer(sniffer);
wolfSSL 0:9d17e4342598 938 return -1;
wolfSSL 0:9d17e4342598 939 }
wolfSSL 0:9d17e4342598 940
wolfSSL 0:9d17e4342598 941 if (password){
wolfSSL 0:9d17e4342598 942 SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
wolfSSL 0:9d17e4342598 943 SSL_CTX_set_default_passwd_cb_userdata(sniffer->ctx, (void*)password);
wolfSSL 0:9d17e4342598 944 }
wolfSSL 0:9d17e4342598 945 ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
wolfSSL 0:9d17e4342598 946 if (ret != SSL_SUCCESS) {
wolfSSL 0:9d17e4342598 947 SetError(KEY_FILE_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 948 FreeSnifferServer(sniffer);
wolfSSL 0:9d17e4342598 949 return -1;
wolfSSL 0:9d17e4342598 950 }
wolfSSL 0:9d17e4342598 951 Trace(NEW_SERVER_STR);
wolfSSL 0:9d17e4342598 952
wolfSSL 0:9d17e4342598 953 LockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 954
wolfSSL 0:9d17e4342598 955 sniffer->next = ServerList;
wolfSSL 0:9d17e4342598 956 ServerList = sniffer;
wolfSSL 0:9d17e4342598 957
wolfSSL 0:9d17e4342598 958 UnLockMutex(&ServerListMutex);
wolfSSL 0:9d17e4342598 959
wolfSSL 0:9d17e4342598 960 return 0;
wolfSSL 0:9d17e4342598 961 }
wolfSSL 0:9d17e4342598 962
wolfSSL 0:9d17e4342598 963
wolfSSL 0:9d17e4342598 964 /* Check IP Header for IPV4, TCP, and a registered server address */
wolfSSL 0:9d17e4342598 965 /* returns 0 on success, -1 on error */
wolfSSL 0:9d17e4342598 966 static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
wolfSSL 0:9d17e4342598 967 {
wolfSSL 0:9d17e4342598 968 int version = IP_V(iphdr);
wolfSSL 0:9d17e4342598 969
wolfSSL 0:9d17e4342598 970 TraceIP(iphdr);
wolfSSL 0:9d17e4342598 971 Trace(IP_CHECK_STR);
wolfSSL 0:9d17e4342598 972
wolfSSL 0:9d17e4342598 973 if (version != IPV4) {
wolfSSL 0:9d17e4342598 974 SetError(BAD_IPVER_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 975 return -1;
wolfSSL 0:9d17e4342598 976 }
wolfSSL 0:9d17e4342598 977
wolfSSL 0:9d17e4342598 978 if (iphdr->protocol != TCP_PROTOCOL) {
wolfSSL 0:9d17e4342598 979 SetError(BAD_PROTO_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 980 return -1;
wolfSSL 0:9d17e4342598 981 }
wolfSSL 0:9d17e4342598 982
wolfSSL 0:9d17e4342598 983 if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
wolfSSL 0:9d17e4342598 984 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 985 return -1;
wolfSSL 0:9d17e4342598 986 }
wolfSSL 0:9d17e4342598 987
wolfSSL 0:9d17e4342598 988 info->length = IP_HL(iphdr);
wolfSSL 0:9d17e4342598 989 info->total = ntohs(iphdr->length);
wolfSSL 0:9d17e4342598 990 info->src = iphdr->src;
wolfSSL 0:9d17e4342598 991 info->dst = iphdr->dst;
wolfSSL 0:9d17e4342598 992
wolfSSL 0:9d17e4342598 993 if (info->total == 0)
wolfSSL 0:9d17e4342598 994 info->total = length; /* reassembled may be off */
wolfSSL 0:9d17e4342598 995
wolfSSL 0:9d17e4342598 996 return 0;
wolfSSL 0:9d17e4342598 997 }
wolfSSL 0:9d17e4342598 998
wolfSSL 0:9d17e4342598 999
wolfSSL 0:9d17e4342598 1000 /* Check TCP Header for a registered port */
wolfSSL 0:9d17e4342598 1001 /* returns 0 on success, -1 on error */
wolfSSL 0:9d17e4342598 1002 static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
wolfSSL 0:9d17e4342598 1003 {
wolfSSL 0:9d17e4342598 1004 TraceTcp(tcphdr);
wolfSSL 0:9d17e4342598 1005 Trace(TCP_CHECK_STR);
wolfSSL 0:9d17e4342598 1006 info->srcPort = ntohs(tcphdr->srcPort);
wolfSSL 0:9d17e4342598 1007 info->dstPort = ntohs(tcphdr->dstPort);
wolfSSL 0:9d17e4342598 1008 info->length = TCP_LEN(tcphdr);
wolfSSL 0:9d17e4342598 1009 info->sequence = ntohl(tcphdr->sequence);
wolfSSL 0:9d17e4342598 1010 info->fin = tcphdr->flags & TCP_FIN;
wolfSSL 0:9d17e4342598 1011 info->rst = tcphdr->flags & TCP_RST;
wolfSSL 0:9d17e4342598 1012 info->syn = tcphdr->flags & TCP_SYN;
wolfSSL 0:9d17e4342598 1013 info->ack = tcphdr->flags & TCP_ACK;
wolfSSL 0:9d17e4342598 1014 if (info->ack)
wolfSSL 0:9d17e4342598 1015 info->ackNumber = ntohl(tcphdr->ack);
wolfSSL 0:9d17e4342598 1016
wolfSSL 0:9d17e4342598 1017 if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
wolfSSL 0:9d17e4342598 1018 SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1019 return -1;
wolfSSL 0:9d17e4342598 1020 }
wolfSSL 0:9d17e4342598 1021
wolfSSL 0:9d17e4342598 1022 return 0;
wolfSSL 0:9d17e4342598 1023 }
wolfSSL 0:9d17e4342598 1024
wolfSSL 0:9d17e4342598 1025
wolfSSL 0:9d17e4342598 1026 /* Decode Record Layer Header */
wolfSSL 0:9d17e4342598 1027 static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
wolfSSL 0:9d17e4342598 1028 {
wolfSSL 0:9d17e4342598 1029 XMEMCPY(rh, input, RECORD_HEADER_SZ);
wolfSSL 0:9d17e4342598 1030 *size = (rh->length[0] << 8) | rh->length[1];
wolfSSL 0:9d17e4342598 1031
wolfSSL 0:9d17e4342598 1032 if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
wolfSSL 0:9d17e4342598 1033 return LENGTH_ERROR;
wolfSSL 0:9d17e4342598 1034
wolfSSL 0:9d17e4342598 1035 return 0;
wolfSSL 0:9d17e4342598 1036 }
wolfSSL 0:9d17e4342598 1037
wolfSSL 0:9d17e4342598 1038
wolfSSL 0:9d17e4342598 1039 /* Process Client Key Exchange, RSA only */
wolfSSL 0:9d17e4342598 1040 static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
wolfSSL 0:9d17e4342598 1041 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1042 {
wolfSSL 0:9d17e4342598 1043 word32 idx = 0;
wolfSSL 0:9d17e4342598 1044 RsaKey key;
wolfSSL 0:9d17e4342598 1045 int ret;
wolfSSL 0:9d17e4342598 1046
wolfSSL 0:9d17e4342598 1047 ret = InitRsaKey(&key, 0);
wolfSSL 0:9d17e4342598 1048 if (ret == 0)
wolfSSL 0:9d17e4342598 1049 ret = RsaPrivateKeyDecode(session->context->ctx->privateKey.buffer,
wolfSSL 0:9d17e4342598 1050 &idx, &key, session->context->ctx->privateKey.length);
wolfSSL 0:9d17e4342598 1051 if (ret == 0) {
wolfSSL 0:9d17e4342598 1052 int length = RsaEncryptSize(&key);
wolfSSL 0:9d17e4342598 1053
wolfSSL 0:9d17e4342598 1054 if (IsTLS(session->sslServer))
wolfSSL 0:9d17e4342598 1055 input += 2; /* tls pre length */
wolfSSL 0:9d17e4342598 1056
wolfSSL 0:9d17e4342598 1057 if (length > *sslBytes) {
wolfSSL 0:9d17e4342598 1058 SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1059 FreeRsaKey(&key);
wolfSSL 0:9d17e4342598 1060 return -1;
wolfSSL 0:9d17e4342598 1061 }
wolfSSL 0:9d17e4342598 1062 ret = RsaPrivateDecrypt(input, length,
wolfSSL 0:9d17e4342598 1063 session->sslServer->arrays->preMasterSecret,SECRET_LEN, &key);
wolfSSL 0:9d17e4342598 1064
wolfSSL 0:9d17e4342598 1065 if (ret != SECRET_LEN) {
wolfSSL 0:9d17e4342598 1066 SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1067 FreeRsaKey(&key);
wolfSSL 0:9d17e4342598 1068 return -1;
wolfSSL 0:9d17e4342598 1069 }
wolfSSL 0:9d17e4342598 1070 ret = 0; /* not in error state */
wolfSSL 0:9d17e4342598 1071 session->sslServer->arrays->preMasterSz = SECRET_LEN;
wolfSSL 0:9d17e4342598 1072
wolfSSL 0:9d17e4342598 1073 /* store for client side as well */
wolfSSL 0:9d17e4342598 1074 XMEMCPY(session->sslClient->arrays->preMasterSecret,
wolfSSL 0:9d17e4342598 1075 session->sslServer->arrays->preMasterSecret, SECRET_LEN);
wolfSSL 0:9d17e4342598 1076 session->sslClient->arrays->preMasterSz = SECRET_LEN;
wolfSSL 0:9d17e4342598 1077
wolfSSL 0:9d17e4342598 1078 #ifdef SHOW_SECRETS
wolfSSL 0:9d17e4342598 1079 {
wolfSSL 0:9d17e4342598 1080 int i;
wolfSSL 0:9d17e4342598 1081 printf("pre master secret: ");
wolfSSL 0:9d17e4342598 1082 for (i = 0; i < SECRET_LEN; i++)
wolfSSL 0:9d17e4342598 1083 printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
wolfSSL 0:9d17e4342598 1084 printf("\n");
wolfSSL 0:9d17e4342598 1085 }
wolfSSL 0:9d17e4342598 1086 #endif
wolfSSL 0:9d17e4342598 1087 }
wolfSSL 0:9d17e4342598 1088 else {
wolfSSL 0:9d17e4342598 1089 SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1090 FreeRsaKey(&key);
wolfSSL 0:9d17e4342598 1091 return -1;
wolfSSL 0:9d17e4342598 1092 }
wolfSSL 0:9d17e4342598 1093
wolfSSL 0:9d17e4342598 1094 if (SetCipherSpecs(session->sslServer) != 0) {
wolfSSL 0:9d17e4342598 1095 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1096 FreeRsaKey(&key);
wolfSSL 0:9d17e4342598 1097 return -1;
wolfSSL 0:9d17e4342598 1098 }
wolfSSL 0:9d17e4342598 1099
wolfSSL 0:9d17e4342598 1100 if (SetCipherSpecs(session->sslClient) != 0) {
wolfSSL 0:9d17e4342598 1101 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1102 FreeRsaKey(&key);
wolfSSL 0:9d17e4342598 1103 return -1;
wolfSSL 0:9d17e4342598 1104 }
wolfSSL 0:9d17e4342598 1105
wolfSSL 0:9d17e4342598 1106 MakeMasterSecret(session->sslServer);
wolfSSL 0:9d17e4342598 1107 MakeMasterSecret(session->sslClient);
wolfSSL 0:9d17e4342598 1108 #ifdef SHOW_SECRETS
wolfSSL 0:9d17e4342598 1109 {
wolfSSL 0:9d17e4342598 1110 int i;
wolfSSL 0:9d17e4342598 1111 printf("server master secret: ");
wolfSSL 0:9d17e4342598 1112 for (i = 0; i < SECRET_LEN; i++)
wolfSSL 0:9d17e4342598 1113 printf("%02x", session->sslServer->arrays->masterSecret[i]);
wolfSSL 0:9d17e4342598 1114 printf("\n");
wolfSSL 0:9d17e4342598 1115
wolfSSL 0:9d17e4342598 1116 printf("client master secret: ");
wolfSSL 0:9d17e4342598 1117 for (i = 0; i < SECRET_LEN; i++)
wolfSSL 0:9d17e4342598 1118 printf("%02x", session->sslClient->arrays->masterSecret[i]);
wolfSSL 0:9d17e4342598 1119 printf("\n");
wolfSSL 0:9d17e4342598 1120
wolfSSL 0:9d17e4342598 1121 printf("server suite = %d\n", session->sslServer->options.cipherSuite);
wolfSSL 0:9d17e4342598 1122 printf("client suite = %d\n", session->sslClient->options.cipherSuite);
wolfSSL 0:9d17e4342598 1123 }
wolfSSL 0:9d17e4342598 1124 #endif
wolfSSL 0:9d17e4342598 1125
wolfSSL 0:9d17e4342598 1126 FreeRsaKey(&key);
wolfSSL 0:9d17e4342598 1127 return ret;
wolfSSL 0:9d17e4342598 1128 }
wolfSSL 0:9d17e4342598 1129
wolfSSL 0:9d17e4342598 1130
wolfSSL 0:9d17e4342598 1131 /* Process Session Ticket */
wolfSSL 0:9d17e4342598 1132 static int ProcessSessionTicket(const byte* input, int* sslBytes,
wolfSSL 0:9d17e4342598 1133 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1134 {
wolfSSL 0:9d17e4342598 1135 word16 len;
wolfSSL 0:9d17e4342598 1136
wolfSSL 0:9d17e4342598 1137 /* make sure can read through hint and len */
wolfSSL 0:9d17e4342598 1138 if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) {
wolfSSL 0:9d17e4342598 1139 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1140 return -1;
wolfSSL 0:9d17e4342598 1141 }
wolfSSL 0:9d17e4342598 1142
wolfSSL 0:9d17e4342598 1143 input += TICKET_HINT_LEN; /* skip over hint */
wolfSSL 0:9d17e4342598 1144 *sslBytes -= TICKET_HINT_LEN;
wolfSSL 0:9d17e4342598 1145
wolfSSL 0:9d17e4342598 1146 len = (word16)((input[0] << 8) | input[1]);
wolfSSL 0:9d17e4342598 1147 input += LENGTH_SZ;
wolfSSL 0:9d17e4342598 1148 *sslBytes -= LENGTH_SZ;
wolfSSL 0:9d17e4342598 1149
wolfSSL 0:9d17e4342598 1150 /* make sure can read through ticket */
wolfSSL 0:9d17e4342598 1151 if (len > *sslBytes || len < ID_LEN) {
wolfSSL 0:9d17e4342598 1152 SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1153 return -1;
wolfSSL 0:9d17e4342598 1154 }
wolfSSL 0:9d17e4342598 1155
wolfSSL 0:9d17e4342598 1156 /* store session with macID as sessionID */
wolfSSL 0:9d17e4342598 1157 session->sslServer->options.haveSessionId = 1;
wolfSSL 0:9d17e4342598 1158 XMEMCPY(session->sslServer->arrays->sessionID, input + len - ID_LEN,ID_LEN);
wolfSSL 0:9d17e4342598 1159
wolfSSL 0:9d17e4342598 1160 return 0;
wolfSSL 0:9d17e4342598 1161 }
wolfSSL 0:9d17e4342598 1162
wolfSSL 0:9d17e4342598 1163
wolfSSL 0:9d17e4342598 1164 /* Process Server Hello */
wolfSSL 0:9d17e4342598 1165 static int ProcessServerHello(const byte* input, int* sslBytes,
wolfSSL 0:9d17e4342598 1166 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1167 {
wolfSSL 0:9d17e4342598 1168 ProtocolVersion pv;
wolfSSL 0:9d17e4342598 1169 byte b;
wolfSSL 0:9d17e4342598 1170 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
wolfSSL 0:9d17e4342598 1171 int doResume = 0;
wolfSSL 0:9d17e4342598 1172
wolfSSL 0:9d17e4342598 1173 /* make sure we didn't miss ClientHello */
wolfSSL 0:9d17e4342598 1174 if (session->flags.clientHello == 0) {
wolfSSL 0:9d17e4342598 1175 SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1176 return -1;
wolfSSL 0:9d17e4342598 1177 }
wolfSSL 0:9d17e4342598 1178
wolfSSL 0:9d17e4342598 1179 /* make sure can read through session len */
wolfSSL 0:9d17e4342598 1180 if (toRead > *sslBytes) {
wolfSSL 0:9d17e4342598 1181 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1182 return -1;
wolfSSL 0:9d17e4342598 1183 }
wolfSSL 0:9d17e4342598 1184
wolfSSL 0:9d17e4342598 1185 XMEMCPY(&pv, input, VERSION_SZ);
wolfSSL 0:9d17e4342598 1186 input += VERSION_SZ;
wolfSSL 0:9d17e4342598 1187 *sslBytes -= VERSION_SZ;
wolfSSL 0:9d17e4342598 1188
wolfSSL 0:9d17e4342598 1189 session->sslServer->version = pv;
wolfSSL 0:9d17e4342598 1190 session->sslClient->version = pv;
wolfSSL 0:9d17e4342598 1191
wolfSSL 0:9d17e4342598 1192 XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN);
wolfSSL 0:9d17e4342598 1193 XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN);
wolfSSL 0:9d17e4342598 1194 input += RAN_LEN;
wolfSSL 0:9d17e4342598 1195 *sslBytes -= RAN_LEN;
wolfSSL 0:9d17e4342598 1196
wolfSSL 0:9d17e4342598 1197 b = *input++;
wolfSSL 0:9d17e4342598 1198 *sslBytes -= 1;
wolfSSL 0:9d17e4342598 1199
wolfSSL 0:9d17e4342598 1200 /* make sure can read through compression */
wolfSSL 0:9d17e4342598 1201 if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
wolfSSL 0:9d17e4342598 1202 SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1203 return -1;
wolfSSL 0:9d17e4342598 1204 }
wolfSSL 0:9d17e4342598 1205 if (b) {
wolfSSL 0:9d17e4342598 1206 XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN);
wolfSSL 0:9d17e4342598 1207 session->sslServer->options.haveSessionId = 1;
wolfSSL 0:9d17e4342598 1208 }
wolfSSL 0:9d17e4342598 1209 input += b;
wolfSSL 0:9d17e4342598 1210 *sslBytes -= b;
wolfSSL 0:9d17e4342598 1211
wolfSSL 0:9d17e4342598 1212 /* cipher suite */
wolfSSL 0:9d17e4342598 1213 b = *input++; /* first byte, ECC or not */
wolfSSL 0:9d17e4342598 1214 session->sslServer->options.cipherSuite0 = b;
wolfSSL 0:9d17e4342598 1215 session->sslClient->options.cipherSuite0 = b;
wolfSSL 0:9d17e4342598 1216 b = *input++;
wolfSSL 0:9d17e4342598 1217 session->sslServer->options.cipherSuite = b;
wolfSSL 0:9d17e4342598 1218 session->sslClient->options.cipherSuite = b;
wolfSSL 0:9d17e4342598 1219 *sslBytes -= SUITE_LEN;
wolfSSL 0:9d17e4342598 1220
wolfSSL 0:9d17e4342598 1221 /* compression */
wolfSSL 0:9d17e4342598 1222 b = *input++;
wolfSSL 0:9d17e4342598 1223 *sslBytes -= ENUM_LEN;
wolfSSL 0:9d17e4342598 1224
wolfSSL 0:9d17e4342598 1225 if (b) {
wolfSSL 0:9d17e4342598 1226 SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1227 return -1;
wolfSSL 0:9d17e4342598 1228 }
wolfSSL 0:9d17e4342598 1229
wolfSSL 0:9d17e4342598 1230 if (session->sslServer->options.haveSessionId &&
wolfSSL 0:9d17e4342598 1231 XMEMCMP(session->sslServer->arrays->sessionID,
wolfSSL 0:9d17e4342598 1232 session->sslClient->arrays->sessionID, ID_LEN) == 0)
wolfSSL 0:9d17e4342598 1233 doResume = 1;
wolfSSL 0:9d17e4342598 1234 else if (session->sslClient->options.haveSessionId == 0 &&
wolfSSL 0:9d17e4342598 1235 session->sslServer->options.haveSessionId == 0 &&
wolfSSL 0:9d17e4342598 1236 session->ticketID)
wolfSSL 0:9d17e4342598 1237 doResume = 1;
wolfSSL 0:9d17e4342598 1238
wolfSSL 0:9d17e4342598 1239 if (session->ticketID && doResume) {
wolfSSL 0:9d17e4342598 1240 /* use ticketID to retrieve from session, prefer over sessionID */
wolfSSL 0:9d17e4342598 1241 XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN);
wolfSSL 0:9d17e4342598 1242 session->sslServer->options.haveSessionId = 1; /* may not have
wolfSSL 0:9d17e4342598 1243 actual sessionID */
wolfSSL 0:9d17e4342598 1244 }
wolfSSL 0:9d17e4342598 1245
wolfSSL 0:9d17e4342598 1246 if (doResume ) {
wolfSSL 0:9d17e4342598 1247 int ret = 0;
wolfSSL 0:9d17e4342598 1248 SSL_SESSION* resume = GetSession(session->sslServer,
wolfSSL 0:9d17e4342598 1249 session->sslServer->arrays->masterSecret);
wolfSSL 0:9d17e4342598 1250 if (resume == NULL) {
wolfSSL 0:9d17e4342598 1251 SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1252 return -1;
wolfSSL 0:9d17e4342598 1253 }
wolfSSL 0:9d17e4342598 1254 /* make sure client has master secret too */
wolfSSL 0:9d17e4342598 1255 XMEMCPY(session->sslClient->arrays->masterSecret,
wolfSSL 0:9d17e4342598 1256 session->sslServer->arrays->masterSecret, SECRET_LEN);
wolfSSL 0:9d17e4342598 1257 session->flags.resuming = 1;
wolfSSL 0:9d17e4342598 1258
wolfSSL 0:9d17e4342598 1259 Trace(SERVER_DID_RESUMPTION_STR);
wolfSSL 0:9d17e4342598 1260 if (SetCipherSpecs(session->sslServer) != 0) {
wolfSSL 0:9d17e4342598 1261 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1262 return -1;
wolfSSL 0:9d17e4342598 1263 }
wolfSSL 0:9d17e4342598 1264
wolfSSL 0:9d17e4342598 1265 if (SetCipherSpecs(session->sslClient) != 0) {
wolfSSL 0:9d17e4342598 1266 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1267 return -1;
wolfSSL 0:9d17e4342598 1268 }
wolfSSL 0:9d17e4342598 1269
wolfSSL 0:9d17e4342598 1270 if (session->sslServer->options.tls) {
wolfSSL 0:9d17e4342598 1271 ret = DeriveTlsKeys(session->sslServer);
wolfSSL 0:9d17e4342598 1272 ret += DeriveTlsKeys(session->sslClient);
wolfSSL 0:9d17e4342598 1273 }
wolfSSL 0:9d17e4342598 1274 else {
wolfSSL 0:9d17e4342598 1275 ret = DeriveKeys(session->sslServer);
wolfSSL 0:9d17e4342598 1276 ret += DeriveKeys(session->sslClient);
wolfSSL 0:9d17e4342598 1277 }
wolfSSL 0:9d17e4342598 1278 if (ret != 0) {
wolfSSL 0:9d17e4342598 1279 SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1280 return -1;
wolfSSL 0:9d17e4342598 1281 }
wolfSSL 0:9d17e4342598 1282 }
wolfSSL 0:9d17e4342598 1283 #ifdef SHOW_SECRETS
wolfSSL 0:9d17e4342598 1284 {
wolfSSL 0:9d17e4342598 1285 int i;
wolfSSL 0:9d17e4342598 1286 printf("cipher suite = 0x%02x\n",
wolfSSL 0:9d17e4342598 1287 session->sslServer->options.cipherSuite);
wolfSSL 0:9d17e4342598 1288 printf("server random: ");
wolfSSL 0:9d17e4342598 1289 for (i = 0; i < RAN_LEN; i++)
wolfSSL 0:9d17e4342598 1290 printf("%02x", session->sslServer->arrays->serverRandom[i]);
wolfSSL 0:9d17e4342598 1291 printf("\n");
wolfSSL 0:9d17e4342598 1292 }
wolfSSL 0:9d17e4342598 1293 #endif
wolfSSL 0:9d17e4342598 1294 return 0;
wolfSSL 0:9d17e4342598 1295 }
wolfSSL 0:9d17e4342598 1296
wolfSSL 0:9d17e4342598 1297
wolfSSL 0:9d17e4342598 1298 /* Process normal Client Hello */
wolfSSL 0:9d17e4342598 1299 static int ProcessClientHello(const byte* input, int* sslBytes,
wolfSSL 0:9d17e4342598 1300 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1301 {
wolfSSL 0:9d17e4342598 1302 byte bLen;
wolfSSL 0:9d17e4342598 1303 word16 len;
wolfSSL 0:9d17e4342598 1304 int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
wolfSSL 0:9d17e4342598 1305
wolfSSL 0:9d17e4342598 1306 session->flags.clientHello = 1; /* don't process again */
wolfSSL 0:9d17e4342598 1307
wolfSSL 0:9d17e4342598 1308 /* make sure can read up to session len */
wolfSSL 0:9d17e4342598 1309 if (toRead > *sslBytes) {
wolfSSL 0:9d17e4342598 1310 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1311 return -1;
wolfSSL 0:9d17e4342598 1312 }
wolfSSL 0:9d17e4342598 1313
wolfSSL 0:9d17e4342598 1314 /* skip, get negotiated one from server hello */
wolfSSL 0:9d17e4342598 1315 input += VERSION_SZ;
wolfSSL 0:9d17e4342598 1316 *sslBytes -= VERSION_SZ;
wolfSSL 0:9d17e4342598 1317
wolfSSL 0:9d17e4342598 1318 XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN);
wolfSSL 0:9d17e4342598 1319 XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN);
wolfSSL 0:9d17e4342598 1320
wolfSSL 0:9d17e4342598 1321 input += RAN_LEN;
wolfSSL 0:9d17e4342598 1322 *sslBytes -= RAN_LEN;
wolfSSL 0:9d17e4342598 1323
wolfSSL 0:9d17e4342598 1324 /* store session in case trying to resume */
wolfSSL 0:9d17e4342598 1325 bLen = *input++;
wolfSSL 0:9d17e4342598 1326 *sslBytes -= ENUM_LEN;
wolfSSL 0:9d17e4342598 1327 if (bLen) {
wolfSSL 0:9d17e4342598 1328 if (ID_LEN > *sslBytes) {
wolfSSL 0:9d17e4342598 1329 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1330 return -1;
wolfSSL 0:9d17e4342598 1331 }
wolfSSL 0:9d17e4342598 1332 Trace(CLIENT_RESUME_TRY_STR);
wolfSSL 0:9d17e4342598 1333 XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN);
wolfSSL 0:9d17e4342598 1334 session->sslClient->options.haveSessionId = 1;
wolfSSL 0:9d17e4342598 1335 }
wolfSSL 0:9d17e4342598 1336 #ifdef SHOW_SECRETS
wolfSSL 0:9d17e4342598 1337 {
wolfSSL 0:9d17e4342598 1338 int i;
wolfSSL 0:9d17e4342598 1339 printf("client random: ");
wolfSSL 0:9d17e4342598 1340 for (i = 0; i < RAN_LEN; i++)
wolfSSL 0:9d17e4342598 1341 printf("%02x", session->sslServer->arrays->clientRandom[i]);
wolfSSL 0:9d17e4342598 1342 printf("\n");
wolfSSL 0:9d17e4342598 1343 }
wolfSSL 0:9d17e4342598 1344 #endif
wolfSSL 0:9d17e4342598 1345
wolfSSL 0:9d17e4342598 1346 input += bLen;
wolfSSL 0:9d17e4342598 1347 *sslBytes -= bLen;
wolfSSL 0:9d17e4342598 1348
wolfSSL 0:9d17e4342598 1349 /* skip cipher suites */
wolfSSL 0:9d17e4342598 1350 /* make sure can read len */
wolfSSL 0:9d17e4342598 1351 if (SUITE_LEN > *sslBytes) {
wolfSSL 0:9d17e4342598 1352 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1353 return -1;
wolfSSL 0:9d17e4342598 1354 }
wolfSSL 0:9d17e4342598 1355 len = (word16)((input[0] << 8) | input[1]);
wolfSSL 0:9d17e4342598 1356 input += SUITE_LEN;
wolfSSL 0:9d17e4342598 1357 *sslBytes -= SUITE_LEN;
wolfSSL 0:9d17e4342598 1358 /* make sure can read suites + comp len */
wolfSSL 0:9d17e4342598 1359 if (len + ENUM_LEN > *sslBytes) {
wolfSSL 0:9d17e4342598 1360 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1361 return -1;
wolfSSL 0:9d17e4342598 1362 }
wolfSSL 0:9d17e4342598 1363 input += len;
wolfSSL 0:9d17e4342598 1364 *sslBytes -= len;
wolfSSL 0:9d17e4342598 1365
wolfSSL 0:9d17e4342598 1366 /* skip compression */
wolfSSL 0:9d17e4342598 1367 bLen = *input++;
wolfSSL 0:9d17e4342598 1368 *sslBytes -= ENUM_LEN;
wolfSSL 0:9d17e4342598 1369 /* make sure can read len */
wolfSSL 0:9d17e4342598 1370 if (bLen > *sslBytes) {
wolfSSL 0:9d17e4342598 1371 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1372 return -1;
wolfSSL 0:9d17e4342598 1373 }
wolfSSL 0:9d17e4342598 1374 input += bLen;
wolfSSL 0:9d17e4342598 1375 *sslBytes -= bLen;
wolfSSL 0:9d17e4342598 1376
wolfSSL 0:9d17e4342598 1377 if (*sslBytes == 0) {
wolfSSL 0:9d17e4342598 1378 /* no extensions */
wolfSSL 0:9d17e4342598 1379 return 0;
wolfSSL 0:9d17e4342598 1380 }
wolfSSL 0:9d17e4342598 1381
wolfSSL 0:9d17e4342598 1382 /* skip extensions until session ticket */
wolfSSL 0:9d17e4342598 1383 /* make sure can read len */
wolfSSL 0:9d17e4342598 1384 if (SUITE_LEN > *sslBytes) {
wolfSSL 0:9d17e4342598 1385 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1386 return -1;
wolfSSL 0:9d17e4342598 1387 }
wolfSSL 0:9d17e4342598 1388 len = (word16)((input[0] << 8) | input[1]);
wolfSSL 0:9d17e4342598 1389 input += SUITE_LEN;
wolfSSL 0:9d17e4342598 1390 *sslBytes -= SUITE_LEN;
wolfSSL 0:9d17e4342598 1391 /* make sure can read through all extensions */
wolfSSL 0:9d17e4342598 1392 if (len > *sslBytes) {
wolfSSL 0:9d17e4342598 1393 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1394 return -1;
wolfSSL 0:9d17e4342598 1395 }
wolfSSL 0:9d17e4342598 1396
wolfSSL 0:9d17e4342598 1397 while (len > EXT_TYPE_SZ + LENGTH_SZ) {
wolfSSL 0:9d17e4342598 1398 byte extType[EXT_TYPE_SZ];
wolfSSL 0:9d17e4342598 1399 word16 extLen;
wolfSSL 0:9d17e4342598 1400
wolfSSL 0:9d17e4342598 1401 extType[0] = input[0];
wolfSSL 0:9d17e4342598 1402 extType[1] = input[1];
wolfSSL 0:9d17e4342598 1403 input += EXT_TYPE_SZ;
wolfSSL 0:9d17e4342598 1404 *sslBytes -= EXT_TYPE_SZ;
wolfSSL 0:9d17e4342598 1405
wolfSSL 0:9d17e4342598 1406 extLen = (word16)((input[0] << 8) | input[1]);
wolfSSL 0:9d17e4342598 1407 input += LENGTH_SZ;
wolfSSL 0:9d17e4342598 1408 *sslBytes -= LENGTH_SZ;
wolfSSL 0:9d17e4342598 1409
wolfSSL 0:9d17e4342598 1410 /* make sure can read through individual extension */
wolfSSL 0:9d17e4342598 1411 if (extLen > *sslBytes) {
wolfSSL 0:9d17e4342598 1412 SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1413 return -1;
wolfSSL 0:9d17e4342598 1414 }
wolfSSL 0:9d17e4342598 1415
wolfSSL 0:9d17e4342598 1416 if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) {
wolfSSL 0:9d17e4342598 1417
wolfSSL 0:9d17e4342598 1418 /* make sure can read through ticket if there is a non blank one */
wolfSSL 0:9d17e4342598 1419 if (extLen && extLen < ID_LEN) {
wolfSSL 0:9d17e4342598 1420 SetError(CLIENT_HELLO_INPUT_STR, error, session,
wolfSSL 0:9d17e4342598 1421 FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1422 return -1;
wolfSSL 0:9d17e4342598 1423 }
wolfSSL 0:9d17e4342598 1424
wolfSSL 0:9d17e4342598 1425 if (extLen) {
wolfSSL 0:9d17e4342598 1426 if (session->ticketID == 0) {
wolfSSL 0:9d17e4342598 1427 session->ticketID = (byte*)malloc(ID_LEN);
wolfSSL 0:9d17e4342598 1428 if (session->ticketID == 0) {
wolfSSL 0:9d17e4342598 1429 SetError(MEMORY_STR, error, session,
wolfSSL 0:9d17e4342598 1430 FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1431 return -1;
wolfSSL 0:9d17e4342598 1432 }
wolfSSL 0:9d17e4342598 1433 }
wolfSSL 0:9d17e4342598 1434 XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
wolfSSL 0:9d17e4342598 1435 }
wolfSSL 0:9d17e4342598 1436 }
wolfSSL 0:9d17e4342598 1437
wolfSSL 0:9d17e4342598 1438 input += extLen;
wolfSSL 0:9d17e4342598 1439 *sslBytes -= extLen;
wolfSSL 0:9d17e4342598 1440 len -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
wolfSSL 0:9d17e4342598 1441 }
wolfSSL 0:9d17e4342598 1442
wolfSSL 0:9d17e4342598 1443 return 0;
wolfSSL 0:9d17e4342598 1444 }
wolfSSL 0:9d17e4342598 1445
wolfSSL 0:9d17e4342598 1446
wolfSSL 0:9d17e4342598 1447 /* Process Finished */
wolfSSL 0:9d17e4342598 1448 static int ProcessFinished(const byte* input, int size, int* sslBytes,
wolfSSL 0:9d17e4342598 1449 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1450 {
wolfSSL 0:9d17e4342598 1451 SSL* ssl;
wolfSSL 0:9d17e4342598 1452 word32 inOutIdx = 0;
wolfSSL 0:9d17e4342598 1453 int ret;
wolfSSL 0:9d17e4342598 1454
wolfSSL 0:9d17e4342598 1455 if (session->flags.side == CYASSL_SERVER_END)
wolfSSL 0:9d17e4342598 1456 ssl = session->sslServer;
wolfSSL 0:9d17e4342598 1457 else
wolfSSL 0:9d17e4342598 1458 ssl = session->sslClient;
wolfSSL 0:9d17e4342598 1459
wolfSSL 0:9d17e4342598 1460 ret = DoFinished(ssl, input, &inOutIdx, (word32) size, (word32) *sslBytes,
wolfSSL 0:9d17e4342598 1461 SNIFF);
wolfSSL 0:9d17e4342598 1462 *sslBytes -= (int)inOutIdx;
wolfSSL 0:9d17e4342598 1463
wolfSSL 0:9d17e4342598 1464 if (ret < 0) {
wolfSSL 0:9d17e4342598 1465 SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1466 return ret;
wolfSSL 0:9d17e4342598 1467 }
wolfSSL 0:9d17e4342598 1468
wolfSSL 0:9d17e4342598 1469 if (ret == 0 && session->flags.cached == 0) {
wolfSSL 0:9d17e4342598 1470 if (session->sslServer->options.haveSessionId) {
wolfSSL 0:9d17e4342598 1471 CYASSL_SESSION* sess = GetSession(session->sslServer, NULL);
wolfSSL 0:9d17e4342598 1472 if (sess == NULL)
wolfSSL 0:9d17e4342598 1473 AddSession(session->sslServer); /* don't re add */
wolfSSL 0:9d17e4342598 1474 session->flags.cached = 1;
wolfSSL 0:9d17e4342598 1475 }
wolfSSL 0:9d17e4342598 1476 }
wolfSSL 0:9d17e4342598 1477
wolfSSL 0:9d17e4342598 1478 FreeHandshakeResources(ssl);
wolfSSL 0:9d17e4342598 1479
wolfSSL 0:9d17e4342598 1480 return ret;
wolfSSL 0:9d17e4342598 1481 }
wolfSSL 0:9d17e4342598 1482
wolfSSL 0:9d17e4342598 1483
wolfSSL 0:9d17e4342598 1484 /* Process HandShake input */
wolfSSL 0:9d17e4342598 1485 static int DoHandShake(const byte* input, int* sslBytes,
wolfSSL 0:9d17e4342598 1486 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1487 {
wolfSSL 0:9d17e4342598 1488 byte type;
wolfSSL 0:9d17e4342598 1489 int size;
wolfSSL 0:9d17e4342598 1490 int ret = 0;
wolfSSL 0:9d17e4342598 1491
wolfSSL 0:9d17e4342598 1492 if (*sslBytes < HANDSHAKE_HEADER_SZ) {
wolfSSL 0:9d17e4342598 1493 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1494 return -1;
wolfSSL 0:9d17e4342598 1495 }
wolfSSL 0:9d17e4342598 1496 type = input[0];
wolfSSL 0:9d17e4342598 1497 size = (input[1] << 16) | (input[2] << 8) | input[3];
wolfSSL 0:9d17e4342598 1498
wolfSSL 0:9d17e4342598 1499 input += HANDSHAKE_HEADER_SZ;
wolfSSL 0:9d17e4342598 1500 *sslBytes -= HANDSHAKE_HEADER_SZ;
wolfSSL 0:9d17e4342598 1501
wolfSSL 0:9d17e4342598 1502 if (*sslBytes < size) {
wolfSSL 0:9d17e4342598 1503 SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1504 return -1;
wolfSSL 0:9d17e4342598 1505 }
wolfSSL 0:9d17e4342598 1506
wolfSSL 0:9d17e4342598 1507 switch (type) {
wolfSSL 0:9d17e4342598 1508 case hello_verify_request:
wolfSSL 0:9d17e4342598 1509 Trace(GOT_HELLO_VERIFY_STR);
wolfSSL 0:9d17e4342598 1510 break;
wolfSSL 0:9d17e4342598 1511 case hello_request:
wolfSSL 0:9d17e4342598 1512 Trace(GOT_HELLO_REQUEST_STR);
wolfSSL 0:9d17e4342598 1513 break;
wolfSSL 0:9d17e4342598 1514 case session_ticket:
wolfSSL 0:9d17e4342598 1515 Trace(GOT_SESSION_TICKET_STR);
wolfSSL 0:9d17e4342598 1516 ret = ProcessSessionTicket(input, sslBytes, session, error);
wolfSSL 0:9d17e4342598 1517 break;
wolfSSL 0:9d17e4342598 1518 case server_hello:
wolfSSL 0:9d17e4342598 1519 Trace(GOT_SERVER_HELLO_STR);
wolfSSL 0:9d17e4342598 1520 ret = ProcessServerHello(input, sslBytes, session, error);
wolfSSL 0:9d17e4342598 1521 break;
wolfSSL 0:9d17e4342598 1522 case certificate_request:
wolfSSL 0:9d17e4342598 1523 Trace(GOT_CERT_REQ_STR);
wolfSSL 0:9d17e4342598 1524 break;
wolfSSL 0:9d17e4342598 1525 case server_key_exchange:
wolfSSL 0:9d17e4342598 1526 Trace(GOT_SERVER_KEY_EX_STR);
wolfSSL 0:9d17e4342598 1527 /* can't know temp key passively */
wolfSSL 0:9d17e4342598 1528 SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1529 ret = -1;
wolfSSL 0:9d17e4342598 1530 break;
wolfSSL 0:9d17e4342598 1531 case certificate:
wolfSSL 0:9d17e4342598 1532 Trace(GOT_CERT_STR);
wolfSSL 0:9d17e4342598 1533 break;
wolfSSL 0:9d17e4342598 1534 case server_hello_done:
wolfSSL 0:9d17e4342598 1535 Trace(GOT_SERVER_HELLO_DONE_STR);
wolfSSL 0:9d17e4342598 1536 break;
wolfSSL 0:9d17e4342598 1537 case finished:
wolfSSL 0:9d17e4342598 1538 Trace(GOT_FINISHED_STR);
wolfSSL 0:9d17e4342598 1539 ret = ProcessFinished(input, size, sslBytes, session, error);
wolfSSL 0:9d17e4342598 1540 break;
wolfSSL 0:9d17e4342598 1541 case client_hello:
wolfSSL 0:9d17e4342598 1542 Trace(GOT_CLIENT_HELLO_STR);
wolfSSL 0:9d17e4342598 1543 ret = ProcessClientHello(input, sslBytes, session, error);
wolfSSL 0:9d17e4342598 1544 break;
wolfSSL 0:9d17e4342598 1545 case client_key_exchange:
wolfSSL 0:9d17e4342598 1546 Trace(GOT_CLIENT_KEY_EX_STR);
wolfSSL 0:9d17e4342598 1547 ret = ProcessClientKeyExchange(input, sslBytes, session, error);
wolfSSL 0:9d17e4342598 1548 break;
wolfSSL 0:9d17e4342598 1549 case certificate_verify:
wolfSSL 0:9d17e4342598 1550 Trace(GOT_CERT_VER_STR);
wolfSSL 0:9d17e4342598 1551 break;
wolfSSL 0:9d17e4342598 1552 default:
wolfSSL 0:9d17e4342598 1553 SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
wolfSSL 0:9d17e4342598 1554 return -1;
wolfSSL 0:9d17e4342598 1555 }
wolfSSL 0:9d17e4342598 1556
wolfSSL 0:9d17e4342598 1557 return ret;
wolfSSL 0:9d17e4342598 1558 }
wolfSSL 0:9d17e4342598 1559
wolfSSL 0:9d17e4342598 1560
wolfSSL 0:9d17e4342598 1561 /* Decrypt input into plain output, 0 on success */
wolfSSL 0:9d17e4342598 1562 static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
wolfSSL 0:9d17e4342598 1563 {
wolfSSL 0:9d17e4342598 1564 int ret = 0;
wolfSSL 0:9d17e4342598 1565
wolfSSL 0:9d17e4342598 1566 switch (ssl->specs.bulk_cipher_algorithm) {
wolfSSL 0:9d17e4342598 1567 #ifdef BUILD_ARC4
wolfSSL 0:9d17e4342598 1568 case cyassl_rc4:
wolfSSL 0:9d17e4342598 1569 Arc4Process(ssl->decrypt.arc4, output, input, sz);
wolfSSL 0:9d17e4342598 1570 break;
wolfSSL 0:9d17e4342598 1571 #endif
wolfSSL 0:9d17e4342598 1572
wolfSSL 0:9d17e4342598 1573 #ifdef BUILD_DES3
wolfSSL 0:9d17e4342598 1574 case cyassl_triple_des:
wolfSSL 0:9d17e4342598 1575 ret = Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz);
wolfSSL 0:9d17e4342598 1576 break;
wolfSSL 0:9d17e4342598 1577 #endif
wolfSSL 0:9d17e4342598 1578
wolfSSL 0:9d17e4342598 1579 #ifdef BUILD_AES
wolfSSL 0:9d17e4342598 1580 case cyassl_aes:
wolfSSL 0:9d17e4342598 1581 ret = AesCbcDecrypt(ssl->decrypt.aes, output, input, sz);
wolfSSL 0:9d17e4342598 1582 break;
wolfSSL 0:9d17e4342598 1583 #endif
wolfSSL 0:9d17e4342598 1584
wolfSSL 0:9d17e4342598 1585 #ifdef HAVE_HC128
wolfSSL 0:9d17e4342598 1586 case cyassl_hc128:
wolfSSL 0:9d17e4342598 1587 Hc128_Process(ssl->decrypt.hc128, output, input, sz);
wolfSSL 0:9d17e4342598 1588 break;
wolfSSL 0:9d17e4342598 1589 #endif
wolfSSL 0:9d17e4342598 1590
wolfSSL 0:9d17e4342598 1591 #ifdef BUILD_RABBIT
wolfSSL 0:9d17e4342598 1592 case cyassl_rabbit:
wolfSSL 0:9d17e4342598 1593 RabbitProcess(ssl->decrypt.rabbit, output, input, sz);
wolfSSL 0:9d17e4342598 1594 break;
wolfSSL 0:9d17e4342598 1595 #endif
wolfSSL 0:9d17e4342598 1596
wolfSSL 0:9d17e4342598 1597 #ifdef HAVE_CAMELLIA
wolfSSL 0:9d17e4342598 1598 case cyassl_camellia:
wolfSSL 0:9d17e4342598 1599 CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz);
wolfSSL 0:9d17e4342598 1600 break;
wolfSSL 0:9d17e4342598 1601 #endif
wolfSSL 0:9d17e4342598 1602
wolfSSL 0:9d17e4342598 1603 default:
wolfSSL 0:9d17e4342598 1604 Trace(BAD_DECRYPT_TYPE);
wolfSSL 0:9d17e4342598 1605 ret = -1;
wolfSSL 0:9d17e4342598 1606 break;
wolfSSL 0:9d17e4342598 1607 }
wolfSSL 0:9d17e4342598 1608
wolfSSL 0:9d17e4342598 1609 return ret;
wolfSSL 0:9d17e4342598 1610 }
wolfSSL 0:9d17e4342598 1611
wolfSSL 0:9d17e4342598 1612
wolfSSL 0:9d17e4342598 1613 /* Decrypt input message into output, adjust output steam if needed */
wolfSSL 0:9d17e4342598 1614 static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz,
wolfSSL 0:9d17e4342598 1615 byte* output, int* error)
wolfSSL 0:9d17e4342598 1616 {
wolfSSL 0:9d17e4342598 1617 int ivExtra = 0;
wolfSSL 0:9d17e4342598 1618
wolfSSL 0:9d17e4342598 1619 int ret = Decrypt(ssl, output, input, sz);
wolfSSL 0:9d17e4342598 1620 if (ret != 0) {
wolfSSL 0:9d17e4342598 1621 *error = ret;
wolfSSL 0:9d17e4342598 1622 return NULL;
wolfSSL 0:9d17e4342598 1623 }
wolfSSL 0:9d17e4342598 1624 ssl->keys.encryptSz = sz;
wolfSSL 0:9d17e4342598 1625 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) {
wolfSSL 0:9d17e4342598 1626 output += ssl->specs.block_size; /* go past TLSv1.1 IV */
wolfSSL 0:9d17e4342598 1627 ivExtra = ssl->specs.block_size;
wolfSSL 0:9d17e4342598 1628 }
wolfSSL 0:9d17e4342598 1629
wolfSSL 0:9d17e4342598 1630 ssl->keys.padSz = ssl->specs.hash_size;
wolfSSL 0:9d17e4342598 1631
wolfSSL 0:9d17e4342598 1632 if (ssl->specs.cipher_type == block)
wolfSSL 0:9d17e4342598 1633 ssl->keys.padSz += *(output + sz - ivExtra - 1) + 1;
wolfSSL 0:9d17e4342598 1634
wolfSSL 0:9d17e4342598 1635 return output;
wolfSSL 0:9d17e4342598 1636 }
wolfSSL 0:9d17e4342598 1637
wolfSSL 0:9d17e4342598 1638
wolfSSL 0:9d17e4342598 1639 /* remove session from table, use rowHint if no info (means we have a lock) */
wolfSSL 0:9d17e4342598 1640 static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
wolfSSL 0:9d17e4342598 1641 TcpInfo* tcpInfo, word32 rowHint)
wolfSSL 0:9d17e4342598 1642 {
wolfSSL 0:9d17e4342598 1643 SnifferSession* previous = 0;
wolfSSL 0:9d17e4342598 1644 SnifferSession* current;
wolfSSL 0:9d17e4342598 1645 word32 row = rowHint;
wolfSSL 0:9d17e4342598 1646 int haveLock = 0;
wolfSSL 0:9d17e4342598 1647
wolfSSL 0:9d17e4342598 1648 if (ipInfo && tcpInfo)
wolfSSL 0:9d17e4342598 1649 row = SessionHash(ipInfo, tcpInfo);
wolfSSL 0:9d17e4342598 1650 else
wolfSSL 0:9d17e4342598 1651 haveLock = 1;
wolfSSL 0:9d17e4342598 1652
wolfSSL 0:9d17e4342598 1653 assert(row <= HASH_SIZE);
wolfSSL 0:9d17e4342598 1654 Trace(REMOVE_SESSION_STR);
wolfSSL 0:9d17e4342598 1655
wolfSSL 0:9d17e4342598 1656 if (!haveLock)
wolfSSL 0:9d17e4342598 1657 LockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 1658
wolfSSL 0:9d17e4342598 1659 current = SessionTable[row];
wolfSSL 0:9d17e4342598 1660
wolfSSL 0:9d17e4342598 1661 while (current) {
wolfSSL 0:9d17e4342598 1662 if (current == session) {
wolfSSL 0:9d17e4342598 1663 if (previous)
wolfSSL 0:9d17e4342598 1664 previous->next = current->next;
wolfSSL 0:9d17e4342598 1665 else
wolfSSL 0:9d17e4342598 1666 SessionTable[row] = current->next;
wolfSSL 0:9d17e4342598 1667 FreeSnifferSession(session);
wolfSSL 0:9d17e4342598 1668 TraceRemovedSession();
wolfSSL 0:9d17e4342598 1669 break;
wolfSSL 0:9d17e4342598 1670 }
wolfSSL 0:9d17e4342598 1671 previous = current;
wolfSSL 0:9d17e4342598 1672 current = current->next;
wolfSSL 0:9d17e4342598 1673 }
wolfSSL 0:9d17e4342598 1674
wolfSSL 0:9d17e4342598 1675 if (!haveLock)
wolfSSL 0:9d17e4342598 1676 UnLockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 1677 }
wolfSSL 0:9d17e4342598 1678
wolfSSL 0:9d17e4342598 1679
wolfSSL 0:9d17e4342598 1680 /* Remove stale sessions from the Session Table, have a lock */
wolfSSL 0:9d17e4342598 1681 static void RemoveStaleSessions(void)
wolfSSL 0:9d17e4342598 1682 {
wolfSSL 0:9d17e4342598 1683 word32 i;
wolfSSL 0:9d17e4342598 1684 SnifferSession* session;
wolfSSL 0:9d17e4342598 1685
wolfSSL 0:9d17e4342598 1686 for (i = 0; i < HASH_SIZE; i++) {
wolfSSL 0:9d17e4342598 1687 session = SessionTable[i];
wolfSSL 0:9d17e4342598 1688 while (session) {
wolfSSL 0:9d17e4342598 1689 SnifferSession* next = session->next;
wolfSSL 0:9d17e4342598 1690 if (time(NULL) >= session->lastUsed + SNIFFER_TIMEOUT) {
wolfSSL 0:9d17e4342598 1691 TraceStaleSession();
wolfSSL 0:9d17e4342598 1692 RemoveSession(session, NULL, NULL, i);
wolfSSL 0:9d17e4342598 1693 }
wolfSSL 0:9d17e4342598 1694 session = next;
wolfSSL 0:9d17e4342598 1695 }
wolfSSL 0:9d17e4342598 1696 }
wolfSSL 0:9d17e4342598 1697 }
wolfSSL 0:9d17e4342598 1698
wolfSSL 0:9d17e4342598 1699
wolfSSL 0:9d17e4342598 1700 /* Create a new Sniffer Session */
wolfSSL 0:9d17e4342598 1701 static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
wolfSSL 0:9d17e4342598 1702 char* error)
wolfSSL 0:9d17e4342598 1703 {
wolfSSL 0:9d17e4342598 1704 SnifferSession* session = 0;
wolfSSL 0:9d17e4342598 1705 int row;
wolfSSL 0:9d17e4342598 1706
wolfSSL 0:9d17e4342598 1707 Trace(NEW_SESSION_STR);
wolfSSL 0:9d17e4342598 1708 /* create a new one */
wolfSSL 0:9d17e4342598 1709 session = (SnifferSession*)malloc(sizeof(SnifferSession));
wolfSSL 0:9d17e4342598 1710 if (session == NULL) {
wolfSSL 0:9d17e4342598 1711 SetError(MEMORY_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1712 return 0;
wolfSSL 0:9d17e4342598 1713 }
wolfSSL 0:9d17e4342598 1714 InitSession(session);
wolfSSL 0:9d17e4342598 1715 session->server = ipInfo->dst;
wolfSSL 0:9d17e4342598 1716 session->client = ipInfo->src;
wolfSSL 0:9d17e4342598 1717 session->srvPort = (word16)tcpInfo->dstPort;
wolfSSL 0:9d17e4342598 1718 session->cliPort = (word16)tcpInfo->srcPort;
wolfSSL 0:9d17e4342598 1719 session->cliSeqStart = tcpInfo->sequence;
wolfSSL 0:9d17e4342598 1720 session->cliExpected = 1; /* relative */
wolfSSL 0:9d17e4342598 1721 session->lastUsed= time(NULL);
wolfSSL 0:9d17e4342598 1722
wolfSSL 0:9d17e4342598 1723 session->context = GetSnifferServer(ipInfo, tcpInfo);
wolfSSL 0:9d17e4342598 1724 if (session->context == NULL) {
wolfSSL 0:9d17e4342598 1725 SetError(SERVER_NOT_REG_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1726 free(session);
wolfSSL 0:9d17e4342598 1727 return 0;
wolfSSL 0:9d17e4342598 1728 }
wolfSSL 0:9d17e4342598 1729
wolfSSL 0:9d17e4342598 1730 session->sslServer = SSL_new(session->context->ctx);
wolfSSL 0:9d17e4342598 1731 if (session->sslServer == NULL) {
wolfSSL 0:9d17e4342598 1732 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1733 free(session);
wolfSSL 0:9d17e4342598 1734 return 0;
wolfSSL 0:9d17e4342598 1735 }
wolfSSL 0:9d17e4342598 1736 session->sslClient = SSL_new(session->context->ctx);
wolfSSL 0:9d17e4342598 1737 if (session->sslClient == NULL) {
wolfSSL 0:9d17e4342598 1738 SSL_free(session->sslServer);
wolfSSL 0:9d17e4342598 1739 session->sslServer = 0;
wolfSSL 0:9d17e4342598 1740
wolfSSL 0:9d17e4342598 1741 SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1742 free(session);
wolfSSL 0:9d17e4342598 1743 return 0;
wolfSSL 0:9d17e4342598 1744 }
wolfSSL 0:9d17e4342598 1745 /* put server back into server mode */
wolfSSL 0:9d17e4342598 1746 session->sslServer->options.side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 1747
wolfSSL 0:9d17e4342598 1748 row = SessionHash(ipInfo, tcpInfo);
wolfSSL 0:9d17e4342598 1749
wolfSSL 0:9d17e4342598 1750 /* add it to the session table */
wolfSSL 0:9d17e4342598 1751 LockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 1752
wolfSSL 0:9d17e4342598 1753 session->next = SessionTable[row];
wolfSSL 0:9d17e4342598 1754 SessionTable[row] = session;
wolfSSL 0:9d17e4342598 1755
wolfSSL 0:9d17e4342598 1756 SessionCount++;
wolfSSL 0:9d17e4342598 1757
wolfSSL 0:9d17e4342598 1758 if ( (SessionCount % HASH_SIZE) == 0) {
wolfSSL 0:9d17e4342598 1759 TraceFindingStale();
wolfSSL 0:9d17e4342598 1760 RemoveStaleSessions();
wolfSSL 0:9d17e4342598 1761 }
wolfSSL 0:9d17e4342598 1762
wolfSSL 0:9d17e4342598 1763 UnLockMutex(&SessionMutex);
wolfSSL 0:9d17e4342598 1764
wolfSSL 0:9d17e4342598 1765 /* determine headed side */
wolfSSL 0:9d17e4342598 1766 if (ipInfo->dst == session->context->server &&
wolfSSL 0:9d17e4342598 1767 tcpInfo->dstPort == session->context->port)
wolfSSL 0:9d17e4342598 1768 session->flags.side = CYASSL_SERVER_END;
wolfSSL 0:9d17e4342598 1769 else
wolfSSL 0:9d17e4342598 1770 session->flags.side = CYASSL_CLIENT_END;
wolfSSL 0:9d17e4342598 1771
wolfSSL 0:9d17e4342598 1772 return session;
wolfSSL 0:9d17e4342598 1773 }
wolfSSL 0:9d17e4342598 1774
wolfSSL 0:9d17e4342598 1775
wolfSSL 0:9d17e4342598 1776 /* Process Old Client Hello Input */
wolfSSL 0:9d17e4342598 1777 static int DoOldHello(SnifferSession* session, const byte* sslFrame,
wolfSSL 0:9d17e4342598 1778 int* rhSize, int* sslBytes, char* error)
wolfSSL 0:9d17e4342598 1779 {
wolfSSL 0:9d17e4342598 1780 const byte* input = sslFrame;
wolfSSL 0:9d17e4342598 1781 byte b0, b1;
wolfSSL 0:9d17e4342598 1782 word32 idx = 0;
wolfSSL 0:9d17e4342598 1783 int ret;
wolfSSL 0:9d17e4342598 1784
wolfSSL 0:9d17e4342598 1785 Trace(GOT_OLD_CLIENT_HELLO_STR);
wolfSSL 0:9d17e4342598 1786 session->flags.clientHello = 1; /* don't process again */
wolfSSL 0:9d17e4342598 1787 b0 = *input++;
wolfSSL 0:9d17e4342598 1788 b1 = *input++;
wolfSSL 0:9d17e4342598 1789 *sslBytes -= 2;
wolfSSL 0:9d17e4342598 1790 *rhSize = ((b0 & 0x7f) << 8) | b1;
wolfSSL 0:9d17e4342598 1791
wolfSSL 0:9d17e4342598 1792 if (*rhSize > *sslBytes) {
wolfSSL 0:9d17e4342598 1793 SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1794 return -1;
wolfSSL 0:9d17e4342598 1795 }
wolfSSL 0:9d17e4342598 1796
wolfSSL 0:9d17e4342598 1797 ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
wolfSSL 0:9d17e4342598 1798 (word16)*rhSize);
wolfSSL 0:9d17e4342598 1799 if (ret < 0 && ret != MATCH_SUITE_ERROR) {
wolfSSL 0:9d17e4342598 1800 SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1801 return -1;
wolfSSL 0:9d17e4342598 1802 }
wolfSSL 0:9d17e4342598 1803
wolfSSL 0:9d17e4342598 1804 Trace(OLD_CLIENT_OK_STR);
wolfSSL 0:9d17e4342598 1805 XMEMCPY(session->sslClient->arrays->clientRandom,
wolfSSL 0:9d17e4342598 1806 session->sslServer->arrays->clientRandom, RAN_LEN);
wolfSSL 0:9d17e4342598 1807
wolfSSL 0:9d17e4342598 1808 *sslBytes -= *rhSize;
wolfSSL 0:9d17e4342598 1809 return 0;
wolfSSL 0:9d17e4342598 1810 }
wolfSSL 0:9d17e4342598 1811
wolfSSL 0:9d17e4342598 1812
wolfSSL 0:9d17e4342598 1813 #if 0
wolfSSL 0:9d17e4342598 1814 /* Calculate the TCP checksum, see RFC 1071 */
wolfSSL 0:9d17e4342598 1815 /* return 0 for success, -1 on error */
wolfSSL 0:9d17e4342598 1816 /* can be called from decode() with
wolfSSL 0:9d17e4342598 1817 TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
wolfSSL 0:9d17e4342598 1818 could also add a 64bit version if type available and using this
wolfSSL 0:9d17e4342598 1819 */
wolfSSL 0:9d17e4342598 1820 int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
wolfSSL 0:9d17e4342598 1821 const byte* packet)
wolfSSL 0:9d17e4342598 1822 {
wolfSSL 0:9d17e4342598 1823 TcpPseudoHdr pseudo;
wolfSSL 0:9d17e4342598 1824 int count = PSEUDO_HDR_SZ;
wolfSSL 0:9d17e4342598 1825 const word16* data = (word16*)&pseudo;
wolfSSL 0:9d17e4342598 1826 word32 sum = 0;
wolfSSL 0:9d17e4342598 1827 word16 checksum;
wolfSSL 0:9d17e4342598 1828
wolfSSL 0:9d17e4342598 1829 pseudo.src = ipInfo->src;
wolfSSL 0:9d17e4342598 1830 pseudo.dst = ipInfo->dst;
wolfSSL 0:9d17e4342598 1831 pseudo.rsv = 0;
wolfSSL 0:9d17e4342598 1832 pseudo.protocol = TCP_PROTO;
wolfSSL 0:9d17e4342598 1833 pseudo.legnth = htons(tcpInfo->length + dataLen);
wolfSSL 0:9d17e4342598 1834
wolfSSL 0:9d17e4342598 1835 /* pseudo header sum */
wolfSSL 0:9d17e4342598 1836 while (count >= 2) {
wolfSSL 0:9d17e4342598 1837 sum += *data++;
wolfSSL 0:9d17e4342598 1838 count -= 2;
wolfSSL 0:9d17e4342598 1839 }
wolfSSL 0:9d17e4342598 1840
wolfSSL 0:9d17e4342598 1841 count = tcpInfo->length + dataLen;
wolfSSL 0:9d17e4342598 1842 data = (word16*)packet;
wolfSSL 0:9d17e4342598 1843
wolfSSL 0:9d17e4342598 1844 /* main sum */
wolfSSL 0:9d17e4342598 1845 while (count > 1) {
wolfSSL 0:9d17e4342598 1846 sum += *data++;
wolfSSL 0:9d17e4342598 1847 count -=2;
wolfSSL 0:9d17e4342598 1848 }
wolfSSL 0:9d17e4342598 1849
wolfSSL 0:9d17e4342598 1850 /* get left-over, if any */
wolfSSL 0:9d17e4342598 1851 packet = (byte*)data;
wolfSSL 0:9d17e4342598 1852 if (count > 0) {
wolfSSL 0:9d17e4342598 1853 sum += *packet;
wolfSSL 0:9d17e4342598 1854 }
wolfSSL 0:9d17e4342598 1855
wolfSSL 0:9d17e4342598 1856 /* fold 32bit sum into 16 bits */
wolfSSL 0:9d17e4342598 1857 while (sum >> 16)
wolfSSL 0:9d17e4342598 1858 sum = (sum & 0xffff) + (sum >> 16);
wolfSSL 0:9d17e4342598 1859
wolfSSL 0:9d17e4342598 1860 checksum = (word16)~sum;
wolfSSL 0:9d17e4342598 1861 /* checksum should now equal 0, since included already calcd checksum */
wolfSSL 0:9d17e4342598 1862 /* field, but tcp checksum offloading could negate calculation */
wolfSSL 0:9d17e4342598 1863 if (checksum == 0)
wolfSSL 0:9d17e4342598 1864 return 0;
wolfSSL 0:9d17e4342598 1865 return -1;
wolfSSL 0:9d17e4342598 1866 }
wolfSSL 0:9d17e4342598 1867 #endif
wolfSSL 0:9d17e4342598 1868
wolfSSL 0:9d17e4342598 1869
wolfSSL 0:9d17e4342598 1870 /* Check IP and TCP headers, set payload */
wolfSSL 0:9d17e4342598 1871 /* returns 0 on success, -1 on error */
wolfSSL 0:9d17e4342598 1872 static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
wolfSSL 0:9d17e4342598 1873 int length, const byte** sslFrame, int* sslBytes, char* error)
wolfSSL 0:9d17e4342598 1874 {
wolfSSL 0:9d17e4342598 1875 TraceHeader();
wolfSSL 0:9d17e4342598 1876 TracePacket();
wolfSSL 0:9d17e4342598 1877
wolfSSL 0:9d17e4342598 1878 /* ip header */
wolfSSL 0:9d17e4342598 1879 if (length < IP_HDR_SZ) {
wolfSSL 0:9d17e4342598 1880 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1881 return -1;
wolfSSL 0:9d17e4342598 1882 }
wolfSSL 0:9d17e4342598 1883 if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
wolfSSL 0:9d17e4342598 1884 return -1;
wolfSSL 0:9d17e4342598 1885
wolfSSL 0:9d17e4342598 1886 /* tcp header */
wolfSSL 0:9d17e4342598 1887 if (length < (ipInfo->length + TCP_HDR_SZ)) {
wolfSSL 0:9d17e4342598 1888 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1889 return -1;
wolfSSL 0:9d17e4342598 1890 }
wolfSSL 0:9d17e4342598 1891 if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0)
wolfSSL 0:9d17e4342598 1892 return -1;
wolfSSL 0:9d17e4342598 1893
wolfSSL 0:9d17e4342598 1894 /* setup */
wolfSSL 0:9d17e4342598 1895 *sslFrame = packet + ipInfo->length + tcpInfo->length;
wolfSSL 0:9d17e4342598 1896 if (*sslFrame > packet + length) {
wolfSSL 0:9d17e4342598 1897 SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1898 return -1;
wolfSSL 0:9d17e4342598 1899 }
wolfSSL 0:9d17e4342598 1900 *sslBytes = (int)(packet + length - *sslFrame);
wolfSSL 0:9d17e4342598 1901
wolfSSL 0:9d17e4342598 1902 return 0;
wolfSSL 0:9d17e4342598 1903 }
wolfSSL 0:9d17e4342598 1904
wolfSSL 0:9d17e4342598 1905
wolfSSL 0:9d17e4342598 1906 /* Create or Find existing session */
wolfSSL 0:9d17e4342598 1907 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
wolfSSL 0:9d17e4342598 1908 static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes,
wolfSSL 0:9d17e4342598 1909 SnifferSession** session, char* error)
wolfSSL 0:9d17e4342598 1910 {
wolfSSL 0:9d17e4342598 1911 /* create a new SnifferSession on client SYN */
wolfSSL 0:9d17e4342598 1912 if (tcpInfo->syn && !tcpInfo->ack) {
wolfSSL 0:9d17e4342598 1913 TraceClientSyn(tcpInfo->sequence);
wolfSSL 0:9d17e4342598 1914 *session = CreateSession(ipInfo, tcpInfo, error);
wolfSSL 0:9d17e4342598 1915 if (*session == NULL) {
wolfSSL 0:9d17e4342598 1916 *session = GetSnifferSession(ipInfo, tcpInfo);
wolfSSL 0:9d17e4342598 1917 /* already had exisiting, so OK */
wolfSSL 0:9d17e4342598 1918 if (*session)
wolfSSL 0:9d17e4342598 1919 return 1;
wolfSSL 0:9d17e4342598 1920
wolfSSL 0:9d17e4342598 1921 SetError(MEMORY_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1922 return -1;
wolfSSL 0:9d17e4342598 1923 }
wolfSSL 0:9d17e4342598 1924 return 1;
wolfSSL 0:9d17e4342598 1925 }
wolfSSL 0:9d17e4342598 1926 /* get existing sniffer session */
wolfSSL 0:9d17e4342598 1927 else {
wolfSSL 0:9d17e4342598 1928 *session = GetSnifferSession(ipInfo, tcpInfo);
wolfSSL 0:9d17e4342598 1929 if (*session == NULL) {
wolfSSL 0:9d17e4342598 1930 /* don't worry about extraneous RST or duplicate FINs */
wolfSSL 0:9d17e4342598 1931 if (tcpInfo->fin || tcpInfo->rst)
wolfSSL 0:9d17e4342598 1932 return 1;
wolfSSL 0:9d17e4342598 1933 /* don't worry about duplicate ACKs either */
wolfSSL 0:9d17e4342598 1934 if (sslBytes == 0 && tcpInfo->ack)
wolfSSL 0:9d17e4342598 1935 return 1;
wolfSSL 0:9d17e4342598 1936
wolfSSL 0:9d17e4342598 1937 SetError(BAD_SESSION_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 1938 return -1;
wolfSSL 0:9d17e4342598 1939 }
wolfSSL 0:9d17e4342598 1940 }
wolfSSL 0:9d17e4342598 1941 return 0;
wolfSSL 0:9d17e4342598 1942 }
wolfSSL 0:9d17e4342598 1943
wolfSSL 0:9d17e4342598 1944
wolfSSL 0:9d17e4342598 1945 /* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */
wolfSSL 0:9d17e4342598 1946 static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data,
wolfSSL 0:9d17e4342598 1947 int* bytesLeft)
wolfSSL 0:9d17e4342598 1948 {
wolfSSL 0:9d17e4342598 1949 PacketBuffer* pb;
wolfSSL 0:9d17e4342598 1950
wolfSSL 0:9d17e4342598 1951 int added = end - *begin + 1;
wolfSSL 0:9d17e4342598 1952 assert(*begin <= end);
wolfSSL 0:9d17e4342598 1953
wolfSSL 0:9d17e4342598 1954 pb = (PacketBuffer*)malloc(sizeof(PacketBuffer));
wolfSSL 0:9d17e4342598 1955 if (pb == NULL) return NULL;
wolfSSL 0:9d17e4342598 1956
wolfSSL 0:9d17e4342598 1957 pb->next = 0;
wolfSSL 0:9d17e4342598 1958 pb->begin = *begin;
wolfSSL 0:9d17e4342598 1959 pb->end = end;
wolfSSL 0:9d17e4342598 1960 pb->data = (byte*)malloc(added);
wolfSSL 0:9d17e4342598 1961
wolfSSL 0:9d17e4342598 1962 if (pb->data == NULL) {
wolfSSL 0:9d17e4342598 1963 free(pb);
wolfSSL 0:9d17e4342598 1964 return NULL;
wolfSSL 0:9d17e4342598 1965 }
wolfSSL 0:9d17e4342598 1966 XMEMCPY(pb->data, data, added);
wolfSSL 0:9d17e4342598 1967
wolfSSL 0:9d17e4342598 1968 *bytesLeft -= added;
wolfSSL 0:9d17e4342598 1969 *begin = pb->end + 1;
wolfSSL 0:9d17e4342598 1970
wolfSSL 0:9d17e4342598 1971 return pb;
wolfSSL 0:9d17e4342598 1972 }
wolfSSL 0:9d17e4342598 1973
wolfSSL 0:9d17e4342598 1974
wolfSSL 0:9d17e4342598 1975 /* Add sslFrame to Reassembly List */
wolfSSL 0:9d17e4342598 1976 /* returns 1 (end) on success, -1, on error */
wolfSSL 0:9d17e4342598 1977 static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
wolfSSL 0:9d17e4342598 1978 int sslBytes, SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 1979 {
wolfSSL 0:9d17e4342598 1980 PacketBuffer* add;
wolfSSL 0:9d17e4342598 1981 PacketBuffer** front = (from == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 1982 &session->cliReassemblyList: &session->srvReassemblyList;
wolfSSL 0:9d17e4342598 1983 PacketBuffer* curr = *front;
wolfSSL 0:9d17e4342598 1984 PacketBuffer* prev = curr;
wolfSSL 0:9d17e4342598 1985
wolfSSL 0:9d17e4342598 1986 word32 startSeq = seq;
wolfSSL 0:9d17e4342598 1987 word32 added;
wolfSSL 0:9d17e4342598 1988 int bytesLeft = sslBytes; /* could be overlapping fragment */
wolfSSL 0:9d17e4342598 1989
wolfSSL 0:9d17e4342598 1990 /* if list is empty add full frame to front */
wolfSSL 0:9d17e4342598 1991 if (!curr) {
wolfSSL 0:9d17e4342598 1992 add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft);
wolfSSL 0:9d17e4342598 1993 if (add == NULL) {
wolfSSL 0:9d17e4342598 1994 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 1995 return -1;
wolfSSL 0:9d17e4342598 1996 }
wolfSSL 0:9d17e4342598 1997 *front = add;
wolfSSL 0:9d17e4342598 1998 return 1;
wolfSSL 0:9d17e4342598 1999 }
wolfSSL 0:9d17e4342598 2000
wolfSSL 0:9d17e4342598 2001 /* add to front if before current front, up to next->begin */
wolfSSL 0:9d17e4342598 2002 if (seq < curr->begin) {
wolfSSL 0:9d17e4342598 2003 word32 end = seq + sslBytes - 1;
wolfSSL 0:9d17e4342598 2004
wolfSSL 0:9d17e4342598 2005 if (end >= curr->begin)
wolfSSL 0:9d17e4342598 2006 end = curr->begin - 1;
wolfSSL 0:9d17e4342598 2007
wolfSSL 0:9d17e4342598 2008 add = CreateBuffer(&seq, end, sslFrame, &bytesLeft);
wolfSSL 0:9d17e4342598 2009 if (add == NULL) {
wolfSSL 0:9d17e4342598 2010 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2011 return -1;
wolfSSL 0:9d17e4342598 2012 }
wolfSSL 0:9d17e4342598 2013 add->next = curr;
wolfSSL 0:9d17e4342598 2014 *front = add;
wolfSSL 0:9d17e4342598 2015 }
wolfSSL 0:9d17e4342598 2016
wolfSSL 0:9d17e4342598 2017 /* while we have bytes left, try to find a gap to fill */
wolfSSL 0:9d17e4342598 2018 while (bytesLeft > 0) {
wolfSSL 0:9d17e4342598 2019 /* get previous packet in list */
wolfSSL 0:9d17e4342598 2020 while (curr && (seq >= curr->begin)) {
wolfSSL 0:9d17e4342598 2021 prev = curr;
wolfSSL 0:9d17e4342598 2022 curr = curr->next;
wolfSSL 0:9d17e4342598 2023 }
wolfSSL 0:9d17e4342598 2024
wolfSSL 0:9d17e4342598 2025 /* don't add duplicate data */
wolfSSL 0:9d17e4342598 2026 if (prev->end >= seq) {
wolfSSL 0:9d17e4342598 2027 if ( (seq + bytesLeft - 1) <= prev->end)
wolfSSL 0:9d17e4342598 2028 return 1;
wolfSSL 0:9d17e4342598 2029 seq = prev->end + 1;
wolfSSL 0:9d17e4342598 2030 bytesLeft = startSeq + sslBytes - seq;
wolfSSL 0:9d17e4342598 2031 }
wolfSSL 0:9d17e4342598 2032
wolfSSL 0:9d17e4342598 2033 if (!curr)
wolfSSL 0:9d17e4342598 2034 /* we're at the end */
wolfSSL 0:9d17e4342598 2035 added = bytesLeft;
wolfSSL 0:9d17e4342598 2036 else
wolfSSL 0:9d17e4342598 2037 /* we're in between two frames */
wolfSSL 0:9d17e4342598 2038 added = min((word32)bytesLeft, curr->begin - seq);
wolfSSL 0:9d17e4342598 2039
wolfSSL 0:9d17e4342598 2040 /* data already there */
wolfSSL 0:9d17e4342598 2041 if (added == 0)
wolfSSL 0:9d17e4342598 2042 continue;
wolfSSL 0:9d17e4342598 2043
wolfSSL 0:9d17e4342598 2044 add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq],
wolfSSL 0:9d17e4342598 2045 &bytesLeft);
wolfSSL 0:9d17e4342598 2046 if (add == NULL) {
wolfSSL 0:9d17e4342598 2047 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2048 return -1;
wolfSSL 0:9d17e4342598 2049 }
wolfSSL 0:9d17e4342598 2050 add->next = prev->next;
wolfSSL 0:9d17e4342598 2051 prev->next = add;
wolfSSL 0:9d17e4342598 2052 }
wolfSSL 0:9d17e4342598 2053 return 1;
wolfSSL 0:9d17e4342598 2054 }
wolfSSL 0:9d17e4342598 2055
wolfSSL 0:9d17e4342598 2056
wolfSSL 0:9d17e4342598 2057 /* Add out of order FIN capture */
wolfSSL 0:9d17e4342598 2058 /* returns 1 for success (end) */
wolfSSL 0:9d17e4342598 2059 static int AddFinCapture(SnifferSession* session, word32 sequence)
wolfSSL 0:9d17e4342598 2060 {
wolfSSL 0:9d17e4342598 2061 if (session->flags.side == CYASSL_SERVER_END) {
wolfSSL 0:9d17e4342598 2062 if (session->finCaputre.cliCounted == 0)
wolfSSL 0:9d17e4342598 2063 session->finCaputre.cliFinSeq = sequence;
wolfSSL 0:9d17e4342598 2064 }
wolfSSL 0:9d17e4342598 2065 else {
wolfSSL 0:9d17e4342598 2066 if (session->finCaputre.srvCounted == 0)
wolfSSL 0:9d17e4342598 2067 session->finCaputre.srvFinSeq = sequence;
wolfSSL 0:9d17e4342598 2068 }
wolfSSL 0:9d17e4342598 2069 return 1;
wolfSSL 0:9d17e4342598 2070 }
wolfSSL 0:9d17e4342598 2071
wolfSSL 0:9d17e4342598 2072
wolfSSL 0:9d17e4342598 2073 /* Adjust incoming sequence based on side */
wolfSSL 0:9d17e4342598 2074 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
wolfSSL 0:9d17e4342598 2075 static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
wolfSSL 0:9d17e4342598 2076 int* sslBytes, const byte** sslFrame, char* error)
wolfSSL 0:9d17e4342598 2077 {
wolfSSL 0:9d17e4342598 2078 word32 seqStart = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2079 session->cliSeqStart :session->srvSeqStart;
wolfSSL 0:9d17e4342598 2080 word32 real = tcpInfo->sequence - seqStart;
wolfSSL 0:9d17e4342598 2081 word32* expected = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2082 &session->cliExpected : &session->srvExpected;
wolfSSL 0:9d17e4342598 2083 PacketBuffer* reassemblyList = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2084 session->cliReassemblyList : session->srvReassemblyList;
wolfSSL 0:9d17e4342598 2085
wolfSSL 0:9d17e4342598 2086 /* handle rollover of sequence */
wolfSSL 0:9d17e4342598 2087 if (tcpInfo->sequence < seqStart)
wolfSSL 0:9d17e4342598 2088 real = 0xffffffffU - seqStart + tcpInfo->sequence;
wolfSSL 0:9d17e4342598 2089
wolfSSL 0:9d17e4342598 2090 TraceRelativeSequence(*expected, real);
wolfSSL 0:9d17e4342598 2091
wolfSSL 0:9d17e4342598 2092 if (real < *expected) {
wolfSSL 0:9d17e4342598 2093 Trace(DUPLICATE_STR);
wolfSSL 0:9d17e4342598 2094 if (real + *sslBytes > *expected) {
wolfSSL 0:9d17e4342598 2095 int overlap = *expected - real;
wolfSSL 0:9d17e4342598 2096 Trace(OVERLAP_DUPLICATE_STR);
wolfSSL 0:9d17e4342598 2097
wolfSSL 0:9d17e4342598 2098 /* adjust to expected, remove duplicate */
wolfSSL 0:9d17e4342598 2099 *sslFrame += overlap;
wolfSSL 0:9d17e4342598 2100 *sslBytes -= overlap;
wolfSSL 0:9d17e4342598 2101
wolfSSL 0:9d17e4342598 2102 if (reassemblyList) {
wolfSSL 0:9d17e4342598 2103 word32 newEnd = *expected + *sslBytes;
wolfSSL 0:9d17e4342598 2104
wolfSSL 0:9d17e4342598 2105 if (newEnd > reassemblyList->begin) {
wolfSSL 0:9d17e4342598 2106 Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
wolfSSL 0:9d17e4342598 2107
wolfSSL 0:9d17e4342598 2108 /* remove bytes already on reassembly list */
wolfSSL 0:9d17e4342598 2109 *sslBytes -= newEnd - reassemblyList->begin;
wolfSSL 0:9d17e4342598 2110 }
wolfSSL 0:9d17e4342598 2111 if (newEnd > reassemblyList->end) {
wolfSSL 0:9d17e4342598 2112 Trace(OVERLAP_REASSEMBLY_END_STR);
wolfSSL 0:9d17e4342598 2113
wolfSSL 0:9d17e4342598 2114 /* may be past reassembly list end (could have more on list)
wolfSSL 0:9d17e4342598 2115 so try to add what's past the front->end */
wolfSSL 0:9d17e4342598 2116 AddToReassembly(session->flags.side, reassemblyList->end +1,
wolfSSL 0:9d17e4342598 2117 *sslFrame + reassemblyList->end - *expected + 1,
wolfSSL 0:9d17e4342598 2118 newEnd - reassemblyList->end, session, error);
wolfSSL 0:9d17e4342598 2119 }
wolfSSL 0:9d17e4342598 2120 }
wolfSSL 0:9d17e4342598 2121 }
wolfSSL 0:9d17e4342598 2122 else
wolfSSL 0:9d17e4342598 2123 return 1;
wolfSSL 0:9d17e4342598 2124 }
wolfSSL 0:9d17e4342598 2125 else if (real > *expected) {
wolfSSL 0:9d17e4342598 2126 Trace(OUT_OF_ORDER_STR);
wolfSSL 0:9d17e4342598 2127 if (*sslBytes > 0)
wolfSSL 0:9d17e4342598 2128 return AddToReassembly(session->flags.side, real, *sslFrame,
wolfSSL 0:9d17e4342598 2129 *sslBytes, session, error);
wolfSSL 0:9d17e4342598 2130 else if (tcpInfo->fin)
wolfSSL 0:9d17e4342598 2131 return AddFinCapture(session, real);
wolfSSL 0:9d17e4342598 2132 }
wolfSSL 0:9d17e4342598 2133 /* got expected sequence */
wolfSSL 0:9d17e4342598 2134 *expected += *sslBytes;
wolfSSL 0:9d17e4342598 2135 if (tcpInfo->fin)
wolfSSL 0:9d17e4342598 2136 *expected += 1;
wolfSSL 0:9d17e4342598 2137
wolfSSL 0:9d17e4342598 2138 return 0;
wolfSSL 0:9d17e4342598 2139 }
wolfSSL 0:9d17e4342598 2140
wolfSSL 0:9d17e4342598 2141
wolfSSL 0:9d17e4342598 2142 /* Check latest ack number for missing packets
wolfSSL 0:9d17e4342598 2143 return 0 ok, <0 on error */
wolfSSL 0:9d17e4342598 2144 static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session)
wolfSSL 0:9d17e4342598 2145 {
wolfSSL 0:9d17e4342598 2146 if (tcpInfo->ack) {
wolfSSL 0:9d17e4342598 2147 word32 seqStart = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2148 session->srvSeqStart :session->cliSeqStart;
wolfSSL 0:9d17e4342598 2149 word32 real = tcpInfo->ackNumber - seqStart;
wolfSSL 0:9d17e4342598 2150 word32 expected = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2151 session->srvExpected : session->cliExpected;
wolfSSL 0:9d17e4342598 2152
wolfSSL 0:9d17e4342598 2153 /* handle rollover of sequence */
wolfSSL 0:9d17e4342598 2154 if (tcpInfo->ackNumber < seqStart)
wolfSSL 0:9d17e4342598 2155 real = 0xffffffffU - seqStart + tcpInfo->ackNumber;
wolfSSL 0:9d17e4342598 2156
wolfSSL 0:9d17e4342598 2157 TraceAck(real, expected);
wolfSSL 0:9d17e4342598 2158
wolfSSL 0:9d17e4342598 2159 if (real > expected)
wolfSSL 0:9d17e4342598 2160 return -1; /* we missed a packet, ACKing data we never saw */
wolfSSL 0:9d17e4342598 2161 }
wolfSSL 0:9d17e4342598 2162 return 0;
wolfSSL 0:9d17e4342598 2163 }
wolfSSL 0:9d17e4342598 2164
wolfSSL 0:9d17e4342598 2165
wolfSSL 0:9d17e4342598 2166 /* Check TCP Sequence status */
wolfSSL 0:9d17e4342598 2167 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
wolfSSL 0:9d17e4342598 2168 static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
wolfSSL 0:9d17e4342598 2169 SnifferSession* session, int* sslBytes,
wolfSSL 0:9d17e4342598 2170 const byte** sslFrame, char* error)
wolfSSL 0:9d17e4342598 2171 {
wolfSSL 0:9d17e4342598 2172 int actualLen;
wolfSSL 0:9d17e4342598 2173
wolfSSL 0:9d17e4342598 2174 /* init SEQ from server to client */
wolfSSL 0:9d17e4342598 2175 if (tcpInfo->syn && tcpInfo->ack) {
wolfSSL 0:9d17e4342598 2176 session->srvSeqStart = tcpInfo->sequence;
wolfSSL 0:9d17e4342598 2177 session->srvExpected = 1;
wolfSSL 0:9d17e4342598 2178 TraceServerSyn(tcpInfo->sequence);
wolfSSL 0:9d17e4342598 2179 return 1;
wolfSSL 0:9d17e4342598 2180 }
wolfSSL 0:9d17e4342598 2181
wolfSSL 0:9d17e4342598 2182 /* adjust potential ethernet trailer */
wolfSSL 0:9d17e4342598 2183 actualLen = ipInfo->total - ipInfo->length - tcpInfo->length;
wolfSSL 0:9d17e4342598 2184 if (*sslBytes > actualLen) {
wolfSSL 0:9d17e4342598 2185 *sslBytes = actualLen;
wolfSSL 0:9d17e4342598 2186 }
wolfSSL 0:9d17e4342598 2187
wolfSSL 0:9d17e4342598 2188 TraceSequence(tcpInfo->sequence, *sslBytes);
wolfSSL 0:9d17e4342598 2189 if (CheckAck(tcpInfo, session) < 0) {
wolfSSL 0:9d17e4342598 2190 SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2191 return -1;
wolfSSL 0:9d17e4342598 2192 }
wolfSSL 0:9d17e4342598 2193
wolfSSL 0:9d17e4342598 2194 return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);
wolfSSL 0:9d17e4342598 2195 }
wolfSSL 0:9d17e4342598 2196
wolfSSL 0:9d17e4342598 2197
wolfSSL 0:9d17e4342598 2198 /* Check Status before record processing */
wolfSSL 0:9d17e4342598 2199 /* returns 0 on success (continue), -1 on error, 1 on success (end) */
wolfSSL 0:9d17e4342598 2200 static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
wolfSSL 0:9d17e4342598 2201 const byte** sslFrame, SnifferSession** session,
wolfSSL 0:9d17e4342598 2202 int* sslBytes, const byte** end, char* error)
wolfSSL 0:9d17e4342598 2203 {
wolfSSL 0:9d17e4342598 2204 word32 length;
wolfSSL 0:9d17e4342598 2205 SSL* ssl = ((*session)->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2206 (*session)->sslServer : (*session)->sslClient;
wolfSSL 0:9d17e4342598 2207 /* remove SnifferSession on 2nd FIN or RST */
wolfSSL 0:9d17e4342598 2208 if (tcpInfo->fin || tcpInfo->rst) {
wolfSSL 0:9d17e4342598 2209 /* flag FIN and RST */
wolfSSL 0:9d17e4342598 2210 if (tcpInfo->fin)
wolfSSL 0:9d17e4342598 2211 (*session)->flags.finCount += 1;
wolfSSL 0:9d17e4342598 2212 else if (tcpInfo->rst)
wolfSSL 0:9d17e4342598 2213 (*session)->flags.finCount += 2;
wolfSSL 0:9d17e4342598 2214
wolfSSL 0:9d17e4342598 2215 if ((*session)->flags.finCount >= 2) {
wolfSSL 0:9d17e4342598 2216 RemoveSession(*session, ipInfo, tcpInfo, 0);
wolfSSL 0:9d17e4342598 2217 *session = NULL;
wolfSSL 0:9d17e4342598 2218 return 1;
wolfSSL 0:9d17e4342598 2219 }
wolfSSL 0:9d17e4342598 2220 }
wolfSSL 0:9d17e4342598 2221
wolfSSL 0:9d17e4342598 2222 if ((*session)->flags.fatalError == FATAL_ERROR_STATE) {
wolfSSL 0:9d17e4342598 2223 SetError(FATAL_ERROR_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 2224 return -1;
wolfSSL 0:9d17e4342598 2225 }
wolfSSL 0:9d17e4342598 2226
wolfSSL 0:9d17e4342598 2227 if (*sslBytes == 0) {
wolfSSL 0:9d17e4342598 2228 Trace(NO_DATA_STR);
wolfSSL 0:9d17e4342598 2229 return 1;
wolfSSL 0:9d17e4342598 2230 }
wolfSSL 0:9d17e4342598 2231
wolfSSL 0:9d17e4342598 2232 /* if current partial data, add to end of partial */
wolfSSL 0:9d17e4342598 2233 if ( (length = ssl->buffers.inputBuffer.length) ) {
wolfSSL 0:9d17e4342598 2234 Trace(PARTIAL_ADD_STR);
wolfSSL 0:9d17e4342598 2235
wolfSSL 0:9d17e4342598 2236 if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
wolfSSL 0:9d17e4342598 2237 if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
wolfSSL 0:9d17e4342598 2238 SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2239 return -1;
wolfSSL 0:9d17e4342598 2240 }
wolfSSL 0:9d17e4342598 2241 }
wolfSSL 0:9d17e4342598 2242 XMEMCPY(&ssl->buffers.inputBuffer.buffer[length], *sslFrame, *sslBytes);
wolfSSL 0:9d17e4342598 2243 *sslBytes += length;
wolfSSL 0:9d17e4342598 2244 ssl->buffers.inputBuffer.length = *sslBytes;
wolfSSL 0:9d17e4342598 2245 *sslFrame = ssl->buffers.inputBuffer.buffer;
wolfSSL 0:9d17e4342598 2246 *end = *sslFrame + *sslBytes;
wolfSSL 0:9d17e4342598 2247 }
wolfSSL 0:9d17e4342598 2248
wolfSSL 0:9d17e4342598 2249 if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) {
wolfSSL 0:9d17e4342598 2250 int rhSize;
wolfSSL 0:9d17e4342598 2251 int ret = DoOldHello(*session, *sslFrame, &rhSize, sslBytes, error);
wolfSSL 0:9d17e4342598 2252 if (ret < 0)
wolfSSL 0:9d17e4342598 2253 return -1; /* error already set */
wolfSSL 0:9d17e4342598 2254 if (*sslBytes <= 0)
wolfSSL 0:9d17e4342598 2255 return 1;
wolfSSL 0:9d17e4342598 2256 }
wolfSSL 0:9d17e4342598 2257
wolfSSL 0:9d17e4342598 2258 return 0;
wolfSSL 0:9d17e4342598 2259 }
wolfSSL 0:9d17e4342598 2260
wolfSSL 0:9d17e4342598 2261
wolfSSL 0:9d17e4342598 2262 /* See if input on the reassembly list is ready for consuming */
wolfSSL 0:9d17e4342598 2263 /* returns 1 for TRUE, 0 for FALSE */
wolfSSL 0:9d17e4342598 2264 static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
wolfSSL 0:9d17e4342598 2265 int* sslBytes, const byte** end, char* error)
wolfSSL 0:9d17e4342598 2266 {
wolfSSL 0:9d17e4342598 2267 /* sequence and reassembly based on from, not to */
wolfSSL 0:9d17e4342598 2268 int moreInput = 0;
wolfSSL 0:9d17e4342598 2269 PacketBuffer** front = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2270 &session->cliReassemblyList : &session->srvReassemblyList;
wolfSSL 0:9d17e4342598 2271 word32* expected = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2272 &session->cliExpected : &session->srvExpected;
wolfSSL 0:9d17e4342598 2273 /* buffer is on receiving end */
wolfSSL 0:9d17e4342598 2274 word32* length = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2275 &session->sslServer->buffers.inputBuffer.length :
wolfSSL 0:9d17e4342598 2276 &session->sslClient->buffers.inputBuffer.length;
wolfSSL 0:9d17e4342598 2277 byte* myBuffer = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2278 session->sslServer->buffers.inputBuffer.buffer :
wolfSSL 0:9d17e4342598 2279 session->sslClient->buffers.inputBuffer.buffer;
wolfSSL 0:9d17e4342598 2280 word32 bufferSize = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2281 session->sslServer->buffers.inputBuffer.bufferSize :
wolfSSL 0:9d17e4342598 2282 session->sslClient->buffers.inputBuffer.bufferSize;
wolfSSL 0:9d17e4342598 2283 SSL* ssl = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2284 session->sslServer : session->sslClient;
wolfSSL 0:9d17e4342598 2285
wolfSSL 0:9d17e4342598 2286 while (*front && ((*front)->begin == *expected) ) {
wolfSSL 0:9d17e4342598 2287 word32 room = bufferSize - *length;
wolfSSL 0:9d17e4342598 2288 word32 packetLen = (*front)->end - (*front)->begin + 1;
wolfSSL 0:9d17e4342598 2289
wolfSSL 0:9d17e4342598 2290 if (packetLen > room && bufferSize < MAX_INPUT_SZ) {
wolfSSL 0:9d17e4342598 2291 if (GrowInputBuffer(ssl, packetLen, *length) < 0) {
wolfSSL 0:9d17e4342598 2292 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2293 return 0;
wolfSSL 0:9d17e4342598 2294 }
wolfSSL 0:9d17e4342598 2295 }
wolfSSL 0:9d17e4342598 2296
wolfSSL 0:9d17e4342598 2297 if (packetLen <= room) {
wolfSSL 0:9d17e4342598 2298 PacketBuffer* del = *front;
wolfSSL 0:9d17e4342598 2299
wolfSSL 0:9d17e4342598 2300 XMEMCPY(&myBuffer[*length], (*front)->data, packetLen);
wolfSSL 0:9d17e4342598 2301 *length += packetLen;
wolfSSL 0:9d17e4342598 2302 *expected += packetLen;
wolfSSL 0:9d17e4342598 2303
wolfSSL 0:9d17e4342598 2304 /* remove used packet */
wolfSSL 0:9d17e4342598 2305 *front = (*front)->next;
wolfSSL 0:9d17e4342598 2306 FreePacketBuffer(del);
wolfSSL 0:9d17e4342598 2307
wolfSSL 0:9d17e4342598 2308 moreInput = 1;
wolfSSL 0:9d17e4342598 2309 }
wolfSSL 0:9d17e4342598 2310 else
wolfSSL 0:9d17e4342598 2311 break;
wolfSSL 0:9d17e4342598 2312 }
wolfSSL 0:9d17e4342598 2313 if (moreInput) {
wolfSSL 0:9d17e4342598 2314 *sslFrame = myBuffer;
wolfSSL 0:9d17e4342598 2315 *sslBytes = *length;
wolfSSL 0:9d17e4342598 2316 *end = myBuffer + *length;
wolfSSL 0:9d17e4342598 2317 }
wolfSSL 0:9d17e4342598 2318 return moreInput;
wolfSSL 0:9d17e4342598 2319 }
wolfSSL 0:9d17e4342598 2320
wolfSSL 0:9d17e4342598 2321
wolfSSL 0:9d17e4342598 2322
wolfSSL 0:9d17e4342598 2323 /* Process Message(s) from sslFrame */
wolfSSL 0:9d17e4342598 2324 /* return Number of bytes on success, 0 for no data yet, and -1 on error */
wolfSSL 0:9d17e4342598 2325 static int ProcessMessage(const byte* sslFrame, SnifferSession* session,
wolfSSL 0:9d17e4342598 2326 int sslBytes, byte* data, const byte* end,char* error)
wolfSSL 0:9d17e4342598 2327 {
wolfSSL 0:9d17e4342598 2328 const byte* sslBegin = sslFrame;
wolfSSL 0:9d17e4342598 2329 const byte* tmp;
wolfSSL 0:9d17e4342598 2330 RecordLayerHeader rh;
wolfSSL 0:9d17e4342598 2331 int rhSize = 0;
wolfSSL 0:9d17e4342598 2332 int ret;
wolfSSL 0:9d17e4342598 2333 int errCode = 0;
wolfSSL 0:9d17e4342598 2334 int decoded = 0; /* bytes stored for user in data */
wolfSSL 0:9d17e4342598 2335 int notEnough; /* notEnough bytes yet flag */
wolfSSL 0:9d17e4342598 2336 SSL* ssl = (session->flags.side == CYASSL_SERVER_END) ?
wolfSSL 0:9d17e4342598 2337 session->sslServer : session->sslClient;
wolfSSL 0:9d17e4342598 2338 doMessage:
wolfSSL 0:9d17e4342598 2339 notEnough = 0;
wolfSSL 0:9d17e4342598 2340 if (sslBytes < 0) {
wolfSSL 0:9d17e4342598 2341 SetError(PACKET_HDR_SHORT_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2342 return -1;
wolfSSL 0:9d17e4342598 2343 }
wolfSSL 0:9d17e4342598 2344 if (sslBytes >= RECORD_HEADER_SZ) {
wolfSSL 0:9d17e4342598 2345 if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) {
wolfSSL 0:9d17e4342598 2346 SetError(BAD_RECORD_HDR_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2347 return -1;
wolfSSL 0:9d17e4342598 2348 }
wolfSSL 0:9d17e4342598 2349 }
wolfSSL 0:9d17e4342598 2350 else
wolfSSL 0:9d17e4342598 2351 notEnough = 1;
wolfSSL 0:9d17e4342598 2352
wolfSSL 0:9d17e4342598 2353 if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) {
wolfSSL 0:9d17e4342598 2354 /* don't have enough input yet to process full SSL record */
wolfSSL 0:9d17e4342598 2355 Trace(PARTIAL_INPUT_STR);
wolfSSL 0:9d17e4342598 2356
wolfSSL 0:9d17e4342598 2357 /* store partial if not there already or we advanced */
wolfSSL 0:9d17e4342598 2358 if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
wolfSSL 0:9d17e4342598 2359 if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
wolfSSL 0:9d17e4342598 2360 if (GrowInputBuffer(ssl, sslBytes, 0) < 0) {
wolfSSL 0:9d17e4342598 2361 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2362 return -1;
wolfSSL 0:9d17e4342598 2363 }
wolfSSL 0:9d17e4342598 2364 }
wolfSSL 0:9d17e4342598 2365 XMEMCPY(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
wolfSSL 0:9d17e4342598 2366 ssl->buffers.inputBuffer.length = sslBytes;
wolfSSL 0:9d17e4342598 2367 }
wolfSSL 0:9d17e4342598 2368 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
wolfSSL 0:9d17e4342598 2369 goto doMessage;
wolfSSL 0:9d17e4342598 2370 return decoded;
wolfSSL 0:9d17e4342598 2371 }
wolfSSL 0:9d17e4342598 2372 sslFrame += RECORD_HEADER_SZ;
wolfSSL 0:9d17e4342598 2373 sslBytes -= RECORD_HEADER_SZ;
wolfSSL 0:9d17e4342598 2374 tmp = sslFrame + rhSize; /* may have more than one record to process */
wolfSSL 0:9d17e4342598 2375
wolfSSL 0:9d17e4342598 2376 /* decrypt if needed */
wolfSSL 0:9d17e4342598 2377 if ((session->flags.side == CYASSL_SERVER_END &&
wolfSSL 0:9d17e4342598 2378 session->flags.serverCipherOn)
wolfSSL 0:9d17e4342598 2379 || (session->flags.side == CYASSL_CLIENT_END &&
wolfSSL 0:9d17e4342598 2380 session->flags.clientCipherOn)) {
wolfSSL 0:9d17e4342598 2381 if (CheckAvailableSize(ssl, rhSize) < 0) {
wolfSSL 0:9d17e4342598 2382 SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2383 return -1;
wolfSSL 0:9d17e4342598 2384 }
wolfSSL 0:9d17e4342598 2385 sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
wolfSSL 0:9d17e4342598 2386 ssl->buffers.outputBuffer.buffer, &errCode);
wolfSSL 0:9d17e4342598 2387 if (errCode != 0) {
wolfSSL 0:9d17e4342598 2388 SetError(BAD_DECRYPT, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2389 return -1;
wolfSSL 0:9d17e4342598 2390 }
wolfSSL 0:9d17e4342598 2391 }
wolfSSL 0:9d17e4342598 2392
wolfSSL 0:9d17e4342598 2393 switch ((enum ContentType)rh.type) {
wolfSSL 0:9d17e4342598 2394 case handshake:
wolfSSL 0:9d17e4342598 2395 Trace(GOT_HANDSHAKE_STR);
wolfSSL 0:9d17e4342598 2396 ret = DoHandShake(sslFrame, &sslBytes, session, error);
wolfSSL 0:9d17e4342598 2397 if (ret != 0) {
wolfSSL 0:9d17e4342598 2398 if (session->flags.fatalError == 0)
wolfSSL 0:9d17e4342598 2399 SetError(BAD_HANDSHAKE_STR,error,session,FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2400 return -1;
wolfSSL 0:9d17e4342598 2401 }
wolfSSL 0:9d17e4342598 2402 break;
wolfSSL 0:9d17e4342598 2403 case change_cipher_spec:
wolfSSL 0:9d17e4342598 2404 if (session->flags.side == CYASSL_SERVER_END)
wolfSSL 0:9d17e4342598 2405 session->flags.serverCipherOn = 1;
wolfSSL 0:9d17e4342598 2406 else
wolfSSL 0:9d17e4342598 2407 session->flags.clientCipherOn = 1;
wolfSSL 0:9d17e4342598 2408 Trace(GOT_CHANGE_CIPHER_STR);
wolfSSL 0:9d17e4342598 2409 ssl->options.handShakeState = HANDSHAKE_DONE;
wolfSSL 0:9d17e4342598 2410 break;
wolfSSL 0:9d17e4342598 2411 case application_data:
wolfSSL 0:9d17e4342598 2412 Trace(GOT_APP_DATA_STR);
wolfSSL 0:9d17e4342598 2413 {
wolfSSL 0:9d17e4342598 2414 word32 inOutIdx = 0;
wolfSSL 0:9d17e4342598 2415
wolfSSL 0:9d17e4342598 2416 ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx);
wolfSSL 0:9d17e4342598 2417 if (ret == 0) {
wolfSSL 0:9d17e4342598 2418 ret = ssl->buffers.clearOutputBuffer.length;
wolfSSL 0:9d17e4342598 2419 TraceGotData(ret);
wolfSSL 0:9d17e4342598 2420 if (ret) { /* may be blank message */
wolfSSL 0:9d17e4342598 2421 XMEMCPY(&data[decoded],
wolfSSL 0:9d17e4342598 2422 ssl->buffers.clearOutputBuffer.buffer, ret);
wolfSSL 0:9d17e4342598 2423 TraceAddedData(ret, decoded);
wolfSSL 0:9d17e4342598 2424 decoded += ret;
wolfSSL 0:9d17e4342598 2425 ssl->buffers.clearOutputBuffer.length = 0;
wolfSSL 0:9d17e4342598 2426 }
wolfSSL 0:9d17e4342598 2427 }
wolfSSL 0:9d17e4342598 2428 else {
wolfSSL 0:9d17e4342598 2429 SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2430 return -1;
wolfSSL 0:9d17e4342598 2431 }
wolfSSL 0:9d17e4342598 2432 if (ssl->buffers.outputBuffer.dynamicFlag)
wolfSSL 0:9d17e4342598 2433 ShrinkOutputBuffer(ssl);
wolfSSL 0:9d17e4342598 2434 }
wolfSSL 0:9d17e4342598 2435 break;
wolfSSL 0:9d17e4342598 2436 case alert:
wolfSSL 0:9d17e4342598 2437 Trace(GOT_ALERT_STR);
wolfSSL 0:9d17e4342598 2438 break;
wolfSSL 0:9d17e4342598 2439 case no_type:
wolfSSL 0:9d17e4342598 2440 default:
wolfSSL 0:9d17e4342598 2441 SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);
wolfSSL 0:9d17e4342598 2442 return -1;
wolfSSL 0:9d17e4342598 2443 }
wolfSSL 0:9d17e4342598 2444
wolfSSL 0:9d17e4342598 2445 if (tmp < end) {
wolfSSL 0:9d17e4342598 2446 Trace(ANOTHER_MSG_STR);
wolfSSL 0:9d17e4342598 2447 sslFrame = tmp;
wolfSSL 0:9d17e4342598 2448 sslBytes = (int)(end - tmp);
wolfSSL 0:9d17e4342598 2449 goto doMessage;
wolfSSL 0:9d17e4342598 2450 }
wolfSSL 0:9d17e4342598 2451
wolfSSL 0:9d17e4342598 2452 /* clear used input */
wolfSSL 0:9d17e4342598 2453 ssl->buffers.inputBuffer.length = 0;
wolfSSL 0:9d17e4342598 2454
wolfSSL 0:9d17e4342598 2455 /* could have more input ready now */
wolfSSL 0:9d17e4342598 2456 if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
wolfSSL 0:9d17e4342598 2457 goto doMessage;
wolfSSL 0:9d17e4342598 2458
wolfSSL 0:9d17e4342598 2459 if (ssl->buffers.inputBuffer.dynamicFlag)
wolfSSL 0:9d17e4342598 2460 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
wolfSSL 0:9d17e4342598 2461
wolfSSL 0:9d17e4342598 2462 return decoded;
wolfSSL 0:9d17e4342598 2463 }
wolfSSL 0:9d17e4342598 2464
wolfSSL 0:9d17e4342598 2465
wolfSSL 0:9d17e4342598 2466 /* See if we need to process any pending FIN captures */
wolfSSL 0:9d17e4342598 2467 static void CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo,
wolfSSL 0:9d17e4342598 2468 SnifferSession* session)
wolfSSL 0:9d17e4342598 2469 {
wolfSSL 0:9d17e4342598 2470 if (session->finCaputre.cliFinSeq && session->finCaputre.cliFinSeq <=
wolfSSL 0:9d17e4342598 2471 session->cliExpected) {
wolfSSL 0:9d17e4342598 2472 if (session->finCaputre.cliCounted == 0) {
wolfSSL 0:9d17e4342598 2473 session->flags.finCount += 1;
wolfSSL 0:9d17e4342598 2474 session->finCaputre.cliCounted = 1;
wolfSSL 0:9d17e4342598 2475 TraceClientFin(session->finCaputre.cliFinSeq, session->cliExpected);
wolfSSL 0:9d17e4342598 2476 }
wolfSSL 0:9d17e4342598 2477 }
wolfSSL 0:9d17e4342598 2478
wolfSSL 0:9d17e4342598 2479 if (session->finCaputre.srvFinSeq && session->finCaputre.srvFinSeq <=
wolfSSL 0:9d17e4342598 2480 session->srvExpected) {
wolfSSL 0:9d17e4342598 2481 if (session->finCaputre.srvCounted == 0) {
wolfSSL 0:9d17e4342598 2482 session->flags.finCount += 1;
wolfSSL 0:9d17e4342598 2483 session->finCaputre.srvCounted = 1;
wolfSSL 0:9d17e4342598 2484 TraceServerFin(session->finCaputre.srvFinSeq, session->srvExpected);
wolfSSL 0:9d17e4342598 2485 }
wolfSSL 0:9d17e4342598 2486 }
wolfSSL 0:9d17e4342598 2487
wolfSSL 0:9d17e4342598 2488 if (session->flags.finCount >= 2)
wolfSSL 0:9d17e4342598 2489 RemoveSession(session, ipInfo, tcpInfo, 0);
wolfSSL 0:9d17e4342598 2490 }
wolfSSL 0:9d17e4342598 2491
wolfSSL 0:9d17e4342598 2492
wolfSSL 0:9d17e4342598 2493 /* If session is in fatal error state free resources now
wolfSSL 0:9d17e4342598 2494 return true if removed, 0 otherwise */
wolfSSL 0:9d17e4342598 2495 static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
wolfSSL 0:9d17e4342598 2496 SnifferSession* session, char* error)
wolfSSL 0:9d17e4342598 2497 {
wolfSSL 0:9d17e4342598 2498 if (session && session->flags.fatalError == FATAL_ERROR_STATE) {
wolfSSL 0:9d17e4342598 2499 RemoveSession(session, ipInfo, tcpInfo, 0);
wolfSSL 0:9d17e4342598 2500 SetError(FATAL_ERROR_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 2501 return 1;
wolfSSL 0:9d17e4342598 2502 }
wolfSSL 0:9d17e4342598 2503 return 0;
wolfSSL 0:9d17e4342598 2504 }
wolfSSL 0:9d17e4342598 2505
wolfSSL 0:9d17e4342598 2506
wolfSSL 0:9d17e4342598 2507 /* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
wolfSSL 0:9d17e4342598 2508 /* returns Number of bytes on success, 0 for no data yet, and -1 on error */
wolfSSL 0:9d17e4342598 2509 int ssl_DecodePacket(const byte* packet, int length, byte* data, char* error)
wolfSSL 0:9d17e4342598 2510 {
wolfSSL 0:9d17e4342598 2511 TcpInfo tcpInfo;
wolfSSL 0:9d17e4342598 2512 IpInfo ipInfo;
wolfSSL 0:9d17e4342598 2513 const byte* sslFrame;
wolfSSL 0:9d17e4342598 2514 const byte* end = packet + length;
wolfSSL 0:9d17e4342598 2515 int sslBytes; /* ssl bytes unconsumed */
wolfSSL 0:9d17e4342598 2516 int ret;
wolfSSL 0:9d17e4342598 2517 SnifferSession* session = 0;
wolfSSL 0:9d17e4342598 2518
wolfSSL 0:9d17e4342598 2519 if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
wolfSSL 0:9d17e4342598 2520 error) != 0)
wolfSSL 0:9d17e4342598 2521 return -1;
wolfSSL 0:9d17e4342598 2522
wolfSSL 0:9d17e4342598 2523 ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
wolfSSL 0:9d17e4342598 2524 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
wolfSSL 0:9d17e4342598 2525 else if (ret == -1) return -1;
wolfSSL 0:9d17e4342598 2526 else if (ret == 1) return 0; /* done for now */
wolfSSL 0:9d17e4342598 2527
wolfSSL 0:9d17e4342598 2528 ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
wolfSSL 0:9d17e4342598 2529 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
wolfSSL 0:9d17e4342598 2530 else if (ret == -1) return -1;
wolfSSL 0:9d17e4342598 2531 else if (ret == 1) return 0; /* done for now */
wolfSSL 0:9d17e4342598 2532
wolfSSL 0:9d17e4342598 2533 ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
wolfSSL 0:9d17e4342598 2534 &end, error);
wolfSSL 0:9d17e4342598 2535 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
wolfSSL 0:9d17e4342598 2536 else if (ret == -1) return -1;
wolfSSL 0:9d17e4342598 2537 else if (ret == 1) return 0; /* done for now */
wolfSSL 0:9d17e4342598 2538
wolfSSL 0:9d17e4342598 2539 ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error);
wolfSSL 0:9d17e4342598 2540 if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
wolfSSL 0:9d17e4342598 2541 CheckFinCapture(&ipInfo, &tcpInfo, session);
wolfSSL 0:9d17e4342598 2542 return ret;
wolfSSL 0:9d17e4342598 2543 }
wolfSSL 0:9d17e4342598 2544
wolfSSL 0:9d17e4342598 2545
wolfSSL 0:9d17e4342598 2546 /* Enables (if traceFile)/ Disables debug tracing */
wolfSSL 0:9d17e4342598 2547 /* returns 0 on success, -1 on error */
wolfSSL 0:9d17e4342598 2548 int ssl_Trace(const char* traceFile, char* error)
wolfSSL 0:9d17e4342598 2549 {
wolfSSL 0:9d17e4342598 2550 if (traceFile) {
wolfSSL 0:9d17e4342598 2551 TraceFile = fopen(traceFile, "a");
wolfSSL 0:9d17e4342598 2552 if (!TraceFile) {
wolfSSL 0:9d17e4342598 2553 SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
wolfSSL 0:9d17e4342598 2554 return -1;
wolfSSL 0:9d17e4342598 2555 }
wolfSSL 0:9d17e4342598 2556 TraceOn = 1;
wolfSSL 0:9d17e4342598 2557 }
wolfSSL 0:9d17e4342598 2558 else
wolfSSL 0:9d17e4342598 2559 TraceOn = 0;
wolfSSL 0:9d17e4342598 2560
wolfSSL 0:9d17e4342598 2561 return 0;
wolfSSL 0:9d17e4342598 2562 }
wolfSSL 0:9d17e4342598 2563
wolfSSL 0:9d17e4342598 2564
wolfSSL 0:9d17e4342598 2565
wolfSSL 0:9d17e4342598 2566
wolfSSL 0:9d17e4342598 2567 #endif /* CYASSL_SNIFFER */