libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
crypto.h
1 /*
2  * Copyright (c) 2016, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include "config.h"
31 
32 #if !defined(TINS_CRYPTO_H) && defined(TINS_HAVE_DOT11)
33 #define TINS_CRYPTO_H
34 
35 #include <map>
36 #include <string>
37 #include <algorithm>
38 #include <vector>
39 #ifdef TINS_HAVE_WPA2_CALLBACKS
40  #include <functional>
41 #endif // TINS_HAVE_WPA2_CALLBACKS
42 #include "utils.h"
43 #include "snap.h"
44 #include "rawpdu.h"
45 #include "macros.h"
46 #include "handshake_capturer.h"
47 
48 namespace Tins {
49 
50 class PDU;
51 class Dot11;
52 class Dot11Data;
53 
54 namespace Crypto {
55 
56 struct RC4Key;
57 
58 #ifdef TINS_HAVE_WPA2_DECRYPTION
59 namespace WPA2 {
60 
64 class TINS_API SessionKeys {
65 public:
69  static const size_t PMK_SIZE;
70 
74  static const size_t PTK_SIZE;
75 
79  typedef std::vector<uint8_t> ptk_type;
80 
84  typedef std::vector<uint8_t> pmk_type;
85 
89  SessionKeys();
90 
98  SessionKeys(const ptk_type& ptk, bool is_ccmp);
99 
108  SessionKeys(const RSNHandshake& hs, const pmk_type& pmk);
109 
118  SNAP* decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
119 
124  const ptk_type& get_ptk() const;
125 
130  bool uses_ccmp() const;
131 private:
132  SNAP* ccmp_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
133  SNAP* tkip_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
134  RC4Key generate_rc4_key(const Dot11Data& dot11, const RawPDU& raw) const;
135 
136  ptk_type ptk_;
137  bool is_ccmp_;
138 };
139 
147 class TINS_API SupplicantData {
148 public:
153 
159  SupplicantData(const std::string& psk, const std::string& ssid);
160 
165  const pmk_type& pmk() const;
166 
171  const std::string& ssid() const;
172 private:
173  pmk_type pmk_;
174  std::string ssid_;
175 };
176 
177 } // WPA2
178 #endif // TINS_HAVE_WPA2_DECRYPTION
179 
183 struct RC4Key {
184  static const size_t data_size = 256;
185 
192  template<typename ForwardIterator>
193  RC4Key(ForwardIterator start, ForwardIterator end);
194 
198  uint8_t data[data_size];
199 };
200 
204 class TINS_API WEPDecrypter {
205 public:
206  typedef HWAddress<6> address_type;
207 
211  WEPDecrypter();
212 
220  void add_password(const address_type& addr, const std::string& password);
221 
227  void remove_password(const address_type& addr);
228 
243  bool decrypt(PDU& pdu);
244 private:
245  typedef std::map<address_type, std::string> passwords_type;
246 
247  PDU* decrypt(RawPDU& raw, const std::string& password);
248 
249  passwords_type passwords_;
250  std::vector<uint8_t> key_buffer_;
251 };
252 
253 #ifdef TINS_HAVE_WPA2_DECRYPTION
254 
260 class TINS_API WPA2Decrypter {
261 public:
262  /*
263  * \brief The type used to store Dot11 addresses.
264  */
265  typedef HWAddress<6> address_type;
266 
276  typedef std::pair<address_type, address_type> addr_pair;
277 
286  typedef std::map<addr_pair, WPA2::SessionKeys> keys_map;
287 
288  #ifdef TINS_HAVE_WPA2_CALLBACKS
289 
297  typedef std::function<void(const std::string&,
299 
308  typedef std::function<void(const std::string&,
309  const address_type&,
311 
312  #endif // TINS_HAVE_WPA2_CALLBACKS
313 
332  void add_ap_data(const std::string& psk, const std::string& ssid);
333 
348  void add_ap_data(const std::string& psk,
349  const std::string& ssid,
350  const address_type& addr);
351 
372  void add_decryption_keys(const addr_pair& addresses,
373  const WPA2::SessionKeys& session_keys);
374 
390  bool decrypt(PDU& pdu);
391 
392  #ifdef TINS_HAVE_WPA2_CALLBACKS
393 
401  void handshake_captured_callback(const handshake_captured_callback_type& callback);
402 
412  void ap_found_callback(const ap_found_callback_type& callback);
413 
414  #endif // TINS_HAVE_WPA2_CALLBACKS
415 
424  const keys_map& get_keys() const;
425 private:
426  typedef std::map<std::string, WPA2::SupplicantData> pmks_map;
427  typedef std::map<address_type, WPA2::SupplicantData> bssids_map;
428 
429  void try_add_keys(const Dot11Data& dot11, const RSNHandshake& hs);
430  addr_pair make_addr_pair(const address_type& addr1, const address_type& addr2) {
431  return (addr1 < addr2) ?
432  std::make_pair(addr1, addr2) :
433  std::make_pair(addr2, addr1);
434  }
435  addr_pair extract_addr_pair(const Dot11Data& dot11);
436  addr_pair extract_addr_pair_dst(const Dot11Data& dot11);
437  bssids_map::const_iterator find_ap(const Dot11Data& dot11);
438  void add_access_point(const std::string& ssid, const address_type& addr);
439 
440  RSNHandshakeCapturer capturer_;
441  pmks_map pmks_;
442  bssids_map aps_;
443  keys_map keys_;
444  #ifdef TINS_HAVE_WPA2_CALLBACKS
445  handshake_captured_callback_type handshake_captured_callback_;
446  ap_found_callback_type ap_found_callback_;
447  #endif // TINS_HAVE_WPA2_CALLBACKS
448 };
449 #endif // TINS_HAVE_WPA2_DECRYPTION
450 
459 template<typename Functor, typename Decrypter>
461 public:
465  typedef Functor functor_type;
466 
470  typedef Decrypter decrypter_type;
471 
479  DecrypterProxy(const functor_type& func,
480  const decrypter_type& decr = decrypter_type());
481 
486 
490  const decrypter_type& decrypter() const;
491 
496  bool operator() (PDU& pdu);
497 private:
498  Functor functor_;
499  decrypter_type decrypter_;
500 };
501 
513 template<typename ForwardIterator, typename OutputIterator>
514 void rc4(ForwardIterator start, ForwardIterator end, RC4Key& key, OutputIterator output);
515 
523 template<typename Functor>
524 DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor);
525 
526 #ifdef TINS_HAVE_WPA2_DECRYPTION
527 
534 template<typename Functor>
535 DecrypterProxy<Functor, WPA2Decrypter> make_wpa2_decrypter_proxy(const Functor& functor) {
537 }
538 #endif // TINS_HAVE_WPA2_DECRYPTION
539 
540 // Implementation section
541 
542 // DecrypterProxy
543 
544 template<typename Functor, typename Decrypter>
546  const decrypter_type& decr)
547 : functor_(func), decrypter_(decr) {
548 
549 }
550 
551 template<typename Functor, typename Decrypter>
554  return decrypter_;
555 }
556 
557 template<typename Functor, typename Decrypter>
560  return decrypter_;
561 }
562 
563 template<typename Functor, typename Decrypter>
565  return decrypter_.decrypt(pdu) ? functor_(pdu) : true;
566 }
567 
568 template<typename Functor>
569 DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor) {
571 }
572 
573 // RC4 stuff
574 
575 template<typename ForwardIterator>
576 RC4Key::RC4Key(ForwardIterator start, ForwardIterator end) {
577  for (size_t i = 0; i < data_size; ++i) {
578  data[i] = static_cast<uint8_t>(i);
579  }
580  size_t j = 0;
581  ForwardIterator iter = start;
582  for (size_t i = 0; i < data_size; ++i) {
583  j = (j + data[i] + *iter++) % 256;
584  if(iter == end) {
585  iter = start;
586  }
587  std::swap(data[i], data[j]);
588  }
589 }
590 
591 template<typename ForwardIterator, typename OutputIterator>
592 void rc4(ForwardIterator start, ForwardIterator end, RC4Key& key, OutputIterator output) {
593  size_t i = 0, j = 0;
594  while (start != end) {
595  i = (i + 1) % RC4Key::data_size;
596  j = (j + key.data[i]) % RC4Key::data_size;
597  std::swap(key.data[i], key.data[j]);
598  *output++ = *start++ ^ key.data[(key.data[i] + key.data[j]) % RC4Key::data_size];
599  }
600 }
601 
602 } // Crypto
603 } // Tins
604 
605 #endif // TINS_CRYPTO_H
RC4Key(ForwardIterator start, ForwardIterator end)
Initializes the key using the provided iterator range.
Definition: crypto.h:576
decrypter_type & decrypter()
Retrieves a reference to the decrypter object.
Definition: crypto.h:553
Class that represents the keys used to decrypt a session.
Definition: crypto.h:64
Definition: handshake_capturer.h:109
DecrypterProxy(const functor_type &func, const decrypter_type &decr=decrypter_type())
Constructs an object from a functor and a decrypter.
Definition: crypto.h:545
std::function< void(const std::string &, const address_type &)> ap_found_callback_type
The type used to store the callback type used when a new access point is found.
Definition: crypto.h:298
Generic EAPOL handshake.
Definition: handshake_capturer.h:51
Decrypter decrypter_type
Definition: crypto.h:470
std::vector< uint8_t > pmk_type
Definition: crypto.h:84
Represents an IEEE 802.11 data frame.
Definition: dot11_data.h:43
RC4 Key abstraction.
Definition: crypto.h:183
bool operator()(PDU &pdu)
The operator() which decrypts packets and forwards them to the functor.
Definition: crypto.h:564
Decrypts WEP-encrypted traffic.
Definition: crypto.h:204
std::map< addr_pair, WPA2::SessionKeys > keys_map
Maps an address pair to the session keys.
Definition: crypto.h:286
Decrypts WPA2-encrypted traffic.
Definition: crypto.h:260
std::function< void(const std::string &, const address_type &, const address_type &)> handshake_captured_callback_type
Definition: crypto.h:310
Pluggable decrypter object which can be used to decrypt data on sniffing sessions.
Definition: crypto.h:460
std::pair< address_type, address_type > addr_pair
Represents a pair of mac addresses.
Definition: crypto.h:276
Functor functor_type
Definition: crypto.h:465
Represents a SNAP frame.
Definition: snap.h:49
Definition: rawpdu.h:64
static const size_t PMK_SIZE
Definition: crypto.h:69
std::vector< uint8_t > ptk_type
Definition: crypto.h:79
Base class for protocol data units.
Definition: pdu.h:108
SessionKeys::pmk_type pmk_type
Definition: crypto.h:152
static const size_t PTK_SIZE
Definition: crypto.h:74
Represents a WPA2 supplicant's data.
Definition: crypto.h:147
uint8_t data[data_size]
Definition: crypto.h:198