libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
eapol.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 #ifndef TINS_EAPOL_H
31 #define TINS_EAPOL_H
32 
33 #include <stdint.h>
34 #include "pdu.h"
35 #include "macros.h"
36 #include "small_uint.h"
37 #include "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:
194  void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
195 
196  eapol_header header_;
197 };
198 
199 
200 
204 class TINS_API RC4EAPOL : public EAPOL {
205 public:
209  typedef std::vector<uint8_t> key_type;
210 
214  static const PDU::PDUType pdu_flag = PDU::RC4EAPOL;
215 
219  static const size_t key_iv_size = 16;
220 
224  static const size_t key_sign_size = 16;
225 
229  RC4EAPOL();
230 
240  RC4EAPOL(const uint8_t* buffer, uint32_t total_sz);
241 
242  /* Getters */
243 
248  uint16_t key_length() const {
249  return Endian::be_to_host(header_.key_length);
250  }
251 
256  uint64_t replay_counter() const {
257  return Endian::be_to_host(header_.replay_counter);
258  }
259 
264  const uint8_t* key_iv() const {
265  return header_.key_iv;
266  }
267 
273  return header_.key_flag;
274  }
275 
281  return header_.key_index;
282  }
283 
288  const uint8_t* key_sign() const {
289  return header_.key_sign;
290  }
291 
296  const key_type& key() const {
297  return key_;
298  }
299 
300  /* Setters */
301 
306  void key_length(uint16_t value);
307 
312  void replay_counter(uint64_t value);
313 
318  void key_iv(const uint8_t* value);
319 
324  void key_flag(small_uint<1> value);
325 
330  void key_index(small_uint<7> value);
331 
336  void key_sign(const uint8_t* value);
337 
342  void key(const key_type& value);
343 
344  /* Virtual method override. */
345 
354  uint32_t header_size() const;
355 
360  PDUType pdu_type() const {
361  return pdu_flag;
362  }
363 
369  bool matches_flag(PDUType flag) const {
370  return flag == pdu_flag || EAPOL::matches_flag(flag);
371  }
372 
378  RC4EAPOL* clone() const {
379  return new RC4EAPOL(*this);
380  }
381 private:
382  TINS_BEGIN_PACK
383  struct rc4_eapol_header {
384  uint16_t key_length;
385  uint64_t replay_counter;
386  uint8_t key_iv[key_iv_size];
387  uint8_t key_index:7,
388  key_flag:1;
389  uint8_t key_sign[16];
390  } TINS_END_PACK;
391 
392  void write_body(Memory::OutputMemoryStream& stream);
393 
394 
395  key_type key_;
396  rc4_eapol_header header_;
397 };
398 
399 
403 class TINS_API RSNEAPOL : public EAPOL {
404 public:
408  typedef std::vector<uint8_t> key_type;
409 
413  static const PDU::PDUType pdu_flag = PDU::RSNEAPOL;
414 
418  static const size_t key_iv_size = 16;
419 
423  static const size_t nonce_size = 32;
424 
428  static const size_t mic_size = 16;
429 
433  static const size_t rsc_size = 8;
434 
438  static const size_t id_size = 8;
439 
443  RSNEAPOL();
444 
454  RSNEAPOL(const uint8_t* buffer, uint32_t total_sz);
455 
456  /* Getters */
457 
462  uint16_t key_length() const {
463  return Endian::be_to_host(header_.key_length);
464  }
465 
470  uint64_t replay_counter() const {
471  return Endian::be_to_host(header_.replay_counter);
472  }
473 
478  const uint8_t* key_iv() const {
479  return header_.key_iv;
480  }
481 
486  const uint8_t* nonce() const {
487  return header_.nonce;
488  }
489 
494  const uint8_t* rsc() const {
495  return header_.rsc;
496  }
497 
502  const uint8_t* id() const {
503  return header_.id;
504  }
505 
510  const uint8_t* mic() const {
511  return header_.mic;
512  }
513 
518  uint16_t wpa_length() const {
519  return Endian::be_to_host(header_.wpa_length);
520  }
521 
526  const key_type& key() const {
527  return key_;
528  }
529 
535  return header_.key_mic;
536  }
537 
543  return header_.secure;
544  }
545 
551  return header_.error;
552  }
553 
559  return header_.request;
560  }
561 
567  return header_.encrypted;
568  }
569 
575  return header_.key_descriptor;
576  }
577 
584  return header_.key_t;
585  }
586 
592  return header_.key_index;
593  }
594 
600  return header_.install;
601  }
602 
608  return header_.key_ack;
609  }
610 
619  uint32_t header_size() const;
620 
621  /* Setters */
622 
627  void key_length(uint16_t value);
628 
633  void replay_counter(uint64_t value);
634 
643  void key_iv(const uint8_t* ptr);
644 
653  void nonce(const uint8_t* ptr);
654 
663  void rsc(const uint8_t* ptr);
664 
673  void id(const uint8_t* ptr);
674 
683  void mic(const uint8_t* ptr);
684 
689  void wpa_length(uint16_t length);
690 
695  void key(const key_type& value);
696 
701  void key_mic(small_uint<1> value);
702 
707  void secure(small_uint<1> value);
708 
713  void error(small_uint<1> flag);
714 
719  void request(small_uint<1> flag);
720 
725  void encrypted(small_uint<1 > flag);
726 
731  void key_descriptor(small_uint<3> value);
732 
737  void key_t(small_uint<1> flag);
738 
743  void key_index(small_uint<2> value);
744 
749  void install(small_uint<1> flag);
750 
755  void key_ack(small_uint<1> flag);
756 
761  PDUType pdu_type() const {
762  return pdu_flag;
763  }
764 
770  bool matches_flag(PDUType flag) const {
771  return flag == pdu_flag || EAPOL::matches_flag(flag);
772  }
773 
779  RSNEAPOL* clone() const {
780  return new RSNEAPOL(*this);
781  }
782 private:
783  TINS_BEGIN_PACK
784  struct rsn_eapol_header {
785  #if TINS_IS_LITTLE_ENDIAN
786  uint16_t key_mic:1,
787  secure:1,
788  error:1,
789  request:1,
790  encrypted:1,
791  reserved:3,
792  key_descriptor:3,
793  key_t:1,
794  key_index:2,
795  install:1,
796  key_ack:1;
797  uint16_t key_length;
798  uint64_t replay_counter;
799  uint8_t nonce[nonce_size], key_iv[key_iv_size];
800  uint8_t rsc[rsc_size], id[id_size];
801  uint8_t mic[mic_size];
802  uint16_t wpa_length;
803  #else
804  uint16_t reserved:3,
805  encrypted:1,
806  request:1,
807  error:1,
808  secure:1,
809  key_mic:1,
810  key_ack:1,
811  install:1,
812  key_index:2,
813  key_t:1,
814  key_descriptor:3;
815  uint16_t key_length;
816  uint64_t replay_counter;
817  uint8_t nonce[nonce_size], key_iv[key_iv_size];
818  uint8_t rsc[rsc_size], id[id_size];
819  uint8_t mic[mic_size];
820  uint16_t wpa_length;
821  #endif
822  } TINS_END_PACK;
823 
824  void write_body(Memory::OutputMemoryStream& stream);
825 
826 
827  rsn_eapol_header header_;
828  key_type key_;
829 };
830 
831 } // Tins
832 
833 #endif // TINS_EAPOL_H
const uint8_t * id() const
Getter for the id field.
Definition: eapol.h:502
virtual bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: pdu.h:449
uint16_t key_length() const
Getter for the key length field.
Definition: eapol.h:462
PDUType pdu_type() const
Getter for the PDU's type.
Definition: eapol.h:761
const uint8_t * key_sign() const
Getter for the key signature field.
Definition: eapol.h:288
uint8_t type() const
Getter for the type field.
Definition: eapol.h:124
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:128
const uint8_t * key_iv() const
Getter for the key IV field.
Definition: eapol.h:478
RC4EAPOL * clone() const
Clones this PDU.
Definition: eapol.h:378
PDUType pdu_type() const
Getter for the PDU's type.
Definition: eapol.h:360
small_uint< 1 > error() const
Getter for the error field.
Definition: eapol.h:550
uint16_t key_length() const
Getter for the key length field.
Definition: eapol.h:248
RSNEAPOL * clone() const
Clones this PDU.
Definition: eapol.h:779
small_uint< 7 > key_index() const
Getter for the key index field.
Definition: eapol.h:280
bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: eapol.h:369
small_uint< 1 > key_t() const
Getter for the key type field.
Definition: eapol.h:583
uint16_t wpa_length() const
Getter for the wpa length field.
Definition: eapol.h:518
std::vector< uint8_t > key_type
Definition: eapol.h:408
small_uint< 2 > key_index() const
Getter for the key_index field.
Definition: eapol.h:591
small_uint< 1 > key_ack() const
Getter for the key_ack field.
Definition: eapol.h:607
const key_type & key() const
Getter for the key field.
Definition: eapol.h:526
std::vector< uint8_t > key_type
Definition: eapol.h:209
uint64_t replay_counter() const
Getter for the replay counter field.
Definition: eapol.h:470
small_uint< 1 > key_flag() const
Getter for the key flag field.
Definition: eapol.h:272
bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: eapol.h:770
small_uint< 1 > key_mic() const
Getter for the key mic field.
Definition: eapol.h:534
small_uint< 1 > secure() const
Getter for the secure field.
Definition: eapol.h:542
small_uint< 1 > request() const
Getter for the request field.
Definition: eapol.h:558
Class that represents the RC4 EAPOL PDU.
Definition: eapol.h:204
Definition: eapol.h:173
Class that represents the RSN EAPOL PDU.
Definition: eapol.h:403
const uint8_t * mic() const
Getter for the mic field.
Definition: eapol.h:510
const uint8_t * nonce() const
Getter for the nonce field.
Definition: eapol.h:486
const uint8_t * rsc() const
Getter for the rsc field.
Definition: eapol.h:494
EAPOLTYPE
Definition: eapol.h:66
small_uint< 3 > key_descriptor() const
Getter for the key descriptor field.
Definition: eapol.h:574
Represents the EAP encapsulation over LAN.
Definition: eapol.h:56
uint64_t replay_counter() const
Getter for the replay counter field.
Definition: eapol.h:256
small_uint< 1 > install() const
Getter for the install field.
Definition: eapol.h:599
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:566
PDUType pdu_type() const
Getter for the PDU's type.
Definition: eapol.h:158
Base class for protocol data units.
Definition: pdu.h:108
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:296
const uint8_t * key_iv() const
Getter for the key IV field.
Definition: eapol.h:264