libtins  4.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
crypto.h
1 /*
2  * Copyright (c) 2017, 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 <tins/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 <vector>
38 #ifdef TINS_HAVE_WPA2_CALLBACKS
39  #include <functional>
40 #endif // TINS_HAVE_WPA2_CALLBACKS
41 #include <tins/macros.h>
42 #include <tins/handshake_capturer.h>
43 
44 namespace Tins {
45 
46 class PDU;
47 class Dot11;
48 class Dot11Data;
49 class SNAP;
50 class RawPDU;
51 
52 namespace Crypto {
53 
54 #ifdef TINS_HAVE_WPA2_DECRYPTION
55 namespace WPA2 {
56 
60 class TINS_API SessionKeys {
61 public:
65  static const size_t PMK_SIZE;
66 
70  static const size_t PTK_SIZE;
71 
75  typedef std::vector<uint8_t> ptk_type;
76 
80  typedef std::vector<uint8_t> pmk_type;
81 
85  SessionKeys();
86 
94  SessionKeys(const ptk_type& ptk, bool is_ccmp);
95 
104  SessionKeys(const RSNHandshake& hs, const pmk_type& pmk);
105 
114  SNAP* decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
115 
120  const ptk_type& get_ptk() const;
121 
126  bool uses_ccmp() const;
127 private:
128  SNAP* ccmp_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
129  SNAP* tkip_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
130 
131  ptk_type ptk_;
132  bool is_ccmp_;
133 };
134 
142 class TINS_API SupplicantData {
143 public:
147  typedef SessionKeys::pmk_type pmk_type;
148 
154  SupplicantData(const std::string& psk, const std::string& ssid);
155 
160  const pmk_type& pmk() const;
161 
166  const std::string& ssid() const;
167 private:
168  pmk_type pmk_;
169  std::string ssid_;
170 };
171 
172 } // WPA2
173 #endif // TINS_HAVE_WPA2_DECRYPTION
174 
178 class TINS_API WEPDecrypter {
179 public:
180  typedef HWAddress<6> address_type;
181 
185  WEPDecrypter();
186 
194  void add_password(const address_type& addr, const std::string& password);
195 
201  void remove_password(const address_type& addr);
202 
217  bool decrypt(PDU& pdu);
218 private:
219  typedef std::map<address_type, std::string> passwords_type;
220 
221  PDU* decrypt(RawPDU& raw, const std::string& password);
222 
223  passwords_type passwords_;
224  std::vector<uint8_t> key_buffer_;
225 };
226 
227 #ifdef TINS_HAVE_WPA2_DECRYPTION
228 
234 class TINS_API WPA2Decrypter {
235 public:
236  /*
237  * \brief The type used to store Dot11 addresses.
238  */
239  typedef HWAddress<6> address_type;
240 
250  typedef std::pair<address_type, address_type> addr_pair;
251 
260  typedef std::map<addr_pair, WPA2::SessionKeys> keys_map;
261 
262  #ifdef TINS_HAVE_WPA2_CALLBACKS
263 
271  typedef std::function<void(const std::string&,
272  const address_type&)> ap_found_callback_type;
273 
282  typedef std::function<void(const std::string&,
283  const address_type&,
284  const address_type&)> handshake_captured_callback_type;
285 
286  #endif // TINS_HAVE_WPA2_CALLBACKS
287 
306  void add_ap_data(const std::string& psk, const std::string& ssid);
307 
322  void add_ap_data(const std::string& psk,
323  const std::string& ssid,
324  const address_type& addr);
325 
346  void add_decryption_keys(const addr_pair& addresses,
347  const WPA2::SessionKeys& session_keys);
348 
364  bool decrypt(PDU& pdu);
365 
366  #ifdef TINS_HAVE_WPA2_CALLBACKS
367 
375  void handshake_captured_callback(const handshake_captured_callback_type& callback);
376 
386  void ap_found_callback(const ap_found_callback_type& callback);
387 
388  #endif // TINS_HAVE_WPA2_CALLBACKS
389 
398  const keys_map& get_keys() const;
399 private:
400  typedef std::map<std::string, WPA2::SupplicantData> pmks_map;
401  typedef std::map<address_type, WPA2::SupplicantData> bssids_map;
402 
403  void try_add_keys(const Dot11Data& dot11, const RSNHandshake& hs);
404  addr_pair make_addr_pair(const address_type& addr1, const address_type& addr2) {
405  return (addr1 < addr2) ?
406  std::make_pair(addr1, addr2) :
407  std::make_pair(addr2, addr1);
408  }
409  addr_pair extract_addr_pair(const Dot11Data& dot11);
410  addr_pair extract_addr_pair_dst(const Dot11Data& dot11);
411  bssids_map::const_iterator find_ap(const Dot11Data& dot11);
412  void add_access_point(const std::string& ssid, const address_type& addr);
413 
414  RSNHandshakeCapturer capturer_;
415  pmks_map pmks_;
416  bssids_map aps_;
417  keys_map keys_;
418  #ifdef TINS_HAVE_WPA2_CALLBACKS
419  handshake_captured_callback_type handshake_captured_callback_;
420  ap_found_callback_type ap_found_callback_;
421  #endif // TINS_HAVE_WPA2_CALLBACKS
422 };
423 #endif // TINS_HAVE_WPA2_DECRYPTION
424 
433 template<typename Functor, typename Decrypter>
434 class DecrypterProxy {
435 public:
439  typedef Functor functor_type;
440 
444  typedef Decrypter decrypter_type;
445 
453  DecrypterProxy(const functor_type& func,
454  const decrypter_type& decr = decrypter_type());
455 
459  decrypter_type& decrypter();
460 
464  const decrypter_type& decrypter() const;
465 
470  bool operator() (PDU& pdu);
471 private:
472  Functor functor_;
473  decrypter_type decrypter_;
474 };
475 
483 template<typename Functor>
484 DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor);
485 
486 #ifdef TINS_HAVE_WPA2_DECRYPTION
487 
494 template<typename Functor>
495 DecrypterProxy<Functor, WPA2Decrypter> make_wpa2_decrypter_proxy(const Functor& functor) {
496  return DecrypterProxy<Functor, WPA2Decrypter>(functor);
497 }
498 #endif // TINS_HAVE_WPA2_DECRYPTION
499 
500 // Implementation section
501 
502 // DecrypterProxy
503 
504 template<typename Functor, typename Decrypter>
505 DecrypterProxy<Functor, Decrypter>::DecrypterProxy(const functor_type& func,
506  const decrypter_type& decr)
507 : functor_(func), decrypter_(decr) {
508 
509 }
510 
511 template<typename Functor, typename Decrypter>
512 typename DecrypterProxy<Functor, Decrypter>::decrypter_type &
513  DecrypterProxy<Functor, Decrypter>::decrypter() {
514  return decrypter_;
515 }
516 
517 template<typename Functor, typename Decrypter>
518 const typename DecrypterProxy<Functor, Decrypter>::decrypter_type &
519  DecrypterProxy<Functor, Decrypter>::decrypter() const {
520  return decrypter_;
521 }
522 
523 template<typename Functor, typename Decrypter>
524 bool DecrypterProxy<Functor, Decrypter>::operator() (PDU& pdu) {
525  return decrypter_.decrypt(pdu) ? functor_(pdu) : true;
526 }
527 
528 template<typename Functor>
529 DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor) {
530  return DecrypterProxy<Functor, WEPDecrypter>(functor);
531 }
532 
533 } // Crypto
534 } // Tins
535 
536 #endif // TINS_CRYPTO_H