A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

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