mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added several tests for EAPOL. Now both RadioTap and EAPOL work on big endian architectures.
This commit is contained in:
@@ -14,7 +14,7 @@ compile: $(OBJECTS)
|
||||
|
||||
recompile: clean all
|
||||
|
||||
depends: $(SOURCES) $(DEPS)
|
||||
depends: $(SOURCES)
|
||||
rm -f ./depends.d
|
||||
make do_make_deps
|
||||
|
||||
|
||||
185
include/eapol.h
185
include/eapol.h
@@ -368,7 +368,32 @@ namespace Tins {
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::RSNEAPOL;
|
||||
|
||||
/**
|
||||
* The length of the key IV field
|
||||
*/
|
||||
static const size_t key_iv_size = 16;
|
||||
|
||||
/**
|
||||
* The length of the nonce field
|
||||
*/
|
||||
static const size_t nonce_size = 32;
|
||||
|
||||
/**
|
||||
* The length of the mic field
|
||||
*/
|
||||
static const size_t mic_size = 16;
|
||||
|
||||
/**
|
||||
* The length of the rsc field
|
||||
*/
|
||||
static const size_t rsc_size = 8;
|
||||
|
||||
/**
|
||||
* The length of the id field
|
||||
*/
|
||||
static const size_t id_size = 8;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNEAPOL.
|
||||
*/
|
||||
@@ -411,13 +436,13 @@ namespace Tins {
|
||||
* \brief Getter for the rsc field.
|
||||
* \return The rsc field.
|
||||
*/
|
||||
uint64_t rsc() const { return Endian::be_to_host(_header.rsc); }
|
||||
const uint8_t *rsc() const { return _header.rsc; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the id field.
|
||||
* \return The id field.
|
||||
*/
|
||||
uint64_t id() const { return Endian::be_to_host(_header.id); }
|
||||
const uint8_t *id() const { return _header.id; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the mic field.
|
||||
@@ -437,6 +462,66 @@ namespace Tins {
|
||||
*/
|
||||
const key_type &key() const { return _key; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_mic field.
|
||||
* \return The key_mic field.
|
||||
*/
|
||||
small_uint<1> key_mic() const { return _header.key_mic; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the secure field.
|
||||
* \return The secure field.
|
||||
*/
|
||||
small_uint<1> secure() const { return _header.secure; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the error field.
|
||||
* \return The error field.
|
||||
*/
|
||||
small_uint<1> error() const { return _header.error; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the request field.
|
||||
* \return The request field.
|
||||
*/
|
||||
small_uint<1> request() const { return _header.request; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the encrypted field.
|
||||
* \return The encrypted field.
|
||||
*/
|
||||
small_uint<1 > encrypted() const { return _header.encrypted; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_descriptor field.
|
||||
* \return The key_descriptor field.
|
||||
*/
|
||||
small_uint<3> key_descriptor() const { return _header.key_descriptor; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_t field.
|
||||
* \return The key_t field.
|
||||
*/
|
||||
small_uint<1> key_t() const { return _header.key_t; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_index field.
|
||||
* \return The key_index field.
|
||||
*/
|
||||
small_uint<2> key_index() const { return _header.key_index; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the install field.
|
||||
* \return The install field.
|
||||
*/
|
||||
small_uint<1> install() const { return _header.install; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_ack field.
|
||||
* \return The key_ack field.
|
||||
*/
|
||||
small_uint<1> key_ack() const { return _header.key_ack; };
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
@@ -459,7 +544,7 @@ namespace Tins {
|
||||
* \brief Sets the replay counter field.
|
||||
* \param new_replay_counter The new replay counter to be set.
|
||||
*/
|
||||
void replay_counter(uint16_t new_replay_counter);
|
||||
void replay_counter(uint64_t new_replay_counter);
|
||||
|
||||
/**
|
||||
* \brief Sets the key IV field.
|
||||
@@ -480,13 +565,13 @@ namespace Tins {
|
||||
* \brief Sets the rsc field.
|
||||
* \param new_rsc The new rsc to be set.
|
||||
*/
|
||||
void rsc(uint64_t new_rsc);
|
||||
void rsc(const uint8_t *new_rsc);
|
||||
|
||||
/**
|
||||
* \brief Sets the id field.
|
||||
* \param new_id The new id to be set.
|
||||
*/
|
||||
void id(uint64_t new_id);
|
||||
void id(const uint8_t *new_id);
|
||||
|
||||
/**
|
||||
* \brief Sets the mic field.
|
||||
@@ -510,14 +595,64 @@ namespace Tins {
|
||||
void key(const key_type &new_key);
|
||||
|
||||
/**
|
||||
* \brief Sets RSN information for this EAPOL PDU.
|
||||
*
|
||||
* This method copies the RSN information and copies it in the
|
||||
* key field. Therefore, if a key has been set, this will remove it.
|
||||
* \param rsn The RSN information to be set.
|
||||
* \sa RSNInformation.
|
||||
* \brief Setter for the key_mic field.
|
||||
* \param new_key_mic The new to be set.
|
||||
*/
|
||||
void rsn_information(const RSNInformation &rsn);
|
||||
void key_mic(small_uint<1> new_key_mic);
|
||||
|
||||
/**
|
||||
* \brief Setter for the secure field.
|
||||
* \param new_secure The new to be set.
|
||||
*/
|
||||
void secure(small_uint<1> new_secure);
|
||||
|
||||
/**
|
||||
* \brief Setter for the error field.
|
||||
* \param new_error The new to be set.
|
||||
*/
|
||||
void error(small_uint<1> new_error);
|
||||
|
||||
/**
|
||||
* \brief Setter for the request field.
|
||||
* \param new_request The new to be set.
|
||||
*/
|
||||
void request(small_uint<1> new_request);
|
||||
|
||||
/**
|
||||
* \brief Setter for the encrypted field.
|
||||
* \param new_encrypted The new to be set.
|
||||
*/
|
||||
void encrypted(small_uint<1 > new_encrypted);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_descriptor field.
|
||||
* \param new_key_descriptor The new to be set.
|
||||
*/
|
||||
void key_descriptor(small_uint<3> new_key_descriptor);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_t field.
|
||||
* \param new_key_t The new to be set.
|
||||
*/
|
||||
void key_t(small_uint<1> new_key_t);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_index field.
|
||||
* \param new_key_index The new to be set.
|
||||
*/
|
||||
void key_index(small_uint<2> new_key_index);
|
||||
|
||||
/**
|
||||
* \brief Setter for the install field.
|
||||
* \param new_install The new to be set.
|
||||
*/
|
||||
void install(small_uint<1> new_install);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_ack field.
|
||||
* \param new_key_ack The new to be set.
|
||||
*/
|
||||
void key_ack(small_uint<1> new_key_ack);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
@@ -544,6 +679,7 @@ namespace Tins {
|
||||
}
|
||||
private:
|
||||
struct rsnhdr {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint16_t key_mic:1,
|
||||
secure:1,
|
||||
error:1,
|
||||
@@ -557,10 +693,29 @@ namespace Tins {
|
||||
key_ack:1;
|
||||
uint16_t key_length;
|
||||
uint64_t replay_counter;
|
||||
uint8_t nonce[32], key_iv[16];
|
||||
uint64_t rsc, id;
|
||||
uint8_t mic[16];
|
||||
uint8_t nonce[nonce_size], key_iv[key_iv_size];
|
||||
uint8_t rsc[rsc_size], id[id_size];
|
||||
uint8_t mic[mic_size];
|
||||
uint16_t wpa_length;
|
||||
#else
|
||||
uint16_t reserved:3,
|
||||
encrypted:1,
|
||||
request:1,
|
||||
error:1,
|
||||
secure:1,
|
||||
key_mic:1,
|
||||
key_ack:1,
|
||||
install:1,
|
||||
key_index:2,
|
||||
key_t:1,
|
||||
key_descriptor:3;
|
||||
uint16_t key_length;
|
||||
uint64_t replay_counter;
|
||||
uint8_t nonce[nonce_size], key_iv[key_iv_size];
|
||||
uint8_t rsc[rsc_size], id[id_size];
|
||||
uint8_t mic[mic_size];
|
||||
uint16_t wpa_length;
|
||||
#endif
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_body(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
@@ -96,23 +96,14 @@ namespace Tins {
|
||||
* \brief Flags used in the RadioTap::flags() method.
|
||||
*/
|
||||
enum FrameFlags {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
CFP = 1,
|
||||
PREAMBLE = 2,
|
||||
WEP = 4,
|
||||
FRAGMENTATION = 8,
|
||||
FCS = 16,
|
||||
PADDING = 32,
|
||||
FAILED_FCS = 64
|
||||
#else
|
||||
CFP = 64,
|
||||
PREAMBLE = 32,
|
||||
WEP = 16,
|
||||
FRAGMENTATION = 8,
|
||||
FCS = 4,
|
||||
PADDING = 2,
|
||||
FAILED_FCS = 1
|
||||
#endif
|
||||
FAILED_FCS = 64,
|
||||
SHORT_GI = 128
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -154,7 +145,7 @@ namespace Tins {
|
||||
* \brief Setter for the length field.
|
||||
* \param new_length The new length.
|
||||
*/
|
||||
void length(uint8_t new_length);
|
||||
void length(uint16_t new_length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the TSFT field.
|
||||
@@ -223,7 +214,7 @@ namespace Tins {
|
||||
* \brief Getter for the length field.
|
||||
* \return The length field.
|
||||
*/
|
||||
uint8_t length() const { return _radio.it_len; }
|
||||
uint16_t length() const { return Endian::le_to_host(_radio.it_len); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the tsft field.
|
||||
@@ -324,6 +315,7 @@ namespace Tins {
|
||||
PDUType pdu_type() const { return PDU::RADIOTAP; }
|
||||
private:
|
||||
struct radiotap_hdr {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint8_t it_version;
|
||||
uint8_t it_pad;
|
||||
uint16_t it_len;
|
||||
@@ -346,6 +338,32 @@ namespace Tins {
|
||||
channel_plus:1,
|
||||
reserved2:12,
|
||||
ext:1;
|
||||
#else
|
||||
uint8_t it_pad;
|
||||
uint8_t it_version;
|
||||
uint16_t it_len;
|
||||
uint32_t lock_quality:1,
|
||||
dbm_noise:1,
|
||||
dbm_signal:1,
|
||||
fhss:1,
|
||||
channel:1,
|
||||
rate:1,
|
||||
flags:1,
|
||||
tsft:1,
|
||||
reserved3:1,
|
||||
tx_attenuation:1,
|
||||
db_tx_attenuation:1,
|
||||
dbm_tx_attenuation:1,
|
||||
antenna:1,
|
||||
db_signal:1,
|
||||
db_noise:1,
|
||||
rx_flags:1,
|
||||
reserved2:5,
|
||||
channel_plus:1,
|
||||
reserved1:2,
|
||||
reserved4:7,
|
||||
ext:1;
|
||||
#endif
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void init();
|
||||
|
||||
@@ -80,6 +80,14 @@ namespace Tins{
|
||||
*/
|
||||
RSNInformation();
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNInformation from a
|
||||
* serialization_type object.
|
||||
*
|
||||
* \param buffer The buffer from which to construct this object.
|
||||
*/
|
||||
RSNInformation(const serialization_type &buffer);
|
||||
|
||||
/**
|
||||
* \brief Constructor from buffer.
|
||||
*
|
||||
@@ -163,6 +171,8 @@ namespace Tins{
|
||||
*/
|
||||
serialization_type serialize() const;
|
||||
private:
|
||||
void init(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
uint16_t _version, _capabilities;
|
||||
CypherSuites _group_suite;
|
||||
akm_type _akm_cyphers;
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#endif
|
||||
#include "dot11.h"
|
||||
#include "rawpdu.h"
|
||||
#include "radiotap.h"
|
||||
#include "rsn_information.h"
|
||||
#include "packet_sender.h"
|
||||
#include "snap.h"
|
||||
|
||||
@@ -90,8 +90,8 @@ void EAPOL::type(uint8_t new_type) {
|
||||
void EAPOL::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
uint32_t sz = header_size();
|
||||
assert(total_sz >= sz);
|
||||
if(!_header.length)
|
||||
length(sz - sizeof(_header.version) - sizeof(_header.length) - sizeof(_header.type));
|
||||
//if(!_header.length)
|
||||
// length(sz - sizeof(_header.version) - sizeof(_header.length) - sizeof(_header.type));
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
write_body(buffer + sizeof(_header), total_sz - sizeof(_header));
|
||||
}
|
||||
@@ -132,7 +132,7 @@ void RC4EAPOL::replay_counter(uint64_t new_replay_counter) {
|
||||
}
|
||||
|
||||
void RC4EAPOL::key_iv(const uint8_t *new_key_iv) {
|
||||
std::memcpy(_header.key_iv, new_key_iv, sizeof(_header.key_iv));
|
||||
std::copy(new_key_iv, new_key_iv + sizeof(_header.key_iv), _header.key_iv);
|
||||
}
|
||||
|
||||
void RC4EAPOL::key_flag(small_uint<1> new_key_flag) {
|
||||
@@ -175,7 +175,7 @@ RSNEAPOL::RSNEAPOL()
|
||||
}
|
||||
|
||||
RSNEAPOL::RSNEAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
: EAPOL(0x03, RSN)
|
||||
: EAPOL(buffer, total_sz)
|
||||
{
|
||||
buffer += sizeof(eapolhdr);
|
||||
total_sz -= sizeof(eapolhdr);
|
||||
@@ -189,40 +189,84 @@ RSNEAPOL::RSNEAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
}
|
||||
|
||||
void RSNEAPOL::RSNEAPOL::nonce(const uint8_t *new_nonce) {
|
||||
std::memcpy(_header.nonce, new_nonce, sizeof(_header.nonce));
|
||||
std::copy(new_nonce, new_nonce + nonce_size, _header.nonce);
|
||||
}
|
||||
|
||||
void RSNEAPOL::rsc(uint64_t new_rsc) {
|
||||
_header.rsc = Endian::host_to_be(new_rsc);
|
||||
void RSNEAPOL::rsc(const uint8_t *new_rsc) {
|
||||
std::copy(new_rsc, new_rsc + rsc_size, _header.rsc);
|
||||
}
|
||||
|
||||
void RSNEAPOL::id(uint64_t new_id) {
|
||||
_header.id = Endian::host_to_be(new_id);
|
||||
void RSNEAPOL::id(const uint8_t *new_id) {
|
||||
std::copy(new_id, new_id + id_size, _header.id);
|
||||
}
|
||||
|
||||
void RSNEAPOL::replay_counter(uint64_t new_replay_counter) {
|
||||
_header.replay_counter = Endian::host_to_be(new_replay_counter);
|
||||
}
|
||||
|
||||
void RSNEAPOL::mic(const uint8_t *new_mic) {
|
||||
std::memcpy(_header.mic, new_mic, sizeof(_header.mic));
|
||||
std::copy(new_mic, new_mic + mic_size, _header.mic);
|
||||
}
|
||||
|
||||
void RSNEAPOL::wpa_length(uint16_t new_wpa_length) {
|
||||
_header.wpa_length = Endian::host_to_be(new_wpa_length);
|
||||
}
|
||||
|
||||
void RSNEAPOL::key_iv(const uint8_t *new_key_iv) {
|
||||
std::copy(new_key_iv, new_key_iv + sizeof(_header.key_iv), _header.key_iv);
|
||||
}
|
||||
|
||||
void RSNEAPOL::key_length(uint16_t new_key_length) {
|
||||
_header.key_length = Endian::host_to_be(new_key_length);
|
||||
}
|
||||
|
||||
void RSNEAPOL::key(const key_type &new_key) {
|
||||
_key = new_key;
|
||||
_header.key_t = 0;
|
||||
}
|
||||
|
||||
void RSNEAPOL::rsn_information(const RSNInformation &rsn) {
|
||||
_key = rsn.serialize();
|
||||
_header.key_t = 1;
|
||||
void RSNEAPOL::key_mic(small_uint<1> new_key_mic) {
|
||||
_header.key_mic = new_key_mic;
|
||||
}
|
||||
|
||||
void RSNEAPOL::secure(small_uint<1> new_secure) {
|
||||
_header.secure = new_secure;
|
||||
}
|
||||
|
||||
void RSNEAPOL::error(small_uint<1> new_error) {
|
||||
_header.error = new_error;
|
||||
}
|
||||
|
||||
void RSNEAPOL::request(small_uint<1> new_request) {
|
||||
_header.request = new_request;
|
||||
}
|
||||
|
||||
void RSNEAPOL::encrypted(small_uint<1 > new_encrypted) {
|
||||
_header.encrypted = new_encrypted;
|
||||
}
|
||||
|
||||
void RSNEAPOL::key_descriptor(small_uint<3> new_key_descriptor) {
|
||||
_header.key_descriptor = new_key_descriptor;
|
||||
}
|
||||
|
||||
void RSNEAPOL::key_t(small_uint<1> new_key_t) {
|
||||
_header.key_t = new_key_t;
|
||||
}
|
||||
|
||||
void RSNEAPOL::key_index(small_uint<2> new_key_index) {
|
||||
_header.key_index = new_key_index;
|
||||
}
|
||||
|
||||
void RSNEAPOL::install(small_uint<1> new_install) {
|
||||
_header.install = new_install;
|
||||
}
|
||||
|
||||
void RSNEAPOL::key_ack(small_uint<1> new_key_ack) {
|
||||
_header.key_ack = new_key_ack;
|
||||
}
|
||||
|
||||
uint32_t RSNEAPOL::header_size() const {
|
||||
uint32_t padding(0);
|
||||
if(_header.key_t && _key.size())
|
||||
padding = 2;
|
||||
return sizeof(eapolhdr) + sizeof(_header) + _key.size() + padding;
|
||||
return sizeof(eapolhdr) + sizeof(_header) + _key.size();
|
||||
}
|
||||
|
||||
void RSNEAPOL::write_body(uint8_t *buffer, uint32_t total_sz) {
|
||||
@@ -234,18 +278,11 @@ void RSNEAPOL::write_body(uint8_t *buffer, uint32_t total_sz) {
|
||||
wpa_length(_key.size());
|
||||
}
|
||||
else if(_key.size()) {
|
||||
_header.key_length = 0;
|
||||
wpa_length(_key.size() + 2);
|
||||
wpa_length(_key.size());
|
||||
}
|
||||
else
|
||||
wpa_length(0);
|
||||
}
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
if(_header.key_t && _key.size()) {
|
||||
*(buffer++) = Dot11::RSN;
|
||||
*(buffer++) = _key.size();
|
||||
}
|
||||
std::copy(_key.begin(), _key.end(), buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ void RadioTap::padding(uint8_t new_padding) {
|
||||
_radio.it_pad = new_padding;
|
||||
}
|
||||
|
||||
void RadioTap::length(uint8_t new_length) {
|
||||
_radio.it_len = new_length;
|
||||
void RadioTap::length(uint16_t new_length) {
|
||||
_radio.it_len = Endian::host_to_le(new_length);
|
||||
}
|
||||
|
||||
void RadioTap::tsft(uint64_t new_tsft) {
|
||||
@@ -162,7 +162,7 @@ void RadioTap::rate(uint8_t new_rate) {
|
||||
|
||||
void RadioTap::channel(uint16_t new_freq, uint16_t new_type) {
|
||||
_channel_freq = Endian::host_to_le(new_freq);
|
||||
_channel_type = Endian::host_to_le(new_type);
|
||||
_channel_type = Endian::host_to_le<uint32_t>(new_type);
|
||||
_radio.channel = 1;
|
||||
}
|
||||
void RadioTap::dbm_signal(uint8_t new_dbm_signal) {
|
||||
@@ -309,6 +309,8 @@ void RadioTap::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU
|
||||
buffer += sizeof(_max_power);
|
||||
}
|
||||
if((_flags & 0x10) != 0 && inner_pdu())
|
||||
*(uint32_t*)(buffer + inner_pdu()->size()) = Utils::crc32(buffer, inner_pdu()->size());
|
||||
*(uint32_t*)(buffer + inner_pdu()->size()) = Endian::host_to_le(
|
||||
Utils::crc32(buffer, inner_pdu()->size())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,22 +31,41 @@
|
||||
#include "rsn_information.h"
|
||||
|
||||
namespace Tins {
|
||||
template<typename T>
|
||||
void check_size(uint32_t total_sz, const char* err_msg) {
|
||||
if(total_sz < sizeof(T))
|
||||
throw std::runtime_error(err_msg);
|
||||
}
|
||||
|
||||
RSNInformation::RSNInformation() : _version(1), _capabilities(0) {
|
||||
|
||||
}
|
||||
|
||||
RSNInformation::RSNInformation(const serialization_type &buffer) {
|
||||
init(&buffer[0], buffer.size());
|
||||
}
|
||||
|
||||
RSNInformation::RSNInformation(const uint8_t *buffer, uint32_t total_sz) {
|
||||
init(buffer, total_sz);
|
||||
}
|
||||
|
||||
void RSNInformation::init(const uint8_t *buffer, uint32_t total_sz) {
|
||||
const char *err_msg = "Malformed RSN information structure";
|
||||
check_size<uint16_t>(total_sz, err_msg);
|
||||
version(Endian::le_to_host(*(uint16_t*)buffer));
|
||||
buffer += sizeof(uint16_t);
|
||||
total_sz -= sizeof(uint16_t);
|
||||
group_suite((RSNInformation::CypherSuites)*(uint32_t*)buffer);
|
||||
|
||||
check_size<uint32_t>(total_sz, err_msg);
|
||||
buffer += sizeof(uint32_t);
|
||||
total_sz -= sizeof(uint32_t);
|
||||
|
||||
check_size<uint16_t>(total_sz, err_msg);
|
||||
|
||||
total_sz -= (sizeof(uint16_t) << 1) + sizeof(uint32_t);
|
||||
if(total_sz < sizeof(uint16_t))
|
||||
throw std::runtime_error(err_msg);
|
||||
uint16_t count = *(uint16_t*)buffer;
|
||||
buffer += sizeof(uint16_t);
|
||||
total_sz -= sizeof(uint16_t);
|
||||
if(count * sizeof(uint32_t) > total_sz)
|
||||
throw std::runtime_error(err_msg);
|
||||
total_sz -= count * sizeof(uint32_t);
|
||||
@@ -54,8 +73,8 @@ RSNInformation::RSNInformation(const uint8_t *buffer, uint32_t total_sz) {
|
||||
add_pairwise_cypher((RSNInformation::CypherSuites)*(uint32_t*)buffer);
|
||||
buffer += sizeof(uint32_t);
|
||||
}
|
||||
if(total_sz < sizeof(uint16_t))
|
||||
throw std::runtime_error(err_msg);
|
||||
check_size<uint16_t>(total_sz, err_msg);
|
||||
|
||||
count = *(uint16_t*)buffer;
|
||||
buffer += sizeof(uint16_t);
|
||||
total_sz -= sizeof(uint16_t);
|
||||
@@ -66,8 +85,8 @@ RSNInformation::RSNInformation(const uint8_t *buffer, uint32_t total_sz) {
|
||||
add_akm_cypher((RSNInformation::AKMSuites)*(uint32_t*)buffer);
|
||||
buffer += sizeof(uint32_t);
|
||||
}
|
||||
if(total_sz < sizeof(uint16_t))
|
||||
throw std::runtime_error(err_msg);
|
||||
check_size<uint16_t>(total_sz, err_msg);
|
||||
|
||||
capabilities(Endian::le_to_host(*(uint16_t*)buffer));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ compile: $(OBJECTS)
|
||||
|
||||
recompile: clean all
|
||||
|
||||
depends: $(SOURCES) $(DEPS)
|
||||
depends: $(SOURCES)
|
||||
rm -f ./depends.d
|
||||
make do_make_deps
|
||||
|
||||
|
||||
@@ -214,6 +214,26 @@ src/rc4eapol.o: src/rc4eapol.cpp ../include/eapol.h ../include/pdu.h \
|
||||
../include/ip_address.h:
|
||||
|
||||
../include/hw_address.h:
|
||||
src/rsn_eapol.o: src/rsn_eapol.cpp ../include/eapol.h ../include/pdu.h \
|
||||
../include/small_uint.h ../include/endianness.h ../include/utils.h \
|
||||
../include/ip_address.h ../include/hw_address.h \
|
||||
../include/rsn_information.h
|
||||
|
||||
../include/eapol.h:
|
||||
|
||||
../include/pdu.h:
|
||||
|
||||
../include/small_uint.h:
|
||||
|
||||
../include/endianness.h:
|
||||
|
||||
../include/utils.h:
|
||||
|
||||
../include/ip_address.h:
|
||||
|
||||
../include/hw_address.h:
|
||||
|
||||
../include/rsn_information.h:
|
||||
src/snap.o: src/snap.cpp ../include/snap.h ../include/pdu.h \
|
||||
../include/endianness.h ../include/small_uint.h ../include/utils.h \
|
||||
../include/ip_address.h ../include/hw_address.h
|
||||
@@ -319,7 +339,7 @@ src/wep_decrypt.o: src/wep_decrypt.cpp ../include/crypto.h \
|
||||
../include/hw_address.h ../include/small_uint.h ../include/pdu_option.h \
|
||||
../include/network_interface.h ../include/ip_address.h \
|
||||
../include/utils.h ../include/snap.h ../include/rawpdu.h \
|
||||
../include/radiotap.h ../include/arp.h
|
||||
../include/arp.h
|
||||
|
||||
../include/crypto.h:
|
||||
|
||||
@@ -345,8 +365,6 @@ src/wep_decrypt.o: src/wep_decrypt.cpp ../include/crypto.h \
|
||||
|
||||
../include/rawpdu.h:
|
||||
|
||||
../include/radiotap.h:
|
||||
|
||||
../include/arp.h:
|
||||
src/dot11/ack.o: src/dot11/ack.cpp ../include/dot11.h ../include/pdu.h \
|
||||
../include/endianness.h ../include/hw_address.h ../include/small_uint.h \
|
||||
@@ -917,9 +935,8 @@ include/tests/dot11.h:
|
||||
../src/dot11.o: ../src/dot11.cpp ../include/dot11.h ../include/pdu.h \
|
||||
../include/endianness.h ../include/hw_address.h ../include/small_uint.h \
|
||||
../include/pdu_option.h ../include/network_interface.h \
|
||||
../include/ip_address.h ../include/rawpdu.h ../include/radiotap.h \
|
||||
../include/rsn_information.h ../include/packet_sender.h \
|
||||
../include/snap.h
|
||||
../include/ip_address.h ../include/rawpdu.h ../include/rsn_information.h \
|
||||
../include/packet_sender.h ../include/snap.h
|
||||
|
||||
../include/dot11.h:
|
||||
|
||||
@@ -939,8 +956,6 @@ include/tests/dot11.h:
|
||||
|
||||
../include/rawpdu.h:
|
||||
|
||||
../include/radiotap.h:
|
||||
|
||||
../include/rsn_information.h:
|
||||
|
||||
../include/packet_sender.h:
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
|
||||
const uint8_t RadioTapTest::expected_packet[] = {
|
||||
'\x00', '\x00', ' ', '\x00', 'g', '\x08', '\x04', '\x00', 'T', '\xc6',
|
||||
'\xb8', '$', '\x00', '\x00', '\x00', '\x00', '"', '\x0c', '\xda',
|
||||
'\xb8', '$', '\x00', '\x00', '\x00', '\x00', '\x10', '\x0c', '\xda',
|
||||
'\xa0', '\x02', '\x00', '\x00', '\x00', '@', '\x01', '\x00', '\x00',
|
||||
'<', '\x14', '$', '\x11', '\x80', '\x00', '\x00', '\x00', '\xff',
|
||||
'\xff', '\xff', '\xff', '\xff', '\xff', '\x06', '\x03', '\x7f',
|
||||
@@ -31,7 +31,8 @@ const uint8_t RadioTapTest::expected_packet[] = {
|
||||
'\x1e', '\x9d', '\x01', '\x1e', '\xa1', '\x01', '\x1e', '\xa5', '\x01',
|
||||
'\x1e', ' ', '\x01', '\x00', '\xdd', '\x18', '\x00', 'P', '\xf2',
|
||||
'\x02', '\x01', '\x01', '\x00', '\x00', '\x03', '\xa4', '\x00', '\x00',
|
||||
'\'', '\xa4', '\x00', '\x00', 'B', 'C', '^', '\x00', 'b', '2', '/', '\x00'
|
||||
'\'', '\xa4', '\x00', '\x00', 'B', 'C', '^', '\x00', 'b', '2', '/', '\x00',
|
||||
'\xe5', '\x2d', '\x92', '\x11'
|
||||
};
|
||||
|
||||
TEST_F(RadioTapTest, DefaultConstructor) {
|
||||
@@ -48,6 +49,10 @@ TEST_F(RadioTapTest, DefaultConstructor) {
|
||||
TEST_F(RadioTapTest, ConstructorFromBuffer) {
|
||||
RadioTap radio(expected_packet, sizeof(expected_packet));
|
||||
EXPECT_EQ(radio.version(), 0);
|
||||
EXPECT_EQ(radio.length(), 32);
|
||||
EXPECT_EQ(radio.rate(), 0xc);
|
||||
EXPECT_EQ(radio.flags(), 0x10);
|
||||
EXPECT_TRUE(radio.flags() & RadioTap::FCS);
|
||||
EXPECT_EQ(radio.channel_type(), 0x140);
|
||||
EXPECT_EQ(radio.tsft(), 616089172);
|
||||
EXPECT_EQ(radio.dbm_signal(), 0xda);
|
||||
@@ -60,6 +65,7 @@ TEST_F(RadioTapTest, Serialize) {
|
||||
RadioTap::serialization_type buffer = radio.serialize();
|
||||
|
||||
ASSERT_EQ(buffer.size(), sizeof(expected_packet));
|
||||
|
||||
EXPECT_TRUE(std::equal(buffer.begin(), buffer.end(), expected_packet));
|
||||
}
|
||||
|
||||
|
||||
200
tests/src/rsn_eapol.cpp
Normal file
200
tests/src/rsn_eapol.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "eapol.h"
|
||||
#include "utils.h"
|
||||
#include "rsn_information.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Tins;
|
||||
|
||||
class RSNEAPOLTest : public testing::Test {
|
||||
public:
|
||||
static const uint8_t expected_packet[];
|
||||
|
||||
void test_equals(const RSNEAPOL &eapol1, const RSNEAPOL &eapol2);
|
||||
};
|
||||
|
||||
uint8_t empty_iv[RSNEAPOL::key_iv_size] = { 0 };
|
||||
|
||||
const uint8_t nonce[RSNEAPOL::nonce_size] = {
|
||||
'\xb9', 'o', '\xe7', '\xfa', '\xca', '[', '\'', '\xe2', 'M', '\x04',
|
||||
'\xf1', '\xe6', 'l', '\x06', '\xe1', '\x9b', '\xb3', ':', 'k', '$',
|
||||
'\xb4', '9', '\xbb', '\xe4', '\xde', '\xd9', '\n', '\xcc', '\xd1',
|
||||
'3', '\x1e', '\x9e'
|
||||
};
|
||||
const uint8_t mic[RSNEAPOL::mic_size] = {
|
||||
'\xb1', '\xba', '\xac', 'U', '\x96', 'J', '\xbd', '0', 'V',
|
||||
'\x85', 'e', '*', '\xb2', '&', 'u', '\x82'
|
||||
};
|
||||
const uint8_t key[56] = {
|
||||
'\xe2', '\xc5', 'O', 'G', '\xf3', '\x0e', '\xc9', '/', 'B', '\xd8',
|
||||
'\xd5', '\x1e', '1', '\x9d', '\xf5', 'H', '`', 'm', 'N', '\xe3',
|
||||
'\xd9', '\x84', '\xd3', 'C', 'Z', '\x15', '\xfc', 'X', '\x0f',
|
||||
'>', 't', '`', '@', '\x91', '\x10', '`', '\xef', '\xb1', 'C',
|
||||
'\xf8', '\xfd', '\xb6', '\n', '6', '\xcb', '\xa4', 'D', '\x98',
|
||||
'&', '\x07', '\x1a', '\xff', '\x8b', '\x93', '\xd3', '.'
|
||||
};
|
||||
const uint8_t rsc[RSNEAPOL::rsc_size] = {
|
||||
'\xb1', '\x06'
|
||||
};
|
||||
const uint8_t id[RSNEAPOL::id_size] = {
|
||||
0
|
||||
};
|
||||
|
||||
const uint8_t RSNEAPOLTest::expected_packet[] = {
|
||||
'\x01', '\x03', '\x00', '\x97', '\x02', '\x13', '\xca', '\x00',
|
||||
'\x10', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\x02', '\xb9', 'o', '\xe7', '\xfa', '\xca', '[', '\'', '\xe2', 'M',
|
||||
'\x04', '\xf1', '\xe6', 'l', '\x06', '\xe1', '\x9b', '\xb3', ':',
|
||||
'k', '$', '\xb4', '9', '\xbb', '\xe4', '\xde', '\xd9', '\n', '\xcc',
|
||||
'\xd1', '3', '\x1e', '\x9e', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\x00', '\x00', '\xb1', '\x06', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\xb1', '\xba', '\xac', 'U', '\x96', 'J', '\xbd', '0', 'V', '\x85',
|
||||
'e', '*', '\xb2', '&', 'u', '\x82', '\x00', '8', '\xe2', '\xc5', 'O',
|
||||
'G', '\xf3', '\x0e', '\xc9', '/', 'B', '\xd8', '\xd5', '\x1e', '1',
|
||||
'\x9d', '\xf5', 'H', '`', 'm', 'N', '\xe3', '\xd9', '\x84', '\xd3',
|
||||
'C', 'Z', '\x15', '\xfc', 'X', '\x0f', '>', 't', '`', '@', '\x91',
|
||||
'\x10', '`', '\xef', '\xb1', 'C', '\xf8', '\xfd', '\xb6', '\n', '6',
|
||||
'\xcb', '\xa4', 'D', '\x98', '&', '\x07', '\x1a', '\xff', '\x8b',
|
||||
'\x93', '\xd3', '.'
|
||||
};
|
||||
|
||||
void RSNEAPOLTest::test_equals(const RSNEAPOL &eapol1, const RSNEAPOL &eapol2) {
|
||||
EXPECT_EQ(eapol1.version(), eapol2.version());
|
||||
EXPECT_EQ(eapol1.packet_type(), eapol2.packet_type());
|
||||
EXPECT_EQ(eapol1.type(), eapol2.type());
|
||||
EXPECT_EQ(eapol1.length(), eapol2.length());
|
||||
EXPECT_EQ(eapol1.key_length(), eapol2.key_length());
|
||||
EXPECT_EQ(eapol1.replay_counter(), eapol2.replay_counter());
|
||||
EXPECT_TRUE(std::equal(eapol1.key_iv(), eapol1.key_iv() + RSNEAPOL::key_iv_size, eapol2.key_iv()));
|
||||
EXPECT_TRUE(std::equal(eapol1.id(), eapol1.id() + RSNEAPOL::id_size, eapol2.id()));
|
||||
EXPECT_TRUE(std::equal(eapol1.rsc(), eapol1.rsc() + RSNEAPOL::rsc_size, eapol2.rsc()));
|
||||
EXPECT_EQ(eapol1.wpa_length(), eapol2.wpa_length());
|
||||
EXPECT_TRUE(std::equal(eapol1.nonce(), eapol1.nonce() + RSNEAPOL::nonce_size, eapol2.nonce()));
|
||||
EXPECT_TRUE(std::equal(eapol1.mic(), eapol1.mic() + RSNEAPOL::mic_size, eapol2.mic()));
|
||||
EXPECT_EQ(eapol1.key(), eapol2.key());
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, DefaultConstructor) {
|
||||
uint8_t empty_nonce[RSNEAPOL::nonce_size] = { 0 };
|
||||
uint8_t empty_rsc[RSNEAPOL::rsc_size] = { 0 };
|
||||
|
||||
RSNEAPOL eapol;
|
||||
EXPECT_EQ(1, eapol.version());
|
||||
EXPECT_EQ(0x3, eapol.packet_type());
|
||||
EXPECT_EQ(EAPOL::RSN, eapol.type());
|
||||
EXPECT_EQ(0, eapol.length());
|
||||
EXPECT_EQ(0, eapol.key_length());
|
||||
EXPECT_EQ(0, eapol.replay_counter());
|
||||
EXPECT_TRUE(std::equal(empty_iv, empty_iv + sizeof(empty_iv), eapol.key_iv()));
|
||||
EXPECT_TRUE(std::equal(empty_rsc, empty_rsc + sizeof(empty_rsc), eapol.id()));
|
||||
EXPECT_TRUE(std::equal(empty_rsc, empty_rsc + sizeof(empty_rsc), eapol.rsc()));
|
||||
EXPECT_EQ(0, eapol.wpa_length());
|
||||
EXPECT_TRUE(std::equal(empty_nonce, empty_nonce + sizeof(empty_nonce), eapol.nonce()));
|
||||
EXPECT_TRUE(std::equal(empty_iv, empty_iv + sizeof(empty_iv), eapol.mic()));
|
||||
EXPECT_EQ(RSNEAPOL::key_type(), eapol.key());
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, ConstructorFromBuffer) {
|
||||
RSNEAPOL eapol(expected_packet, sizeof(expected_packet));
|
||||
EXPECT_EQ(1, eapol.version());
|
||||
EXPECT_EQ(3, eapol.packet_type());
|
||||
EXPECT_EQ(151, eapol.length());
|
||||
EXPECT_EQ(EAPOL::RSN, eapol.type());
|
||||
|
||||
EXPECT_EQ(1, eapol.key_t());
|
||||
EXPECT_EQ(0, eapol.key_index());
|
||||
EXPECT_EQ(1, eapol.install());
|
||||
EXPECT_EQ(1, eapol.key_ack());
|
||||
EXPECT_EQ(1, eapol.key_mic());
|
||||
EXPECT_EQ(1, eapol.secure());
|
||||
EXPECT_EQ(0, eapol.error());
|
||||
EXPECT_EQ(0, eapol.request());
|
||||
EXPECT_EQ(1, eapol.encrypted());
|
||||
|
||||
EXPECT_EQ(16, eapol.key_length());
|
||||
EXPECT_EQ(2, eapol.replay_counter());
|
||||
EXPECT_TRUE(std::equal(nonce, nonce + sizeof(nonce), eapol.nonce()));
|
||||
EXPECT_TRUE(std::equal(empty_iv, empty_iv + sizeof(empty_iv), eapol.key_iv()));
|
||||
EXPECT_TRUE(std::equal(rsc, rsc + sizeof(rsc), eapol.rsc()));
|
||||
EXPECT_TRUE(std::equal(id, id + sizeof(id), eapol.id()));
|
||||
EXPECT_TRUE(std::equal(mic, mic + sizeof(mic), eapol.mic()));
|
||||
ASSERT_EQ(56, eapol.wpa_length());
|
||||
RSNEAPOL::key_type key_found = eapol.key();
|
||||
ASSERT_EQ(56, key_found.size());
|
||||
EXPECT_TRUE(std::equal(key, key + sizeof(key), key_found.begin()));
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, Serialize) {
|
||||
RSNEAPOL eapol(expected_packet, sizeof(expected_packet));
|
||||
RSNEAPOL::serialization_type buffer = eapol.serialize();
|
||||
ASSERT_EQ(sizeof(expected_packet), buffer.size());
|
||||
EXPECT_TRUE(std::equal(buffer.begin(), buffer.end(), expected_packet));
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, ConstructionTest) {
|
||||
RSNEAPOL eapol;
|
||||
eapol.version(1);
|
||||
eapol.packet_type(3);
|
||||
eapol.length(151);
|
||||
eapol.key_length(16);
|
||||
eapol.replay_counter(2);
|
||||
eapol.nonce(nonce);
|
||||
eapol.key_iv(empty_iv);
|
||||
eapol.rsc(rsc);
|
||||
eapol.id(id);
|
||||
eapol.mic(mic);
|
||||
eapol.key(RSNEAPOL::key_type(key, key + sizeof(key)));
|
||||
|
||||
eapol.key_descriptor(2);
|
||||
eapol.key_t(1);
|
||||
eapol.install(1);
|
||||
eapol.key_ack(1);
|
||||
eapol.key_mic(1);
|
||||
eapol.secure(1);
|
||||
eapol.encrypted(1);
|
||||
|
||||
RSNEAPOL::serialization_type buffer = eapol.serialize();
|
||||
ASSERT_EQ(sizeof(expected_packet), buffer.size());
|
||||
|
||||
RSNEAPOL eapol2(&buffer[0], buffer.size());
|
||||
test_equals(eapol, eapol2);
|
||||
|
||||
EXPECT_TRUE(std::equal(buffer.begin(), buffer.end(), expected_packet));
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, ReplayCounter) {
|
||||
RSNEAPOL eapol;
|
||||
eapol.replay_counter(0x7af3d91a1fd3abLL);
|
||||
EXPECT_EQ(0x7af3d91a1fd3abLL, eapol.replay_counter());
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, WPALength) {
|
||||
RSNEAPOL eapol;
|
||||
eapol.wpa_length(0x9af1);
|
||||
EXPECT_EQ(0x9af1, eapol.wpa_length());
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, KeyIV) {
|
||||
RSNEAPOL eapol;
|
||||
eapol.key_iv(empty_iv);
|
||||
EXPECT_TRUE(std::equal(empty_iv, empty_iv + sizeof(empty_iv), eapol.key_iv()));
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, Nonce) {
|
||||
RSNEAPOL eapol;
|
||||
eapol.nonce(nonce);
|
||||
EXPECT_TRUE(std::equal(nonce, nonce + sizeof(nonce), eapol.nonce()));
|
||||
}
|
||||
|
||||
TEST_F(RSNEAPOLTest, Key) {
|
||||
RSNEAPOL eapol;
|
||||
uint8_t arr[] = { 1, 9, 2, 0x71, 0x87, 0xfa, 0xdf };
|
||||
RSNEAPOL::key_type key(arr, arr + sizeof(arr));
|
||||
eapol.key(key);
|
||||
EXPECT_EQ(key, eapol.key());
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "crypto.h"
|
||||
#include "radiotap.h"
|
||||
#include "arp.h"
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
Reference in New Issue
Block a user