wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Fri Jun 26 00:39:20 2015 +0000
Revision:
0:d92f9d21154c
wolfSSL 3.6.0

Who changed what in which revision?

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