libtins  4.0
eapol.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 #ifndef TINS_EAPOL_H
31 #define TINS_EAPOL_H
32 
33 #include <stdint.h>
34 #include <tins/pdu.h>
35 #include <tins/macros.h>
36 #include <tins/small_uint.h>
37 #include <tins/endianness.h>
38 
39 namespace Tins {
40 namespace Memory {
41 
42 class OutputMemoryStream;
43 
44 } // Memory
45 
49 class RSNInformation;
56 class TINS_API EAPOL : public PDU {
57 public:
61  static const PDU::PDUType pdu_flag = PDU::EAPOL;
62 
66  enum EAPOLTYPE {
67  RC4 = 1,
68  RSN,
69  EAPOL_WPA = 254
70  };
71 
78  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
79 
92  static EAPOL* from_bytes(const uint8_t* buffer, uint32_t total_sz);
93 
94  /* Getters */
95 
100  uint8_t version() const {
101  return header_.version;
102  }
103 
108  uint8_t packet_type() const {
109  return header_.packet_type;
110  }
111 
116  uint16_t length() const {
117  return Endian::be_to_host(header_.length);
118  }
119 
124  uint8_t type() const {
125  return header_.type;
126  }
127 
128  /* Setters */
129 
134  void version(uint8_t value);
135 
140  void packet_type(uint8_t value);
141 
146  void length(uint16_t value);
147 
152  void type(uint8_t value);
153 
158  PDUType pdu_type() const { return PDU::EAPOL; }
159 protected:
163  EAPOL(uint8_t packet_type, EAPOLTYPE type);
164 
170  EAPOL(const uint8_t* buffer, uint32_t total_sz);
171 
172  TINS_BEGIN_PACK
173  struct eapol_header {
174  uint8_t version, packet_type;
175  uint16_t length;
176  uint8_t type;
177  } TINS_END_PACK;
178 
186  virtual void write_body(Memory::OutputMemoryStream& stream) = 0;
187 private:
188  void write_serialization(uint8_t* buffer, uint32_t total_sz);
189 
190  eapol_header header_;
191 };
192 
193 
194 
198 class TINS_API RC4EAPOL : public EAPOL {
199 public:
203  typedef std::vector<uint8_t> key_type;
204 
208  static const PDU::PDUType pdu_flag = PDU::RC4EAPOL;
209 
213  static const size_t key_iv_size = 16;
214 
218  static const size_t key_sign_size = 16;
219 
223  RC4EAPOL();
224 
234  RC4EAPOL(const uint8_t* buffer, uint32_t total_sz);
235 
236  /* Getters */
237 
242  uint16_t key_length() const {
243  return Endian::be_to_host(header_.key_length);
244  }
245 
250  uint64_t replay_counter() const {
251  return Endian::be_to_host(header_.replay_counter);
252  }
253 
258  const uint8_t* key_iv() const {
259  return header_.key_iv;
260  }
261 
267  return header_.key_flag;
268  }
269 
275  return header_.key_index;
276  }
277 
282  const uint8_t* key_sign() const {
283  return header_.key_sign;
284  }
285 
290  const key_type& key() const {
291  return key_;
292  }
293 
294  /* Setters */
295 
300  void key_length(uint16_t value);
301 
306  void replay_counter(uint64_t value);
307 
312  void key_iv(const uint8_t* value);
313 
318  void key_flag(small_uint<1> value);
319 
324  void key_index(small_uint<7> value);
325 
330  void key_sign(const uint8_t* value);
331 
336  void key(const key_type& value);
337 
338  /* Virtual method override. */
339 
348  uint32_t header_size() const;
349 
354  PDUType pdu_type() const {
355  return pdu_flag;
356  }
357 
363  bool matches_flag(PDUType flag) const {
364  return flag == pdu_flag || EAPOL::matches_flag(flag);
365  }
366 
372  RC4EAPOL* clone() const {
373  return new RC4EAPOL(*this);
374  }
375 private:
376  TINS_BEGIN_PACK
377  struct rc4_eapol_header {
378  uint16_t key_length;
379  uint64_t replay_counter;
380  uint8_t key_iv[key_iv_size];
381  uint8_t key_index:7,
382  key_flag:1;
383  uint8_t key_sign[16];
384  } TINS_END_PACK;
385 
386  void write_body(Memory::OutputMemoryStream& stream);
387 
388 
389  key_type key_;
390  rc4_eapol_header header_;
391 };
392 
393 
397 class TINS_API RSNEAPOL : public EAPOL {
398 public:
402  typedef std::vector<uint8_t> key_type;
403 
407  static const PDU::PDUType pdu_flag = PDU::RSNEAPOL;
408 
412  static const size_t key_iv_size = 16;
413 
417  static const size_t nonce_size = 32;
418 
422  static const size_t mic_size = 16;
423 
427  static const size_t rsc_size = 8;
428 
432  static const size_t id_size = 8;
433 
437  RSNEAPOL();
438 
448  RSNEAPOL(const uint8_t* buffer, uint32_t total_sz);
449 
450  /* Getters */
451 
456  uint16_t key_length() const {
457  return Endian::be_to_host(header_.key_length);
458  }
459 
464  uint64_t replay_counter() const {
465  return Endian::be_to_host(header_.replay_counter);
466  }
467 
472  const uint8_t* key_iv() const {
473  return header_.key_iv;
474  }
475 
480  const uint8_t* nonce() const {
481  return header_.nonce;
482  }
483 
488  const uint8_t* rsc() const {
489  return header_.rsc;
490  }
491 
496  const uint8_t* id() const {
497  return header_.id;
498  }
499 
504  const uint8_t* mic() const {
505  return header_.mic;
506  }
507 
512  uint16_t wpa_length() const {
513  return Endian::be_to_host(header_.wpa_length);
514  }
515 
520  const key_type& key() const {
521  return key_;
522  }
523 
529  return header_.key_mic;
530  }
531 
537  return header_.secure;
538  }
539 
545  return header_.error;
546  }
547 
553  return header_.request;
554  }
555 
561  return header_.encrypted;
562  }
563 
569  return header_.key_descriptor;
570  }
571 
578  return header_.key_t;
579  }
580 
586  return header_.key_index;
587  }
588 
594  return header_.install;
595  }
596 
602  return header_.key_ack;
603  }
604 
613  uint32_t header_size() const;
614 
615  /* Setters */
616 
621  void key_length(uint16_t value);
622 
627  void replay_counter(uint64_t value);
628 
637  void key_iv(const uint8_t* ptr);
638 
647  void nonce(const uint8_t* ptr);
648 
657  void rsc(const uint8_t* ptr);
658 
667  void id(const uint8_t* ptr);
668 
677  void mic(const uint8_t* ptr);
678 
683  void wpa_length(uint16_t length);
684 
689  void key(const key_type& value);
690 
695  void key_mic(small_uint<1> value);
696 
701  void secure(small_uint<1> value);
702 
707  void error(small_uint<1> flag);
708 
713  void request(small_uint<1> flag);
714 
719  void encrypted(small_uint<1 > flag);
720 
725  void key_descriptor(small_uint<3> value);
726 
731  void key_t(small_uint<1> flag);
732 
737  void key_index(small_uint<2> value);
738 
743  void install(small_uint<1> flag);
744 
749  void key_ack(small_uint<1> flag);
750 
755  PDUType pdu_type() const {
756  return pdu_flag;
757  }
758 
764  bool matches_flag(PDUType flag) const {
765  return flag == pdu_flag || EAPOL::matches_flag(flag);
766  }
767 
773  RSNEAPOL* clone() const {
774  return new RSNEAPOL(*this);
775  }
776 private:
777  TINS_BEGIN_PACK
778  struct rsn_eapol_header {
779  #if TINS_IS_LITTLE_ENDIAN
780  uint16_t key_mic:1,
781  secure:1,
782  error:1,
783  request:1,
784  encrypted:1,
785  reserved:3,
786  key_descriptor:3,
787  key_t:1,
788  key_index:2,
789  install:1,
790  key_ack:1;
791  uint16_t key_length;
792  uint64_t replay_counter;
793  uint8_t nonce[nonce_size], key_iv[key_iv_size];
794  uint8_t rsc[rsc_size], id[id_size];
795  uint8_t mic[mic_size];
796  uint16_t wpa_length;
797  #else
798  uint16_t reserved:3,
799  encrypted:1,
800  request:1,
801  error:1,
802  secure:1,
803  key_mic:1,
804  key_ack:1,
805  install:1,
806  key_index:2,
807  key_t:1,
808  key_descriptor:3;
809  uint16_t key_length;
810  uint64_t replay_counter;
811  uint8_t nonce[nonce_size], key_iv[key_iv_size];
812  uint8_t rsc[rsc_size], id[id_size];
813  uint8_t mic[mic_size];
814  uint16_t wpa_length;
815  #endif
816  } TINS_END_PACK;
817 
818  void write_body(Memory::OutputMemoryStream& stream);
819 
820 
821  rsn_eapol_header header_;
822  key_type key_;
823 };
824 
825 } // Tins
826 
827 #endif // TINS_EAPOL_H
const uint8_t * id() const
Getter for the id field.
Definition: eapol.h:496
virtual bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: pdu.h:461
uint16_t key_length() const
Getter for the key length field.
Definition: eapol.h:456
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: eapol.h:755
const uint8_t * key_sign() const
Getter for the key signature field.
Definition: eapol.h:282
uint8_t type() const
Getter for the type field.
Definition: eapol.h:124
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
const uint8_t * key_iv() const
Getter for the key IV field.
Definition: eapol.h:472
RC4EAPOL * clone() const
Clones this PDU.
Definition: eapol.h:372
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: eapol.h:354
small_uint< 1 > error() const
Getter for the error field.
Definition: eapol.h:544
uint16_t key_length() const
Getter for the key length field.
Definition: eapol.h:242
RSNEAPOL * clone() const
Clones this PDU.
Definition: eapol.h:773
small_uint< 7 > key_index() const
Getter for the key index field.
Definition: eapol.h:274
bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: eapol.h:363
small_uint< 1 > key_t() const
Getter for the key type field.
Definition: eapol.h:577
uint16_t wpa_length() const
Getter for the wpa length field.
Definition: eapol.h:512
std::vector< uint8_t > key_type
Definition: eapol.h:402
small_uint< 2 > key_index() const
Getter for the key_index field.
Definition: eapol.h:585
small_uint< 1 > key_ack() const
Getter for the key_ack field.
Definition: eapol.h:601
const key_type & key() const
Getter for the key field.
Definition: eapol.h:520
std::vector< uint8_t > key_type
Definition: eapol.h:203
uint64_t replay_counter() const
Getter for the replay counter field.
Definition: eapol.h:464
small_uint< 1 > key_flag() const
Getter for the key flag field.
Definition: eapol.h:266
bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: eapol.h:764
The Tins namespace.
Definition: address_range.h:38
small_uint< 1 > key_mic() const
Getter for the key mic field.
Definition: eapol.h:528
small_uint< 1 > secure() const
Getter for the secure field.
Definition: eapol.h:536
small_uint< 1 > request() const
Getter for the request field.
Definition: eapol.h:552
Type used to store a PDU header&#39;s data.
Definition: pdu.h:194
Class that represents the RC4 EAPOL PDU.
Definition: eapol.h:198
Definition: eapol.h:173
Class that represents the RSN EAPOL PDU.
Definition: eapol.h:397
const uint8_t * mic() const
Getter for the mic field.
Definition: eapol.h:504
const uint8_t * nonce() const
Getter for the nonce field.
Definition: eapol.h:480
const uint8_t * rsc() const
Getter for the rsc field.
Definition: eapol.h:488
EAPOLTYPE
Definition: eapol.h:66
small_uint< 3 > key_descriptor() const
Getter for the key descriptor field.
Definition: eapol.h:568
Represents the EAP encapsulation over LAN.
Definition: eapol.h:56
uint64_t replay_counter() const
Getter for the replay counter field.
Definition: eapol.h:250
small_uint< 1 > install() const
Getter for the install field.
Definition: eapol.h:593
uint8_t version() const
Getter for the version field.
Definition: eapol.h:100
uint16_t length() const
Getter for the length field.
Definition: eapol.h:116
small_uint< 1 > encrypted() const
Getter for the encrypted field.
Definition: eapol.h:560
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: eapol.h:158
Base class for protocol data units.
Definition: pdu.h:107
uint8_t packet_type() const
Getter for the packet type field.
Definition: eapol.h:108
const key_type & key() const
Getter for the key field.
Definition: eapol.h:290
const uint8_t * key_iv() const
Getter for the key IV field.
Definition: eapol.h:258