PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sniffer.c

https://github.com/andersmalm/cyassl
C | 2503 lines | 1853 code | 436 blank | 214 comment | 381 complexity | 2635158af98fee29ba546b0e7d9e0b1f MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /* sniffer.c
  2. *
  3. * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
  4. *
  5. * This file is part of CyaSSL.
  6. *
  7. * CyaSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * CyaSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  20. */
  21. #ifdef CYASSL_SNIFFER
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <assert.h>
  26. #include <time.h>
  27. #ifndef _WIN32
  28. #include <arpa/inet.h>
  29. #endif
  30. #ifdef _WIN32
  31. #define SNPRINTF _snprintf
  32. #else
  33. #define SNPRINTF snprintf
  34. #endif
  35. #include <cyassl/openssl/ssl.h>
  36. #include <cyassl/internal.h>
  37. #include <cyassl/error.h>
  38. #include <cyassl/sniffer.h>
  39. #include <cyassl/sniffer_error.h>
  40. #ifndef min
  41. static INLINE word32 min(word32 a, word32 b)
  42. {
  43. return a > b ? b : a;
  44. }
  45. #endif
  46. /* Misc constants */
  47. enum {
  48. MAX_SERVER_ADDRESS = 128, /* maximum server address length */
  49. MAX_ERROR_LEN = 80, /* maximum error length */
  50. ETHER_IF_ADDR_LEN = 6, /* ethernet interface address length */
  51. LOCAL_IF_ADDR_LEN = 4, /* localhost interface address length, !windows */
  52. TCP_PROTO = 6, /* TCP_PROTOCOL */
  53. IP_HDR_SZ = 20, /* IP header legnth, min */
  54. TCP_HDR_SZ = 20, /* TCP header legnth, min */
  55. IPV4 = 4, /* IP version 4 */
  56. TCP_PROTOCOL = 6, /* TCP Protocol id */
  57. TRACE_MSG_SZ = 80, /* Trace Message buffer size */
  58. HASH_SIZE = 499, /* Session Hash Table Rows */
  59. PSEUDO_HDR_SZ = 12, /* TCP Pseudo Header size in bytes */
  60. FATAL_ERROR_STATE = 1, /* SnifferSession fatal error state */
  61. SNIFFER_TIMEOUT = 900, /* Cache unclosed Sessions for 15 minutes */
  62. TICKET_HINT_LEN = 4, /* Session Ticket Hint length */
  63. EXT_TYPE_SZ = 2, /* Extension length */
  64. MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
  65. MTU_EXTRA, /* Max input sz of reassembly */
  66. TICKET_EXT_ID = 0x23 /* Session Ticket Extension ID */
  67. };
  68. #ifdef _WIN32
  69. static HMODULE dllModule; /* for error string resources */
  70. BOOL APIENTRY DllMain( HMODULE hModule,
  71. DWORD ul_reason_for_call,
  72. LPVOID lpReserved
  73. )
  74. {
  75. static int didInit = 0;
  76. switch (ul_reason_for_call)
  77. {
  78. case DLL_PROCESS_ATTACH:
  79. if (didInit == 0) {
  80. dllModule = hModule;
  81. ssl_InitSniffer();
  82. didInit = 1;
  83. }
  84. break;
  85. case DLL_THREAD_ATTACH:
  86. break;
  87. case DLL_THREAD_DETACH:
  88. break;
  89. case DLL_PROCESS_DETACH:
  90. if (didInit) {
  91. ssl_FreeSniffer();
  92. didInit = 0;
  93. }
  94. break;
  95. }
  96. return TRUE;
  97. }
  98. #endif /* _WIN32 */
  99. static int TraceOn = 0; /* Trace is off by default */
  100. static FILE* TraceFile = 0;
  101. /* windows uses .rc table for this */
  102. #ifndef _WIN32
  103. static const char* const msgTable[] =
  104. {
  105. /* 1 */
  106. "Out of Memory",
  107. "New SSL Sniffer Server Registered",
  108. "Checking IP Header",
  109. "SSL Sniffer Server Not Registered",
  110. "Checking TCP Header",
  111. /* 6 */
  112. "SSL Sniffer Server Port Not Registered",
  113. "RSA Private Decrypt Error",
  114. "RSA Private Decode Error",
  115. "Set Cipher Spec Error",
  116. "Server Hello Input Malformed",
  117. /* 11 */
  118. "Couldn't Resume Session Error",
  119. "Server Did Resumption",
  120. "Client Hello Input Malformed",
  121. "Client Trying to Resume",
  122. "Handshake Input Malformed",
  123. /* 16 */
  124. "Got Hello Verify msg",
  125. "Got Server Hello msg",
  126. "Got Cert Request msg",
  127. "Got Server Key Exchange msg",
  128. "Got Cert msg",
  129. /* 21 */
  130. "Got Server Hello Done msg",
  131. "Got Finished msg",
  132. "Got Client Hello msg",
  133. "Got Client Key Exchange msg",
  134. "Got Cert Verify msg",
  135. /* 26 */
  136. "Got Unknown Handshake msg",
  137. "New SSL Sniffer Session created",
  138. "Couldn't create new SSL",
  139. "Got a Packet to decode",
  140. "No data present",
  141. /* 31 */
  142. "Session Not Found",
  143. "Got an Old Client Hello msg",
  144. "Old Client Hello Input Malformed",
  145. "Old Client Hello OK",
  146. "Bad Old Client Hello",
  147. /* 36 */
  148. "Bad Record Header",
  149. "Record Header Input Malformed",
  150. "Got a HandShake msg",
  151. "Bad HandShake msg",
  152. "Got a Change Cipher Spec msg",
  153. /* 41 */
  154. "Got Application Data msg",
  155. "Bad Application Data",
  156. "Got an Alert msg",
  157. "Another msg to Process",
  158. "Removing Session From Table",
  159. /* 46 */
  160. "Bad Key File",
  161. "Wrong IP Version",
  162. "Wrong Protocol type",
  163. "Packet Short for header processing",
  164. "Got Unknown Record Type",
  165. /* 51 */
  166. "Can't Open Trace File",
  167. "Session in Fatal Error State",
  168. "Partial SSL record received",
  169. "Buffer Error, malformed input",
  170. "Added to Partial Input",
  171. /* 56 */
  172. "Received a Duplicate Packet",
  173. "Received an Out of Order Packet",
  174. "Received an Overlap Duplicate Packet",
  175. "Received an Overlap Reassembly Begin Duplicate Packet",
  176. "Received an Overlap Reassembly End Duplicate Packet",
  177. /* 61 */
  178. "Missed the Client Hello Entirely",
  179. "Got Hello Request msg",
  180. "Got Session Ticket msg",
  181. "Bad Input",
  182. "Bad Decrypt Type",
  183. /* 66 */
  184. "Bad Finished Message Processing",
  185. "Bad Compression Type",
  186. "Bad DeriveKeys Error",
  187. "Saw ACK for Missing Packet Error"
  188. };
  189. /* *nix version uses table above */
  190. static void GetError(int idx, char* str)
  191. {
  192. XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN);
  193. }
  194. #else /* _WIN32 */
  195. /* Windows version uses .rc table */
  196. static void GetError(int idx, char* buffer)
  197. {
  198. if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
  199. buffer[0] = 0;
  200. }
  201. #endif /* _WIN32 */
  202. /* Packet Buffer for reassembly list and ready list */
  203. typedef struct PacketBuffer {
  204. word32 begin; /* relative sequence begin */
  205. word32 end; /* relative sequence end */
  206. byte* data; /* actual data */
  207. struct PacketBuffer* next; /* next on reassembly list or ready list */
  208. } PacketBuffer;
  209. /* Sniffer Server holds info for each server/port monitored */
  210. typedef struct SnifferServer {
  211. SSL_CTX* ctx; /* SSL context */
  212. char address[MAX_SERVER_ADDRESS]; /* passed in server address */
  213. word32 server; /* netowrk order address */
  214. int port; /* server port */
  215. struct SnifferServer* next; /* for list */
  216. } SnifferServer;
  217. /* Session Flags */
  218. typedef struct Flags {
  219. byte side; /* which end is current packet headed */
  220. byte serverCipherOn; /* indicates whether cipher is active */
  221. byte clientCipherOn; /* indicates whether cipher is active */
  222. byte resuming; /* did this session come from resumption */
  223. byte cached; /* have we cached this session yet */
  224. byte clientHello; /* processed client hello yet, for SSLv2 */
  225. byte finCount; /* get both FINs before removing */
  226. byte fatalError; /* fatal error state */
  227. } Flags;
  228. /* Out of Order FIN caputre */
  229. typedef struct FinCaputre {
  230. word32 cliFinSeq; /* client relative sequence FIN 0 is no */
  231. word32 srvFinSeq; /* server relative sequence FIN, 0 is no */
  232. byte cliCounted; /* did we count yet, detects duplicates */
  233. byte srvCounted; /* did we count yet, detects duplicates */
  234. } FinCaputre;
  235. /* Sniffer Session holds info for each client/server SSL/TLS session */
  236. typedef struct SnifferSession {
  237. SnifferServer* context; /* server context */
  238. SSL* sslServer; /* SSL server side decode */
  239. SSL* sslClient; /* SSL client side decode */
  240. word32 server; /* server address in network byte order */
  241. word32 client; /* client address in network byte order */
  242. word16 srvPort; /* server port */
  243. word16 cliPort; /* client port */
  244. word32 cliSeqStart; /* client start sequence */
  245. word32 srvSeqStart; /* server start sequence */
  246. word32 cliExpected; /* client expected sequence (relative) */
  247. word32 srvExpected; /* server expected sequence (relative) */
  248. FinCaputre finCaputre; /* retain out of order FIN s */
  249. Flags flags; /* session flags */
  250. time_t bornOn; /* born on ticks */
  251. PacketBuffer* cliReassemblyList; /* client out of order packets */
  252. PacketBuffer* srvReassemblyList; /* server out of order packets */
  253. struct SnifferSession* next; /* for hash table list */
  254. byte* ticketID; /* mac ID of session ticket */
  255. } SnifferSession;
  256. /* Sniffer Server List and mutex */
  257. static SnifferServer* ServerList = 0;
  258. static CyaSSL_Mutex ServerListMutex;
  259. /* Session Hash Table, mutex, and count */
  260. static SnifferSession* SessionTable[HASH_SIZE];
  261. static CyaSSL_Mutex SessionMutex;
  262. static int SessionCount = 0;
  263. /* Initialize overall Sniffer */
  264. void ssl_InitSniffer(void)
  265. {
  266. CyaSSL_Init();
  267. InitMutex(&ServerListMutex);
  268. InitMutex(&SessionMutex);
  269. }
  270. /* Free Sniffer Server's resources/self */
  271. static void FreeSnifferServer(SnifferServer* srv)
  272. {
  273. if (srv)
  274. SSL_CTX_free(srv->ctx);
  275. free(srv);
  276. }
  277. /* free PacketBuffer's resources/self */
  278. static void FreePacketBuffer(PacketBuffer* del)
  279. {
  280. if (del) {
  281. free(del->data);
  282. free(del);
  283. }
  284. }
  285. /* remove PacketBuffer List */
  286. static void FreePacketList(PacketBuffer* in)
  287. {
  288. if (in) {
  289. PacketBuffer* del;
  290. PacketBuffer* packet = in;
  291. while (packet) {
  292. del = packet;
  293. packet = packet->next;
  294. FreePacketBuffer(del);
  295. }
  296. }
  297. }
  298. /* Free Sniffer Session's resources/self */
  299. static void FreeSnifferSession(SnifferSession* session)
  300. {
  301. if (session) {
  302. SSL_free(session->sslClient);
  303. SSL_free(session->sslServer);
  304. FreePacketList(session->cliReassemblyList);
  305. FreePacketList(session->srvReassemblyList);
  306. free(session->ticketID);
  307. }
  308. free(session);
  309. }
  310. /* Free overall Sniffer */
  311. void ssl_FreeSniffer(void)
  312. {
  313. SnifferServer* srv;
  314. SnifferServer* removeServer;
  315. SnifferSession* session;
  316. SnifferSession* removeSession;
  317. int i;
  318. LockMutex(&ServerListMutex);
  319. LockMutex(&SessionMutex);
  320. srv = ServerList;
  321. while (srv) {
  322. removeServer = srv;
  323. srv = srv->next;
  324. FreeSnifferServer(removeServer);
  325. }
  326. for (i = 0; i < HASH_SIZE; i++) {
  327. session = SessionTable[i];
  328. while (session) {
  329. removeSession = session;
  330. session = session->next;
  331. FreeSnifferSession(removeSession);
  332. }
  333. }
  334. UnLockMutex(&SessionMutex);
  335. UnLockMutex(&ServerListMutex);
  336. FreeMutex(&SessionMutex);
  337. FreeMutex(&ServerListMutex);
  338. CyaSSL_Cleanup();
  339. }
  340. /* Initialize a SnifferServer */
  341. static void InitSnifferServer(SnifferServer* sniffer)
  342. {
  343. sniffer->ctx = 0;
  344. XMEMSET(sniffer->address, 0, MAX_SERVER_ADDRESS);
  345. sniffer->server = 0;
  346. sniffer->port = 0;
  347. sniffer->next = 0;
  348. }
  349. /* Initialize session flags */
  350. static void InitFlags(Flags* flags)
  351. {
  352. flags->side = 0;
  353. flags->serverCipherOn = 0;
  354. flags->clientCipherOn = 0;
  355. flags->resuming = 0;
  356. flags->cached = 0;
  357. flags->clientHello = 0;
  358. flags->finCount = 0;
  359. flags->fatalError = 0;
  360. }
  361. /* Initialize FIN Capture */
  362. static void InitFinCapture(FinCaputre* cap)
  363. {
  364. cap->cliFinSeq = 0;
  365. cap->srvFinSeq = 0;
  366. cap->cliCounted = 0;
  367. cap->srvCounted = 0;
  368. }
  369. /* Initialize a Sniffer Session */
  370. static void InitSession(SnifferSession* session)
  371. {
  372. session->context = 0;
  373. session->sslServer = 0;
  374. session->sslClient = 0;
  375. session->server = 0;
  376. session->client = 0;
  377. session->srvPort = 0;
  378. session->cliPort = 0;
  379. session->cliSeqStart = 0;
  380. session->srvSeqStart = 0;
  381. session->cliExpected = 0;
  382. session->srvExpected = 0;
  383. session->bornOn = 0;
  384. session->cliReassemblyList = 0;
  385. session->srvReassemblyList = 0;
  386. session->next = 0;
  387. session->ticketID = 0;
  388. InitFlags(&session->flags);
  389. InitFinCapture(&session->finCaputre);
  390. }
  391. /* IP Info from IP Header */
  392. typedef struct IpInfo {
  393. int length; /* length of this header */
  394. int total; /* total length of fragment */
  395. word32 src; /* network order source address */
  396. word32 dst; /* network order destination address */
  397. } IpInfo;
  398. /* TCP Info from TCP Header */
  399. typedef struct TcpInfo {
  400. int srcPort; /* source port */
  401. int dstPort; /* source port */
  402. int length; /* length of this header */
  403. word32 sequence; /* sequence number */
  404. word32 ackNumber; /* ack number */
  405. byte fin; /* FIN set */
  406. byte rst; /* RST set */
  407. byte syn; /* SYN set */
  408. byte ack; /* ACK set */
  409. } TcpInfo;
  410. /* Tcp Pseudo Header for Checksum calculation */
  411. typedef struct TcpPseudoHdr {
  412. word32 src; /* source address */
  413. word32 dst; /* destination address */
  414. byte rsv; /* reserved, always 0 */
  415. byte protocol; /* IP protocol */
  416. word16 legnth; /* tcp header length + data length (doesn't include */
  417. /* pseudo header length) network order */
  418. } TcpPseudoHdr;
  419. /* Password Setting Callback */
  420. static int SetPassword(char* passwd, int sz, int rw, void* userdata)
  421. {
  422. (void)rw;
  423. XSTRNCPY(passwd, userdata, sz);
  424. return (int)XSTRLEN(userdata);
  425. }
  426. /* Ethernet Header */
  427. typedef struct EthernetHdr {
  428. byte dst[ETHER_IF_ADDR_LEN]; /* destination host address */
  429. byte src[ETHER_IF_ADDR_LEN]; /* source host address */
  430. word16 type; /* IP, ARP, etc */
  431. } EthernetHdr;
  432. /* IP Header */
  433. typedef struct IpHdr {
  434. byte ver_hl; /* version/header length */
  435. byte tos; /* type of service */
  436. word16 length; /* total length */
  437. word16 id; /* identification */
  438. word16 offset; /* fragment offset field */
  439. byte ttl; /* time to live */
  440. byte protocol; /* protocol */
  441. word16 sum; /* checksum */
  442. word32 src; /* source address */
  443. word32 dst; /* destination address */
  444. } IpHdr;
  445. #define IP_HL(ip) ( (((ip)->ver_hl) & 0x0f) * 4)
  446. #define IP_V(ip) ( ((ip)->ver_hl) >> 4)
  447. /* TCP Header */
  448. typedef struct TcpHdr {
  449. word16 srcPort; /* source port */
  450. word16 dstPort; /* destination port */
  451. word32 sequence; /* sequence number */
  452. word32 ack; /* acknoledgment number */
  453. byte offset; /* data offset, reserved */
  454. byte flags; /* option flags */
  455. word16 window; /* window */
  456. word16 sum; /* checksum */
  457. word16 urgent; /* urgent pointer */
  458. } TcpHdr;
  459. #define TCP_LEN(tcp) ( (((tcp)->offset & 0xf0) >> 4) * 4)
  460. #define TCP_FIN 0x01
  461. #define TCP_SYN 0x02
  462. #define TCP_RST 0x04
  463. #define TCP_ACK 0x10
  464. /* Use platform specific GetError to write to tracfile if tracing */
  465. static void Trace(int idx)
  466. {
  467. if (TraceOn) {
  468. char myBuffer[MAX_ERROR_LEN];
  469. GetError(idx, myBuffer);
  470. fprintf(TraceFile, "\t%s\n", myBuffer);
  471. #ifdef DEBUG_SNIFFER
  472. fprintf(stderr, "\t%s\n", myBuffer);
  473. #endif
  474. }
  475. }
  476. /* Show TimeStamp for beginning of packet Trace */
  477. static void TraceHeader(void)
  478. {
  479. if (TraceOn) {
  480. time_t ticks = time(NULL);
  481. fprintf(TraceFile, "\n%s", ctime(&ticks));
  482. }
  483. }
  484. /* Show Set Server info for Trace */
  485. static void TraceSetServer(const char* srv, int port, const char* keyFile)
  486. {
  487. if (TraceOn) {
  488. fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
  489. fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
  490. keyFile);
  491. }
  492. }
  493. /* Trace got packet number */
  494. static void TracePacket(void)
  495. {
  496. if (TraceOn) {
  497. static word32 packetNumber = 0;
  498. fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n",
  499. ++packetNumber);
  500. }
  501. }
  502. /* Convert network byte order address into human readable */
  503. static char* IpToS(word32 addr, char* str)
  504. {
  505. byte* p = (byte*)&addr;
  506. SNPRINTF(str, TRACE_MSG_SZ, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  507. return str;
  508. }
  509. /* Show destination and source address from Ip Hdr for packet Trace */
  510. static void TraceIP(IpHdr* iphdr)
  511. {
  512. if (TraceOn) {
  513. char src[TRACE_MSG_SZ];
  514. char dst[TRACE_MSG_SZ];
  515. fprintf(TraceFile, "\tdst:%s src:%s\n", IpToS(iphdr->dst, dst),
  516. IpToS(iphdr->src, src));
  517. }
  518. }
  519. /* Show destination and source port from Tcp Hdr for packet Trace */
  520. static void TraceTcp(TcpHdr* tcphdr)
  521. {
  522. if (TraceOn) {
  523. fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort),
  524. ntohs(tcphdr->srcPort));
  525. }
  526. }
  527. /* Show sequence and payload length for Trace */
  528. static void TraceSequence(word32 seq, int len)
  529. {
  530. if (TraceOn) {
  531. fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
  532. }
  533. }
  534. /* Show sequence and payload length for Trace */
  535. static void TraceAck(word32 ack, word32 expected)
  536. {
  537. if (TraceOn) {
  538. fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected);
  539. }
  540. }
  541. /* Show relative expected and relative received sequences */
  542. static void TraceRelativeSequence(word32 expected, word32 got)
  543. {
  544. if (TraceOn) {
  545. fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
  546. expected, got);
  547. }
  548. }
  549. /* Show server sequence startup from SYN */
  550. static void TraceServerSyn(word32 seq)
  551. {
  552. if (TraceOn) {
  553. fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
  554. }
  555. }
  556. /* Show client sequence startup from SYN */
  557. static void TraceClientSyn(word32 seq)
  558. {
  559. if (TraceOn) {
  560. fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
  561. }
  562. }
  563. /* Show client FIN capture */
  564. static void TraceClientFin(word32 finSeq, word32 relSeq)
  565. {
  566. if (TraceOn) {
  567. fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
  568. finSeq, relSeq);
  569. }
  570. }
  571. /* Show server FIN capture */
  572. static void TraceServerFin(word32 finSeq, word32 relSeq)
  573. {
  574. if (TraceOn) {
  575. fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
  576. finSeq, relSeq);
  577. }
  578. }
  579. /* Show number of SSL data bytes decoded, could be 0 (ok) */
  580. static void TraceGotData(int bytes)
  581. {
  582. if (TraceOn) {
  583. fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
  584. }
  585. }
  586. /* Show bytes added to old SSL App data */
  587. static void TraceAddedData(int newBytes, int existingBytes)
  588. {
  589. if (TraceOn) {
  590. fprintf(TraceFile,
  591. "\t%d bytes added to %d exisiting bytes in User Buffer\n",
  592. newBytes, existingBytes);
  593. }
  594. }
  595. /* Show Stale Session */
  596. static void TraceStaleSession(void)
  597. {
  598. if (TraceOn) {
  599. fprintf(TraceFile, "\tFound a stale session\n");
  600. }
  601. }
  602. /* Show Finding Stale Sessions */
  603. static void TraceFindingStale(void)
  604. {
  605. if (TraceOn) {
  606. fprintf(TraceFile, "\tTrying to find Stale Sessions\n");
  607. }
  608. }
  609. /* Show Removed Session */
  610. static void TraceRemovedSession(void)
  611. {
  612. if (TraceOn) {
  613. fprintf(TraceFile, "\tRemoved it\n");
  614. }
  615. }
  616. /* Set user error string */
  617. static void SetError(int idx, char* error, SnifferSession* session, int fatal)
  618. {
  619. GetError(idx, error);
  620. Trace(idx);
  621. if (session && fatal == FATAL_ERROR_STATE)
  622. session->flags.fatalError = 1;
  623. }
  624. /* See if this IPV4 network order address has been registered */
  625. /* return 1 is true, 0 is false */
  626. static int IsServerRegistered(word32 addr)
  627. {
  628. int ret = 0; /* false */
  629. SnifferServer* sniffer;
  630. LockMutex(&ServerListMutex);
  631. sniffer = ServerList;
  632. while (sniffer) {
  633. if (sniffer->server == addr) {
  634. ret = 1;
  635. break;
  636. }
  637. sniffer = sniffer->next;
  638. }
  639. UnLockMutex(&ServerListMutex);
  640. return ret;
  641. }
  642. /* See if this port has been registered to watch */
  643. /* return 1 is true, 0 is false */
  644. static int IsPortRegistered(word32 port)
  645. {
  646. int ret = 0; /* false */
  647. SnifferServer* sniffer;
  648. LockMutex(&ServerListMutex);
  649. sniffer = ServerList;
  650. while (sniffer) {
  651. if (sniffer->port == (int)port) {
  652. ret = 1;
  653. break;
  654. }
  655. sniffer = sniffer->next;
  656. }
  657. UnLockMutex(&ServerListMutex);
  658. return ret;
  659. }
  660. /* Get SnifferServer from IP and Port */
  661. static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
  662. {
  663. SnifferServer* sniffer;
  664. LockMutex(&ServerListMutex);
  665. sniffer = ServerList;
  666. while (sniffer) {
  667. if (sniffer->port == tcpInfo->srcPort && sniffer->server == ipInfo->src)
  668. break;
  669. if (sniffer->port == tcpInfo->dstPort && sniffer->server == ipInfo->dst)
  670. break;
  671. sniffer = sniffer->next;
  672. }
  673. UnLockMutex(&ServerListMutex);
  674. return sniffer;
  675. }
  676. /* Hash the Session Info, return hash row */
  677. static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
  678. {
  679. word32 hash = ipInfo->src * ipInfo->dst;
  680. hash *= tcpInfo->srcPort * tcpInfo->dstPort;
  681. return hash % HASH_SIZE;
  682. }
  683. /* Get Exisiting SnifferSession from IP and Port */
  684. static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
  685. {
  686. SnifferSession* session;
  687. word32 row = SessionHash(ipInfo, tcpInfo);
  688. assert(row <= HASH_SIZE);
  689. LockMutex(&SessionMutex);
  690. session = SessionTable[row];
  691. while (session) {
  692. if (session->server == ipInfo->src && session->client == ipInfo->dst &&
  693. session->srvPort == tcpInfo->srcPort &&
  694. session->cliPort == tcpInfo->dstPort)
  695. break;
  696. if (session->client == ipInfo->src && session->server == ipInfo->dst &&
  697. session->cliPort == tcpInfo->srcPort &&
  698. session->srvPort == tcpInfo->dstPort)
  699. break;
  700. session = session->next;
  701. }
  702. UnLockMutex(&SessionMutex);
  703. /* determine side */
  704. if (session) {
  705. if (ipInfo->dst == session->context->server &&
  706. tcpInfo->dstPort == session->context->port)
  707. session->flags.side = SERVER_END;
  708. else
  709. session->flags.side = CLIENT_END;
  710. }
  711. return session;
  712. }
  713. /* Sets the private key for a specific server and port */
  714. /* returns 0 on success, -1 on error */
  715. int ssl_SetPrivateKey(const char* serverAddress, int port, const char* keyFile,
  716. int typeKey, const char* password, char* error)
  717. {
  718. int ret;
  719. int type = (typeKey == FILETYPE_PEM) ? SSL_FILETYPE_PEM :
  720. SSL_FILETYPE_ASN1;
  721. SnifferServer* sniffer;
  722. TraceHeader();
  723. TraceSetServer(serverAddress, port, keyFile);
  724. sniffer = (SnifferServer*)malloc(sizeof(SnifferServer));
  725. if (sniffer == NULL) {
  726. SetError(MEMORY_STR, error, NULL, 0);
  727. return -1;
  728. }
  729. InitSnifferServer(sniffer);
  730. XSTRNCPY(sniffer->address, serverAddress, MAX_SERVER_ADDRESS);
  731. sniffer->server = inet_addr(sniffer->address);
  732. sniffer->port = port;
  733. /* start in client mode since SSL_new needs a cert for server */
  734. sniffer->ctx = SSL_CTX_new(SSLv3_client_method());
  735. if (!sniffer->ctx) {
  736. SetError(MEMORY_STR, error, NULL, 0);
  737. FreeSnifferServer(sniffer);
  738. return -1;
  739. }
  740. if (password){
  741. SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
  742. SSL_CTX_set_default_passwd_cb_userdata(sniffer->ctx, (void*)password);
  743. }
  744. ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
  745. if (ret != SSL_SUCCESS) {
  746. SetError(KEY_FILE_STR, error, NULL, 0);
  747. FreeSnifferServer(sniffer);
  748. return -1;
  749. }
  750. Trace(NEW_SERVER_STR);
  751. LockMutex(&ServerListMutex);
  752. sniffer->next = ServerList;
  753. ServerList = sniffer;
  754. UnLockMutex(&ServerListMutex);
  755. return 0;
  756. }
  757. /* Check IP Header for IPV4, TCP, and a registered server address */
  758. /* returns 0 on success, -1 on error */
  759. static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, char* error)
  760. {
  761. int version = IP_V(iphdr);
  762. TraceIP(iphdr);
  763. Trace(IP_CHECK_STR);
  764. if (version != IPV4) {
  765. SetError(BAD_IPVER_STR, error, NULL, 0);
  766. return -1;
  767. }
  768. if (iphdr->protocol != TCP_PROTOCOL) {
  769. SetError(BAD_PROTO_STR, error, NULL, 0);
  770. return -1;
  771. }
  772. if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
  773. SetError(SERVER_NOT_REG_STR, error, NULL, 0);
  774. return -1;
  775. }
  776. info->length = IP_HL(iphdr);
  777. info->total = ntohs(iphdr->length);
  778. info->src = iphdr->src;
  779. info->dst = iphdr->dst;
  780. return 0;
  781. }
  782. /* Check TCP Header for a registered port */
  783. /* returns 0 on success, -1 on error */
  784. static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
  785. {
  786. TraceTcp(tcphdr);
  787. Trace(TCP_CHECK_STR);
  788. info->srcPort = ntohs(tcphdr->srcPort);
  789. info->dstPort = ntohs(tcphdr->dstPort);
  790. info->length = TCP_LEN(tcphdr);
  791. info->sequence = ntohl(tcphdr->sequence);
  792. info->fin = tcphdr->flags & TCP_FIN;
  793. info->rst = tcphdr->flags & TCP_RST;
  794. info->syn = tcphdr->flags & TCP_SYN;
  795. info->ack = tcphdr->flags & TCP_ACK;
  796. if (info->ack)
  797. info->ackNumber = ntohl(tcphdr->ack);
  798. if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
  799. SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
  800. return -1;
  801. }
  802. return 0;
  803. }
  804. /* Decode Record Layer Header */
  805. static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
  806. {
  807. XMEMCPY(rh, input, RECORD_HEADER_SZ);
  808. *size = (rh->length[0] << 8) | rh->length[1];
  809. if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
  810. return LENGTH_ERROR;
  811. return 0;
  812. }
  813. /* Process Client Key Exchange, RSA only */
  814. static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
  815. SnifferSession* session, char* error)
  816. {
  817. word32 idx = 0;
  818. RsaKey key;
  819. int ret;
  820. InitRsaKey(&key, 0);
  821. ret = RsaPrivateKeyDecode(session->context->ctx->privateKey.buffer,
  822. &idx, &key, session->context->ctx->privateKey.length);
  823. if (ret == 0) {
  824. int length = RsaEncryptSize(&key);
  825. if (IsTLS(session->sslServer))
  826. input += 2; /* tls pre length */
  827. if (length > *sslBytes) {
  828. SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
  829. FreeRsaKey(&key);
  830. return -1;
  831. }
  832. ret = RsaPrivateDecrypt(input, length,
  833. session->sslServer->arrays->preMasterSecret,SECRET_LEN, &key);
  834. if (ret != SECRET_LEN) {
  835. SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
  836. FreeRsaKey(&key);
  837. return -1;
  838. }
  839. ret = 0; /* not in error state */
  840. session->sslServer->arrays->preMasterSz = SECRET_LEN;
  841. /* store for client side as well */
  842. XMEMCPY(session->sslClient->arrays->preMasterSecret,
  843. session->sslServer->arrays->preMasterSecret, SECRET_LEN);
  844. session->sslClient->arrays->preMasterSz = SECRET_LEN;
  845. #ifdef SHOW_SECRETS
  846. {
  847. int i;
  848. printf("pre master secret: ");
  849. for (i = 0; i < SECRET_LEN; i++)
  850. printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
  851. printf("\n");
  852. }
  853. #endif
  854. }
  855. else {
  856. SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
  857. FreeRsaKey(&key);
  858. return -1;
  859. }
  860. if (SetCipherSpecs(session->sslServer) != 0) {
  861. SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
  862. FreeRsaKey(&key);
  863. return -1;
  864. }
  865. if (SetCipherSpecs(session->sslClient) != 0) {
  866. SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
  867. FreeRsaKey(&key);
  868. return -1;
  869. }
  870. MakeMasterSecret(session->sslServer);
  871. MakeMasterSecret(session->sslClient);
  872. #ifdef SHOW_SECRETS
  873. {
  874. int i;
  875. printf("server master secret: ");
  876. for (i = 0; i < SECRET_LEN; i++)
  877. printf("%02x", session->sslServer->arrays->masterSecret[i]);
  878. printf("\n");
  879. printf("client master secret: ");
  880. for (i = 0; i < SECRET_LEN; i++)
  881. printf("%02x", session->sslClient->arrays->masterSecret[i]);
  882. printf("\n");
  883. printf("server suite = %d\n", session->sslServer->options.cipherSuite);
  884. printf("client suite = %d\n", session->sslClient->options.cipherSuite);
  885. }
  886. #endif
  887. FreeRsaKey(&key);
  888. return ret;
  889. }
  890. /* Process Session Ticket */
  891. static int ProcessSessionTicket(const byte* input, int* sslBytes,
  892. SnifferSession* session, char* error)
  893. {
  894. word16 len;
  895. /* make sure can read through hint and len */
  896. if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) {
  897. SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
  898. return -1;
  899. }
  900. input += TICKET_HINT_LEN; /* skip over hint */
  901. *sslBytes -= TICKET_HINT_LEN;
  902. len = (input[0] << 8) | input[1];
  903. input += LENGTH_SZ;
  904. *sslBytes -= LENGTH_SZ;
  905. /* make sure can read through ticket */
  906. if (len > *sslBytes || len < ID_LEN) {
  907. SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
  908. return -1;
  909. }
  910. /* store session with macID as sessionID */
  911. session->sslServer->options.haveSessionId = 1;
  912. XMEMCPY(session->sslServer->arrays->sessionID, input + len - ID_LEN,ID_LEN);
  913. return 0;
  914. }
  915. /* Process Server Hello */
  916. static int ProcessServerHello(const byte* input, int* sslBytes,
  917. SnifferSession* session, char* error)
  918. {
  919. ProtocolVersion pv;
  920. byte b;
  921. int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
  922. int doResume = 0;
  923. /* make sure we didn't miss ClientHello */
  924. if (session->flags.clientHello == 0) {
  925. SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE);
  926. return -1;
  927. }
  928. /* make sure can read through session len */
  929. if (toRead > *sslBytes) {
  930. SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  931. return -1;
  932. }
  933. XMEMCPY(&pv, input, VERSION_SZ);
  934. input += VERSION_SZ;
  935. *sslBytes -= VERSION_SZ;
  936. session->sslServer->version = pv;
  937. session->sslClient->version = pv;
  938. XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN);
  939. XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN);
  940. input += RAN_LEN;
  941. *sslBytes -= RAN_LEN;
  942. b = *input++;
  943. *sslBytes -= 1;
  944. /* make sure can read through compression */
  945. if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
  946. SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  947. return -1;
  948. }
  949. if (b) {
  950. XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN);
  951. session->sslServer->options.haveSessionId = 1;
  952. }
  953. input += b;
  954. *sslBytes -= b;
  955. /* cipher suite */
  956. (void)*input++; /* eat first byte, always 0 */
  957. b = *input++;
  958. session->sslServer->options.cipherSuite = b;
  959. session->sslClient->options.cipherSuite = b;
  960. *sslBytes -= SUITE_LEN;
  961. /* compression */
  962. b = *input++;
  963. *sslBytes -= ENUM_LEN;
  964. if (b) {
  965. SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
  966. return -1;
  967. }
  968. if (session->sslServer->options.haveSessionId &&
  969. XMEMCMP(session->sslServer->arrays->sessionID,
  970. session->sslClient->arrays->sessionID, ID_LEN) == 0)
  971. doResume = 1;
  972. else if (session->sslClient->options.haveSessionId == 0 &&
  973. session->sslServer->options.haveSessionId == 0 &&
  974. session->ticketID)
  975. doResume = 1;
  976. if (session->ticketID && doResume) {
  977. /* use ticketID to retrieve from session */
  978. XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN);
  979. }
  980. if (doResume ) {
  981. int ret = 0;
  982. SSL_SESSION* resume = GetSession(session->sslServer,
  983. session->sslServer->arrays->masterSecret);
  984. if (resume == NULL) {
  985. SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
  986. return -1;
  987. }
  988. /* make sure client has master secret too */
  989. XMEMCPY(session->sslClient->arrays->masterSecret,
  990. session->sslServer->arrays->masterSecret, SECRET_LEN);
  991. session->flags.resuming = 1;
  992. Trace(SERVER_DID_RESUMPTION_STR);
  993. if (SetCipherSpecs(session->sslServer) != 0) {
  994. SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
  995. return -1;
  996. }
  997. if (SetCipherSpecs(session->sslClient) != 0) {
  998. SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
  999. return -1;
  1000. }
  1001. if (session->sslServer->options.tls) {
  1002. ret = DeriveTlsKeys(session->sslServer);
  1003. ret += DeriveTlsKeys(session->sslClient);
  1004. }
  1005. else {
  1006. ret = DeriveKeys(session->sslServer);
  1007. ret += DeriveKeys(session->sslClient);
  1008. }
  1009. if (ret != 0) {
  1010. SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
  1011. return -1;
  1012. }
  1013. }
  1014. #ifdef SHOW_SECRETS
  1015. {
  1016. int i;
  1017. printf("cipher suite = 0x%02x\n",
  1018. session->sslServer->options.cipherSuite);
  1019. printf("server random: ");
  1020. for (i = 0; i < RAN_LEN; i++)
  1021. printf("%02x", session->sslServer->arrays->serverRandom[i]);
  1022. printf("\n");
  1023. }
  1024. #endif
  1025. return 0;
  1026. }
  1027. /* Process normal Client Hello */
  1028. static int ProcessClientHello(const byte* input, int* sslBytes,
  1029. SnifferSession* session, char* error)
  1030. {
  1031. byte bLen;
  1032. word16 len;
  1033. int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
  1034. session->flags.clientHello = 1; /* don't process again */
  1035. /* make sure can read up to session len */
  1036. if (toRead > *sslBytes) {
  1037. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1038. return -1;
  1039. }
  1040. /* skip, get negotiated one from server hello */
  1041. input += VERSION_SZ;
  1042. *sslBytes -= VERSION_SZ;
  1043. XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN);
  1044. XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN);
  1045. input += RAN_LEN;
  1046. *sslBytes -= RAN_LEN;
  1047. /* store session in case trying to resume */
  1048. bLen = *input++;
  1049. *sslBytes -= ENUM_LEN;
  1050. if (bLen) {
  1051. if (ID_LEN > *sslBytes) {
  1052. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1053. return -1;
  1054. }
  1055. Trace(CLIENT_RESUME_TRY_STR);
  1056. XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN);
  1057. session->sslClient->options.haveSessionId = 1;
  1058. }
  1059. #ifdef SHOW_SECRETS
  1060. {
  1061. int i;
  1062. printf("client random: ");
  1063. for (i = 0; i < RAN_LEN; i++)
  1064. printf("%02x", session->sslServer->arrays->clientRandom[i]);
  1065. printf("\n");
  1066. }
  1067. #endif
  1068. input += bLen;
  1069. *sslBytes -= bLen;
  1070. /* skip cipher suites */
  1071. /* make sure can read len */
  1072. if (SUITE_LEN > *sslBytes) {
  1073. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1074. return -1;
  1075. }
  1076. len = (input[0] << 8) | input[1];
  1077. input += SUITE_LEN;
  1078. *sslBytes -= SUITE_LEN;
  1079. /* make sure can read suites + comp len */
  1080. if (len + ENUM_LEN > *sslBytes) {
  1081. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1082. return -1;
  1083. }
  1084. input += len;
  1085. *sslBytes -= len;
  1086. /* skip compression */
  1087. bLen = *input++;
  1088. *sslBytes -= ENUM_LEN;
  1089. /* make sure can read len */
  1090. if (bLen > *sslBytes) {
  1091. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1092. return -1;
  1093. }
  1094. input += bLen;
  1095. *sslBytes -= bLen;
  1096. if (*sslBytes == 0) {
  1097. /* no extensions */
  1098. return 0;
  1099. }
  1100. /* skip extensions until session ticket */
  1101. /* make sure can read len */
  1102. if (SUITE_LEN > *sslBytes) {
  1103. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1104. return -1;
  1105. }
  1106. len = (input[0] << 8) | input[1];
  1107. input += SUITE_LEN;
  1108. *sslBytes -= SUITE_LEN;
  1109. /* make sure can read through all extensions */
  1110. if (len > *sslBytes) {
  1111. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1112. return -1;
  1113. }
  1114. while (len > EXT_TYPE_SZ + LENGTH_SZ) {
  1115. byte extType[EXT_TYPE_SZ];
  1116. word16 extLen;
  1117. extType[0] = input[0];
  1118. extType[1] = input[1];
  1119. input += EXT_TYPE_SZ;
  1120. *sslBytes -= EXT_TYPE_SZ;
  1121. extLen = (input[0] << 8) | input[1];
  1122. input += LENGTH_SZ;
  1123. *sslBytes -= LENGTH_SZ;
  1124. /* make sure can read through individual extension */
  1125. if (extLen > *sslBytes) {
  1126. SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1127. return -1;
  1128. }
  1129. if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) {
  1130. /* make sure can read through ticket if there is a non blank one */
  1131. if (extLen && extLen < ID_LEN) {
  1132. SetError(CLIENT_HELLO_INPUT_STR, error, session,
  1133. FATAL_ERROR_STATE);
  1134. return -1;
  1135. }
  1136. if (extLen) {
  1137. if (session->ticketID == 0) {
  1138. session->ticketID = (byte*)malloc(ID_LEN);
  1139. if (session->ticketID == 0) {
  1140. SetError(MEMORY_STR, error, session,
  1141. FATAL_ERROR_STATE);
  1142. return -1;
  1143. }
  1144. }
  1145. XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
  1146. }
  1147. }
  1148. input += extLen;
  1149. *sslBytes -= extLen;
  1150. len -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
  1151. }
  1152. return 0;
  1153. }
  1154. /* Process Finished */
  1155. static int ProcessFinished(const byte* input, int* sslBytes,
  1156. SnifferSession* session, char* error)
  1157. {
  1158. SSL* ssl;
  1159. word32 inOutIdx = 0;
  1160. int ret;
  1161. if (session->flags.side == SERVER_END)
  1162. ssl = session->sslServer;
  1163. else
  1164. ssl = session->sslClient;
  1165. ret = DoFinished(ssl, input, &inOutIdx, SNIFF);
  1166. *sslBytes -= (int)inOutIdx;
  1167. if (ret < 0) {
  1168. SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
  1169. return ret;
  1170. }
  1171. if (ret == 0 && session->flags.cached == 0) {
  1172. if (session->sslServer->options.haveSessionId) {
  1173. CYASSL_SESSION* sess = GetSession(session->sslServer, NULL);
  1174. if (sess == NULL)
  1175. AddSession(session->sslServer); /* don't re add */
  1176. session->flags.cached = 1;
  1177. }
  1178. }
  1179. FreeHandshakeResources(ssl);
  1180. return ret;
  1181. }
  1182. /* Process HandShake input */
  1183. static int DoHandShake(const byte* input, int* sslBytes,
  1184. SnifferSession* session, char* error)
  1185. {
  1186. byte type;
  1187. int size;
  1188. int ret = 0;
  1189. if (*sslBytes < HANDSHAKE_HEADER_SZ) {
  1190. SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1191. return -1;
  1192. }
  1193. type = input[0];
  1194. size = (input[1] << 16) | (input[2] << 8) | input[3];
  1195. input += HANDSHAKE_HEADER_SZ;
  1196. *sslBytes -= HANDSHAKE_HEADER_SZ;
  1197. if (*sslBytes < size) {
  1198. SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1199. return -1;
  1200. }
  1201. switch (type) {
  1202. case hello_verify_request:
  1203. Trace(GOT_HELLO_VERIFY_STR);
  1204. break;
  1205. case hello_request:
  1206. Trace(GOT_HELLO_REQUEST_STR);
  1207. break;
  1208. case session_ticket:
  1209. Trace(GOT_SESSION_TICKET_STR);
  1210. ret = ProcessSessionTicket(input, sslBytes, session, error);
  1211. break;
  1212. case server_hello:
  1213. Trace(GOT_SERVER_HELLO_STR);
  1214. ret = ProcessServerHello(input, sslBytes, session, error);
  1215. break;
  1216. case certificate_request:
  1217. Trace(GOT_CERT_REQ_STR);
  1218. break;
  1219. case server_key_exchange:
  1220. Trace(GOT_SERVER_KEY_EX_STR);
  1221. /* can't know temp key passively */
  1222. SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
  1223. ret = -1;
  1224. break;
  1225. case certificate:
  1226. Trace(GOT_CERT_STR);
  1227. break;
  1228. case server_hello_done:
  1229. Trace(GOT_SERVER_HELLO_DONE_STR);
  1230. break;
  1231. case finished:
  1232. Trace(GOT_FINISHED_STR);
  1233. ret = ProcessFinished(input, sslBytes, session, error);
  1234. break;
  1235. case client_hello:
  1236. Trace(GOT_CLIENT_HELLO_STR);
  1237. ret = ProcessClientHello(input, sslBytes, session, error);
  1238. break;
  1239. case client_key_exchange:
  1240. Trace(GOT_CLIENT_KEY_EX_STR);
  1241. ret = ProcessClientKeyExchange(input, sslBytes, session, error);
  1242. break;
  1243. case certificate_verify:
  1244. Trace(GOT_CERT_VER_STR);
  1245. break;
  1246. default:
  1247. SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
  1248. return -1;
  1249. }
  1250. return ret;
  1251. }
  1252. /* Decrypt input into plain output */
  1253. static void Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
  1254. {
  1255. switch (ssl->specs.bulk_cipher_algorithm) {
  1256. #ifdef BUILD_ARC4
  1257. case rc4:
  1258. Arc4Process(ssl->decrypt.arc4, output, input, sz);
  1259. break;
  1260. #endif
  1261. #ifdef BUILD_DES3
  1262. case triple_des:
  1263. Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz);
  1264. break;
  1265. #endif
  1266. #ifdef BUILD_AES
  1267. case aes:
  1268. AesCbcDecrypt(ssl->decrypt.aes, output, input, sz);
  1269. break;
  1270. #endif
  1271. #ifdef HAVE_HC128
  1272. case hc128:
  1273. Hc128_Process(ssl->decrypt.hc128, output, input, sz);
  1274. break;
  1275. #endif
  1276. #ifdef BUILD_RABBIT
  1277. case rabbit:
  1278. RabbitProcess(ssl->decrypt.rabbit, output, input, sz);
  1279. break;
  1280. #endif
  1281. default:
  1282. Trace(BAD_DECRYPT_TYPE);
  1283. break;
  1284. }
  1285. }
  1286. /* Decrypt input message into output, adjust output steam if needed */
  1287. static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz,
  1288. byte* output)
  1289. {
  1290. Decrypt(ssl, output, input, sz);
  1291. ssl->keys.encryptSz = sz;
  1292. if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
  1293. return output + ssl->specs.block_size; /* go past TLSv1.1 IV */
  1294. return output;
  1295. }
  1296. /* remove session from table, use rowHint if no info (means we have a lock) */
  1297. static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
  1298. TcpInfo* tcpInfo, word32 rowHint)
  1299. {
  1300. SnifferSession* previous = 0;
  1301. SnifferSession* current;
  1302. word32 row = rowHint;
  1303. int haveLock = 0;
  1304. if (ipInfo && tcpInfo)
  1305. row = SessionHash(ipInfo, tcpInfo);
  1306. else
  1307. haveLock = 1;
  1308. assert(row <= HASH_SIZE);
  1309. Trace(REMOVE_SESSION_STR);
  1310. if (!haveLock)
  1311. LockMutex(&SessionMutex);
  1312. current = SessionTable[row];
  1313. while (current) {
  1314. if (current == session) {
  1315. if (previous)
  1316. previous->next = current->next;
  1317. else
  1318. SessionTable[row] = current->next;
  1319. FreeSnifferSession(session);
  1320. TraceRemovedSession();
  1321. break;
  1322. }
  1323. previous = current;
  1324. current = current->next;
  1325. }
  1326. if (!haveLock)
  1327. UnLockMutex(&SessionMutex);
  1328. }
  1329. /* Remove stale sessions from the Session Table, have a lock */
  1330. static void RemoveStaleSessions(void)
  1331. {
  1332. word32 i;
  1333. SnifferSession* session;
  1334. for (i = 0; i < HASH_SIZE; i++) {
  1335. session = SessionTable[i];
  1336. while (session) {
  1337. SnifferSession* next = session->next;
  1338. if (time(NULL) >= session->bornOn + SNIFFER_TIMEOUT) {
  1339. TraceStaleSession();
  1340. RemoveSession(session, NULL, NULL, i);
  1341. }
  1342. session = next;
  1343. }
  1344. }
  1345. }
  1346. /* Create a new Sniffer Session */
  1347. static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
  1348. char* error)
  1349. {
  1350. SnifferSession* session = 0;
  1351. int row;
  1352. Trace(NEW_SESSION_STR);
  1353. /* create a new one */
  1354. session = (SnifferSession*)malloc(sizeof(SnifferSession));
  1355. if (session == NULL) {
  1356. SetError(MEMORY_STR, error, NULL, 0);
  1357. return 0;
  1358. }
  1359. InitSession(session);
  1360. session->server = ipInfo->dst;
  1361. session->client = ipInfo->src;
  1362. session->srvPort = tcpInfo->dstPort;
  1363. session->cliPort = tcpInfo->srcPort;
  1364. session->cliSeqStart = tcpInfo->sequence;
  1365. session->cliExpected = 1; /* relative */
  1366. session->bornOn = time(NULL);
  1367. session->context = GetSnifferServer(ipInfo, tcpInfo);
  1368. if (session->context == NULL) {
  1369. SetError(SERVER_NOT_REG_STR, error, NULL, 0);
  1370. free(session);
  1371. return 0;
  1372. }
  1373. session->sslServer = SSL_new(session->context->ctx);
  1374. if (session->sslServer == NULL) {
  1375. SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
  1376. free(session);
  1377. return 0;
  1378. }
  1379. session->sslClient = SSL_new(session->context->ctx);
  1380. if (session->sslClient == NULL) {
  1381. SSL_free(session->sslServer);
  1382. session->sslServer = 0;
  1383. SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
  1384. free(session);
  1385. return 0;
  1386. }
  1387. /* put server back into server mode */
  1388. session->sslServer->options.side = SERVER_END;
  1389. row = SessionHash(ipInfo, tcpInfo);
  1390. /* add it to the session table */
  1391. LockMutex(&SessionMutex);
  1392. session->next = SessionTable[row];
  1393. SessionTable[row] = session;
  1394. SessionCount++;
  1395. if ( (SessionCount % HASH_SIZE) == 0) {
  1396. TraceFindingStale();
  1397. RemoveStaleSessions();
  1398. }
  1399. UnLockMutex(&SessionMutex);
  1400. /* determine headed side */
  1401. if (ipInfo->dst == session->context->server &&
  1402. tcpInfo->dstPort == session->context->port)
  1403. session->flags.side = SERVER_END;
  1404. else
  1405. session->flags.side = CLIENT_END;
  1406. return session;
  1407. }
  1408. /* Process Old Client Hello Input */
  1409. static int DoOldHello(SnifferSession* session, const byte* sslFrame,
  1410. int* rhSize, int* sslBytes, char* error)
  1411. {
  1412. const byte* input = sslFrame;
  1413. byte b0, b1;
  1414. word32 idx = 0;
  1415. int ret;
  1416. Trace(GOT_OLD_CLIENT_HELLO_STR);
  1417. session->flags.clientHello = 1; /* don't process again */
  1418. b0 = *input++;
  1419. b1 = *input++;
  1420. *sslBytes -= 2;
  1421. *rhSize = ((b0 & 0x7f) << 8) | b1;
  1422. if (*rhSize > *sslBytes) {
  1423. SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
  1424. return -1;
  1425. }
  1426. ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
  1427. *rhSize);
  1428. if (ret < 0) {
  1429. SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
  1430. return -1;
  1431. }
  1432. Trace(OLD_CLIENT_OK_STR);
  1433. XMEMCPY(session->sslClient->arrays->clientRandom,
  1434. session->sslServer->arrays->clientRandom, RAN_LEN);
  1435. *sslBytes -= *rhSize;
  1436. return 0;
  1437. }
  1438. #if 0
  1439. /* Calculate the TCP checksum, see RFC 1071 */
  1440. /* return 0 for success, -1 on error */
  1441. /* can be called from decode() with
  1442. TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
  1443. could also add a 64bit version if type available and using this
  1444. */
  1445. int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
  1446. const byte* packet)
  1447. {
  1448. TcpPseudoHdr pseudo;
  1449. int count = PSEUDO_HDR_SZ;
  1450. const word16* data = (word16*)&pseudo;
  1451. word32 sum = 0;
  1452. word16 checksum;
  1453. pseudo.src = ipInfo->src;
  1454. pseudo.dst = ipInfo->dst;
  1455. pseudo.rsv = 0;
  1456. pseudo.protocol = TCP_PROTO;
  1457. pseudo.legnth = htons(tcpInfo->length + dataLen);

Large files files are truncated, but you can click here to view the full file