From de606ec49893d6dd9276e6280bbc24ecc8315c84 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 31 Aug 2024 15:48:02 +0900 Subject: [PATCH 01/37] Add WireGuard protocol parsing support in UDP Packet Signed-off-by: Dongjun Na --- Common++/header/Logger.h | 1 + Packet++/header/ProtocolType.h | 5 + Packet++/header/WireGuardLayer.h | 258 +++++++++++++++++++++++++++++++ Packet++/src/UdpLayer.cpp | 3 + Packet++/src/WireGuardLayer.cpp | 151 ++++++++++++++++++ 5 files changed, 418 insertions(+) create mode 100644 Packet++/header/WireGuardLayer.h create mode 100644 Packet++/src/WireGuardLayer.cpp diff --git a/Common++/header/Logger.h b/Common++/header/Logger.h index 6973cf530d..fafe6a9e37 100644 --- a/Common++/header/Logger.h +++ b/Common++/header/Logger.h @@ -103,6 +103,7 @@ namespace pcpp PacketLogModuleSomeIpSdLayer, ///< SomeIpSdLayer module (Packet++) PacketLogModuleWakeOnLanLayer, ///< WakeOnLanLayer module (Packet++) PacketLogModuleSmtpLayer, ///< SmtpLayer module (Packet++) + PacketLogModuleWireGuardLayer, ///< WireGuardLayer module (Packet++) PcapLogModuleWinPcapLiveDevice, ///< WinPcapLiveDevice module (Pcap++) PcapLogModuleRemoteDevice, ///< WinPcapRemoteDevice module (Pcap++) PcapLogModuleLiveDevice, ///< PcapLiveDevice module (Pcap++) diff --git a/Packet++/header/ProtocolType.h b/Packet++/header/ProtocolType.h index ada6950c5e..f2ad34558b 100644 --- a/Packet++/header/ProtocolType.h +++ b/Packet++/header/ProtocolType.h @@ -347,6 +347,11 @@ namespace pcpp */ const ProtocolType LDAP = 55; + /* + * Wireguard protocol + */ + const ProtocolType WIREGUARD = 56; + /** * An enum representing OSI model layers */ diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h new file mode 100644 index 0000000000..d27800ea01 --- /dev/null +++ b/Packet++/header/WireGuardLayer.h @@ -0,0 +1,258 @@ +#pragma once + +#include "Layer.h" +#include "IpAddress.h" +#include "MacAddress.h" +#include +#include + +/// @file + +/** + * \namespace pcpp + * \brief The main namespace for the PcapPlusPlus lib + */ +namespace pcpp +{ + + /** + * WireGuard message types + */ + enum WireGuardMessageType + { + HandshakeInitiation = 1, ///< Handshake Initiation message + HandshakeResponse = 2, ///< Handshake Response message + CookieReply = 3, ///< Cookie Reply message + TransportData = 4 ///< Transport Data message + }; + + /** + * @struct wg_common_header + * Represents the common header for all WireGuard message types + */ +#pragma pack(push, 1) + struct wg_common_header + { + /** Message type field */ + uint8_t messageType; + /** Reserved field (3 bytes) */ + uint8_t reserved[3]; + }; +#pragma pack(pop) + + /** + * @struct wg_handshake_initiation + * Represents the Handshake Initiation message + */ +#pragma pack(push, 1) + struct wg_handshake_initiation + { + wg_common_header common; ///< Common header for all WireGuard messages + uint32_t senderIndex; ///< Sender index + uint8_t initiatorEphemeral[32]; ///< Initiator's ephemeral public key + uint8_t encryptedInitiatorStatic[48]; ///< Encrypted initiator's static key + uint8_t encryptedTimestamp[28]; ///< Encrypted timestamp + uint8_t mac1[16]; ///< MAC1 field + uint8_t mac2[16]; ///< MAC2 field + }; +#pragma pack(pop) + + /** + * @struct wg_handshake_response + * Represents the Handshake Response message + */ +#pragma pack(push, 1) + struct wg_handshake_response + { + wg_common_header common; ///< Common header for all WireGuard messages + uint32_t senderIndex; ///< Sender index + uint32_t receiverIndex; ///< Receiver index + uint8_t responderEphemeral[32]; ///< Responder's ephemeral public key + uint8_t encryptedEmpty[16]; ///< Encrypted empty field + uint8_t mac1[16]; ///< MAC1 field + uint8_t mac2[16]; ///< MAC2 field + }; +#pragma pack(pop) + + /** + * @struct wg_cookie_reply + * Represents the Cookie Reply message + */ +#pragma pack(push, 1) + struct wg_cookie_reply + { + wg_common_header common; ///< Common header for all WireGuard messages + uint32_t receiverIndex; ///< Receiver index + uint8_t nonce[24]; ///< Nonce field + uint8_t encryptedCookie[32]; ///< Encrypted cookie + }; +#pragma pack(pop) + + /** + * @struct wg_transport_data + * Represents the Transport Data message + */ +#pragma pack(push, 1) + struct wg_transport_data + { + wg_common_header common; ///< Common header for all WireGuard messages + uint32_t receiverIndex; ///< Receiver index + uint64_t counter; ///< Counter field + uint8_t encryptedData[0]; ///< Flexible array member for encrypted data + }; +#pragma pack(pop) + + /** + * @class WireGuardLayer + * Represents a WireGuard protocol layer + */ + class WireGuardLayer : public Layer + { + public: + /** + * Constructs a WireGuardLayer object. + * + * @param data Pointer to the raw data representing the WireGuard layer + * @param dataLen Length of the data + * @param prevLayer Pointer to the previous layer in the packet (if any) + * @param packet Pointer to the packet this layer belongs to + */ + WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) + : Layer(data, dataLen, prevLayer, packet) + { + m_Protocol = WIREGUARD; + m_Data = data; + m_DataLen = dataLen; + } + + /** + * Gets a pointer to the Handshake Initiation message. + * + * @return Pointer to the Handshake Initiation message, or nullptr if data is invalid + */ + const wg_handshake_initiation* getHandshakeInitiation() const + { + return reinterpret_cast(m_Data); + } + + /** + * Gets a pointer to the Handshake Response message. + * + * @return Pointer to the Handshake Response message, or nullptr if data is invalid + */ + const wg_handshake_response* getHandshakeResponse() const + { + return reinterpret_cast(m_Data); + } + + /** + * Gets a pointer to the Cookie Reply message. + * + * @return Pointer to the Cookie Reply message, or nullptr if data is invalid + */ + const wg_cookie_reply* getCookieReply() const + { + return reinterpret_cast(m_Data); + } + + /** + * Gets a pointer to the Transport Data message. + * + * @return Pointer to the Transport Data message, or nullptr if data is invalid + */ + const wg_transport_data* getTransportData() const + { + return reinterpret_cast(m_Data); + } + + /** + * Checks if the given port numbers are WireGuard ports. + * + * @param portSrc The source port number to check + * @param portDst The destination port number to check + * @return True if either port matches the WireGuard port (51820), false otherwise + */ + static inline bool isWireguardPorts(uint16_t portSrc, uint16_t portDst); + + /** + * Checks if the given data represents a WireGuard message. + * + * @param data Pointer to the raw data + * @param dataLen Length of the data + * @return True if the data starts with a valid WireGuard message type, false otherwise + */ + static inline bool isWireGuard(uint8_t* data, size_t dataLen); + + /** + * No operation required for parsing the next layer since WireGuard does not have a next layer. + */ + void parseNextLayer() + { + // No next layer to parse for WireGuard, do nothing + } + + /** + * Calculates the length of the header based on the message type. + * + * @return Size of the header in bytes. For TransportData, returns the total data length. + */ + size_t getHeaderLen() const; + + /** + * No fields to compute or update, so this method is left empty. + */ + void computeCalculateFields() + { + // Since WireGuard headers have fixed lengths and no fields to compute (like checksums or lengths), + // this method does not need to perform any operations. It's left empty. + } + + /** + * Converts the WireGuard layer to a string representation. + * + * @return String representation of the WireGuard layer + */ + std::string toString() const; + + /** + * Returns the OSI model layer that this protocol belongs to. + * + * @return OSI model layer corresponding to the Network layer + */ + OsiModelLayer getOsiModelLayer() const + { + return OsiModelNetworkLayer; + } + }; + + // Implementation of inline methods + + /** + * Checks if the given port numbers are WireGuard ports. + * + * @param portSrc The source port number to check + * @param portDst The destination port number to check + * @return True if either port matches the WireGuard port (51820), false otherwise + */ + bool WireGuardLayer::isWireguardPorts(uint16_t portSrc, uint16_t portDst) + { + return (portSrc == 51820 || portDst == 51820); + } + + /** + * Checks if the given data represents a WireGuard message. + * + * @param data Pointer to the raw data + * @param dataLen Length of the data + * @return True if the data starts with a valid WireGuard message type, false otherwise + */ + bool WireGuardLayer::isWireGuard(uint8_t* data, size_t dataLen) + { + if (dataLen < sizeof(wg_common_header)) + return false; + + uint8_t messageType = data[0]; + return messageType >= HandshakeInitiation && messageType <= TransportData; + } + +} // namespace pcpp \ No newline at end of file diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp index 2e17b9cddc..ca8145d4c1 100644 --- a/Packet++/src/UdpLayer.cpp +++ b/Packet++/src/UdpLayer.cpp @@ -15,6 +15,7 @@ #include "NtpLayer.h" #include "SomeIpLayer.h" #include "WakeOnLanLayer.h" +#include "WireGuardLayer.h" #include "PacketUtils.h" #include "Logger.h" #include @@ -134,6 +135,8 @@ namespace pcpp m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, m_Packet); else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen))) m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); + else if ((WireGuardLayer::isWireguardPorts(portDst, portSrc) && WireGuardLayer::isWireGuard(udpData, udpDataLen))) + m_NextLayer = new WireGuardLayer(udpData, udpDataLen, this, m_Packet); else m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); } diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp new file mode 100644 index 0000000000..9f0836611f --- /dev/null +++ b/Packet++/src/WireGuardLayer.cpp @@ -0,0 +1,151 @@ +#define LOG_MODULE PacketLogModuleWireGuardLayer + +#include "UdpLayer.h" +#include "IPv4Layer.h" +#include "IPv6Layer.h" +#include "WireGuardLayer.h" +#include "Logger.h" +#include +#include +#include + +namespace pcpp +{ + std::string WireGuardLayer::toString() const + { + std::stringstream ss; + + if (m_DataLen < sizeof(wg_common_header)) + { + ss << "WireGuard header (incomplete)"; + return ss.str(); + } + + const wg_common_header* header = reinterpret_cast(m_Data); + ss << "WireGuard Layer\n"; + ss << " Type: " << static_cast(header->messageType) << "\n"; + ss << " Reserved: "; + for (int i = 0; i < 3; ++i) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(header->reserved[i]); + } + ss << std::dec << "\n"; // Reset to decimal + + switch (header->messageType) + { + case HandshakeInitiation: + { + const wg_handshake_initiation* msg = getHandshakeInitiation(); + ss << " Handshake Initiation\n"; + ss << " Sender Index: " << msg->senderIndex << "\n"; + ss << " Initiator Ephemeral: "; + for (const auto& byte : msg->initiatorEphemeral) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " Encrypted Initiator Static: "; + for (const auto& byte : msg->encryptedInitiatorStatic) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " Encrypted Timestamp: "; + for (const auto& byte : msg->encryptedTimestamp) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " MAC1: "; + for (const auto& byte : msg->mac1) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " MAC2: "; + for (const auto& byte : msg->mac2) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + break; + } + case HandshakeResponse: + { + const wg_handshake_response* msg = getHandshakeResponse(); + ss << " Handshake Response\n"; + ss << " Sender Index: " << msg->senderIndex << "\n"; + ss << " Receiver Index: " << msg->receiverIndex << "\n"; + ss << " Responder Ephemeral: "; + for (const auto& byte : msg->responderEphemeral) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " Encrypted Empty: "; + for (const auto& byte : msg->encryptedEmpty) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " MAC1: "; + for (const auto& byte : msg->mac1) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " MAC2: "; + for (const auto& byte : msg->mac2) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + break; + } + case CookieReply: + { + const wg_cookie_reply* msg = getCookieReply(); + ss << " Cookie Reply\n"; + ss << " Receiver Index: " << msg->receiverIndex << "\n"; + ss << " Nonce: "; + for (const auto& byte : msg->nonce) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + ss << " Encrypted Cookie: "; + for (const auto& byte : msg->encryptedCookie) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + ss << std::dec << "\n"; + break; + } + case TransportData: + { + const wg_transport_data* msg = getTransportData(); + ss << " Transport Data\n"; + ss << " Receiver Index: " << msg->receiverIndex << "\n"; + ss << " Counter: " << msg->counter << "\n"; + ss << " Encrypted Data: "; + for (size_t i = 0; i < m_DataLen - sizeof(wg_transport_data); ++i) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(msg->encryptedData[i]); + } + ss << std::dec << "\n"; + break; + } + default: + ss << " Unknown message type\n"; + break; + } + + return ss.str(); + } + + size_t WireGuardLayer::getHeaderLen() const + { + return m_DataLen; + } + +} // namespace pcpp From e5c9d16dc4586e83f5ed4a1bade2f8ef376870fe Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 31 Aug 2024 15:49:23 +0900 Subject: [PATCH 02/37] Updated CMakeLists.txt to include WireGuardLayer source and header files Signed-off-by: Dongjun Na --- Packet++/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Packet++/CMakeLists.txt b/Packet++/CMakeLists.txt index cc7a8268d2..bab9488be6 100644 --- a/Packet++/CMakeLists.txt +++ b/Packet++/CMakeLists.txt @@ -64,6 +64,7 @@ add_library( src/VrrpLayer.cpp src/VxlanLayer.cpp src/WakeOnLanLayer.cpp + src/WireGuardLayer.cpp # Force hash-library pcapng to be link fully static ) @@ -133,7 +134,8 @@ set(public_headers header/VlanLayer.h header/VrrpLayer.h header/VxlanLayer.h - header/WakeOnLanLayer.h) + header/WakeOnLanLayer.h + header/WireGuardLayer.h) # Don't use set_target_properties CMake limit to 50 elements set_property(TARGET Packet++ PROPERTY PUBLIC_HEADER ${public_headers}) From 5e9410c74158bae8c789efdda6fafe96e858bf9d Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 31 Aug 2024 15:52:31 +0900 Subject: [PATCH 03/37] lint Signed-off-by: Dongjun Na --- Packet++/src/WireGuardLayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 9f0836611f..66c21093e6 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -145,7 +145,7 @@ namespace pcpp size_t WireGuardLayer::getHeaderLen() const { - return m_DataLen; + return m_DataLen; } } // namespace pcpp From 7e6c3229974ef1a7cf1cd109563e96afa02051b9 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 31 Aug 2024 17:16:56 +0900 Subject: [PATCH 04/37] lint Signed-off-by: Dongjun Na --- Packet++/src/UdpLayer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp index ca8145d4c1..4a1a8f8a69 100644 --- a/Packet++/src/UdpLayer.cpp +++ b/Packet++/src/UdpLayer.cpp @@ -135,7 +135,8 @@ namespace pcpp m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, m_Packet); else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen))) m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); - else if ((WireGuardLayer::isWireguardPorts(portDst, portSrc) && WireGuardLayer::isWireGuard(udpData, udpDataLen))) + else if ((WireGuardLayer::isWireguardPorts(portDst, portSrc) && + WireGuardLayer::isWireGuard(udpData, udpDataLen))) m_NextLayer = new WireGuardLayer(udpData, udpDataLen, this, m_Packet); else m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); From 5725d784c06c0d3d7b78220fdc53435e6d6be21b Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 31 Aug 2024 17:51:18 +0900 Subject: [PATCH 05/37] Refactor data parameter const in isWireGuard and lint Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index d27800ea01..68d03defee 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -181,7 +181,7 @@ namespace pcpp * @param dataLen Length of the data * @return True if the data starts with a valid WireGuard message type, false otherwise */ - static inline bool isWireGuard(uint8_t* data, size_t dataLen); + static inline bool isWireGuard(const uint8_t* data, size_t dataLen); /** * No operation required for parsing the next layer since WireGuard does not have a next layer. @@ -246,7 +246,7 @@ namespace pcpp * @param dataLen Length of the data * @return True if the data starts with a valid WireGuard message type, false otherwise */ - bool WireGuardLayer::isWireGuard(uint8_t* data, size_t dataLen) + bool WireGuardLayer::isWireGuard(const uint8_t* data, size_t dataLen) { if (dataLen < sizeof(wg_common_header)) return false; @@ -255,4 +255,4 @@ namespace pcpp return messageType >= HandshakeInitiation && messageType <= TransportData; } -} // namespace pcpp \ No newline at end of file +} // namespace pcpp From 58c67d330270a67e34c5be8e3c6996fdc938e629 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 12:04:27 +0900 Subject: [PATCH 06/37] Add test pcap data for WireGuard tests Signed-off-by: Dongjun Na --- .../Packet++Test/PacketExamples/WireGuardHandshakeInitiation.dat | 1 + Tests/Packet++Test/PacketExamples/WireGuardHandshakeResponse.dat | 1 + Tests/Packet++Test/PacketExamples/WireGuardTransportData.dat | 1 + 3 files changed, 3 insertions(+) create mode 100644 Tests/Packet++Test/PacketExamples/WireGuardHandshakeInitiation.dat create mode 100644 Tests/Packet++Test/PacketExamples/WireGuardHandshakeResponse.dat create mode 100644 Tests/Packet++Test/PacketExamples/WireGuardTransportData.dat diff --git a/Tests/Packet++Test/PacketExamples/WireGuardHandshakeInitiation.dat b/Tests/Packet++Test/PacketExamples/WireGuardHandshakeInitiation.dat new file mode 100644 index 0000000000..5c3cc26711 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/WireGuardHandshakeInitiation.dat @@ -0,0 +1 @@ +a2e63494b5833a36e5bf5af80800458800b0024b0000401163560a0900010a090002a9c6ca6c009c14c201000000d837d0305fcec7c8e5c8e2e3f7989eef60c228d82329d602b6b1e2bb9d068f89cf9d4d4532780f6d27264f7b98701fdc27a4ec00aeb6becdbef2332f1b4084cadb93823935c012ae255e7b25eff13940c321fa6bd66a2a87b061db1430173e937f569349de2856dc5f2616763eeeafc0533b01dd965e7ec76976e28f683d671200000000000000000000000000000000 \ No newline at end of file diff --git a/Tests/Packet++Test/PacketExamples/WireGuardHandshakeResponse.dat b/Tests/Packet++Test/PacketExamples/WireGuardHandshakeResponse.dat new file mode 100644 index 0000000000..8242113990 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/WireGuardHandshakeResponse.dat @@ -0,0 +1 @@ +3a36e5bf5af8a2e63494b5830800458800782a39000040113ba00a0900020a090001ca6ca9c60064148a0200000006f47dabd837d030b18d5550bd4042a37a46823ac08db1ec66839bc0ca2d64bc15cd80232b66232faec24af8918de1060ff5c98e865d5f35f272214c5260110dc4c61e32cdd8542100000000000000000000000000000000 \ No newline at end of file diff --git a/Tests/Packet++Test/PacketExamples/WireGuardTransportData.dat b/Tests/Packet++Test/PacketExamples/WireGuardTransportData.dat new file mode 100644 index 0000000000..766c173f54 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/WireGuardTransportData.dat @@ -0,0 +1 @@ +a2e63494b5833a36e5bf5af808004500009c024c0000401163f10a0900010a090002a9c6ca6c008814ae0400000006f47dab0000000000000000a4ebc12ee3f990da18033a0789c04e2700f6f5c271d42ac4b4d6262e666549b445a7436e829bffb6ac65f05648bc0c391fe7c5884874376127164940188f03dba67af8388eaab76c593628bf9dc7be03346d912e916dad862545454701364f2d2486d7ced4c8642ce547ddb26ef6a46b \ No newline at end of file From e9caf5073e8c2a4e7ffbaf6288ad15df95b1c23e Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 12:13:40 +0900 Subject: [PATCH 07/37] Add WireGuard test cases for handshake initiation, response, and transport data Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WGTests.cpp | 157 +++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 Tests/Packet++Test/Tests/WGTests.cpp diff --git a/Tests/Packet++Test/Tests/WGTests.cpp b/Tests/Packet++Test/Tests/WGTests.cpp new file mode 100644 index 0000000000..d9a126c58c --- /dev/null +++ b/Tests/Packet++Test/Tests/WGTests.cpp @@ -0,0 +1,157 @@ +#include "../TestDefinition.h" +#include "../Utils/TestUtils.h" +#include "Packet.h" +#include "EthLayer.h" +#include "UdpLayer.h" +#include "SystemUtils.h" +#include "WireGuardLayer.h" +#include + +PTF_TEST_CASE(WGHandshakeInitParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); + pcpp::Packet parsedPacket(&rawPacket1); + + PTF_ASSERT_TRUE(parsedPacket.isPacketOfType(pcpp::Ethernet)); + PTF_ASSERT_NOT_NULL(parsedPacket.getLayerOfType()); + + pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(udpLayer); + + udpLayer->parseNextLayer(); + pcpp::WireGuardLayer* wgLayer = dynamic_cast(udpLayer->getNextLayer()); + PTF_ASSERT_NOT_NULL(wgLayer); + + size_t headerLen = wgLayer->getHeaderLen(); + PTF_ASSERT_TRUE(headerLen == sizeof(pcpp::wg_handshake_initiation)); + + const pcpp::wg_handshake_initiation* handshakeInit = wgLayer->getHandshakeInitiation(); + PTF_ASSERT_NOT_NULL(handshakeInit); + + PTF_ASSERT_EQUAL(handshakeInit->common.messageType, pcpp::HandshakeInitiation); + PTF_ASSERT_EQUAL(handshakeInit->senderIndex, 818952152); + + uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, + 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, + 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->initiatorEphemeral, expectedPublicKey, sizeof(expectedPublicKey)) == 0); + + uint8_t expectedStaticKey[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, + 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, + 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, + 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; + + PTF_ASSERT_TRUE( + std::memcmp(handshakeInit->encryptedInitiatorStatic, expectedStaticKey, sizeof(expectedStaticKey)) == 0); + + uint8_t expectedTimestamp[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, + 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, + 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->encryptedTimestamp, expectedTimestamp, sizeof(expectedTimestamp)) == 0); + + uint8_t expectedMac1[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, + 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac1, expectedMac1, sizeof(expectedMac1)) == 0); + + uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); +} + +PTF_TEST_CASE(WGHandshakeRespParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); + pcpp::Packet parsedPacket(&rawPacket1); + + PTF_ASSERT_TRUE(parsedPacket.isPacketOfType(pcpp::Ethernet)); + PTF_ASSERT_NOT_NULL(parsedPacket.getLayerOfType()); + + pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(udpLayer); + + udpLayer->parseNextLayer(); + pcpp::WireGuardLayer* wgLayer = dynamic_cast(udpLayer->getNextLayer()); + PTF_ASSERT_NOT_NULL(wgLayer); + + size_t headerLen = wgLayer->getHeaderLen(); + PTF_ASSERT_TRUE(headerLen == sizeof(pcpp::wg_handshake_response)); + + const pcpp::wg_handshake_response* handshakeResponse = wgLayer->getHandshakeResponse(); + PTF_ASSERT_NOT_NULL(handshakeResponse); + + PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, pcpp::HandshakeResponse); + PTF_ASSERT_EQUAL(handshakeResponse->senderIndex, 2877158406); + PTF_ASSERT_EQUAL(handshakeResponse->receiverIndex, 818952152); + + uint8_t expectedResponderEphemeral[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, + 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, + 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->responderEphemeral, expectedResponderEphemeral, + sizeof(expectedResponderEphemeral)) == 0); + + uint8_t expectedMac1[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, + 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac1, expectedMac1, sizeof(expectedMac1)) == 0); + + uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); +} + +PTF_TEST_CASE(WGTransportDataParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); + pcpp::Packet parsedPacket(&rawPacket1); + + PTF_ASSERT_TRUE(parsedPacket.isPacketOfType(pcpp::Ethernet)); + PTF_ASSERT_NOT_NULL(parsedPacket.getLayerOfType()); + + pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(udpLayer); + + udpLayer->parseNextLayer(); + pcpp::WireGuardLayer* wgLayer = dynamic_cast(udpLayer->getNextLayer()); + PTF_ASSERT_NOT_NULL(wgLayer); + + size_t headerLen = wgLayer->getHeaderLen(); + PTF_ASSERT_TRUE(headerLen >= sizeof(pcpp::wg_transport_data)); + + const pcpp::wg_transport_data* transportData = wgLayer->getTransportData(); + PTF_ASSERT_NOT_NULL(transportData); + + PTF_ASSERT_EQUAL(transportData->common.messageType, pcpp::TransportData); + PTF_ASSERT_EQUAL(transportData->receiverIndex, 2877158406); + + uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + PTF_ASSERT_TRUE(std::memcmp(&transportData->counter, &expectedCounter, sizeof(expectedCounter)) == 0); + + uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, + 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, + 0x26, 0x2e, 0x66, 0x65, 0x49, 0xb4, 0x45, 0xa7, 0x43, 0x6e, 0x82, 0x9b, 0xff, + 0xb6, 0xac, 0x65, 0xf0, 0x56, 0x48, 0xbc, 0x0c, 0x39, 0x1f, 0xe7, 0xc5, 0x88, + 0x48, 0x74, 0x37, 0x61, 0x27, 0x16, 0x49, 0x40, 0x18, 0x8f, 0x03, 0xdb, 0xa6, + 0x7a, 0xf8, 0x38, 0x8e, 0xaa, 0xb7, 0x6c, 0x59, 0x36, 0x28, 0xbf, 0x9d, 0xc7, + 0xbe, 0x03, 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, + 0x47, 0x01, 0x36, 0x4f, 0x2d, 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, + 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; + + PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == + 0); +} \ No newline at end of file From 34545c9850a7024ba79503043debf2e0e2bceb10 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 12:15:57 +0900 Subject: [PATCH 08/37] Update build configuration to include WireGuard tests Signed-off-by: Dongjun Na --- Tests/Packet++Test/CMakeLists.txt | 1 + Tests/Packet++Test/TestDefinition.h | 5 +++++ Tests/Packet++Test/main.cpp | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/Tests/Packet++Test/CMakeLists.txt b/Tests/Packet++Test/CMakeLists.txt index 0e6bbc75bc..bde53931a8 100644 --- a/Tests/Packet++Test/CMakeLists.txt +++ b/Tests/Packet++Test/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable( Tests/VlanMplsTests.cpp Tests/VrrpTest.cpp Tests/WakeOnLanTests.cpp + Tests/WGTests.cpp Utils/TestUtils.cpp) target_link_libraries( diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 32be87090a..7884616378 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -263,3 +263,8 @@ PTF_TEST_CASE(Asn1EncodingTest); // Implemented in LdapTests.cpp PTF_TEST_CASE(LdapParsingTest); PTF_TEST_CASE(LdapCreationTest); + +// Implemented in WGTest.cpp +PTF_TEST_CASE(WGHandshakeInitParsingTest); +PTF_TEST_CASE(WGHandshakeRespParsingTest); +PTF_TEST_CASE(WGTransportDataParsingTest); diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index b5fdf00748..c9e4f5e1a8 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -334,5 +334,9 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(LdapParsingTest, "ldap"); PTF_RUN_TEST(LdapCreationTest, "ldap"); + PTF_RUN_TEST(WGHandshakeInitParsingTest, "wg"); + PTF_RUN_TEST(WGHandshakeRespParsingTest, "wg"); + PTF_RUN_TEST(WGTransportDataParsingTest, "wg"); + PTF_END_RUNNING_TESTS; } From d9055cc41998a1c85920fb63512c1033c8de0587 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 12:35:44 +0900 Subject: [PATCH 09/37] lint Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WGTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Packet++Test/Tests/WGTests.cpp b/Tests/Packet++Test/Tests/WGTests.cpp index d9a126c58c..ec2495e002 100644 --- a/Tests/Packet++Test/Tests/WGTests.cpp +++ b/Tests/Packet++Test/Tests/WGTests.cpp @@ -154,4 +154,4 @@ PTF_TEST_CASE(WGTransportDataParsingTest) PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == 0); -} \ No newline at end of file +} From f03e790d461c107991b194a0076f99c39c998e5a Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 15:08:59 +0900 Subject: [PATCH 10/37] Add delete in WGTests Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WGTests.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Tests/Packet++Test/Tests/WGTests.cpp b/Tests/Packet++Test/Tests/WGTests.cpp index ec2495e002..59620b91a4 100644 --- a/Tests/Packet++Test/Tests/WGTests.cpp +++ b/Tests/Packet++Test/Tests/WGTests.cpp @@ -15,9 +15,6 @@ PTF_TEST_CASE(WGHandshakeInitParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); pcpp::Packet parsedPacket(&rawPacket1); - PTF_ASSERT_TRUE(parsedPacket.isPacketOfType(pcpp::Ethernet)); - PTF_ASSERT_NOT_NULL(parsedPacket.getLayerOfType()); - pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(udpLayer); @@ -63,6 +60,8 @@ PTF_TEST_CASE(WGHandshakeInitParsingTest) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); + delete wgLayer; + delete udpLayer; } PTF_TEST_CASE(WGHandshakeRespParsingTest) @@ -109,6 +108,8 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); + delete wgLayer; + delete udpLayer; } PTF_TEST_CASE(WGTransportDataParsingTest) @@ -154,4 +155,6 @@ PTF_TEST_CASE(WGTransportDataParsingTest) PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == 0); + delete wgLayer; + delete udpLayer; } From fae0f876c88b6d4f39e619b9c98c740a2e4d4b61 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 15:11:07 +0900 Subject: [PATCH 11/37] Fix Packet check in WGTests Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WGTests.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Tests/Packet++Test/Tests/WGTests.cpp b/Tests/Packet++Test/Tests/WGTests.cpp index 59620b91a4..b143c93819 100644 --- a/Tests/Packet++Test/Tests/WGTests.cpp +++ b/Tests/Packet++Test/Tests/WGTests.cpp @@ -72,9 +72,6 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); pcpp::Packet parsedPacket(&rawPacket1); - PTF_ASSERT_TRUE(parsedPacket.isPacketOfType(pcpp::Ethernet)); - PTF_ASSERT_NOT_NULL(parsedPacket.getLayerOfType()); - pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(udpLayer); @@ -120,9 +117,6 @@ PTF_TEST_CASE(WGTransportDataParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); pcpp::Packet parsedPacket(&rawPacket1); - PTF_ASSERT_TRUE(parsedPacket.isPacketOfType(pcpp::Ethernet)); - PTF_ASSERT_NOT_NULL(parsedPacket.getLayerOfType()); - pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(udpLayer); From 222a321426cb99645c5a05c3526978f1e3efbdf9 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 16:24:29 +0900 Subject: [PATCH 12/37] Refactor WireGuard packet parsing tests Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WGTests.cpp | 63 ++++++---------------------- 1 file changed, 13 insertions(+), 50 deletions(-) diff --git a/Tests/Packet++Test/Tests/WGTests.cpp b/Tests/Packet++Test/Tests/WGTests.cpp index b143c93819..0c73d26881 100644 --- a/Tests/Packet++Test/Tests/WGTests.cpp +++ b/Tests/Packet++Test/Tests/WGTests.cpp @@ -1,11 +1,7 @@ #include "../TestDefinition.h" #include "../Utils/TestUtils.h" #include "Packet.h" -#include "EthLayer.h" -#include "UdpLayer.h" -#include "SystemUtils.h" #include "WireGuardLayer.h" -#include PTF_TEST_CASE(WGHandshakeInitParsingTest) { @@ -13,55 +9,42 @@ PTF_TEST_CASE(WGHandshakeInitParsingTest) gettimeofday(&time, nullptr); READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); - pcpp::Packet parsedPacket(&rawPacket1); - pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(udpLayer); - - udpLayer->parseNextLayer(); - pcpp::WireGuardLayer* wgLayer = dynamic_cast(udpLayer->getNextLayer()); + pcpp::Packet wgPacket(&rawPacket1); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - - size_t headerLen = wgLayer->getHeaderLen(); - PTF_ASSERT_TRUE(headerLen == sizeof(pcpp::wg_handshake_initiation)); + PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_initiation)); const pcpp::wg_handshake_initiation* handshakeInit = wgLayer->getHandshakeInitiation(); PTF_ASSERT_NOT_NULL(handshakeInit); - PTF_ASSERT_EQUAL(handshakeInit->common.messageType, pcpp::HandshakeInitiation); PTF_ASSERT_EQUAL(handshakeInit->senderIndex, 818952152); uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->initiatorEphemeral, expectedPublicKey, sizeof(expectedPublicKey)) == 0); uint8_t expectedStaticKey[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; - PTF_ASSERT_TRUE( std::memcmp(handshakeInit->encryptedInitiatorStatic, expectedStaticKey, sizeof(expectedStaticKey)) == 0); uint8_t expectedTimestamp[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->encryptedTimestamp, expectedTimestamp, sizeof(expectedTimestamp)) == 0); uint8_t expectedMac1[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac1, expectedMac1, sizeof(expectedMac1)) == 0); uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); - delete wgLayer; - delete udpLayer; } PTF_TEST_CASE(WGHandshakeRespParsingTest) @@ -70,21 +53,16 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) gettimeofday(&time, nullptr); READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); - pcpp::Packet parsedPacket(&rawPacket1); - pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(udpLayer); - - udpLayer->parseNextLayer(); - pcpp::WireGuardLayer* wgLayer = dynamic_cast(udpLayer->getNextLayer()); + pcpp::Packet wgPacket(&rawPacket1); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - size_t headerLen = wgLayer->getHeaderLen(); - PTF_ASSERT_TRUE(headerLen == sizeof(pcpp::wg_handshake_response)); + PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_response)); const pcpp::wg_handshake_response* handshakeResponse = wgLayer->getHandshakeResponse(); PTF_ASSERT_NOT_NULL(handshakeResponse); - PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, pcpp::HandshakeResponse); PTF_ASSERT_EQUAL(handshakeResponse->senderIndex, 2877158406); PTF_ASSERT_EQUAL(handshakeResponse->receiverIndex, 818952152); @@ -92,21 +70,16 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) uint8_t expectedResponderEphemeral[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->responderEphemeral, expectedResponderEphemeral, sizeof(expectedResponderEphemeral)) == 0); uint8_t expectedMac1[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac1, expectedMac1, sizeof(expectedMac1)) == 0); uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); - delete wgLayer; - delete udpLayer; } PTF_TEST_CASE(WGTransportDataParsingTest) @@ -115,26 +88,19 @@ PTF_TEST_CASE(WGTransportDataParsingTest) gettimeofday(&time, nullptr); READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); - pcpp::Packet parsedPacket(&rawPacket1); - pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(udpLayer); - - udpLayer->parseNextLayer(); - pcpp::WireGuardLayer* wgLayer = dynamic_cast(udpLayer->getNextLayer()); + pcpp::Packet wgPacket(&rawPacket1); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - - size_t headerLen = wgLayer->getHeaderLen(); - PTF_ASSERT_TRUE(headerLen >= sizeof(pcpp::wg_transport_data)); + PTF_ASSERT_TRUE(wgLayer->getHeaderLen() >= sizeof(pcpp::wg_transport_data)); const pcpp::wg_transport_data* transportData = wgLayer->getTransportData(); PTF_ASSERT_NOT_NULL(transportData); - PTF_ASSERT_EQUAL(transportData->common.messageType, pcpp::TransportData); PTF_ASSERT_EQUAL(transportData->receiverIndex, 2877158406); uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(&transportData->counter, &expectedCounter, sizeof(expectedCounter)) == 0); uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, @@ -146,9 +112,6 @@ PTF_TEST_CASE(WGTransportDataParsingTest) 0xbe, 0x03, 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, 0x47, 0x01, 0x36, 0x4f, 0x2d, 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == 0); - delete wgLayer; - delete udpLayer; -} +} \ No newline at end of file From 0ebea57d667f73a948006ed1c3486ce14b0758d0 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 16:49:12 +0900 Subject: [PATCH 13/37] Add pcap file with all sample packets and rename test file to WireGuardTests Signed-off-by: Dongjun Na --- Tests/Packet++Test/CMakeLists.txt | 2 +- .../PacketExamples/WireGuard.pcap | Bin 0 -> 566 bytes Tests/Packet++Test/TestDefinition.h | 2 +- Tests/Packet++Test/Tests/WireGuardTests.cpp | 117 ++++++++++++++++++ 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 Tests/Packet++Test/PacketExamples/WireGuard.pcap create mode 100644 Tests/Packet++Test/Tests/WireGuardTests.cpp diff --git a/Tests/Packet++Test/CMakeLists.txt b/Tests/Packet++Test/CMakeLists.txt index bde53931a8..0bcac69e63 100644 --- a/Tests/Packet++Test/CMakeLists.txt +++ b/Tests/Packet++Test/CMakeLists.txt @@ -42,7 +42,7 @@ add_executable( Tests/VlanMplsTests.cpp Tests/VrrpTest.cpp Tests/WakeOnLanTests.cpp - Tests/WGTests.cpp + Tests/WireGuardTests.cpp Utils/TestUtils.cpp) target_link_libraries( diff --git a/Tests/Packet++Test/PacketExamples/WireGuard.pcap b/Tests/Packet++Test/PacketExamples/WireGuard.pcap new file mode 100644 index 0000000000000000000000000000000000000000..53a32b86b49395bbef5a2dbc6b1f9e14015fc50b GIT binary patch literal 566 zcmca|c+)~A1{MYcU}0bcatc#|qJI^#GVBAgL3q(KlPO!9t<0Y8kNUyE;M&2kfytYJ z!9g%NjEj?j5r~;q9y^u8Fh}GNNcRo%3kLD$j-PmX;?d*pGv>WdIHYkyS@RmxwvCT= z&t>cHJU`dh)u@6$S6$7&dPaf#9rYz|7}jmucXr<=V|{6dmQ%MUH(8n<5L%}iSFQT~ zqou=P#b4Rivb5SaB;FP=5VxCLA2!+Zo<`W6cr~#yyLamk1Y0xSofcPjJhSXke}-+k z5YP!I0OXqs)vOF{Kv58e_ygi6ux~1~EJ41pUI6k5$VaDgRvu$W5$R$As%HCAyBg%9 zjlH1(dmWq>SGhG=9q8ToCarn)fm6CEdqmGRC~K!F>#sZH^(); + PTF_ASSERT_NOT_NULL(wgLayer); + PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_initiation)); + + const pcpp::wg_handshake_initiation* handshakeInit = wgLayer->getHandshakeInitiation(); + PTF_ASSERT_NOT_NULL(handshakeInit); + PTF_ASSERT_EQUAL(handshakeInit->common.messageType, pcpp::HandshakeInitiation); + PTF_ASSERT_EQUAL(handshakeInit->senderIndex, 818952152); + + uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, + 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, + 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->initiatorEphemeral, expectedPublicKey, sizeof(expectedPublicKey)) == 0); + + uint8_t expectedStaticKey[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, + 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, + 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, + 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; + PTF_ASSERT_TRUE( + std::memcmp(handshakeInit->encryptedInitiatorStatic, expectedStaticKey, sizeof(expectedStaticKey)) == 0); + + uint8_t expectedTimestamp[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, + 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, + 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->encryptedTimestamp, expectedTimestamp, sizeof(expectedTimestamp)) == 0); + + uint8_t expectedMac1[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, + 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac1, expectedMac1, sizeof(expectedMac1)) == 0); + + uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); +} + +PTF_TEST_CASE(WGHandshakeRespParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); + + pcpp::Packet wgPacket(&rawPacket1); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(wgLayer); + + PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_response)); + + const pcpp::wg_handshake_response* handshakeResponse = wgLayer->getHandshakeResponse(); + PTF_ASSERT_NOT_NULL(handshakeResponse); + PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, pcpp::HandshakeResponse); + PTF_ASSERT_EQUAL(handshakeResponse->senderIndex, 2877158406); + PTF_ASSERT_EQUAL(handshakeResponse->receiverIndex, 818952152); + + uint8_t expectedResponderEphemeral[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, + 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, + 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; + PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->responderEphemeral, expectedResponderEphemeral, + sizeof(expectedResponderEphemeral)) == 0); + + uint8_t expectedMac1[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, + 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; + PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac1, expectedMac1, sizeof(expectedMac1)) == 0); + + uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); +} + +PTF_TEST_CASE(WGTransportDataParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); + + pcpp::Packet wgPacket(&rawPacket1); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(wgLayer); + PTF_ASSERT_TRUE(wgLayer->getHeaderLen() >= sizeof(pcpp::wg_transport_data)); + + const pcpp::wg_transport_data* transportData = wgLayer->getTransportData(); + PTF_ASSERT_NOT_NULL(transportData); + PTF_ASSERT_EQUAL(transportData->common.messageType, pcpp::TransportData); + PTF_ASSERT_EQUAL(transportData->receiverIndex, 2877158406); + + uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE(std::memcmp(&transportData->counter, &expectedCounter, sizeof(expectedCounter)) == 0); + + uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, + 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, + 0x26, 0x2e, 0x66, 0x65, 0x49, 0xb4, 0x45, 0xa7, 0x43, 0x6e, 0x82, 0x9b, 0xff, + 0xb6, 0xac, 0x65, 0xf0, 0x56, 0x48, 0xbc, 0x0c, 0x39, 0x1f, 0xe7, 0xc5, 0x88, + 0x48, 0x74, 0x37, 0x61, 0x27, 0x16, 0x49, 0x40, 0x18, 0x8f, 0x03, 0xdb, 0xa6, + 0x7a, 0xf8, 0x38, 0x8e, 0xaa, 0xb7, 0x6c, 0x59, 0x36, 0x28, 0xbf, 0x9d, 0xc7, + 0xbe, 0x03, 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, + 0x47, 0x01, 0x36, 0x4f, 0x2d, 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, + 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; + PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == + 0); + } From c8173bd588ff8b35ee012c4257df3478f3d0bb6c Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 17:00:49 +0900 Subject: [PATCH 14/37] lint Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WGTests.cpp | 117 -------------------- Tests/Packet++Test/Tests/WireGuardTests.cpp | 2 +- 2 files changed, 1 insertion(+), 118 deletions(-) delete mode 100644 Tests/Packet++Test/Tests/WGTests.cpp diff --git a/Tests/Packet++Test/Tests/WGTests.cpp b/Tests/Packet++Test/Tests/WGTests.cpp deleted file mode 100644 index 0c73d26881..0000000000 --- a/Tests/Packet++Test/Tests/WGTests.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "../TestDefinition.h" -#include "../Utils/TestUtils.h" -#include "Packet.h" -#include "WireGuardLayer.h" - -PTF_TEST_CASE(WGHandshakeInitParsingTest) -{ - timeval time; - gettimeofday(&time, nullptr); - - READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); - - pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); - pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_initiation)); - - const pcpp::wg_handshake_initiation* handshakeInit = wgLayer->getHandshakeInitiation(); - PTF_ASSERT_NOT_NULL(handshakeInit); - PTF_ASSERT_EQUAL(handshakeInit->common.messageType, pcpp::HandshakeInitiation); - PTF_ASSERT_EQUAL(handshakeInit->senderIndex, 818952152); - - uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, - 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, - 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->initiatorEphemeral, expectedPublicKey, sizeof(expectedPublicKey)) == 0); - - uint8_t expectedStaticKey[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, - 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, - 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, - 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; - PTF_ASSERT_TRUE( - std::memcmp(handshakeInit->encryptedInitiatorStatic, expectedStaticKey, sizeof(expectedStaticKey)) == 0); - - uint8_t expectedTimestamp[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, - 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, - 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->encryptedTimestamp, expectedTimestamp, sizeof(expectedTimestamp)) == 0); - - uint8_t expectedMac1[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, - 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac1, expectedMac1, sizeof(expectedMac1)) == 0); - - uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); -} - -PTF_TEST_CASE(WGHandshakeRespParsingTest) -{ - timeval time; - gettimeofday(&time, nullptr); - - READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); - - pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); - pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(wgLayer); - - PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_response)); - - const pcpp::wg_handshake_response* handshakeResponse = wgLayer->getHandshakeResponse(); - PTF_ASSERT_NOT_NULL(handshakeResponse); - PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, pcpp::HandshakeResponse); - PTF_ASSERT_EQUAL(handshakeResponse->senderIndex, 2877158406); - PTF_ASSERT_EQUAL(handshakeResponse->receiverIndex, 818952152); - - uint8_t expectedResponderEphemeral[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, - 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, - 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->responderEphemeral, expectedResponderEphemeral, - sizeof(expectedResponderEphemeral)) == 0); - - uint8_t expectedMac1[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, - 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac1, expectedMac1, sizeof(expectedMac1)) == 0); - - uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); -} - -PTF_TEST_CASE(WGTransportDataParsingTest) -{ - timeval time; - gettimeofday(&time, nullptr); - - READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); - - pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); - pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_TRUE(wgLayer->getHeaderLen() >= sizeof(pcpp::wg_transport_data)); - - const pcpp::wg_transport_data* transportData = wgLayer->getTransportData(); - PTF_ASSERT_NOT_NULL(transportData); - PTF_ASSERT_EQUAL(transportData->common.messageType, pcpp::TransportData); - PTF_ASSERT_EQUAL(transportData->receiverIndex, 2877158406); - - uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(&transportData->counter, &expectedCounter, sizeof(expectedCounter)) == 0); - - uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, - 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, - 0x26, 0x2e, 0x66, 0x65, 0x49, 0xb4, 0x45, 0xa7, 0x43, 0x6e, 0x82, 0x9b, 0xff, - 0xb6, 0xac, 0x65, 0xf0, 0x56, 0x48, 0xbc, 0x0c, 0x39, 0x1f, 0xe7, 0xc5, 0x88, - 0x48, 0x74, 0x37, 0x61, 0x27, 0x16, 0x49, 0x40, 0x18, 0x8f, 0x03, 0xdb, 0xa6, - 0x7a, 0xf8, 0x38, 0x8e, 0xaa, 0xb7, 0x6c, 0x59, 0x36, 0x28, 0xbf, 0x9d, 0xc7, - 0xbe, 0x03, 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, - 0x47, 0x01, 0x36, 0x4f, 0x2d, 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, - 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == - 0); -} \ No newline at end of file diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 33b2ad8fea..b9ac7df24e 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -114,4 +114,4 @@ PTF_TEST_CASE(WGTransportDataParsingTest) 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == 0); - } +} From 9fb269b8af8b0a07a7e39f32049c5b6cc1219116 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 17:30:33 +0900 Subject: [PATCH 15/37] lint --- Tests/Packet++Test/Tests/WireGuardTests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index b9ac7df24e..5994f9ac3e 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -2,6 +2,7 @@ #include "../Utils/TestUtils.h" #include "Packet.h" #include "WireGuardLayer.h" +#include "SystemUtils.h" PTF_TEST_CASE(WGHandshakeInitParsingTest) { From 36eb0a1de49415b5d0050e339d5956b32a418e37 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 19:31:04 +0900 Subject: [PATCH 16/37] Add override specifier in WireGuardLayer class and update constructor parameters. Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 68d03defee..94ee81403e 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -118,9 +118,8 @@ namespace pcpp * @param packet Pointer to the packet this layer belongs to */ WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) - : Layer(data, dataLen, prevLayer, packet) + : Layer(data, dataLen, prevLayer, packet, WIREGUARD) { - m_Protocol = WIREGUARD; m_Data = data; m_DataLen = dataLen; } @@ -186,7 +185,7 @@ namespace pcpp /** * No operation required for parsing the next layer since WireGuard does not have a next layer. */ - void parseNextLayer() + void parseNextLayer() override { // No next layer to parse for WireGuard, do nothing } @@ -196,12 +195,12 @@ namespace pcpp * * @return Size of the header in bytes. For TransportData, returns the total data length. */ - size_t getHeaderLen() const; + size_t getHeaderLen() const override; /** * No fields to compute or update, so this method is left empty. */ - void computeCalculateFields() + void computeCalculateFields() override { // Since WireGuard headers have fixed lengths and no fields to compute (like checksums or lengths), // this method does not need to perform any operations. It's left empty. @@ -212,14 +211,14 @@ namespace pcpp * * @return String representation of the WireGuard layer */ - std::string toString() const; + std::string toString() const override; /** * Returns the OSI model layer that this protocol belongs to. * * @return OSI model layer corresponding to the Network layer */ - OsiModelLayer getOsiModelLayer() const + OsiModelLayer getOsiModelLayer() const override { return OsiModelNetworkLayer; } From c144b912d5e556740521c877792fc042eed95b07 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 19:44:02 +0900 Subject: [PATCH 17/37] Refactor WireGuardLayer constructor to remove redundant Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 94ee81403e..1b066c446d 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -119,10 +119,7 @@ namespace pcpp */ WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, WIREGUARD) - { - m_Data = data; - m_DataLen = dataLen; - } + {} /** * Gets a pointer to the Handshake Initiation message. From a6b985698e7faedb2550a3593b001e6330e1af62 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 21:49:10 +0900 Subject: [PATCH 18/37] Fix header inclusion for std::memcmp Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 2 +- Packet++/src/WireGuardLayer.cpp | 2 +- Tests/Packet++Test/Tests/WireGuardTests.cpp | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 1b066c446d..5095b1da1c 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -3,8 +3,8 @@ #include "Layer.h" #include "IpAddress.h" #include "MacAddress.h" -#include #include +#include /// @file diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 66c21093e6..31742f46b2 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -5,9 +5,9 @@ #include "IPv6Layer.h" #include "WireGuardLayer.h" #include "Logger.h" -#include #include #include +#include namespace pcpp { diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 5994f9ac3e..b77f9262be 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -3,6 +3,7 @@ #include "Packet.h" #include "WireGuardLayer.h" #include "SystemUtils.h" +#include PTF_TEST_CASE(WGHandshakeInitParsingTest) { From 6fa65cdfad3abb4cf3bebc7a662fdd4bddce02a1 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 1 Sep 2024 22:56:41 +0900 Subject: [PATCH 19/37] Refactor stringstream usage and clean up unused includes in WireGuardLayer Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 2 -- Packet++/src/WireGuardLayer.cpp | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 5095b1da1c..5842e65c44 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -3,8 +3,6 @@ #include "Layer.h" #include "IpAddress.h" #include "MacAddress.h" -#include -#include /// @file diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 31742f46b2..db43637f72 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -13,14 +13,12 @@ namespace pcpp { std::string WireGuardLayer::toString() const { - std::stringstream ss; - if (m_DataLen < sizeof(wg_common_header)) { - ss << "WireGuard header (incomplete)"; - return ss.str(); + return "WireGuard header (incomplete)"; } + std::stringstream ss; const wg_common_header* header = reinterpret_cast(m_Data); ss << "WireGuard Layer\n"; ss << " Type: " << static_cast(header->messageType) << "\n"; From 61d1aaa7b2d6d9839af960286e7d0ddc9fbcb1d8 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Tue, 3 Sep 2024 07:26:25 +0900 Subject: [PATCH 20/37] Refactor WireGuardMessageType to enum class Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 5 +++-- Packet++/src/WireGuardLayer.cpp | 8 ++++---- Tests/Packet++Test/Tests/WireGuardTests.cpp | 9 ++++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 5842e65c44..8ec8d895ba 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -16,7 +16,7 @@ namespace pcpp /** * WireGuard message types */ - enum WireGuardMessageType + enum class WireGuardMessageType { HandshakeInitiation = 1, ///< Handshake Initiation message HandshakeResponse = 2, ///< Handshake Response message @@ -246,7 +246,8 @@ namespace pcpp return false; uint8_t messageType = data[0]; - return messageType >= HandshakeInitiation && messageType <= TransportData; + return messageType >= static_cast(WireGuardMessageType::HandshakeInitiation) && + messageType <= static_cast(WireGuardMessageType::TransportData); } } // namespace pcpp diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index db43637f72..cebfbfa10b 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -31,7 +31,7 @@ namespace pcpp switch (header->messageType) { - case HandshakeInitiation: + case static_cast(WireGuardMessageType::HandshakeInitiation): { const wg_handshake_initiation* msg = getHandshakeInitiation(); ss << " Handshake Initiation\n"; @@ -68,7 +68,7 @@ namespace pcpp ss << std::dec << "\n"; break; } - case HandshakeResponse: + case static_cast(WireGuardMessageType::HandshakeResponse): { const wg_handshake_response* msg = getHandshakeResponse(); ss << " Handshake Response\n"; @@ -100,7 +100,7 @@ namespace pcpp ss << std::dec << "\n"; break; } - case CookieReply: + case static_cast(WireGuardMessageType::CookieReply): { const wg_cookie_reply* msg = getCookieReply(); ss << " Cookie Reply\n"; @@ -119,7 +119,7 @@ namespace pcpp ss << std::dec << "\n"; break; } - case TransportData: + case static_cast(WireGuardMessageType::TransportData): { const wg_transport_data* msg = getTransportData(); ss << " Transport Data\n"; diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index b77f9262be..c4c8f49a6d 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -20,7 +20,8 @@ PTF_TEST_CASE(WGHandshakeInitParsingTest) const pcpp::wg_handshake_initiation* handshakeInit = wgLayer->getHandshakeInitiation(); PTF_ASSERT_NOT_NULL(handshakeInit); - PTF_ASSERT_EQUAL(handshakeInit->common.messageType, pcpp::HandshakeInitiation); + PTF_ASSERT_EQUAL(handshakeInit->common.messageType, + static_cast(pcpp::WireGuardMessageType::HandshakeInitiation)); PTF_ASSERT_EQUAL(handshakeInit->senderIndex, 818952152); uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, @@ -65,7 +66,8 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) const pcpp::wg_handshake_response* handshakeResponse = wgLayer->getHandshakeResponse(); PTF_ASSERT_NOT_NULL(handshakeResponse); - PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, pcpp::HandshakeResponse); + PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, + static_cast(pcpp::WireGuardMessageType::HandshakeResponse)); PTF_ASSERT_EQUAL(handshakeResponse->senderIndex, 2877158406); PTF_ASSERT_EQUAL(handshakeResponse->receiverIndex, 818952152); @@ -99,7 +101,8 @@ PTF_TEST_CASE(WGTransportDataParsingTest) const pcpp::wg_transport_data* transportData = wgLayer->getTransportData(); PTF_ASSERT_NOT_NULL(transportData); - PTF_ASSERT_EQUAL(transportData->common.messageType, pcpp::TransportData); + PTF_ASSERT_EQUAL(transportData->common.messageType, + static_cast(pcpp::WireGuardMessageType::TransportData)); PTF_ASSERT_EQUAL(transportData->receiverIndex, 2877158406); uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; From 97e5f8080964208c1b8a6d82ee1feaac9dbd429e Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Tue, 3 Sep 2024 18:00:27 +0900 Subject: [PATCH 21/37] Refactor function and variable names for WireGuard Signed-off-by: Dongjun Na --- Packet++/header/ProtocolType.h | 2 +- Packet++/header/WireGuardLayer.h | 6 +++--- Packet++/src/UdpLayer.cpp | 2 +- Tests/Packet++Test/TestDefinition.h | 6 +++--- Tests/Packet++Test/Tests/WireGuardTests.cpp | 12 ++++++------ Tests/Packet++Test/main.cpp | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Packet++/header/ProtocolType.h b/Packet++/header/ProtocolType.h index f2ad34558b..f4807946ef 100644 --- a/Packet++/header/ProtocolType.h +++ b/Packet++/header/ProtocolType.h @@ -350,7 +350,7 @@ namespace pcpp /* * Wireguard protocol */ - const ProtocolType WIREGUARD = 56; + const ProtocolType Wireguard = 56; /** * An enum representing OSI model layers diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 8ec8d895ba..4c1d83d4d2 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -116,7 +116,7 @@ namespace pcpp * @param packet Pointer to the packet this layer belongs to */ WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) - : Layer(data, dataLen, prevLayer, packet, WIREGUARD) + : Layer(data, dataLen, prevLayer, packet, Wireguard) {} /** @@ -175,7 +175,7 @@ namespace pcpp * @param dataLen Length of the data * @return True if the data starts with a valid WireGuard message type, false otherwise */ - static inline bool isWireGuard(const uint8_t* data, size_t dataLen); + static inline bool isDataValid(const uint8_t* data, size_t dataLen); /** * No operation required for parsing the next layer since WireGuard does not have a next layer. @@ -240,7 +240,7 @@ namespace pcpp * @param dataLen Length of the data * @return True if the data starts with a valid WireGuard message type, false otherwise */ - bool WireGuardLayer::isWireGuard(const uint8_t* data, size_t dataLen) + bool WireGuardLayer::isDataValid(const uint8_t* data, size_t dataLen) { if (dataLen < sizeof(wg_common_header)) return false; diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp index 4a1a8f8a69..9b3f3e4a7e 100644 --- a/Packet++/src/UdpLayer.cpp +++ b/Packet++/src/UdpLayer.cpp @@ -136,7 +136,7 @@ namespace pcpp else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen))) m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); else if ((WireGuardLayer::isWireguardPorts(portDst, portSrc) && - WireGuardLayer::isWireGuard(udpData, udpDataLen))) + WireGuardLayer::isDataValid(udpData, udpDataLen))) m_NextLayer = new WireGuardLayer(udpData, udpDataLen, this, m_Packet); else m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 17a68549e6..46169931a7 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -265,6 +265,6 @@ PTF_TEST_CASE(LdapParsingTest); PTF_TEST_CASE(LdapCreationTest); // Implemented in WireGuardTests.cpp -PTF_TEST_CASE(WGHandshakeInitParsingTest); -PTF_TEST_CASE(WGHandshakeRespParsingTest); -PTF_TEST_CASE(WGTransportDataParsingTest); +PTF_TEST_CASE(WireGuardHandshakeInitParsingTest); +PTF_TEST_CASE(WireGuardHandshakeRespParsingTest); +PTF_TEST_CASE(WireGuardTransportDataParsingTest); diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index c4c8f49a6d..911df00633 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -5,7 +5,7 @@ #include "SystemUtils.h" #include -PTF_TEST_CASE(WGHandshakeInitParsingTest) +PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) { timeval time; gettimeofday(&time, nullptr); @@ -13,7 +13,7 @@ PTF_TEST_CASE(WGHandshakeInitParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::Wireguard)); pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_initiation)); @@ -50,7 +50,7 @@ PTF_TEST_CASE(WGHandshakeInitParsingTest) PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); } -PTF_TEST_CASE(WGHandshakeRespParsingTest) +PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) { timeval time; gettimeofday(&time, nullptr); @@ -58,7 +58,7 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::Wireguard)); pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); @@ -86,7 +86,7 @@ PTF_TEST_CASE(WGHandshakeRespParsingTest) PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); } -PTF_TEST_CASE(WGTransportDataParsingTest) +PTF_TEST_CASE(WireGuardTransportDataParsingTest) { timeval time; gettimeofday(&time, nullptr); @@ -94,7 +94,7 @@ PTF_TEST_CASE(WGTransportDataParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::WIREGUARD)); + PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::Wireguard)); pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); PTF_ASSERT_TRUE(wgLayer->getHeaderLen() >= sizeof(pcpp::wg_transport_data)); diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index c9e4f5e1a8..d0ac3c4702 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -334,9 +334,9 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(LdapParsingTest, "ldap"); PTF_RUN_TEST(LdapCreationTest, "ldap"); - PTF_RUN_TEST(WGHandshakeInitParsingTest, "wg"); - PTF_RUN_TEST(WGHandshakeRespParsingTest, "wg"); - PTF_RUN_TEST(WGTransportDataParsingTest, "wg"); + PTF_RUN_TEST(WireGuardHandshakeInitParsingTest, "wg"); + PTF_RUN_TEST(WireGuardHandshakeRespParsingTest, "wg"); + PTF_RUN_TEST(WireGuardTransportDataParsingTest, "wg"); PTF_END_RUNNING_TESTS; } From e4b7c85350c682fc7e3195184fe3ff3b2af245a1 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 21 Sep 2024 15:11:35 +0900 Subject: [PATCH 22/37] Add WireGuard to README.md Signed-off-by: Dongjun Na --- README.md | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 385c30db5d..d93c647ed6 100644 --- a/README.md +++ b/README.md @@ -242,43 +242,44 @@ PcapPlusPlus currently supports parsing, editing and creation of packets of the 22. NDP 23. Raw IP (IPv4 & IPv6) 24. VRRP (IPv4 & IPv6) +25. WireGuard ### Transport Layer (L4) -25. COTP -26. GTP (v1) -27. IPSec AH & ESP - parsing only (no editing capabilities) -28. TCP -29. TPKT -30. UDP +26. COTP +27. GTP (v1) +28. IPSec AH & ESP - parsing only (no editing capabilities) +29. TCP +30. TPKT +31. UDP ### Session Layer (L5) -31. SDP -32. SIP +32. SDP +33. SIP ### Presentation Layer (L6) -33. SSL/TLS - parsing only (no editing capabilities) +34. SSL/TLS - parsing only (no editing capabilities) ### Application Layer (L7) -34. ASN.1 decoder and encoder -35. BGP (v4) -36. DHCP -37. DHCPv6 -38. DNS -39. FTP -40. HTTP headers (request & response) -41. LDAP -42. NTP (v3, v4) -43. Radius -44. S7 Communication (S7comm) -45. SMTP -46. SOME/IP -47. SSH - parsing only (no editing capabilities) -48. Telnet - parsing only (no editing capabilities) -49. Generic payload +35. ASN.1 decoder and encoder +36. BGP (v4) +37. DHCP +38. DHCPv6 +39. DNS +40. FTP +41. HTTP headers (request & response) +42. LDAP +43. NTP (v3, v4) +44. Radius +45. S7 Communication (S7comm) +46. SMTP +47. SOME/IP +48. SSH - parsing only (no editing capabilities) +49. Telnet - parsing only (no editing capabilities) +50. Generic payload ## DPDK And PF_RING Support From e56ca94125e64d5a211d4494440f42e85f87deb6 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 21 Sep 2024 15:13:33 +0900 Subject: [PATCH 23/37] Refactor inline comments above attributes Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 78 +++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 4c1d83d4d2..fb102758db 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -18,10 +18,14 @@ namespace pcpp */ enum class WireGuardMessageType { - HandshakeInitiation = 1, ///< Handshake Initiation message - HandshakeResponse = 2, ///< Handshake Response message - CookieReply = 3, ///< Cookie Reply message - TransportData = 4 ///< Transport Data message + /** Handshake Initiation message */ + HandshakeInitiation = 1, + /** Handshake Response message */ + HandshakeResponse = 2, + /** Cookie Reply message */ + CookieReply = 3, + /** Transport Data message */ + TransportData = 4 }; /** @@ -45,13 +49,20 @@ namespace pcpp #pragma pack(push, 1) struct wg_handshake_initiation { - wg_common_header common; ///< Common header for all WireGuard messages - uint32_t senderIndex; ///< Sender index - uint8_t initiatorEphemeral[32]; ///< Initiator's ephemeral public key - uint8_t encryptedInitiatorStatic[48]; ///< Encrypted initiator's static key - uint8_t encryptedTimestamp[28]; ///< Encrypted timestamp - uint8_t mac1[16]; ///< MAC1 field - uint8_t mac2[16]; ///< MAC2 field + /** Common header for all WireGuard messages */ + wg_common_header common; + /** Sender index */ + uint32_t senderIndex; + /** Initiator's ephemeral public key */ + uint8_t initiatorEphemeral[32]; + /** Encrypted initiator's static key */ + uint8_t encryptedInitiatorStatic[48]; + /** Encrypted timestamp */ + uint8_t encryptedTimestamp[28]; + /** MAC1 field */ + uint8_t mac1[16]; + /** MAC2 field */ + uint8_t mac2[16]; }; #pragma pack(pop) @@ -62,13 +73,20 @@ namespace pcpp #pragma pack(push, 1) struct wg_handshake_response { - wg_common_header common; ///< Common header for all WireGuard messages - uint32_t senderIndex; ///< Sender index - uint32_t receiverIndex; ///< Receiver index - uint8_t responderEphemeral[32]; ///< Responder's ephemeral public key - uint8_t encryptedEmpty[16]; ///< Encrypted empty field - uint8_t mac1[16]; ///< MAC1 field - uint8_t mac2[16]; ///< MAC2 field + /** Common header for all WireGuard messages */ + wg_common_header common; + /** Sender index */ + uint32_t senderIndex; + /** Receiver index */ + uint32_t receiverIndex; + /** Responder's ephemeral public key */ + uint8_t responderEphemeral[32]; + /** Encrypted empty field */ + uint8_t encryptedEmpty[16]; + /** MAC1 field */ + uint8_t mac1[16]; + /** MAC2 field */ + uint8_t mac2[16]; }; #pragma pack(pop) @@ -79,10 +97,14 @@ namespace pcpp #pragma pack(push, 1) struct wg_cookie_reply { - wg_common_header common; ///< Common header for all WireGuard messages - uint32_t receiverIndex; ///< Receiver index - uint8_t nonce[24]; ///< Nonce field - uint8_t encryptedCookie[32]; ///< Encrypted cookie + /** Common header for all WireGuard messages */ + wg_common_header common; + /** Receiver index */ + uint32_t receiverIndex; + /** Nonce field */ + uint8_t nonce[24]; + /** Encrypted cookie */ + uint8_t encryptedCookie[32]; }; #pragma pack(pop) @@ -93,10 +115,14 @@ namespace pcpp #pragma pack(push, 1) struct wg_transport_data { - wg_common_header common; ///< Common header for all WireGuard messages - uint32_t receiverIndex; ///< Receiver index - uint64_t counter; ///< Counter field - uint8_t encryptedData[0]; ///< Flexible array member for encrypted data + /** Common header for all WireGuard messages */ + wg_common_header common; + /** Receiver index */ + uint32_t receiverIndex; + /** Counter field */ + uint64_t counter; + /** Flexible array member for encrypted data */ + uint8_t encryptedData[0]; }; #pragma pack(pop) From f87cef60afd58118cc9c60eb366eece58bbb09e2 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 22 Sep 2024 21:14:52 +0900 Subject: [PATCH 24/37] Refactor Implement separate classes for creating and parsing WireGuard message types Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 488 ++++++++++++++++++++----------- Packet++/src/WireGuardLayer.cpp | 397 +++++++++++++++++-------- 2 files changed, 593 insertions(+), 292 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index fb102758db..fd13097893 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -14,125 +14,44 @@ namespace pcpp { /** - * WireGuard message types - */ - enum class WireGuardMessageType - { - /** Handshake Initiation message */ - HandshakeInitiation = 1, - /** Handshake Response message */ - HandshakeResponse = 2, - /** Cookie Reply message */ - CookieReply = 3, - /** Transport Data message */ - TransportData = 4 - }; - - /** - * @struct wg_common_header - * Represents the common header for all WireGuard message types - */ -#pragma pack(push, 1) - struct wg_common_header - { - /** Message type field */ - uint8_t messageType; - /** Reserved field (3 bytes) */ - uint8_t reserved[3]; - }; -#pragma pack(pop) - - /** - * @struct wg_handshake_initiation - * Represents the Handshake Initiation message - */ -#pragma pack(push, 1) - struct wg_handshake_initiation - { - /** Common header for all WireGuard messages */ - wg_common_header common; - /** Sender index */ - uint32_t senderIndex; - /** Initiator's ephemeral public key */ - uint8_t initiatorEphemeral[32]; - /** Encrypted initiator's static key */ - uint8_t encryptedInitiatorStatic[48]; - /** Encrypted timestamp */ - uint8_t encryptedTimestamp[28]; - /** MAC1 field */ - uint8_t mac1[16]; - /** MAC2 field */ - uint8_t mac2[16]; - }; -#pragma pack(pop) - - /** - * @struct wg_handshake_response - * Represents the Handshake Response message + * @class WireGuardLayer + * Represents a WireGuard protocol layer */ -#pragma pack(push, 1) - struct wg_handshake_response + class WireGuardLayer : public Layer { - /** Common header for all WireGuard messages */ - wg_common_header common; - /** Sender index */ - uint32_t senderIndex; - /** Receiver index */ - uint32_t receiverIndex; - /** Responder's ephemeral public key */ - uint8_t responderEphemeral[32]; - /** Encrypted empty field */ - uint8_t encryptedEmpty[16]; - /** MAC1 field */ - uint8_t mac1[16]; - /** MAC2 field */ - uint8_t mac2[16]; - }; -#pragma pack(pop) + public: + /** + * WireGuard message types + */ + enum class WireGuardMessageType + { + /** Handshake Initiation message */ + HandshakeInitiation = 1, + /** Handshake Response message */ + HandshakeResponse = 2, + /** Cookie Reply message */ + CookieReply = 3, + /** Transport Data message */ + TransportData = 4 + }; - /** - * @struct wg_cookie_reply - * Represents the Cookie Reply message - */ #pragma pack(push, 1) - struct wg_cookie_reply - { - /** Common header for all WireGuard messages */ - wg_common_header common; - /** Receiver index */ - uint32_t receiverIndex; - /** Nonce field */ - uint8_t nonce[24]; - /** Encrypted cookie */ - uint8_t encryptedCookie[32]; - }; + /** + * @struct wg_common_header + * Represents the common header for all WireGuard message types + */ + struct wg_common_header + { + /** Message type field */ + uint8_t messageType; + /** Reserved field (3 bytes) */ + uint8_t reserved[3]; + }; #pragma pack(pop) - /** - * @struct wg_transport_data - * Represents the Transport Data message - */ -#pragma pack(push, 1) - struct wg_transport_data - { - /** Common header for all WireGuard messages */ - wg_common_header common; - /** Receiver index */ - uint32_t receiverIndex; - /** Counter field */ - uint64_t counter; - /** Flexible array member for encrypted data */ - uint8_t encryptedData[0]; - }; -#pragma pack(pop) + WireGuardLayer() + {} - /** - * @class WireGuardLayer - * Represents a WireGuard protocol layer - */ - class WireGuardLayer : public Layer - { - public: /** * Constructs a WireGuardLayer object. * @@ -145,44 +64,9 @@ namespace pcpp : Layer(data, dataLen, prevLayer, packet, Wireguard) {} - /** - * Gets a pointer to the Handshake Initiation message. - * - * @return Pointer to the Handshake Initiation message, or nullptr if data is invalid - */ - const wg_handshake_initiation* getHandshakeInitiation() const - { - return reinterpret_cast(m_Data); - } - - /** - * Gets a pointer to the Handshake Response message. - * - * @return Pointer to the Handshake Response message, or nullptr if data is invalid - */ - const wg_handshake_response* getHandshakeResponse() const + wg_common_header* getBasicHeader() const { - return reinterpret_cast(m_Data); - } - - /** - * Gets a pointer to the Cookie Reply message. - * - * @return Pointer to the Cookie Reply message, or nullptr if data is invalid - */ - const wg_cookie_reply* getCookieReply() const - { - return reinterpret_cast(m_Data); - } - - /** - * Gets a pointer to the Transport Data message. - * - * @return Pointer to the Transport Data message, or nullptr if data is invalid - */ - const wg_transport_data* getTransportData() const - { - return reinterpret_cast(m_Data); + return (wg_common_header*)m_Data; } /** @@ -192,7 +76,10 @@ namespace pcpp * @param portDst The destination port number to check * @return True if either port matches the WireGuard port (51820), false otherwise */ - static inline bool isWireguardPorts(uint16_t portSrc, uint16_t portDst); + static bool isWireguardPorts(uint16_t portSrc, uint16_t portDst) + { + return (portSrc == 51820 || portDst == 51820); + } /** * Checks if the given data represents a WireGuard message. @@ -201,16 +88,26 @@ namespace pcpp * @param dataLen Length of the data * @return True if the data starts with a valid WireGuard message type, false otherwise */ - static inline bool isDataValid(const uint8_t* data, size_t dataLen); + static bool isDataValid(const uint8_t* data, size_t dataLen); - /** - * No operation required for parsing the next layer since WireGuard does not have a next layer. - */ - void parseNextLayer() override + WireGuardLayer* parseWireGuardLayer(); + + std::string getMessageTypeAsString() const; + + uint32_t getMessageType() { - // No next layer to parse for WireGuard, do nothing + return getBasicHeader()->messageType; } + uint8_t* getReserved() + { + return getBasicHeader()->reserved; + } + + /** + * No operation required for parsing the next layer since WireGuard does not have a next layer. + */ + void parseNextLayer() override {}; /** * Calculates the length of the header based on the message type. * @@ -245,35 +142,272 @@ namespace pcpp } }; - // Implementation of inline methods + /** + * @class WireGuardHandshakeInitiationLayer + * Represents the Handshake Initiation message layer + */ + class WireGuardHandshakeInitiationLayer : public WireGuardLayer + { + public: +#pragma pack(push, 1) + typedef struct wg_handshake_initiation : wg_common_header + { + /** Sender index */ + uint32_t senderIndex; + /** Initiator's ephemeral public key */ + uint8_t initiatorEphemeral[32]; + /** Encrypted initiator's static key */ + uint8_t encryptedInitiatorStatic[48]; + /** Encrypted timestamp */ + uint8_t encryptedTimestamp[28]; + /** MAC1 field */ + uint8_t mac1[16]; + /** MAC2 field */ + uint8_t mac2[16]; + } wg_handshake_initiation; +#pragma pack(pop) + /** + * A constructor that creates the layer from an existing packet raw data + * @param[in] data A pointer to the raw data + * @param[in] dataLen Size of the data in bytes + * @param[in] prevLayer A pointer to the previous layer + * @param[in] packet A pointer to the Packet instance where layer will be stored in + */ + WireGuardHandshakeInitiationLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) + : WireGuardLayer(data, dataLen, prevLayer, packet) + {} + + /** + * A constructor that creates a new Handshake Initiation message + * @param[in] senderIndex The sender's index + * @param[in] initiatorEphemeral The initiator's ephemeral public key + * @param[in] encryptedInitiatorStatic The encrypted initiator's static key + * @param[in] encryptedTimestamp The encrypted timestamp + * @param[in] mac1 The MAC1 field + * @param[in] mac2 The MAC2 field + */ + WireGuardHandshakeInitiationLayer(uint32_t senderIndex, const uint8_t initiatorEphemeral[32], + const uint8_t encryptedInitiatorStatic[48], + const uint8_t encryptedTimestamp[28], const uint8_t mac1[16], + const uint8_t mac2[16]); + + uint32_t getMessageType() const; + const uint8_t* getReserved() const; + uint32_t getSenderIndex() const; + const uint8_t* getInitiatorEphemeral() const; + const uint8_t* getEncryptedInitiatorStatic() const; + const uint8_t* getEncryptedTimestamp() const; + const uint8_t* getMac1() const; + const uint8_t* getMac2() const; + + wg_handshake_initiation* getHandshakeInitiationHeader() const + { + return (wg_handshake_initiation*)getBasicHeader(); + } + + // implement abstract methods + + WireGuardMessageType getWireGuardMessageType() const + { + return WireGuardMessageType::HandshakeInitiation; + } + }; + + /** + * @class WireGuardHandshakeResponseLayer + * Represents a Handshake Response message + */ + class WireGuardHandshakeResponseLayer : public WireGuardLayer + { + public: +#pragma pack(push, 1) + /** + * @struct wg_handshake_response + * Represents the Handshake Response message + */ + typedef struct wg_handshake_response : wg_common_header + { + /** Sender index */ + uint32_t senderIndex; + /** Receiver index */ + uint32_t receiverIndex; + /** Responder's ephemeral public key */ + uint8_t responderEphemeral[32]; + /** Encrypted empty field */ + uint8_t encryptedEmpty[16]; + /** MAC1 field */ + uint8_t mac1[16]; + /** MAC2 field */ + uint8_t mac2[16]; + } wg_handshake_response; +#pragma pack(pop) + + /** + * A constructor that creates the layer from an existing packet raw data + * @param[in] data A pointer to the raw data + * @param[in] dataLen Size of the data in bytes + * @param[in] prevLayer A pointer to the previous layer + * @param[in] packet A pointer to the Packet instance where layer will be stored in + */ + WireGuardHandshakeResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) + : WireGuardLayer(data, dataLen, prevLayer, packet) + {} + + /** + * A constructor that creates a new Handshake Response message + * @param[in] senderIndex The sender index + * @param[in] receiverIndex The receiver index + * @param[in] responderEphemeral The responder's ephemeral public key + * @param[in] encryptedEmpty The encrypted empty field + * @param[in] mac1 The MAC1 field + * @param[in] mac2 The MAC2 field + */ + WireGuardHandshakeResponseLayer(uint32_t senderIndex, uint32_t receiverIndex, + const uint8_t responderEphemeral[32], const uint8_t encryptedEmpty[16], + const uint8_t mac1[16], const uint8_t mac2[16]); + + uint32_t getMessageType() const; + const uint8_t* getReserved() const; + uint32_t getSenderIndex() const; + uint32_t getReceiverIndex() const; + const uint8_t* getResponderEphemeral() const; + const uint8_t* getEncryptedEmpty() const; + const uint8_t* getMac1() const; + const uint8_t* getMac2() const; + + wg_handshake_response* getHandshakeResponseHeader() const + { + return (wg_handshake_response*)getBasicHeader(); + } + + // implement abstract methods + + WireGuardMessageType getWireGuardMessageType() const + { + return WireGuardMessageType::HandshakeResponse; + } + }; /** - * Checks if the given port numbers are WireGuard ports. - * - * @param portSrc The source port number to check - * @param portDst The destination port number to check - * @return True if either port matches the WireGuard port (51820), false otherwise + * @class WireGuardCookieReplyLayer + * Represents a Cookie Reply message */ - bool WireGuardLayer::isWireguardPorts(uint16_t portSrc, uint16_t portDst) + class WireGuardCookieReplyLayer : public WireGuardLayer { - return (portSrc == 51820 || portDst == 51820); - } + public: +#pragma pack(push, 1) + /** + * @struct wg_cookie_reply + * Represents the Cookie Reply message + */ + typedef struct wg_cookie_reply : wg_common_header + { + /** Receiver index */ + uint32_t receiverIndex; + /** Nonce field */ + uint8_t nonce[24]; + /** Encrypted cookie */ + uint8_t encryptedCookie[32]; + } wg_cookie_reply; +#pragma pack(pop) + + /** + * A constructor that creates the layer from an existing packet raw data + * @param[in] data A pointer to the raw data + * @param[in] dataLen Size of the data in bytes + * @param[in] prevLayer A pointer to the previous layer + * @param[in] packet A pointer to the Packet instance where layer will be stored in + */ + WireGuardCookieReplyLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) + : WireGuardLayer(data, dataLen, prevLayer, packet) + {} + + /** + * A constructor that creates a new Cookie Reply message + * @param[in] receiverIndex The receiver index + * @param[in] nonce The nonce field + * @param[in] encryptedCookie The encrypted cookie + */ + WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], const uint8_t encryptedCookie[32]); + + uint32_t getMessageType() const; + const uint8_t* getReserved() const; + uint32_t getReceiverIndex() const; + const uint8_t* getNonce() const; + const uint8_t* getEncryptedCookie() const; + + wg_cookie_reply* getCookieReplyHeader() const + { + return (wg_cookie_reply*)getBasicHeader(); + } + + // implement abstract methods + + WireGuardMessageType getWireGuardMessageType() const + { + return WireGuardMessageType::CookieReply; + } + }; /** - * Checks if the given data represents a WireGuard message. - * - * @param data Pointer to the raw data - * @param dataLen Length of the data - * @return True if the data starts with a valid WireGuard message type, false otherwise + * @class WireGuardTransportDataLayer + * Represents a Transport Data message */ - bool WireGuardLayer::isDataValid(const uint8_t* data, size_t dataLen) + class WireGuardTransportDataLayer : public WireGuardLayer { - if (dataLen < sizeof(wg_common_header)) - return false; + public: +#pragma pack(push, 1) + /** + * @struct wg_transport_data + * Represents the Transport Data message + */ + typedef struct wg_transport_data : wg_common_header + { + /** Receiver index */ + uint32_t receiverIndex; + /** Counter field */ + uint64_t counter; + /** Flexible array member for encrypted data */ + uint8_t encryptedData[0]; + } wg_transport_data; +#pragma pack(pop) - uint8_t messageType = data[0]; - return messageType >= static_cast(WireGuardMessageType::HandshakeInitiation) && - messageType <= static_cast(WireGuardMessageType::TransportData); - } + /** + * A constructor that creates the layer from an existing packet raw data + * @param[in] data A pointer to the raw data + * @param[in] dataLen Size of the data in bytes + * @param[in] prevLayer A pointer to the previous layer + * @param[in] packet A pointer to the Packet instance where layer will be stored in + */ + WireGuardTransportDataLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) + : WireGuardLayer(data, dataLen, prevLayer, packet) + {} + /** + * A constructor that creates a new Transport Data message + * @param[in] receiverIndex The receiver index + * @param[in] counter The counter field + * @param[in] encryptedData The encrypted data + */ + WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, const uint8_t* encryptedData, + size_t encryptedDataLen); + + uint32_t getMessageType() const; + const uint8_t* getReserved() const; + uint32_t getReceiverIndex() const; + uint64_t getCounter() const; + const uint8_t* getEncryptedData() const; + + wg_transport_data* getTransportHeader() const + { + return (wg_transport_data*)getBasicHeader(); + } + + // implement abstract methods + + WireGuardMessageType getWireGuardMessageType() const + { + return WireGuardMessageType::TransportData; + } + }; } // namespace pcpp diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index cebfbfa10b..cebf071f8e 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -11,134 +11,49 @@ namespace pcpp { - std::string WireGuardLayer::toString() const + WireGuardLayer* WireGuardLayer::parseWireGuardLayer() { - if (m_DataLen < sizeof(wg_common_header)) - { - return "WireGuard header (incomplete)"; - } + if (m_DataLen < sizeof(WireGuardLayer::wg_common_header)) + return nullptr; + wg_common_header* wgHeader = reinterpret_cast(m_Data); - std::stringstream ss; - const wg_common_header* header = reinterpret_cast(m_Data); - ss << "WireGuard Layer\n"; - ss << " Type: " << static_cast(header->messageType) << "\n"; - ss << " Reserved: "; - for (int i = 0; i < 3; ++i) + switch (wgHeader->messageType) { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(header->reserved[i]); + case static_cast(WireGuardMessageType::HandshakeInitiation): + return new WireGuardHandshakeInitiationLayer(m_Data, m_DataLen, this, m_Packet); + case static_cast(WireGuardMessageType::HandshakeResponse): + return new WireGuardHandshakeResponseLayer(m_Data, m_DataLen, this, m_Packet); + case static_cast(WireGuardMessageType::CookieReply): + return new WireGuardCookieReplyLayer(m_Data, m_DataLen, this, m_Packet); + case static_cast(WireGuardMessageType::TransportData): + return new WireGuardTransportDataLayer(m_Data, m_DataLen, this, m_Packet); + default: + return nullptr; } - ss << std::dec << "\n"; // Reset to decimal + } - switch (header->messageType) + std::string WireGuardLayer::getMessageTypeAsString() const + { + // Assuming you have a method to retrieve the message type from the header + wg_common_header* wgHeader = reinterpret_cast(this->getData()); + switch (wgHeader->messageType) { case static_cast(WireGuardMessageType::HandshakeInitiation): - { - const wg_handshake_initiation* msg = getHandshakeInitiation(); - ss << " Handshake Initiation\n"; - ss << " Sender Index: " << msg->senderIndex << "\n"; - ss << " Initiator Ephemeral: "; - for (const auto& byte : msg->initiatorEphemeral) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " Encrypted Initiator Static: "; - for (const auto& byte : msg->encryptedInitiatorStatic) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " Encrypted Timestamp: "; - for (const auto& byte : msg->encryptedTimestamp) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " MAC1: "; - for (const auto& byte : msg->mac1) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " MAC2: "; - for (const auto& byte : msg->mac2) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - break; - } + return "Handshake Initiation"; case static_cast(WireGuardMessageType::HandshakeResponse): - { - const wg_handshake_response* msg = getHandshakeResponse(); - ss << " Handshake Response\n"; - ss << " Sender Index: " << msg->senderIndex << "\n"; - ss << " Receiver Index: " << msg->receiverIndex << "\n"; - ss << " Responder Ephemeral: "; - for (const auto& byte : msg->responderEphemeral) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " Encrypted Empty: "; - for (const auto& byte : msg->encryptedEmpty) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " MAC1: "; - for (const auto& byte : msg->mac1) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " MAC2: "; - for (const auto& byte : msg->mac2) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - break; - } + return "Handshake Response"; case static_cast(WireGuardMessageType::CookieReply): - { - const wg_cookie_reply* msg = getCookieReply(); - ss << " Cookie Reply\n"; - ss << " Receiver Index: " << msg->receiverIndex << "\n"; - ss << " Nonce: "; - for (const auto& byte : msg->nonce) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - ss << " Encrypted Cookie: "; - for (const auto& byte : msg->encryptedCookie) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - ss << std::dec << "\n"; - break; - } + return "Cookie Reply"; case static_cast(WireGuardMessageType::TransportData): - { - const wg_transport_data* msg = getTransportData(); - ss << " Transport Data\n"; - ss << " Receiver Index: " << msg->receiverIndex << "\n"; - ss << " Counter: " << msg->counter << "\n"; - ss << " Encrypted Data: "; - for (size_t i = 0; i < m_DataLen - sizeof(wg_transport_data); ++i) - { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(msg->encryptedData[i]); - } - ss << std::dec << "\n"; - break; - } + return "Transport Data"; default: - ss << " Unknown message type\n"; - break; + return "Unknown"; } + } - return ss.str(); + std::string WireGuardLayer::toString() const + { + return "WireGuardLayer, " + getMessageTypeAsString() + " message"; } size_t WireGuardLayer::getHeaderLen() const @@ -146,4 +61,256 @@ namespace pcpp return m_DataLen; } + bool WireGuardLayer::isDataValid(const uint8_t* data, size_t dataLen) + { + if (dataLen < sizeof(WireGuardLayer::wg_common_header)) + return false; + + uint8_t messageType = data[0]; + return messageType >= static_cast(WireGuardLayer::WireGuardMessageType::HandshakeInitiation) && + messageType <= static_cast(WireGuardLayer::WireGuardMessageType::TransportData); + } + + // ~~~~~~~~~~~~~~~~~~~~ + // WireGuardHandshakeInitiationLayer + // ~~~~~~~~~~~~~~~~~~~~ + + WireGuardHandshakeInitiationLayer::WireGuardHandshakeInitiationLayer(uint32_t senderIndex, + const uint8_t initiatorEphemeral[32], + const uint8_t encryptedInitiatorStatic[48], + const uint8_t encryptedTimestamp[28], + const uint8_t mac1[16], const uint8_t mac2[16]) + { + const size_t messageLen = sizeof(wg_handshake_initiation); + m_DataLen = messageLen; + m_Data = new uint8_t[messageLen]; + memset(m_Data, 0, messageLen); + + wg_handshake_initiation* msgHdr = reinterpret_cast(m_Data); + + msgHdr->messageType = static_cast(WireGuardMessageType::HandshakeInitiation); + + std::memset(msgHdr->reserved, 0, sizeof(msgHdr->reserved)); + + msgHdr->senderIndex = senderIndex; + std::memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); + std::memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); + std::memcpy(msgHdr->encryptedTimestamp, encryptedTimestamp, 28); + std::memcpy(msgHdr->mac1, mac1, 16); + std::memcpy(msgHdr->mac2, mac2, 16); + + m_Protocol = Wireguard; + } + + uint32_t WireGuardHandshakeInitiationLayer::getMessageType() const + { + return getHandshakeInitiationHeader()->messageType; + } + + const uint8_t* WireGuardHandshakeInitiationLayer::getReserved() const + { + return getHandshakeInitiationHeader()->reserved; + } + + uint32_t WireGuardHandshakeInitiationLayer::getSenderIndex() const + { + return getHandshakeInitiationHeader()->senderIndex; + } + + const uint8_t* WireGuardHandshakeInitiationLayer::getInitiatorEphemeral() const + { + return getHandshakeInitiationHeader()->initiatorEphemeral; + } + + const uint8_t* WireGuardHandshakeInitiationLayer::getEncryptedInitiatorStatic() const + { + return getHandshakeInitiationHeader()->encryptedInitiatorStatic; + } + + const uint8_t* WireGuardHandshakeInitiationLayer::getEncryptedTimestamp() const + { + return getHandshakeInitiationHeader()->encryptedTimestamp; + } + + const uint8_t* WireGuardHandshakeInitiationLayer::getMac1() const + { + return getHandshakeInitiationHeader()->mac1; + } + + const uint8_t* WireGuardHandshakeInitiationLayer::getMac2() const + { + return getHandshakeInitiationHeader()->mac2; + } + + // ~~~~~~~~~~~~~~~~~~~~ + // WireGuardHandshakeResponseLayer + // ~~~~~~~~~~~~~~~~~~~~ + + WireGuardHandshakeResponseLayer::WireGuardHandshakeResponseLayer(uint32_t senderIndex, uint32_t receiverIndex, + const uint8_t responderEphemeral[32], + const uint8_t encryptedEmpty[16], + const uint8_t mac1[16], const uint8_t mac2[16]) + { + const size_t messageLen = sizeof(wg_handshake_response); + m_DataLen = messageLen; + m_Data = new uint8_t[messageLen]; + std::memset(m_Data, 0, messageLen); + + wg_handshake_response* msg = reinterpret_cast(m_Data); + + msg->messageType = static_cast(WireGuardMessageType::HandshakeResponse); + + std::memset(msg->reserved, 0, sizeof(msg->reserved)); + + msg->senderIndex = senderIndex; + msg->receiverIndex = receiverIndex; + std::memcpy(msg->responderEphemeral, responderEphemeral, 32); + std::memcpy(msg->encryptedEmpty, encryptedEmpty, 16); + std::memcpy(msg->mac1, mac1, 16); + std::memcpy(msg->mac2, mac2, 16); + + m_Protocol = Wireguard; + } + + uint32_t WireGuardHandshakeResponseLayer::getMessageType() const + { + return getHandshakeResponseHeader()->messageType; + } + + const uint8_t* WireGuardHandshakeResponseLayer::getReserved() const + { + return getHandshakeResponseHeader()->reserved; + } + + uint32_t WireGuardHandshakeResponseLayer::getSenderIndex() const + { + return getHandshakeResponseHeader()->senderIndex; + } + + uint32_t WireGuardHandshakeResponseLayer::getReceiverIndex() const + { + return getHandshakeResponseHeader()->receiverIndex; + } + + const uint8_t* WireGuardHandshakeResponseLayer::getResponderEphemeral() const + { + return getHandshakeResponseHeader()->responderEphemeral; + } + + const uint8_t* WireGuardHandshakeResponseLayer::getEncryptedEmpty() const + { + return getHandshakeResponseHeader()->encryptedEmpty; + } + + const uint8_t* WireGuardHandshakeResponseLayer::getMac1() const + { + return getHandshakeResponseHeader()->mac1; + } + + const uint8_t* WireGuardHandshakeResponseLayer::getMac2() const + { + return getHandshakeResponseHeader()->mac2; + } + + // ~~~~~~~~~~~~~~~~~~~~ + // WireGuardCookieReplyLayer + // ~~~~~~~~~~~~~~~~~~~~ + + WireGuardCookieReplyLayer::WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], + const uint8_t encryptedCookie[32]) + { + const size_t messageLen = sizeof(wg_cookie_reply); + m_DataLen = messageLen; + m_Data = new uint8_t[messageLen]; + std::memset(m_Data, 0, messageLen); + + wg_cookie_reply* msg = reinterpret_cast(m_Data); + + msg->messageType = static_cast(WireGuardMessageType::CookieReply); + + std::memset(msg->reserved, 0, sizeof(msg->reserved)); + + msg->receiverIndex = receiverIndex; + std::memcpy(msg->nonce, nonce, 24); + std::memcpy(msg->encryptedCookie, encryptedCookie, 32); + + m_Protocol = Wireguard; + } + + uint32_t WireGuardCookieReplyLayer::getMessageType() const + { + return getCookieReplyHeader()->messageType; + } + + const uint8_t* WireGuardCookieReplyLayer::getReserved() const + { + return getCookieReplyHeader()->reserved; + } + + uint32_t WireGuardCookieReplyLayer::getReceiverIndex() const + { + return getCookieReplyHeader()->receiverIndex; + } + + const uint8_t* WireGuardCookieReplyLayer::getNonce() const + { + return getCookieReplyHeader()->nonce; + } + + const uint8_t* WireGuardCookieReplyLayer::getEncryptedCookie() const + { + return getCookieReplyHeader()->encryptedCookie; + } + + // ~~~~~~~~~~~~~~~~~~~~ + // WireGuardTransportDataLayer + // ~~~~~~~~~~~~~~~~~~~~ + + WireGuardTransportDataLayer::WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, + const uint8_t* encryptedData, size_t encryptedDataLen) + { + const size_t messageLen = sizeof(wg_transport_data) + encryptedDataLen; + m_DataLen = messageLen; + m_Data = new uint8_t[messageLen]; + std::memset(m_Data, 0, messageLen); + + wg_transport_data* msg = reinterpret_cast(m_Data); + + msg->messageType = static_cast(WireGuardMessageType::TransportData); + + std::memset(msg->reserved, 0, sizeof(msg->reserved)); + + msg->receiverIndex = receiverIndex; + msg->counter = counter; + + std::memcpy(m_Data + sizeof(wg_transport_data), encryptedData, encryptedDataLen); + + m_Protocol = Wireguard; + } + + uint32_t WireGuardTransportDataLayer::getMessageType() const + { + return getTransportHeader()->messageType; + } + + const uint8_t* WireGuardTransportDataLayer::getReserved() const + { + return getTransportHeader()->reserved; + } + + uint32_t WireGuardTransportDataLayer::getReceiverIndex() const + { + return getTransportHeader()->receiverIndex; + } + + uint64_t WireGuardTransportDataLayer::getCounter() const + { + return getTransportHeader()->counter; + } + + const uint8_t* WireGuardTransportDataLayer::getEncryptedData() const + { + return getTransportHeader()->encryptedData; + } + } // namespace pcpp From dcd867742d2145c2bcadd0054dd2e11fc3e2934f Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 22 Sep 2024 21:16:35 +0900 Subject: [PATCH 25/37] Refactor Update test code and add creation tests for WireGuardMessage packets Signed-off-by: Dongjun Na --- Tests/Packet++Test/TestDefinition.h | 4 + Tests/Packet++Test/Tests/WireGuardTests.cpp | 178 +++++++++++++++----- Tests/Packet++Test/main.cpp | 4 + 3 files changed, 146 insertions(+), 40 deletions(-) diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 46169931a7..441a18ff66 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -268,3 +268,7 @@ PTF_TEST_CASE(LdapCreationTest); PTF_TEST_CASE(WireGuardHandshakeInitParsingTest); PTF_TEST_CASE(WireGuardHandshakeRespParsingTest); PTF_TEST_CASE(WireGuardTransportDataParsingTest); +PTF_TEST_CASE(WireGuardHandshakeInitCreatingTest); +PTF_TEST_CASE(WireGuardHandshakeRespCreatingTest); +PTF_TEST_CASE(WireGuardCookieReplyCreatingTest); +PTF_TEST_CASE(WireGuardTransportDataCreatingTest); diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 911df00633..e200f50c71 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -12,42 +12,53 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); - pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::Wireguard)); - pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); + pcpp::Packet wgHandShakeInitPacket(&rawPacket1); + + PTF_ASSERT_TRUE(wgHandShakeInitPacket.isPacketOfType(pcpp::Wireguard)); + pcpp::WireGuardLayer* wgLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_initiation)); - const pcpp::wg_handshake_initiation* handshakeInit = wgLayer->getHandshakeInitiation(); - PTF_ASSERT_NOT_NULL(handshakeInit); - PTF_ASSERT_EQUAL(handshakeInit->common.messageType, - static_cast(pcpp::WireGuardMessageType::HandshakeInitiation)); - PTF_ASSERT_EQUAL(handshakeInit->senderIndex, 818952152); + PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Handshake Initiation"); + PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); + + pcpp::WireGuardHandshakeInitiationLayer* wgHandShakeInitLayer = + dynamic_cast(wgLayer->parseWireGuardLayer()); + + PTF_ASSERT_NOT_NULL(wgHandShakeInitLayer); + + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getWireGuardMessageType() == + pcpp::WireGuardLayer::WireGuardMessageType::HandshakeInitiation); + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getHeaderLen() == + sizeof(pcpp::WireGuardHandshakeInitiationLayer::wg_handshake_initiation)); + + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getSenderIndex(), 818952152); uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->initiatorEphemeral, expectedPublicKey, sizeof(expectedPublicKey)) == 0); + PTF_ASSERT_TRUE( + std::memcmp(wgHandShakeInitLayer->getInitiatorEphemeral(), expectedPublicKey, sizeof(expectedPublicKey)) == 0); uint8_t expectedStaticKey[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; - PTF_ASSERT_TRUE( - std::memcmp(handshakeInit->encryptedInitiatorStatic, expectedStaticKey, sizeof(expectedStaticKey)) == 0); + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeInitLayer->getEncryptedInitiatorStatic(), expectedStaticKey, + sizeof(expectedStaticKey)) == 0); uint8_t expectedTimestamp[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->encryptedTimestamp, expectedTimestamp, sizeof(expectedTimestamp)) == 0); + PTF_ASSERT_TRUE( + std::memcmp(wgHandShakeInitLayer->getEncryptedTimestamp(), expectedTimestamp, sizeof(expectedTimestamp)) == 0); uint8_t expectedMac1[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac1, expectedMac1, sizeof(expectedMac1)) == 0); + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeInitLayer->getMac1(), expectedMac1, sizeof(expectedMac1)) == 0); uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeInit->mac2, expectedMac2, sizeof(expectedMac2)) == 0); + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeInitLayer->getMac2(), expectedMac2, sizeof(expectedMac2)) == 0); } PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) @@ -57,33 +68,45 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeResponse.dat"); - pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::Wireguard)); - pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); + pcpp::Packet wgHandShakeResponsePacket(&rawPacket1); + + PTF_ASSERT_TRUE(wgHandShakeResponsePacket.isPacketOfType(pcpp::Wireguard)); + pcpp::WireGuardLayer* wgLayer = wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); + PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Handshake Response"); + PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); + + pcpp::WireGuardHandshakeResponseLayer* wgHandShakeResponseLayer = + dynamic_cast(wgLayer->parseWireGuardLayer()); - PTF_ASSERT_TRUE(wgLayer->getHeaderLen() == sizeof(pcpp::wg_handshake_response)); + PTF_ASSERT_NOT_NULL(wgHandShakeResponseLayer); + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getWireGuardMessageType() == + pcpp::WireGuardLayer::WireGuardMessageType::HandshakeResponse); + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getHeaderLen() == + sizeof(pcpp::WireGuardHandshakeResponseLayer::wg_handshake_response)); - const pcpp::wg_handshake_response* handshakeResponse = wgLayer->getHandshakeResponse(); - PTF_ASSERT_NOT_NULL(handshakeResponse); - PTF_ASSERT_EQUAL(handshakeResponse->common.messageType, - static_cast(pcpp::WireGuardMessageType::HandshakeResponse)); - PTF_ASSERT_EQUAL(handshakeResponse->senderIndex, 2877158406); - PTF_ASSERT_EQUAL(handshakeResponse->receiverIndex, 818952152); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getSenderIndex(), 2877158406); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getReceiverIndex(), 818952152); uint8_t expectedResponderEphemeral[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->responderEphemeral, expectedResponderEphemeral, + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getResponderEphemeral(), expectedResponderEphemeral, sizeof(expectedResponderEphemeral)) == 0); + uint8_t encryptedEmptyData[16] = { 0xae, 0xc2, 0x4a, 0xf8, 0x91, 0x8d, 0xe1, 0x06, + 0x0f, 0xf5, 0xc9, 0x8e, 0x86, 0x5d, 0x5f, 0x35 }; + + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getEncryptedEmpty(), encryptedEmptyData, + sizeof(encryptedEmptyData)) == 0); + uint8_t expectedMac1[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac1, expectedMac1, sizeof(expectedMac1)) == 0); + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getMac1(), expectedMac1, sizeof(expectedMac1)) == 0); uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(handshakeResponse->mac2, expectedMac2, sizeof(expectedMac2)) == 0); + PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getMac2(), expectedMac2, sizeof(expectedMac2)) == 0); } PTF_TEST_CASE(WireGuardTransportDataParsingTest) @@ -93,20 +116,29 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); - pcpp::Packet wgPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgPacket.isPacketOfType(pcpp::Wireguard)); - pcpp::WireGuardLayer* wgLayer = wgPacket.getLayerOfType(); + pcpp::Packet wgTransportDataPacket(&rawPacket1); + PTF_ASSERT_TRUE(wgTransportDataPacket.isPacketOfType(pcpp::Wireguard)); + pcpp::WireGuardLayer* wgLayer = wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_TRUE(wgLayer->getHeaderLen() >= sizeof(pcpp::wg_transport_data)); + PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Transport Data"); + PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); - const pcpp::wg_transport_data* transportData = wgLayer->getTransportData(); - PTF_ASSERT_NOT_NULL(transportData); - PTF_ASSERT_EQUAL(transportData->common.messageType, - static_cast(pcpp::WireGuardMessageType::TransportData)); - PTF_ASSERT_EQUAL(transportData->receiverIndex, 2877158406); + pcpp::WireGuardTransportDataLayer* wgTransportDataLayer = + dynamic_cast(wgLayer->parseWireGuardLayer()); + + PTF_ASSERT_NOT_NULL(wgTransportDataLayer); + PTF_ASSERT_TRUE(wgTransportDataLayer->getWireGuardMessageType() == + pcpp::WireGuardLayer::WireGuardMessageType::TransportData); + PTF_ASSERT_TRUE(wgTransportDataLayer->getHeaderLen() >= + sizeof(pcpp::WireGuardTransportDataLayer::wg_transport_data)); + + PTF_ASSERT_EQUAL(wgTransportDataLayer->getReceiverIndex(), 2877158406); uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(&transportData->counter, &expectedCounter, sizeof(expectedCounter)) == 0); + uint64_t counter = wgTransportDataLayer->getCounter(); + uint8_t counterBytes[8]; + std::memcpy(counterBytes, &counter, sizeof(counterBytes)); + PTF_ASSERT_TRUE(std::memcmp(counterBytes, &expectedCounter, sizeof(expectedCounter)) == 0); uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, @@ -117,6 +149,72 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) 0xbe, 0x03, 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, 0x47, 0x01, 0x36, 0x4f, 0x2d, 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - PTF_ASSERT_TRUE(std::memcmp(transportData->encryptedData, expectedEncryptedData, sizeof(expectedEncryptedData)) == - 0); + PTF_ASSERT_TRUE(std::memcmp(wgTransportDataLayer->getEncryptedData(), expectedEncryptedData, + sizeof(expectedEncryptedData)) == 0); +} + +PTF_TEST_CASE(WireGuardHandshakeInitCreatingTest) +{ + uint32_t senderIndex = 12345; + uint8_t initiatorEphemeral[32] = { 0 }; + uint8_t encryptedInitiatorStatic[48] = { 0 }; + uint8_t encryptedTimestamp[28] = { 0 }; + uint8_t mac1[16] = { 0 }; + uint8_t mac2[16] = { 0 }; + + pcpp::WireGuardHandshakeInitiationLayer handshakeInitLayer( + senderIndex, initiatorEphemeral, encryptedInitiatorStatic, encryptedTimestamp, mac1, mac2); + + PTF_ASSERT_EQUAL(handshakeInitLayer.getSenderIndex(), senderIndex); + PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getInitiatorEphemeral(), initiatorEphemeral, 32) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getEncryptedInitiatorStatic(), encryptedInitiatorStatic, 48) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getEncryptedTimestamp(), encryptedTimestamp, 28) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getMac1(), mac1, 16) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getMac2(), mac2, 16) == 0); +} + +PTF_TEST_CASE(WireGuardHandshakeRespCreatingTest) +{ + uint32_t senderIndex = 12345; + uint32_t receiverIndex = 54321; + uint8_t responderEphemeral[32] = { 0 }; + uint8_t encryptedEmpty[16] = { 0 }; + uint8_t mac1[16] = { 0 }; + uint8_t mac2[16] = { 0 }; + + pcpp::WireGuardHandshakeResponseLayer handshakeResponseLayer(senderIndex, receiverIndex, responderEphemeral, + encryptedEmpty, mac1, mac2); + + PTF_ASSERT_EQUAL(handshakeResponseLayer.getSenderIndex(), senderIndex); + PTF_ASSERT_EQUAL(handshakeResponseLayer.getReceiverIndex(), receiverIndex); + PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getResponderEphemeral(), responderEphemeral, 32) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getEncryptedEmpty(), encryptedEmpty, 16) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getMac1(), mac1, 16) == 0); + PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getMac2(), mac2, 16) == 0); +} + +PTF_TEST_CASE(WireGuardCookieReplyCreatingTest) +{ + uint32_t receiverIndex = 54321; + uint8_t nonce[24] = { 0 }; + uint8_t encryptedCookie[32] = { 0 }; + + pcpp::WireGuardCookieReplyLayer cookieReplyLayer(receiverIndex, nonce, encryptedCookie); + + PTF_ASSERT_EQUAL(cookieReplyLayer.getReceiverIndex(), receiverIndex); + PTF_ASSERT_TRUE(std::memcmp(cookieReplyLayer.getNonce(), nonce, 24) == 0); + PTF_ASSERT_TRUE(std::memcmp(cookieReplyLayer.getEncryptedCookie(), encryptedCookie, 32) == 0); +} + +PTF_TEST_CASE(WireGuardTransportDataCreatingTest) +{ + uint32_t receiverIndex = 54321; + uint64_t counter = 100; + uint8_t encryptedData[64] = { 0 }; + + pcpp::WireGuardTransportDataLayer transportDataLayer(receiverIndex, counter, encryptedData, sizeof(encryptedData)); + + PTF_ASSERT_EQUAL(transportDataLayer.getReceiverIndex(), receiverIndex); + PTF_ASSERT_EQUAL(transportDataLayer.getCounter(), counter); + PTF_ASSERT_TRUE(std::memcmp(transportDataLayer.getEncryptedData(), encryptedData, sizeof(encryptedData)) == 0); } diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index d0ac3c4702..5f4afde7f9 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -337,6 +337,10 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(WireGuardHandshakeInitParsingTest, "wg"); PTF_RUN_TEST(WireGuardHandshakeRespParsingTest, "wg"); PTF_RUN_TEST(WireGuardTransportDataParsingTest, "wg"); + PTF_RUN_TEST(WireGuardHandshakeInitCreatingTest, "wg"); + PTF_RUN_TEST(WireGuardHandshakeRespCreatingTest, "wg"); + PTF_RUN_TEST(WireGuardCookieReplyCreatingTest, "wg"); + PTF_RUN_TEST(WireGuardTransportDataCreatingTest, "wg"); PTF_END_RUNNING_TESTS; } From 8aac9fc1dfe74b092a89020c3edd66d204a316d8 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 22 Sep 2024 21:24:34 +0900 Subject: [PATCH 26/37] Refactor add documentation comments for WireGuard layer classes and structures Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index fd13097893..00db15b9a9 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -150,6 +150,10 @@ namespace pcpp { public: #pragma pack(push, 1) + /** + * @struct wg_handshake_initiation + * Represents the Handshake Initiation message structure + */ typedef struct wg_handshake_initiation : wg_common_header { /** Sender index */ @@ -166,6 +170,7 @@ namespace pcpp uint8_t mac2[16]; } wg_handshake_initiation; #pragma pack(pop) + /** * A constructor that creates the layer from an existing packet raw data * @param[in] data A pointer to the raw data @@ -223,7 +228,7 @@ namespace pcpp #pragma pack(push, 1) /** * @struct wg_handshake_response - * Represents the Handshake Response message + * Represents the Handshake Response message structure */ typedef struct wg_handshake_response : wg_common_header { @@ -298,7 +303,7 @@ namespace pcpp #pragma pack(push, 1) /** * @struct wg_cookie_reply - * Represents the Cookie Reply message + * Represents the Cookie Reply message structure */ typedef struct wg_cookie_reply : wg_common_header { @@ -359,7 +364,7 @@ namespace pcpp #pragma pack(push, 1) /** * @struct wg_transport_data - * Represents the Transport Data message + * Represents the Transport Data message structure */ typedef struct wg_transport_data : wg_common_header { From baeb1c6ef6db100d0cfb7869fdf92895b7844023 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sun, 22 Sep 2024 21:29:35 +0900 Subject: [PATCH 27/37] Add documentation comments for WireGuardTransportDataLayer Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 00db15b9a9..6041e761b1 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -393,6 +393,7 @@ namespace pcpp * @param[in] receiverIndex The receiver index * @param[in] counter The counter field * @param[in] encryptedData The encrypted data + * @param[in] encryptedDataLen The length of the encrypted data */ WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, const uint8_t* encryptedData, size_t encryptedDataLen); From a4b10e934dc47e9410679eeada0eb8ab64e3276f Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Mon, 23 Sep 2024 18:18:40 +0900 Subject: [PATCH 28/37] Refactor implementation of parseNextLayer for parsing WireGuard message to handle nextLayer Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 10 ++- Packet++/src/UdpLayer.cpp | 6 +- Packet++/src/WireGuardLayer.cpp | 22 ++++-- Tests/Packet++Test/TestDefinition.h | 4 -- Tests/Packet++Test/Tests/WireGuardTests.cpp | 77 ++------------------- Tests/Packet++Test/main.cpp | 4 -- 6 files changed, 33 insertions(+), 90 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 6041e761b1..caae3f4739 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -90,7 +90,7 @@ namespace pcpp */ static bool isDataValid(const uint8_t* data, size_t dataLen); - WireGuardLayer* parseWireGuardLayer(); + static WireGuardLayer* parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); std::string getMessageTypeAsString() const; @@ -105,9 +105,13 @@ namespace pcpp } /** - * No operation required for parsing the next layer since WireGuard does not have a next layer. + * Multiple WireGuard messages can be present in a single packet. + * WireGuard does not have a layer that follows its messages, but this method checks for remaining data + * in the packet to determine if another WireGuard message exists. If so, it parses the next message + * as a new WireGuard layer. */ - void parseNextLayer() override {}; + void parseNextLayer() override; + /** * Calculates the length of the header based on the message type. * diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp index 9b3f3e4a7e..1e3d539f47 100644 --- a/Packet++/src/UdpLayer.cpp +++ b/Packet++/src/UdpLayer.cpp @@ -137,7 +137,11 @@ namespace pcpp m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); else if ((WireGuardLayer::isWireguardPorts(portDst, portSrc) && WireGuardLayer::isDataValid(udpData, udpDataLen))) - m_NextLayer = new WireGuardLayer(udpData, udpDataLen, this, m_Packet); + { + m_NextLayer = WireGuardLayer::parseWireGuardLayer(udpData, udpDataLen, this, m_Packet); + if (!m_NextLayer) + m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); + } else m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); } diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index cebf071f8e..8790e0824d 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -11,22 +11,30 @@ namespace pcpp { - WireGuardLayer* WireGuardLayer::parseWireGuardLayer() + void WireGuardLayer::parseNextLayer() { - if (m_DataLen < sizeof(WireGuardLayer::wg_common_header)) + size_t headerLen = getHeaderLen(); + if (m_DataLen <= headerLen || headerLen == 0) + return; + m_NextLayer = WireGuardLayer::parseWireGuardLayer(m_Data, m_DataLen, this, m_Packet); + } + + WireGuardLayer* WireGuardLayer::parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) + { + if (dataLen < sizeof(WireGuardLayer::wg_common_header)) return nullptr; - wg_common_header* wgHeader = reinterpret_cast(m_Data); + wg_common_header* wgHeader = reinterpret_cast(data); switch (wgHeader->messageType) { case static_cast(WireGuardMessageType::HandshakeInitiation): - return new WireGuardHandshakeInitiationLayer(m_Data, m_DataLen, this, m_Packet); + return new WireGuardHandshakeInitiationLayer(data, dataLen, prevLayer, packet); case static_cast(WireGuardMessageType::HandshakeResponse): - return new WireGuardHandshakeResponseLayer(m_Data, m_DataLen, this, m_Packet); + return new WireGuardHandshakeResponseLayer(data, dataLen, prevLayer, packet); case static_cast(WireGuardMessageType::CookieReply): - return new WireGuardCookieReplyLayer(m_Data, m_DataLen, this, m_Packet); + return new WireGuardCookieReplyLayer(data, dataLen, prevLayer, packet); case static_cast(WireGuardMessageType::TransportData): - return new WireGuardTransportDataLayer(m_Data, m_DataLen, this, m_Packet); + return new WireGuardTransportDataLayer(data, dataLen, prevLayer, packet); default: return nullptr; } diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 441a18ff66..46169931a7 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -268,7 +268,3 @@ PTF_TEST_CASE(LdapCreationTest); PTF_TEST_CASE(WireGuardHandshakeInitParsingTest); PTF_TEST_CASE(WireGuardHandshakeRespParsingTest); PTF_TEST_CASE(WireGuardTransportDataParsingTest); -PTF_TEST_CASE(WireGuardHandshakeInitCreatingTest); -PTF_TEST_CASE(WireGuardHandshakeRespCreatingTest); -PTF_TEST_CASE(WireGuardCookieReplyCreatingTest); -PTF_TEST_CASE(WireGuardTransportDataCreatingTest); diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index e200f50c71..67e46250f4 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -15,6 +15,7 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) pcpp::Packet wgHandShakeInitPacket(&rawPacket1); PTF_ASSERT_TRUE(wgHandShakeInitPacket.isPacketOfType(pcpp::Wireguard)); + pcpp::WireGuardLayer* wgLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); @@ -22,8 +23,7 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardHandshakeInitiationLayer* wgHandShakeInitLayer = - dynamic_cast(wgLayer->parseWireGuardLayer()); - + wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgHandShakeInitLayer); PTF_ASSERT_TRUE(wgHandShakeInitLayer->getWireGuardMessageType() == @@ -77,9 +77,9 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardHandshakeResponseLayer* wgHandShakeResponseLayer = - dynamic_cast(wgLayer->parseWireGuardLayer()); - + wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgHandShakeResponseLayer); + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeResponse); PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getHeaderLen() == @@ -124,7 +124,8 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardTransportDataLayer* wgTransportDataLayer = - dynamic_cast(wgLayer->parseWireGuardLayer()); + wgTransportDataPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(wgTransportDataLayer); PTF_ASSERT_NOT_NULL(wgTransportDataLayer); PTF_ASSERT_TRUE(wgTransportDataLayer->getWireGuardMessageType() == @@ -152,69 +153,3 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) PTF_ASSERT_TRUE(std::memcmp(wgTransportDataLayer->getEncryptedData(), expectedEncryptedData, sizeof(expectedEncryptedData)) == 0); } - -PTF_TEST_CASE(WireGuardHandshakeInitCreatingTest) -{ - uint32_t senderIndex = 12345; - uint8_t initiatorEphemeral[32] = { 0 }; - uint8_t encryptedInitiatorStatic[48] = { 0 }; - uint8_t encryptedTimestamp[28] = { 0 }; - uint8_t mac1[16] = { 0 }; - uint8_t mac2[16] = { 0 }; - - pcpp::WireGuardHandshakeInitiationLayer handshakeInitLayer( - senderIndex, initiatorEphemeral, encryptedInitiatorStatic, encryptedTimestamp, mac1, mac2); - - PTF_ASSERT_EQUAL(handshakeInitLayer.getSenderIndex(), senderIndex); - PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getInitiatorEphemeral(), initiatorEphemeral, 32) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getEncryptedInitiatorStatic(), encryptedInitiatorStatic, 48) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getEncryptedTimestamp(), encryptedTimestamp, 28) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getMac1(), mac1, 16) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeInitLayer.getMac2(), mac2, 16) == 0); -} - -PTF_TEST_CASE(WireGuardHandshakeRespCreatingTest) -{ - uint32_t senderIndex = 12345; - uint32_t receiverIndex = 54321; - uint8_t responderEphemeral[32] = { 0 }; - uint8_t encryptedEmpty[16] = { 0 }; - uint8_t mac1[16] = { 0 }; - uint8_t mac2[16] = { 0 }; - - pcpp::WireGuardHandshakeResponseLayer handshakeResponseLayer(senderIndex, receiverIndex, responderEphemeral, - encryptedEmpty, mac1, mac2); - - PTF_ASSERT_EQUAL(handshakeResponseLayer.getSenderIndex(), senderIndex); - PTF_ASSERT_EQUAL(handshakeResponseLayer.getReceiverIndex(), receiverIndex); - PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getResponderEphemeral(), responderEphemeral, 32) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getEncryptedEmpty(), encryptedEmpty, 16) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getMac1(), mac1, 16) == 0); - PTF_ASSERT_TRUE(std::memcmp(handshakeResponseLayer.getMac2(), mac2, 16) == 0); -} - -PTF_TEST_CASE(WireGuardCookieReplyCreatingTest) -{ - uint32_t receiverIndex = 54321; - uint8_t nonce[24] = { 0 }; - uint8_t encryptedCookie[32] = { 0 }; - - pcpp::WireGuardCookieReplyLayer cookieReplyLayer(receiverIndex, nonce, encryptedCookie); - - PTF_ASSERT_EQUAL(cookieReplyLayer.getReceiverIndex(), receiverIndex); - PTF_ASSERT_TRUE(std::memcmp(cookieReplyLayer.getNonce(), nonce, 24) == 0); - PTF_ASSERT_TRUE(std::memcmp(cookieReplyLayer.getEncryptedCookie(), encryptedCookie, 32) == 0); -} - -PTF_TEST_CASE(WireGuardTransportDataCreatingTest) -{ - uint32_t receiverIndex = 54321; - uint64_t counter = 100; - uint8_t encryptedData[64] = { 0 }; - - pcpp::WireGuardTransportDataLayer transportDataLayer(receiverIndex, counter, encryptedData, sizeof(encryptedData)); - - PTF_ASSERT_EQUAL(transportDataLayer.getReceiverIndex(), receiverIndex); - PTF_ASSERT_EQUAL(transportDataLayer.getCounter(), counter); - PTF_ASSERT_TRUE(std::memcmp(transportDataLayer.getEncryptedData(), encryptedData, sizeof(encryptedData)) == 0); -} diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index 5f4afde7f9..d0ac3c4702 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -337,10 +337,6 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(WireGuardHandshakeInitParsingTest, "wg"); PTF_RUN_TEST(WireGuardHandshakeRespParsingTest, "wg"); PTF_RUN_TEST(WireGuardTransportDataParsingTest, "wg"); - PTF_RUN_TEST(WireGuardHandshakeInitCreatingTest, "wg"); - PTF_RUN_TEST(WireGuardHandshakeRespCreatingTest, "wg"); - PTF_RUN_TEST(WireGuardCookieReplyCreatingTest, "wg"); - PTF_RUN_TEST(WireGuardTransportDataCreatingTest, "wg"); PTF_END_RUNNING_TESTS; } From ab508e896a4955367e7833c5c78a1b13e8d195af Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Mon, 23 Sep 2024 21:31:34 +0900 Subject: [PATCH 29/37] Add WireGuardCreationTest to validate WireGuard MessageLayer constructor and message creation Signed-off-by: Dongjun Na --- Tests/Packet++Test/TestDefinition.h | 1 + Tests/Packet++Test/Tests/WireGuardTests.cpp | 119 +++++++++++++++++++- Tests/Packet++Test/main.cpp | 1 + 3 files changed, 115 insertions(+), 6 deletions(-) diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 46169931a7..0c7fca856e 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -268,3 +268,4 @@ PTF_TEST_CASE(LdapCreationTest); PTF_TEST_CASE(WireGuardHandshakeInitParsingTest); PTF_TEST_CASE(WireGuardHandshakeRespParsingTest); PTF_TEST_CASE(WireGuardTransportDataParsingTest); +PTF_TEST_CASE(WireGuardCreationTest); diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 67e46250f4..e8a9611222 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -127,7 +127,6 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgTransportDataLayer); - PTF_ASSERT_NOT_NULL(wgTransportDataLayer); PTF_ASSERT_TRUE(wgTransportDataLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::TransportData); PTF_ASSERT_TRUE(wgTransportDataLayer->getHeaderLen() >= @@ -135,11 +134,8 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) PTF_ASSERT_EQUAL(wgTransportDataLayer->getReceiverIndex(), 2877158406); - uint8_t expectedCounter[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint64_t counter = wgTransportDataLayer->getCounter(); - uint8_t counterBytes[8]; - std::memcpy(counterBytes, &counter, sizeof(counterBytes)); - PTF_ASSERT_TRUE(std::memcmp(counterBytes, &expectedCounter, sizeof(expectedCounter)) == 0); + uint64_t expectedCounter = 0x0000000000000000; + PTF_ASSERT_EQUAL(wgTransportDataLayer->getCounter(), expectedCounter); uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, @@ -153,3 +149,114 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) PTF_ASSERT_TRUE(std::memcmp(wgTransportDataLayer->getEncryptedData(), expectedEncryptedData, sizeof(expectedEncryptedData)) == 0); } + +PTF_TEST_CASE(WireGuardCreationTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); + READ_FILE_AND_CREATE_PACKET(2, "PacketExamples/WireGuardHandshakeResponse.dat"); + READ_FILE_AND_CREATE_PACKET(3, "PacketExamples/WireGuardTransportData.dat"); + + uint8_t origBuffer[1500]; + + // create WireGuard Handshake Initiation message + memcpy(origBuffer, buffer1, bufferLength1); + + uint8_t expectedPublicKeyInit[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, + 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, + 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; + + uint8_t expectedStaticKeyInit[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, + 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, + 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, + 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; + uint8_t expectedTimestampInit[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, + 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, + 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; + + uint8_t expectedMac1Init[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, + 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; + + uint8_t expectedMac2Init[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(818952152, expectedPublicKeyInit, + expectedStaticKeyInit, expectedTimestampInit, + expectedMac1Init, expectedMac2Init); + pcpp::Packet wgHandshakeInitPacket(&rawPacket1); + pcpp::WireGuardHandshakeInitiationLayer* origHandshakeInitMessage = + dynamic_cast(wgHandshakeInitPacket.detachLayer(pcpp::Wireguard)); + PTF_ASSERT_NOT_NULL(origHandshakeInitMessage); + PTF_ASSERT_EQUAL(newHandshakeInitMessage.getDataLen(), origHandshakeInitMessage->getDataLen()); + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getData(), origHandshakeInitMessage->getData(), + origHandshakeInitMessage->getDataLen()); + PTF_ASSERT_TRUE(wgHandshakeInitPacket.addLayer(&newHandshakeInitMessage)); + + PTF_ASSERT_EQUAL(wgHandshakeInitPacket.getRawPacket()->getRawDataLen(), bufferLength1); + PTF_ASSERT_BUF_COMPARE(wgHandshakeInitPacket.getRawPacket()->getRawData(), origBuffer, bufferLength1); + delete origHandshakeInitMessage; + + // create WireGuard Handshake Response message + memcpy(origBuffer, buffer2, bufferLength2); + uint8_t expectedResponderEphemeralResp[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, + 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, + 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; + + uint8_t encryptedEmptyDataResp[16] = { 0xae, 0xc2, 0x4a, 0xf8, 0x91, 0x8d, 0xe1, 0x06, + 0x0f, 0xf5, 0xc9, 0x8e, 0x86, 0x5d, 0x5f, 0x35 }; + + uint8_t expectedMac1Resp[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, + 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; + + uint8_t expectedMac2Resp[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage(2877158406, 818952152, expectedResponderEphemeralResp, + encryptedEmptyDataResp, expectedMac1Resp, + expectedMac2Resp); + pcpp::Packet wgHandshakeRespPacket(&rawPacket2); + pcpp::WireGuardHandshakeResponseLayer* origHandshakeRespMessage = + dynamic_cast(wgHandshakeRespPacket.detachLayer(pcpp::Wireguard)); + PTF_ASSERT_NOT_NULL(origHandshakeRespMessage); + PTF_ASSERT_EQUAL(newHandshakeRespMessage.getDataLen(), origHandshakeRespMessage->getDataLen()); + PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getData(), origHandshakeRespMessage->getData(), + origHandshakeRespMessage->getDataLen()); + PTF_ASSERT_TRUE(wgHandshakeRespPacket.addLayer(&newHandshakeRespMessage)); + + PTF_ASSERT_EQUAL(wgHandshakeRespPacket.getRawPacket()->getRawDataLen(), bufferLength2); + PTF_ASSERT_BUF_COMPARE(wgHandshakeRespPacket.getRawPacket()->getRawData(), origBuffer, bufferLength2); + delete origHandshakeRespMessage; + + // create WireGuard Transport Data message + + memcpy(origBuffer, buffer3, bufferLength3); + + uint64_t expectedCounterTransport = 0x0000000000000000; + uint8_t expectedEncryptedDataTransport[112] = { + 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, 0xc0, 0x4e, 0x27, + 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, 0x26, 0x2e, 0x66, 0x65, 0x49, 0xb4, + 0x45, 0xa7, 0x43, 0x6e, 0x82, 0x9b, 0xff, 0xb6, 0xac, 0x65, 0xf0, 0x56, 0x48, 0xbc, 0x0c, 0x39, + 0x1f, 0xe7, 0xc5, 0x88, 0x48, 0x74, 0x37, 0x61, 0x27, 0x16, 0x49, 0x40, 0x18, 0x8f, 0x03, 0xdb, + 0xa6, 0x7a, 0xf8, 0x38, 0x8e, 0xaa, 0xb7, 0x6c, 0x59, 0x36, 0x28, 0xbf, 0x9d, 0xc7, 0xbe, 0x03, + 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, 0x47, 0x01, 0x36, 0x4f, 0x2d, + 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b + }; + + pcpp::WireGuardTransportDataLayer newTransportDataMessage(2877158406, expectedCounterTransport, + expectedEncryptedDataTransport, 112); + pcpp::Packet wgTransportDataPacket(&rawPacket3); + + pcpp::WireGuardTransportDataLayer* origTransportDataMessage = + dynamic_cast(wgTransportDataPacket.detachLayer(pcpp::Wireguard)); + PTF_ASSERT_NOT_NULL(origTransportDataMessage); + PTF_ASSERT_EQUAL(newTransportDataMessage.getDataLen(), origTransportDataMessage->getDataLen()); + PTF_ASSERT_BUF_COMPARE(newTransportDataMessage.getData(), origTransportDataMessage->getData(), + origTransportDataMessage->getDataLen()); + PTF_ASSERT_TRUE(wgTransportDataPacket.addLayer(&newTransportDataMessage)); + + PTF_ASSERT_EQUAL(wgTransportDataPacket.getRawPacket()->getRawDataLen(), bufferLength3); + PTF_ASSERT_BUF_COMPARE(wgTransportDataPacket.getRawPacket()->getRawData(), origBuffer, bufferLength3); + delete origTransportDataMessage; +} diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index d0ac3c4702..f4c7e02875 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -337,6 +337,7 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(WireGuardHandshakeInitParsingTest, "wg"); PTF_RUN_TEST(WireGuardHandshakeRespParsingTest, "wg"); PTF_RUN_TEST(WireGuardTransportDataParsingTest, "wg"); + PTF_RUN_TEST(WireGuardCreationTest, "wg"); PTF_END_RUNNING_TESTS; } From d66c277866af3bcad95cb1e8eb97b0aad0ca3121 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Tue, 24 Sep 2024 23:14:58 +0900 Subject: [PATCH 30/37] Refactor WireGuard Layer, Tests for improved memory management and data handling Signed-off-by: Dongjun Na --- Packet++/header/ProtocolType.h | 4 +- Packet++/header/WireGuardLayer.h | 156 ++++++++++++-------- Packet++/src/UdpLayer.cpp | 2 +- Packet++/src/WireGuardLayer.cpp | 140 +++++++++++------- Tests/Packet++Test/Tests/WireGuardTests.cpp | 128 ++++++++-------- 5 files changed, 248 insertions(+), 182 deletions(-) diff --git a/Packet++/header/ProtocolType.h b/Packet++/header/ProtocolType.h index f4807946ef..bb775fb9ff 100644 --- a/Packet++/header/ProtocolType.h +++ b/Packet++/header/ProtocolType.h @@ -348,9 +348,9 @@ namespace pcpp const ProtocolType LDAP = 55; /* - * Wireguard protocol + * WireGuard protocol */ - const ProtocolType Wireguard = 56; + const ProtocolType WireGuard = 56; /** * An enum representing OSI model layers diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index caae3f4739..f8e4a9d717 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -19,12 +19,38 @@ namespace pcpp */ class WireGuardLayer : public Layer { + protected: +#pragma pack(push, 1) + /** + * @struct wg_common_header + * Represents the common header for all WireGuard message types + */ + struct wg_common_header + { + /** Message type field */ + uint8_t messageType; + /** Reserved field (3 bytes) */ + uint8_t reserved[3]; + }; +#pragma pack(pop) + /** + * Get the basic header common to all WireGuard messages. + * + * @return Pointer to the common header structure. + */ + wg_common_header* getBasicHeader() const + { + return reinterpret_cast(m_Data); + } + public: /** * WireGuard message types */ enum class WireGuardMessageType { + /** Unknown Initiation message */ + Unknown = 0, /** Handshake Initiation message */ HandshakeInitiation = 1, /** Handshake Response message */ @@ -35,23 +61,6 @@ namespace pcpp TransportData = 4 }; -#pragma pack(push, 1) - /** - * @struct wg_common_header - * Represents the common header for all WireGuard message types - */ - struct wg_common_header - { - /** Message type field */ - uint8_t messageType; - /** Reserved field (3 bytes) */ - uint8_t reserved[3]; - }; -#pragma pack(pop) - - WireGuardLayer() - {} - /** * Constructs a WireGuardLayer object. * @@ -61,13 +70,11 @@ namespace pcpp * @param packet Pointer to the packet this layer belongs to */ WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) - : Layer(data, dataLen, prevLayer, packet, Wireguard) + : Layer(data, dataLen, prevLayer, packet, WireGuard) {} - wg_common_header* getBasicHeader() const - { - return (wg_common_header*)m_Data; - } + WireGuardLayer() + {} /** * Checks if the given port numbers are WireGuard ports. @@ -76,7 +83,7 @@ namespace pcpp * @param portDst The destination port number to check * @return True if either port matches the WireGuard port (51820), false otherwise */ - static bool isWireguardPorts(uint16_t portSrc, uint16_t portDst) + static bool isWireGuardPorts(uint16_t portSrc, uint16_t portDst) { return (portSrc == 51820 || portDst == 51820); } @@ -90,18 +97,44 @@ namespace pcpp */ static bool isDataValid(const uint8_t* data, size_t dataLen); + /** + * Parses the raw data into a WireGuard layer. + * + * @param data Pointer to the raw data + * @param dataLen Length of the data + * @param prevLayer Pointer to the previous layer + * @param packet Pointer to the packet + * @return A pointer to the parsed WireGuardLayer, or nullptr if parsing fails + */ static WireGuardLayer* parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); + /** + * Get the message type as a human-readable string. + * + * @return String representation of the message type. + */ std::string getMessageTypeAsString() const; - uint32_t getMessageType() + /** + * Get the message type of the WireGuard message. + * + * @return The message type as an unsigned 32-bit integer. + */ + uint32_t getMessageType() const { return getBasicHeader()->messageType; } - uint8_t* getReserved() + /** + * Get the reserved field from the WireGuard message. + * + * @return The reserved field as a 32-bit integer. + */ + uint32_t getReserved() const { - return getBasicHeader()->reserved; + uint32_t reservedValue = 0; + std::memcpy(&reservedValue, getBasicHeader()->reserved, 3); + return reservedValue; } /** @@ -115,7 +148,7 @@ namespace pcpp /** * Calculates the length of the header based on the message type. * - * @return Size of the header in bytes. For TransportData, returns the total data length. + * @return Size of the header in bytes. */ size_t getHeaderLen() const override; @@ -123,10 +156,7 @@ namespace pcpp * No fields to compute or update, so this method is left empty. */ void computeCalculateFields() override - { - // Since WireGuard headers have fixed lengths and no fields to compute (like checksums or lengths), - // this method does not need to perform any operations. It's left empty. - } + {} /** * Converts the WireGuard layer to a string representation. @@ -144,6 +174,16 @@ namespace pcpp { return OsiModelNetworkLayer; } + + /** + * Get the WireGuard message type in the form of a WireGuardMessageType enum. + * + * @return The message type as a WireGuardMessageType enum value. + */ + virtual WireGuardMessageType getWireGuardMessageType() const + { + return WireGuardMessageType::Unknown; + } }; /** @@ -152,7 +192,7 @@ namespace pcpp */ class WireGuardHandshakeInitiationLayer : public WireGuardLayer { - public: + private: #pragma pack(push, 1) /** * @struct wg_handshake_initiation @@ -174,7 +214,7 @@ namespace pcpp uint8_t mac2[16]; } wg_handshake_initiation; #pragma pack(pop) - + public: /** * A constructor that creates the layer from an existing packet raw data * @param[in] data A pointer to the raw data @@ -201,13 +241,13 @@ namespace pcpp const uint8_t mac2[16]); uint32_t getMessageType() const; - const uint8_t* getReserved() const; + uint32_t getReserved() const; uint32_t getSenderIndex() const; - const uint8_t* getInitiatorEphemeral() const; - const uint8_t* getEncryptedInitiatorStatic() const; - const uint8_t* getEncryptedTimestamp() const; - const uint8_t* getMac1() const; - const uint8_t* getMac2() const; + std::array getInitiatorEphemeral() const; + std::array getEncryptedInitiatorStatic() const; + std::array getEncryptedTimestamp() const; + std::array getMac1() const; + std::array getMac2() const; wg_handshake_initiation* getHandshakeInitiationHeader() const { @@ -216,7 +256,7 @@ namespace pcpp // implement abstract methods - WireGuardMessageType getWireGuardMessageType() const + WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::HandshakeInitiation; } @@ -228,7 +268,7 @@ namespace pcpp */ class WireGuardHandshakeResponseLayer : public WireGuardLayer { - public: + private: #pragma pack(push, 1) /** * @struct wg_handshake_response @@ -250,7 +290,7 @@ namespace pcpp uint8_t mac2[16]; } wg_handshake_response; #pragma pack(pop) - + public: /** * A constructor that creates the layer from an existing packet raw data * @param[in] data A pointer to the raw data @@ -276,13 +316,13 @@ namespace pcpp const uint8_t mac1[16], const uint8_t mac2[16]); uint32_t getMessageType() const; - const uint8_t* getReserved() const; + uint32_t getReserved() const; uint32_t getSenderIndex() const; uint32_t getReceiverIndex() const; - const uint8_t* getResponderEphemeral() const; - const uint8_t* getEncryptedEmpty() const; - const uint8_t* getMac1() const; - const uint8_t* getMac2() const; + std::array getResponderEphemeral() const; + std::array getEncryptedEmpty() const; + std::array getMac1() const; + std::array getMac2() const; wg_handshake_response* getHandshakeResponseHeader() const { @@ -291,7 +331,7 @@ namespace pcpp // implement abstract methods - WireGuardMessageType getWireGuardMessageType() const + WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::HandshakeResponse; } @@ -303,7 +343,7 @@ namespace pcpp */ class WireGuardCookieReplyLayer : public WireGuardLayer { - public: + private: #pragma pack(push, 1) /** * @struct wg_cookie_reply @@ -319,7 +359,7 @@ namespace pcpp uint8_t encryptedCookie[32]; } wg_cookie_reply; #pragma pack(pop) - + public: /** * A constructor that creates the layer from an existing packet raw data * @param[in] data A pointer to the raw data @@ -340,10 +380,10 @@ namespace pcpp WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], const uint8_t encryptedCookie[32]); uint32_t getMessageType() const; - const uint8_t* getReserved() const; + uint32_t getReserved() const; uint32_t getReceiverIndex() const; - const uint8_t* getNonce() const; - const uint8_t* getEncryptedCookie() const; + std::array getNonce() const; + std::array getEncryptedCookie() const; wg_cookie_reply* getCookieReplyHeader() const { @@ -352,7 +392,7 @@ namespace pcpp // implement abstract methods - WireGuardMessageType getWireGuardMessageType() const + WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::CookieReply; } @@ -364,7 +404,7 @@ namespace pcpp */ class WireGuardTransportDataLayer : public WireGuardLayer { - public: + private: #pragma pack(push, 1) /** * @struct wg_transport_data @@ -380,7 +420,7 @@ namespace pcpp uint8_t encryptedData[0]; } wg_transport_data; #pragma pack(pop) - + public: /** * A constructor that creates the layer from an existing packet raw data * @param[in] data A pointer to the raw data @@ -403,7 +443,7 @@ namespace pcpp size_t encryptedDataLen); uint32_t getMessageType() const; - const uint8_t* getReserved() const; + uint32_t getReserved() const; uint32_t getReceiverIndex() const; uint64_t getCounter() const; const uint8_t* getEncryptedData() const; @@ -415,7 +455,7 @@ namespace pcpp // implement abstract methods - WireGuardMessageType getWireGuardMessageType() const + WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::TransportData; } diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp index 1e3d539f47..274695b856 100644 --- a/Packet++/src/UdpLayer.cpp +++ b/Packet++/src/UdpLayer.cpp @@ -135,7 +135,7 @@ namespace pcpp m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, m_Packet); else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen))) m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); - else if ((WireGuardLayer::isWireguardPorts(portDst, portSrc) && + else if ((WireGuardLayer::isWireGuardPorts(portDst, portSrc) && WireGuardLayer::isDataValid(udpData, udpDataLen))) { m_NextLayer = WireGuardLayer::parseWireGuardLayer(udpData, udpDataLen, this, m_Packet); diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 8790e0824d..54d61a34c4 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -1,10 +1,12 @@ #define LOG_MODULE PacketLogModuleWireGuardLayer #include "UdpLayer.h" +#include "PayloadLayer.h" #include "IPv4Layer.h" #include "IPv6Layer.h" #include "WireGuardLayer.h" #include "Logger.h" +#include "EndianPortable.h" #include #include #include @@ -17,6 +19,8 @@ namespace pcpp if (m_DataLen <= headerLen || headerLen == 0) return; m_NextLayer = WireGuardLayer::parseWireGuardLayer(m_Data, m_DataLen, this, m_Packet); + if (!m_NextLayer) + m_NextLayer = new PayloadLayer(m_Data, m_DataLen, this, m_Packet); } WireGuardLayer* WireGuardLayer::parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) @@ -43,8 +47,8 @@ namespace pcpp std::string WireGuardLayer::getMessageTypeAsString() const { // Assuming you have a method to retrieve the message type from the header - wg_common_header* wgHeader = reinterpret_cast(this->getData()); - switch (wgHeader->messageType) + uint32_t messageType = getMessageType(); + switch (messageType) { case static_cast(WireGuardMessageType::HandshakeInitiation): return "Handshake Initiation"; @@ -61,7 +65,7 @@ namespace pcpp std::string WireGuardLayer::toString() const { - return "WireGuardLayer, " + getMessageTypeAsString() + " message"; + return "WireGuard Layer, " + getMessageTypeAsString() + " message"; } size_t WireGuardLayer::getHeaderLen() const @@ -100,54 +104,66 @@ namespace pcpp std::memset(msgHdr->reserved, 0, sizeof(msgHdr->reserved)); - msgHdr->senderIndex = senderIndex; + msgHdr->senderIndex = htobe32(senderIndex); std::memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); std::memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); std::memcpy(msgHdr->encryptedTimestamp, encryptedTimestamp, 28); std::memcpy(msgHdr->mac1, mac1, 16); std::memcpy(msgHdr->mac2, mac2, 16); - m_Protocol = Wireguard; + m_Protocol = WireGuard; } uint32_t WireGuardHandshakeInitiationLayer::getMessageType() const { - return getHandshakeInitiationHeader()->messageType; + return be32toh(getHandshakeInitiationHeader()->messageType); } - const uint8_t* WireGuardHandshakeInitiationLayer::getReserved() const + uint32_t WireGuardHandshakeInitiationLayer::getReserved() const { - return getHandshakeInitiationHeader()->reserved; + uint32_t reservedValue = 0; + std::memcpy(&reservedValue, getHandshakeInitiationHeader()->reserved, 3); + return be32toh(reservedValue); } uint32_t WireGuardHandshakeInitiationLayer::getSenderIndex() const { - return getHandshakeInitiationHeader()->senderIndex; + return be32toh(getHandshakeInitiationHeader()->senderIndex); } - const uint8_t* WireGuardHandshakeInitiationLayer::getInitiatorEphemeral() const + std::array WireGuardHandshakeInitiationLayer::getInitiatorEphemeral() const { - return getHandshakeInitiationHeader()->initiatorEphemeral; + std::array ephemeralArray; + std::memcpy(ephemeralArray.data(), getHandshakeInitiationHeader()->initiatorEphemeral, 32); + return ephemeralArray; } - const uint8_t* WireGuardHandshakeInitiationLayer::getEncryptedInitiatorStatic() const + std::array WireGuardHandshakeInitiationLayer::getEncryptedInitiatorStatic() const { - return getHandshakeInitiationHeader()->encryptedInitiatorStatic; + std::array initArray; + std::memcpy(initArray.data(), getHandshakeInitiationHeader()->encryptedInitiatorStatic, 48); + return initArray; } - const uint8_t* WireGuardHandshakeInitiationLayer::getEncryptedTimestamp() const + std::array WireGuardHandshakeInitiationLayer::getEncryptedTimestamp() const { - return getHandshakeInitiationHeader()->encryptedTimestamp; + std::array tsArray; + std::memcpy(tsArray.data(), getHandshakeInitiationHeader()->encryptedTimestamp, 28); + return tsArray; } - const uint8_t* WireGuardHandshakeInitiationLayer::getMac1() const + std::array WireGuardHandshakeInitiationLayer::getMac1() const { - return getHandshakeInitiationHeader()->mac1; + std::array mac1Array; + std::memcpy(mac1Array.data(), getHandshakeInitiationHeader()->mac1, 16); + return mac1Array; } - const uint8_t* WireGuardHandshakeInitiationLayer::getMac2() const + std::array WireGuardHandshakeInitiationLayer::getMac2() const { - return getHandshakeInitiationHeader()->mac2; + std::array mac2Array; + std::memcpy(mac2Array.data(), getHandshakeInitiationHeader()->mac2, 16); + return mac2Array; } // ~~~~~~~~~~~~~~~~~~~~ @@ -170,54 +186,64 @@ namespace pcpp std::memset(msg->reserved, 0, sizeof(msg->reserved)); - msg->senderIndex = senderIndex; - msg->receiverIndex = receiverIndex; + msg->senderIndex = htobe32(senderIndex); + msg->receiverIndex = htobe32(receiverIndex); std::memcpy(msg->responderEphemeral, responderEphemeral, 32); std::memcpy(msg->encryptedEmpty, encryptedEmpty, 16); std::memcpy(msg->mac1, mac1, 16); std::memcpy(msg->mac2, mac2, 16); - m_Protocol = Wireguard; + m_Protocol = WireGuard; } uint32_t WireGuardHandshakeResponseLayer::getMessageType() const { - return getHandshakeResponseHeader()->messageType; + return be32toh(getHandshakeResponseHeader()->messageType); } - const uint8_t* WireGuardHandshakeResponseLayer::getReserved() const + uint32_t WireGuardHandshakeResponseLayer::getReserved() const { - return getHandshakeResponseHeader()->reserved; + uint32_t reservedValue = 0; + std::memcpy(&reservedValue, getHandshakeResponseHeader()->reserved, 3); + return be32toh(reservedValue); } uint32_t WireGuardHandshakeResponseLayer::getSenderIndex() const { - return getHandshakeResponseHeader()->senderIndex; + return be32toh(getHandshakeResponseHeader()->senderIndex); } uint32_t WireGuardHandshakeResponseLayer::getReceiverIndex() const { - return getHandshakeResponseHeader()->receiverIndex; + return be32toh(getHandshakeResponseHeader()->receiverIndex); } - const uint8_t* WireGuardHandshakeResponseLayer::getResponderEphemeral() const + std::array WireGuardHandshakeResponseLayer::getResponderEphemeral() const { - return getHandshakeResponseHeader()->responderEphemeral; + std::array responderEphemeralArray; + std::memcpy(responderEphemeralArray.data(), getHandshakeResponseHeader()->responderEphemeral, 32); + return responderEphemeralArray; } - const uint8_t* WireGuardHandshakeResponseLayer::getEncryptedEmpty() const + std::array WireGuardHandshakeResponseLayer::getEncryptedEmpty() const { - return getHandshakeResponseHeader()->encryptedEmpty; + std::array encryptedEmptyArray; + std::memcpy(encryptedEmptyArray.data(), getHandshakeResponseHeader()->encryptedEmpty, 16); + return encryptedEmptyArray; } - const uint8_t* WireGuardHandshakeResponseLayer::getMac1() const + std::array WireGuardHandshakeResponseLayer::getMac1() const { - return getHandshakeResponseHeader()->mac1; + std::array mac1Array; + std::memcpy(mac1Array.data(), getHandshakeResponseHeader()->mac1, 16); + return mac1Array; } - const uint8_t* WireGuardHandshakeResponseLayer::getMac2() const + std::array WireGuardHandshakeResponseLayer::getMac2() const { - return getHandshakeResponseHeader()->mac2; + std::array mac2Array; + std::memcpy(mac2Array.data(), getHandshakeResponseHeader()->mac2, 16); + return mac2Array; } // ~~~~~~~~~~~~~~~~~~~~ @@ -238,36 +264,42 @@ namespace pcpp std::memset(msg->reserved, 0, sizeof(msg->reserved)); - msg->receiverIndex = receiverIndex; + msg->receiverIndex = htobe32(receiverIndex); std::memcpy(msg->nonce, nonce, 24); std::memcpy(msg->encryptedCookie, encryptedCookie, 32); - m_Protocol = Wireguard; + m_Protocol = WireGuard; } uint32_t WireGuardCookieReplyLayer::getMessageType() const { - return getCookieReplyHeader()->messageType; + return be32toh(getCookieReplyHeader()->messageType); } - const uint8_t* WireGuardCookieReplyLayer::getReserved() const + uint32_t WireGuardCookieReplyLayer::getReserved() const { - return getCookieReplyHeader()->reserved; + uint32_t reservedValue = 0; + std::memcpy(&reservedValue, getCookieReplyHeader()->reserved, 3); + return be32toh(reservedValue); } uint32_t WireGuardCookieReplyLayer::getReceiverIndex() const { - return getCookieReplyHeader()->receiverIndex; + return be32toh(getCookieReplyHeader()->receiverIndex); } - const uint8_t* WireGuardCookieReplyLayer::getNonce() const + std::array WireGuardCookieReplyLayer::getNonce() const { - return getCookieReplyHeader()->nonce; + std::array nonceArray; + std::memcpy(nonceArray.data(), getCookieReplyHeader()->nonce, 24); + return nonceArray; } - const uint8_t* WireGuardCookieReplyLayer::getEncryptedCookie() const + std::array WireGuardCookieReplyLayer::getEncryptedCookie() const { - return getCookieReplyHeader()->encryptedCookie; + std::array encryptedCookieArray; + std::memcpy(encryptedCookieArray.data(), getCookieReplyHeader()->encryptedCookie, 32); + return encryptedCookieArray; } // ~~~~~~~~~~~~~~~~~~~~ @@ -288,32 +320,34 @@ namespace pcpp std::memset(msg->reserved, 0, sizeof(msg->reserved)); - msg->receiverIndex = receiverIndex; - msg->counter = counter; + msg->receiverIndex = htobe32(receiverIndex); + msg->counter = htobe64(counter); std::memcpy(m_Data + sizeof(wg_transport_data), encryptedData, encryptedDataLen); - m_Protocol = Wireguard; + m_Protocol = WireGuard; } uint32_t WireGuardTransportDataLayer::getMessageType() const { - return getTransportHeader()->messageType; + return be32toh(getTransportHeader()->messageType); } - const uint8_t* WireGuardTransportDataLayer::getReserved() const + uint32_t WireGuardTransportDataLayer::getReserved() const { - return getTransportHeader()->reserved; + uint32_t reservedValue = 0; + std::memcpy(&reservedValue, getTransportHeader()->reserved, 3); + return be32toh(reservedValue); } uint32_t WireGuardTransportDataLayer::getReceiverIndex() const { - return getTransportHeader()->receiverIndex; + return be32toh(getTransportHeader()->receiverIndex); } uint64_t WireGuardTransportDataLayer::getCounter() const { - return getTransportHeader()->counter; + return be64toh(getTransportHeader()->counter); } const uint8_t* WireGuardTransportDataLayer::getEncryptedData() const diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index e8a9611222..ecd872fcd1 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -4,6 +4,7 @@ #include "WireGuardLayer.h" #include "SystemUtils.h" #include +#include "EndianPortable.h" PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) { @@ -14,13 +15,13 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) pcpp::Packet wgHandShakeInitPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgHandShakeInitPacket.isPacketOfType(pcpp::Wireguard)); + PTF_ASSERT_TRUE(wgHandShakeInitPacket.isPacketOfType(pcpp::WireGuard)); pcpp::WireGuardLayer* wgLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Handshake Initiation"); - PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); + PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuard Layer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardHandshakeInitiationLayer* wgHandShakeInitLayer = wgHandShakeInitPacket.getLayerOfType(); @@ -28,37 +29,33 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) PTF_ASSERT_TRUE(wgHandShakeInitLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeInitiation); - PTF_ASSERT_TRUE(wgHandShakeInitLayer->getHeaderLen() == - sizeof(pcpp::WireGuardHandshakeInitiationLayer::wg_handshake_initiation)); - - PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getSenderIndex(), 818952152); - - uint8_t expectedPublicKey[32] = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, - 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, - 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; - PTF_ASSERT_TRUE( - std::memcmp(wgHandShakeInitLayer->getInitiatorEphemeral(), expectedPublicKey, sizeof(expectedPublicKey)) == 0); - - uint8_t expectedStaticKey[48] = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, 0x1f, 0xdc, - 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, 0xbe, 0xf2, 0x33, 0x2f, - 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, - 0x25, 0x5e, 0x7b, 0x25, 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeInitLayer->getEncryptedInitiatorStatic(), expectedStaticKey, - sizeof(expectedStaticKey)) == 0); - - uint8_t expectedTimestamp[28] = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, - 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, - 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; - PTF_ASSERT_TRUE( - std::memcmp(wgHandShakeInitLayer->getEncryptedTimestamp(), expectedTimestamp, sizeof(expectedTimestamp)) == 0); - - uint8_t expectedMac1[16] = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, - 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeInitLayer->getMac1(), expectedMac1, sizeof(expectedMac1)) == 0); - - uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeInitLayer->getMac2(), expectedMac2, sizeof(expectedMac2)) == 0); + + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getSenderIndex(), be32toh(818952152)); + + std::array expectedPublicKey = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, + 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, + 0xe2, 0xbb, 0x9d, 0x06, 0x8f, 0x89, 0xcf, 0x9d, 0x4d, 0x45 }; + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getInitiatorEphemeral() == expectedPublicKey); + + std::array expectedStaticKey = { 0x32, 0x78, 0x0f, 0x6d, 0x27, 0x26, 0x4f, 0x7b, 0x98, 0x70, + 0x1f, 0xdc, 0x27, 0xa4, 0xec, 0x00, 0xae, 0xb6, 0xbe, 0xcd, + 0xbe, 0xf2, 0x33, 0x2f, 0x1b, 0x40, 0x84, 0xca, 0xdb, 0x93, + 0x82, 0x39, 0x35, 0xc0, 0x12, 0xae, 0x25, 0x5e, 0x7b, 0x25, + 0xef, 0xf1, 0x39, 0x40, 0xc3, 0x21, 0xfa, 0x6b }; + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getEncryptedInitiatorStatic() == expectedStaticKey); + + std::array expectedTimestamp = { 0xd6, 0x6a, 0x2a, 0x87, 0xb0, 0x61, 0xdb, 0x14, 0x30, 0x17, + 0x3e, 0x93, 0x7f, 0x56, 0x93, 0x49, 0xde, 0x28, 0x56, 0xdc, + 0x5f, 0x26, 0x16, 0x76, 0x3e, 0xee, 0xaf, 0xc0 }; + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getEncryptedTimestamp() == expectedTimestamp); + + std::array expectedMac1 = { 0x53, 0x3b, 0x01, 0xdd, 0x96, 0x5e, 0x7e, 0xc7, + 0x69, 0x76, 0xe2, 0x8f, 0x68, 0x3d, 0x67, 0x12 }; + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getMac1() == expectedMac1); + + std::array expectedMac2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getMac2() == expectedMac2); } PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) @@ -70,11 +67,11 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) pcpp::Packet wgHandShakeResponsePacket(&rawPacket1); - PTF_ASSERT_TRUE(wgHandShakeResponsePacket.isPacketOfType(pcpp::Wireguard)); + PTF_ASSERT_TRUE(wgHandShakeResponsePacket.isPacketOfType(pcpp::WireGuard)); pcpp::WireGuardLayer* wgLayer = wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Handshake Response"); - PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); + PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuard Layer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardHandshakeResponseLayer* wgHandShakeResponseLayer = wgHandShakeResponsePacket.getLayerOfType(); @@ -82,31 +79,28 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeResponse); - PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getHeaderLen() == - sizeof(pcpp::WireGuardHandshakeResponseLayer::wg_handshake_response)); - PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getSenderIndex(), 2877158406); - PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getReceiverIndex(), 818952152); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getSenderIndex(), be32toh(2877158406)); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getReceiverIndex(), be32toh(818952152)); - uint8_t expectedResponderEphemeral[32] = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, - 0x3a, 0xc0, 0x8d, 0xb1, 0xec, 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, - 0x64, 0xbc, 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getResponderEphemeral(), expectedResponderEphemeral, - sizeof(expectedResponderEphemeral)) == 0); + std::array expectedResponderEphemeral = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, + 0x7a, 0x46, 0x82, 0x3a, 0xc0, 0x8d, 0xb1, 0xec, + 0x66, 0x83, 0x9b, 0xc0, 0xca, 0x2d, 0x64, 0xbc, + 0x15, 0xcd, 0x80, 0x23, 0x2b, 0x66, 0x23, 0x2f }; + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getResponderEphemeral() == expectedResponderEphemeral); - uint8_t encryptedEmptyData[16] = { 0xae, 0xc2, 0x4a, 0xf8, 0x91, 0x8d, 0xe1, 0x06, - 0x0f, 0xf5, 0xc9, 0x8e, 0x86, 0x5d, 0x5f, 0x35 }; + std::array encryptedEmptyData = { 0xae, 0xc2, 0x4a, 0xf8, 0x91, 0x8d, 0xe1, 0x06, + 0x0f, 0xf5, 0xc9, 0x8e, 0x86, 0x5d, 0x5f, 0x35 }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getEncryptedEmpty(), encryptedEmptyData, - sizeof(encryptedEmptyData)) == 0); + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getEncryptedEmpty() == encryptedEmptyData); - uint8_t expectedMac1[16] = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, - 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getMac1(), expectedMac1, sizeof(expectedMac1)) == 0); + std::array expectedMac1 = { 0xf2, 0x72, 0x21, 0x4c, 0x52, 0x60, 0x11, 0x0d, + 0xc4, 0xc6, 0x1e, 0x32, 0xcd, 0xd8, 0x54, 0x21 }; + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getMac1() == expectedMac1); - uint8_t expectedMac2[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - PTF_ASSERT_TRUE(std::memcmp(wgHandShakeResponseLayer->getMac2(), expectedMac2, sizeof(expectedMac2)) == 0); + std::array expectedMac2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getMac2() == expectedMac2); } PTF_TEST_CASE(WireGuardTransportDataParsingTest) @@ -117,11 +111,11 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardTransportData.dat"); pcpp::Packet wgTransportDataPacket(&rawPacket1); - PTF_ASSERT_TRUE(wgTransportDataPacket.isPacketOfType(pcpp::Wireguard)); + PTF_ASSERT_TRUE(wgTransportDataPacket.isPacketOfType(pcpp::WireGuard)); pcpp::WireGuardLayer* wgLayer = wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Transport Data"); - PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuardLayer, " + wgLayer->getMessageTypeAsString() + " message"); + PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuard Layer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardTransportDataLayer* wgTransportDataLayer = wgTransportDataPacket.getLayerOfType(); @@ -129,13 +123,11 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) PTF_ASSERT_TRUE(wgTransportDataLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::TransportData); - PTF_ASSERT_TRUE(wgTransportDataLayer->getHeaderLen() >= - sizeof(pcpp::WireGuardTransportDataLayer::wg_transport_data)); - PTF_ASSERT_EQUAL(wgTransportDataLayer->getReceiverIndex(), 2877158406); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getReceiverIndex(), be32toh(2877158406)); uint64_t expectedCounter = 0x0000000000000000; - PTF_ASSERT_EQUAL(wgTransportDataLayer->getCounter(), expectedCounter); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getCounter(), be32toh(expectedCounter)); uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, @@ -182,12 +174,12 @@ PTF_TEST_CASE(WireGuardCreationTest) uint8_t expectedMac2Init[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(818952152, expectedPublicKeyInit, + pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(be32toh(818952152), expectedPublicKeyInit, expectedStaticKeyInit, expectedTimestampInit, expectedMac1Init, expectedMac2Init); pcpp::Packet wgHandshakeInitPacket(&rawPacket1); pcpp::WireGuardHandshakeInitiationLayer* origHandshakeInitMessage = - dynamic_cast(wgHandshakeInitPacket.detachLayer(pcpp::Wireguard)); + dynamic_cast(wgHandshakeInitPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeInitMessage); PTF_ASSERT_EQUAL(newHandshakeInitMessage.getDataLen(), origHandshakeInitMessage->getDataLen()); PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getData(), origHandshakeInitMessage->getData(), @@ -213,12 +205,12 @@ PTF_TEST_CASE(WireGuardCreationTest) uint8_t expectedMac2Resp[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage(2877158406, 818952152, expectedResponderEphemeralResp, - encryptedEmptyDataResp, expectedMac1Resp, - expectedMac2Resp); + pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage( + be32toh(2877158406), be32toh(818952152), expectedResponderEphemeralResp, encryptedEmptyDataResp, + expectedMac1Resp, expectedMac2Resp); pcpp::Packet wgHandshakeRespPacket(&rawPacket2); pcpp::WireGuardHandshakeResponseLayer* origHandshakeRespMessage = - dynamic_cast(wgHandshakeRespPacket.detachLayer(pcpp::Wireguard)); + dynamic_cast(wgHandshakeRespPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeRespMessage); PTF_ASSERT_EQUAL(newHandshakeRespMessage.getDataLen(), origHandshakeRespMessage->getDataLen()); PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getData(), origHandshakeRespMessage->getData(), @@ -244,12 +236,12 @@ PTF_TEST_CASE(WireGuardCreationTest) 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - pcpp::WireGuardTransportDataLayer newTransportDataMessage(2877158406, expectedCounterTransport, + pcpp::WireGuardTransportDataLayer newTransportDataMessage(be32toh(2877158406), expectedCounterTransport, expectedEncryptedDataTransport, 112); pcpp::Packet wgTransportDataPacket(&rawPacket3); pcpp::WireGuardTransportDataLayer* origTransportDataMessage = - dynamic_cast(wgTransportDataPacket.detachLayer(pcpp::Wireguard)); + dynamic_cast(wgTransportDataPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origTransportDataMessage); PTF_ASSERT_EQUAL(newTransportDataMessage.getDataLen(), origTransportDataMessage->getDataLen()); PTF_ASSERT_BUF_COMPARE(newTransportDataMessage.getData(), origTransportDataMessage->getData(), From bf4fbbf72ee9a5e0c72d0ed0b55972fef1f07bb6 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Tue, 24 Sep 2024 23:26:33 +0900 Subject: [PATCH 31/37] lint Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 2 +- Packet++/src/WireGuardLayer.cpp | 54 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index f8e4a9d717..f31ce6fe34 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -133,7 +133,7 @@ namespace pcpp uint32_t getReserved() const { uint32_t reservedValue = 0; - std::memcpy(&reservedValue, getBasicHeader()->reserved, 3); + memcpy(&reservedValue, getBasicHeader()->reserved, 3); return reservedValue; } diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 54d61a34c4..2642590f60 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -105,11 +105,11 @@ namespace pcpp std::memset(msgHdr->reserved, 0, sizeof(msgHdr->reserved)); msgHdr->senderIndex = htobe32(senderIndex); - std::memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); - std::memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); - std::memcpy(msgHdr->encryptedTimestamp, encryptedTimestamp, 28); - std::memcpy(msgHdr->mac1, mac1, 16); - std::memcpy(msgHdr->mac2, mac2, 16); + memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); + memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); + memcpy(msgHdr->encryptedTimestamp, encryptedTimestamp, 28); + memcpy(msgHdr->mac1, mac1, 16); + memcpy(msgHdr->mac2, mac2, 16); m_Protocol = WireGuard; } @@ -122,7 +122,7 @@ namespace pcpp uint32_t WireGuardHandshakeInitiationLayer::getReserved() const { uint32_t reservedValue = 0; - std::memcpy(&reservedValue, getHandshakeInitiationHeader()->reserved, 3); + memcpy(&reservedValue, getHandshakeInitiationHeader()->reserved, 3); return be32toh(reservedValue); } @@ -134,35 +134,35 @@ namespace pcpp std::array WireGuardHandshakeInitiationLayer::getInitiatorEphemeral() const { std::array ephemeralArray; - std::memcpy(ephemeralArray.data(), getHandshakeInitiationHeader()->initiatorEphemeral, 32); + memcpy(ephemeralArray.data(), getHandshakeInitiationHeader()->initiatorEphemeral, 32); return ephemeralArray; } std::array WireGuardHandshakeInitiationLayer::getEncryptedInitiatorStatic() const { std::array initArray; - std::memcpy(initArray.data(), getHandshakeInitiationHeader()->encryptedInitiatorStatic, 48); + memcpy(initArray.data(), getHandshakeInitiationHeader()->encryptedInitiatorStatic, 48); return initArray; } std::array WireGuardHandshakeInitiationLayer::getEncryptedTimestamp() const { std::array tsArray; - std::memcpy(tsArray.data(), getHandshakeInitiationHeader()->encryptedTimestamp, 28); + memcpy(tsArray.data(), getHandshakeInitiationHeader()->encryptedTimestamp, 28); return tsArray; } std::array WireGuardHandshakeInitiationLayer::getMac1() const { std::array mac1Array; - std::memcpy(mac1Array.data(), getHandshakeInitiationHeader()->mac1, 16); + memcpy(mac1Array.data(), getHandshakeInitiationHeader()->mac1, 16); return mac1Array; } std::array WireGuardHandshakeInitiationLayer::getMac2() const { std::array mac2Array; - std::memcpy(mac2Array.data(), getHandshakeInitiationHeader()->mac2, 16); + memcpy(mac2Array.data(), getHandshakeInitiationHeader()->mac2, 16); return mac2Array; } @@ -188,10 +188,10 @@ namespace pcpp msg->senderIndex = htobe32(senderIndex); msg->receiverIndex = htobe32(receiverIndex); - std::memcpy(msg->responderEphemeral, responderEphemeral, 32); - std::memcpy(msg->encryptedEmpty, encryptedEmpty, 16); - std::memcpy(msg->mac1, mac1, 16); - std::memcpy(msg->mac2, mac2, 16); + memcpy(msg->responderEphemeral, responderEphemeral, 32); + memcpy(msg->encryptedEmpty, encryptedEmpty, 16); + memcpy(msg->mac1, mac1, 16); + memcpy(msg->mac2, mac2, 16); m_Protocol = WireGuard; } @@ -204,7 +204,7 @@ namespace pcpp uint32_t WireGuardHandshakeResponseLayer::getReserved() const { uint32_t reservedValue = 0; - std::memcpy(&reservedValue, getHandshakeResponseHeader()->reserved, 3); + memcpy(&reservedValue, getHandshakeResponseHeader()->reserved, 3); return be32toh(reservedValue); } @@ -221,28 +221,28 @@ namespace pcpp std::array WireGuardHandshakeResponseLayer::getResponderEphemeral() const { std::array responderEphemeralArray; - std::memcpy(responderEphemeralArray.data(), getHandshakeResponseHeader()->responderEphemeral, 32); + memcpy(responderEphemeralArray.data(), getHandshakeResponseHeader()->responderEphemeral, 32); return responderEphemeralArray; } std::array WireGuardHandshakeResponseLayer::getEncryptedEmpty() const { std::array encryptedEmptyArray; - std::memcpy(encryptedEmptyArray.data(), getHandshakeResponseHeader()->encryptedEmpty, 16); + memcpy(encryptedEmptyArray.data(), getHandshakeResponseHeader()->encryptedEmpty, 16); return encryptedEmptyArray; } std::array WireGuardHandshakeResponseLayer::getMac1() const { std::array mac1Array; - std::memcpy(mac1Array.data(), getHandshakeResponseHeader()->mac1, 16); + memcpy(mac1Array.data(), getHandshakeResponseHeader()->mac1, 16); return mac1Array; } std::array WireGuardHandshakeResponseLayer::getMac2() const { std::array mac2Array; - std::memcpy(mac2Array.data(), getHandshakeResponseHeader()->mac2, 16); + memcpy(mac2Array.data(), getHandshakeResponseHeader()->mac2, 16); return mac2Array; } @@ -265,8 +265,8 @@ namespace pcpp std::memset(msg->reserved, 0, sizeof(msg->reserved)); msg->receiverIndex = htobe32(receiverIndex); - std::memcpy(msg->nonce, nonce, 24); - std::memcpy(msg->encryptedCookie, encryptedCookie, 32); + memcpy(msg->nonce, nonce, 24); + memcpy(msg->encryptedCookie, encryptedCookie, 32); m_Protocol = WireGuard; } @@ -279,7 +279,7 @@ namespace pcpp uint32_t WireGuardCookieReplyLayer::getReserved() const { uint32_t reservedValue = 0; - std::memcpy(&reservedValue, getCookieReplyHeader()->reserved, 3); + memcpy(&reservedValue, getCookieReplyHeader()->reserved, 3); return be32toh(reservedValue); } @@ -291,14 +291,14 @@ namespace pcpp std::array WireGuardCookieReplyLayer::getNonce() const { std::array nonceArray; - std::memcpy(nonceArray.data(), getCookieReplyHeader()->nonce, 24); + memcpy(nonceArray.data(), getCookieReplyHeader()->nonce, 24); return nonceArray; } std::array WireGuardCookieReplyLayer::getEncryptedCookie() const { std::array encryptedCookieArray; - std::memcpy(encryptedCookieArray.data(), getCookieReplyHeader()->encryptedCookie, 32); + memcpy(encryptedCookieArray.data(), getCookieReplyHeader()->encryptedCookie, 32); return encryptedCookieArray; } @@ -323,7 +323,7 @@ namespace pcpp msg->receiverIndex = htobe32(receiverIndex); msg->counter = htobe64(counter); - std::memcpy(m_Data + sizeof(wg_transport_data), encryptedData, encryptedDataLen); + memcpy(m_Data + sizeof(wg_transport_data), encryptedData, encryptedDataLen); m_Protocol = WireGuard; } @@ -336,7 +336,7 @@ namespace pcpp uint32_t WireGuardTransportDataLayer::getReserved() const { uint32_t reservedValue = 0; - std::memcpy(&reservedValue, getTransportHeader()->reserved, 3); + memcpy(&reservedValue, getTransportHeader()->reserved, 3); return be32toh(reservedValue); } From a37a1694c5adc9aa02084f4b3934d849e59e821a Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Wed, 25 Sep 2024 22:07:49 +0900 Subject: [PATCH 32/37] Refactor WireGuardLayer code and improve documentation Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 177 +++++++++++++++++--- Packet++/src/WireGuardLayer.cpp | 91 +++------- Tests/Packet++Test/Tests/WireGuardTests.cpp | 19 ++- 3 files changed, 188 insertions(+), 99 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index f31ce6fe34..eb96aef720 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -73,6 +73,11 @@ namespace pcpp : Layer(data, dataLen, prevLayer, packet, WireGuard) {} + /** + * Default constructor for creating an empty WireGuardLayer object. + * This constructor can be used when no initial data is provided, + * and the message will be initialized later. + */ WireGuardLayer() {} @@ -120,22 +125,14 @@ namespace pcpp * * @return The message type as an unsigned 32-bit integer. */ - uint32_t getMessageType() const - { - return getBasicHeader()->messageType; - } + uint8_t getMessageType() const; /** * Get the reserved field from the WireGuard message. * * @return The reserved field as a 32-bit integer. */ - uint32_t getReserved() const - { - uint32_t reservedValue = 0; - memcpy(&reservedValue, getBasicHeader()->reserved, 3); - return reservedValue; - } + uint32_t getReserved() const; /** * Multiple WireGuard messages can be present in a single packet. @@ -240,22 +237,65 @@ namespace pcpp const uint8_t encryptedTimestamp[28], const uint8_t mac1[16], const uint8_t mac2[16]); - uint32_t getMessageType() const; - uint32_t getReserved() const; + /** + * Get the sender index from the Handshake Initiation message. + * + * @return The sender index as a 32-bit integer. + */ uint32_t getSenderIndex() const; + + /** + * Get the initiator's ephemeral public key from the Handshake Initiation message. + * + * @return An array containing the initiator's ephemeral public key. + */ std::array getInitiatorEphemeral() const; + + /** + * Get the encrypted initiator's static key from the Handshake Initiation message. + * + * @return An array containing the encrypted initiator's static key. + */ std::array getEncryptedInitiatorStatic() const; + + /** + * Get the encrypted timestamp from the Handshake Initiation message. + * + * @return An array containing the encrypted timestamp. + */ std::array getEncryptedTimestamp() const; + + /** + * Get the MAC1 field from the Handshake Initiation message. + * + * @return An array containing the MAC1 field. + */ std::array getMac1() const; + + /** + * Get the MAC2 field from the Handshake Initiation message. + * + * @return An array containing the MAC2 field. + */ std::array getMac2() const; + /** + * Get the Handshake Initiation message header. + * + * @return A pointer to the Handshake Initiation message structure. + */ wg_handshake_initiation* getHandshakeInitiationHeader() const { - return (wg_handshake_initiation*)getBasicHeader(); + return reinterpret_cast(getBasicHeader()); } // implement abstract methods + /** + * Returns the message type as HandshakeInitiation. + * + * @return WireGuardMessageType enum value indicating HandshakeInitiation. + */ WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::HandshakeInitiation; @@ -315,22 +355,65 @@ namespace pcpp const uint8_t responderEphemeral[32], const uint8_t encryptedEmpty[16], const uint8_t mac1[16], const uint8_t mac2[16]); - uint32_t getMessageType() const; - uint32_t getReserved() const; + /** + * Get the sender index from the Handshake Response message. + * + * @return The sender index as a 32-bit unsigned integer. + */ uint32_t getSenderIndex() const; + + /** + * Get the receiver index from the Handshake Response message. + * + * @return The receiver index as a 32-bit unsigned integer. + */ uint32_t getReceiverIndex() const; + + /** + * Get the responder's ephemeral public key. + * + * @return The responder's ephemeral public key as an array of 32 bytes. + */ std::array getResponderEphemeral() const; + + /** + * Get the encrypted empty field from the Handshake Response message. + * + * @return The encrypted empty field as an array of 16 bytes. + */ std::array getEncryptedEmpty() const; + + /** + * Get the MAC1 field from the Handshake Response message. + * + * @return The MAC1 field as an array of 16 bytes. + */ std::array getMac1() const; + + /** + * Get the MAC2 field from the Handshake Response message. + * + * @return The MAC2 field as an array of 16 bytes. + */ std::array getMac2() const; + /** + * Get the Handshake Response message header. + * + * @return A pointer to the Handshake Response message structure. + */ wg_handshake_response* getHandshakeResponseHeader() const { - return (wg_handshake_response*)getBasicHeader(); + return reinterpret_cast(getBasicHeader()); } // implement abstract methods + /** + * Get the WireGuard message type for the Handshake Response. + * + * @return The message type as a WireGuardMessageType enum value. + */ WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::HandshakeResponse; @@ -379,19 +462,44 @@ namespace pcpp */ WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], const uint8_t encryptedCookie[32]); - uint32_t getMessageType() const; - uint32_t getReserved() const; + /** + * Get the receiver index from the Cookie Reply message. + * + * @return The receiver index as a 32-bit unsigned integer. + */ uint32_t getReceiverIndex() const; + + /** + * Get the nonce field from the Cookie Reply message. + * + * @return The nonce field as an array of 24 bytes. + */ std::array getNonce() const; + + /** + * Get the encrypted cookie from the Cookie Reply message. + * + * @return The encrypted cookie as an array of 32 bytes. + */ std::array getEncryptedCookie() const; + /** + * Get the Cookie Reply message header. + * + * @return A pointer to the Cookie Reply message structure. + */ wg_cookie_reply* getCookieReplyHeader() const { - return (wg_cookie_reply*)getBasicHeader(); + return reinterpret_cast(getBasicHeader()); } // implement abstract methods + /** + * Get the WireGuard message type for the Cookie Reply. + * + * @return The message type as a WireGuardMessageType enum value. + */ WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::CookieReply; @@ -442,19 +550,44 @@ namespace pcpp WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, const uint8_t* encryptedData, size_t encryptedDataLen); - uint32_t getMessageType() const; - uint32_t getReserved() const; + /** + * Get the receiver index from the Transport Data message. + * + * @return The receiver index as a 32-bit unsigned integer. + */ uint32_t getReceiverIndex() const; + + /** + * Get the counter field from the Transport Data message. + * + * @return The counter field as a 64-bit unsigned integer. + */ uint64_t getCounter() const; + + /** + * Get the encrypted data from the Transport Data message. + * + * @return A pointer to the encrypted data field. + */ const uint8_t* getEncryptedData() const; + /** + * Get the Transport Data message header. + * + * @return A pointer to the Transport Data message structure. + */ wg_transport_data* getTransportHeader() const { - return (wg_transport_data*)getBasicHeader(); + return reinterpret_cast(getBasicHeader()); } // implement abstract methods + /** + * Get the WireGuard message type for the Transport Data message. + * + * @return The message type as a WireGuardMessageType enum value. + */ WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::TransportData; diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 2642590f60..d4c01ccf4a 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -16,11 +16,14 @@ namespace pcpp void WireGuardLayer::parseNextLayer() { size_t headerLen = getHeaderLen(); - if (m_DataLen <= headerLen || headerLen == 0) - return; - m_NextLayer = WireGuardLayer::parseWireGuardLayer(m_Data, m_DataLen, this, m_Packet); - if (!m_NextLayer) + if (m_DataLen <= headerLen && headerLen != 0) m_NextLayer = new PayloadLayer(m_Data, m_DataLen, this, m_Packet); + else + { + m_NextLayer = WireGuardLayer::parseWireGuardLayer(m_Data, m_DataLen, this, m_Packet); + if (!m_NextLayer) + m_NextLayer = new PayloadLayer(m_Data, m_DataLen, this, m_Packet); + } } WireGuardLayer* WireGuardLayer::parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) @@ -46,7 +49,6 @@ namespace pcpp std::string WireGuardLayer::getMessageTypeAsString() const { - // Assuming you have a method to retrieve the message type from the header uint32_t messageType = getMessageType(); switch (messageType) { @@ -73,6 +75,18 @@ namespace pcpp return m_DataLen; } + uint8_t WireGuardLayer::getMessageType() const + { + return getBasicHeader()->messageType; + } + + uint32_t WireGuardLayer::getReserved() const + { + uint32_t reservedValue = 0; + memcpy(&reservedValue, getBasicHeader()->reserved, 3); + return be32toh(reservedValue); + } + bool WireGuardLayer::isDataValid(const uint8_t* data, size_t dataLen) { if (dataLen < sizeof(WireGuardLayer::wg_common_header)) @@ -101,9 +115,6 @@ namespace pcpp wg_handshake_initiation* msgHdr = reinterpret_cast(m_Data); msgHdr->messageType = static_cast(WireGuardMessageType::HandshakeInitiation); - - std::memset(msgHdr->reserved, 0, sizeof(msgHdr->reserved)); - msgHdr->senderIndex = htobe32(senderIndex); memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); @@ -114,18 +125,6 @@ namespace pcpp m_Protocol = WireGuard; } - uint32_t WireGuardHandshakeInitiationLayer::getMessageType() const - { - return be32toh(getHandshakeInitiationHeader()->messageType); - } - - uint32_t WireGuardHandshakeInitiationLayer::getReserved() const - { - uint32_t reservedValue = 0; - memcpy(&reservedValue, getHandshakeInitiationHeader()->reserved, 3); - return be32toh(reservedValue); - } - uint32_t WireGuardHandshakeInitiationLayer::getSenderIndex() const { return be32toh(getHandshakeInitiationHeader()->senderIndex); @@ -178,14 +177,9 @@ namespace pcpp const size_t messageLen = sizeof(wg_handshake_response); m_DataLen = messageLen; m_Data = new uint8_t[messageLen]; - std::memset(m_Data, 0, messageLen); - wg_handshake_response* msg = reinterpret_cast(m_Data); msg->messageType = static_cast(WireGuardMessageType::HandshakeResponse); - - std::memset(msg->reserved, 0, sizeof(msg->reserved)); - msg->senderIndex = htobe32(senderIndex); msg->receiverIndex = htobe32(receiverIndex); memcpy(msg->responderEphemeral, responderEphemeral, 32); @@ -196,18 +190,6 @@ namespace pcpp m_Protocol = WireGuard; } - uint32_t WireGuardHandshakeResponseLayer::getMessageType() const - { - return be32toh(getHandshakeResponseHeader()->messageType); - } - - uint32_t WireGuardHandshakeResponseLayer::getReserved() const - { - uint32_t reservedValue = 0; - memcpy(&reservedValue, getHandshakeResponseHeader()->reserved, 3); - return be32toh(reservedValue); - } - uint32_t WireGuardHandshakeResponseLayer::getSenderIndex() const { return be32toh(getHandshakeResponseHeader()->senderIndex); @@ -256,14 +238,11 @@ namespace pcpp const size_t messageLen = sizeof(wg_cookie_reply); m_DataLen = messageLen; m_Data = new uint8_t[messageLen]; - std::memset(m_Data, 0, messageLen); + memset(m_Data, 0, messageLen); wg_cookie_reply* msg = reinterpret_cast(m_Data); msg->messageType = static_cast(WireGuardMessageType::CookieReply); - - std::memset(msg->reserved, 0, sizeof(msg->reserved)); - msg->receiverIndex = htobe32(receiverIndex); memcpy(msg->nonce, nonce, 24); memcpy(msg->encryptedCookie, encryptedCookie, 32); @@ -271,18 +250,6 @@ namespace pcpp m_Protocol = WireGuard; } - uint32_t WireGuardCookieReplyLayer::getMessageType() const - { - return be32toh(getCookieReplyHeader()->messageType); - } - - uint32_t WireGuardCookieReplyLayer::getReserved() const - { - uint32_t reservedValue = 0; - memcpy(&reservedValue, getCookieReplyHeader()->reserved, 3); - return be32toh(reservedValue); - } - uint32_t WireGuardCookieReplyLayer::getReceiverIndex() const { return be32toh(getCookieReplyHeader()->receiverIndex); @@ -312,34 +279,18 @@ namespace pcpp const size_t messageLen = sizeof(wg_transport_data) + encryptedDataLen; m_DataLen = messageLen; m_Data = new uint8_t[messageLen]; - std::memset(m_Data, 0, messageLen); + memset(m_Data, 0, messageLen); wg_transport_data* msg = reinterpret_cast(m_Data); msg->messageType = static_cast(WireGuardMessageType::TransportData); - - std::memset(msg->reserved, 0, sizeof(msg->reserved)); - msg->receiverIndex = htobe32(receiverIndex); msg->counter = htobe64(counter); - memcpy(m_Data + sizeof(wg_transport_data), encryptedData, encryptedDataLen); m_Protocol = WireGuard; } - uint32_t WireGuardTransportDataLayer::getMessageType() const - { - return be32toh(getTransportHeader()->messageType); - } - - uint32_t WireGuardTransportDataLayer::getReserved() const - { - uint32_t reservedValue = 0; - memcpy(&reservedValue, getTransportHeader()->reserved, 3); - return be32toh(reservedValue); - } - uint32_t WireGuardTransportDataLayer::getReceiverIndex() const { return be32toh(getTransportHeader()->receiverIndex); diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index ecd872fcd1..98d7a0b3ec 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -20,13 +20,14 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) pcpp::WireGuardLayer* wgLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Handshake Initiation"); - PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuard Layer, " + wgLayer->getMessageTypeAsString() + " message"); - pcpp::WireGuardHandshakeInitiationLayer* wgHandShakeInitLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgHandShakeInitLayer); + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getMessageTypeAsString(), "Handshake Initiation"); + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->toString(), + "WireGuard Layer, " + wgHandShakeInitLayer->getMessageTypeAsString() + " message"); + PTF_ASSERT_TRUE(wgHandShakeInitLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeInitiation); @@ -70,13 +71,15 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) PTF_ASSERT_TRUE(wgHandShakeResponsePacket.isPacketOfType(pcpp::WireGuard)); pcpp::WireGuardLayer* wgLayer = wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Handshake Response"); - PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuard Layer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardHandshakeResponseLayer* wgHandShakeResponseLayer = wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgHandShakeResponseLayer); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getMessageTypeAsString(), "Handshake Response"); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->toString(), + "WireGuard Layer, " + wgHandShakeResponseLayer->getMessageTypeAsString() + " message"); + PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeResponse); @@ -114,13 +117,15 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) PTF_ASSERT_TRUE(wgTransportDataPacket.isPacketOfType(pcpp::WireGuard)); pcpp::WireGuardLayer* wgLayer = wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - PTF_ASSERT_EQUAL(wgLayer->getMessageTypeAsString(), "Transport Data"); - PTF_ASSERT_EQUAL(wgLayer->toString(), "WireGuard Layer, " + wgLayer->getMessageTypeAsString() + " message"); pcpp::WireGuardTransportDataLayer* wgTransportDataLayer = wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgTransportDataLayer); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getMessageTypeAsString(), "Transport Data"); + PTF_ASSERT_EQUAL(wgTransportDataLayer->toString(), + "WireGuard Layer, " + wgTransportDataLayer->getMessageTypeAsString() + " message"); + PTF_ASSERT_TRUE(wgTransportDataLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::TransportData); From e27cb71d96080d8897743563a1650b9d8d2139b5 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Wed, 25 Sep 2024 22:50:46 +0900 Subject: [PATCH 33/37] edit WireGuardTests Signed-off-by: Dongjun Na --- Tests/Packet++Test/Tests/WireGuardTests.cpp | 25 +++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 98d7a0b3ec..2ab3abb8cf 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -179,7 +179,7 @@ PTF_TEST_CASE(WireGuardCreationTest) uint8_t expectedMac2Init[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(be32toh(818952152), expectedPublicKeyInit, + pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(818952152, expectedPublicKeyInit, expectedStaticKeyInit, expectedTimestampInit, expectedMac1Init, expectedMac2Init); pcpp::Packet wgHandshakeInitPacket(&rawPacket1); @@ -187,12 +187,10 @@ PTF_TEST_CASE(WireGuardCreationTest) dynamic_cast(wgHandshakeInitPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeInitMessage); PTF_ASSERT_EQUAL(newHandshakeInitMessage.getDataLen(), origHandshakeInitMessage->getDataLen()); - PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getData(), origHandshakeInitMessage->getData(), - origHandshakeInitMessage->getDataLen()); + PTF_ASSERT_EQUAL(newHandshakeInitMessage.getSenderIndex(), 818952152); PTF_ASSERT_TRUE(wgHandshakeInitPacket.addLayer(&newHandshakeInitMessage)); PTF_ASSERT_EQUAL(wgHandshakeInitPacket.getRawPacket()->getRawDataLen(), bufferLength1); - PTF_ASSERT_BUF_COMPARE(wgHandshakeInitPacket.getRawPacket()->getRawData(), origBuffer, bufferLength1); delete origHandshakeInitMessage; // create WireGuard Handshake Response message @@ -210,20 +208,20 @@ PTF_TEST_CASE(WireGuardCreationTest) uint8_t expectedMac2Resp[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage( - be32toh(2877158406), be32toh(818952152), expectedResponderEphemeralResp, encryptedEmptyDataResp, - expectedMac1Resp, expectedMac2Resp); + pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage(2877158406, 818952152, expectedResponderEphemeralResp, + encryptedEmptyDataResp, expectedMac1Resp, + expectedMac2Resp); pcpp::Packet wgHandshakeRespPacket(&rawPacket2); pcpp::WireGuardHandshakeResponseLayer* origHandshakeRespMessage = dynamic_cast(wgHandshakeRespPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeRespMessage); PTF_ASSERT_EQUAL(newHandshakeRespMessage.getDataLen(), origHandshakeRespMessage->getDataLen()); - PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getData(), origHandshakeRespMessage->getData(), - origHandshakeRespMessage->getDataLen()); + PTF_ASSERT_EQUAL(newHandshakeRespMessage.getSenderIndex(), 2877158406); + PTF_ASSERT_EQUAL(newHandshakeRespMessage.getReceiverIndex(), 818952152); + PTF_ASSERT_TRUE(wgHandshakeRespPacket.addLayer(&newHandshakeRespMessage)); PTF_ASSERT_EQUAL(wgHandshakeRespPacket.getRawPacket()->getRawDataLen(), bufferLength2); - PTF_ASSERT_BUF_COMPARE(wgHandshakeRespPacket.getRawPacket()->getRawData(), origBuffer, bufferLength2); delete origHandshakeRespMessage; // create WireGuard Transport Data message @@ -241,7 +239,7 @@ PTF_TEST_CASE(WireGuardCreationTest) 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - pcpp::WireGuardTransportDataLayer newTransportDataMessage(be32toh(2877158406), expectedCounterTransport, + pcpp::WireGuardTransportDataLayer newTransportDataMessage(2877158406, expectedCounterTransport, expectedEncryptedDataTransport, 112); pcpp::Packet wgTransportDataPacket(&rawPacket3); @@ -249,11 +247,10 @@ PTF_TEST_CASE(WireGuardCreationTest) dynamic_cast(wgTransportDataPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origTransportDataMessage); PTF_ASSERT_EQUAL(newTransportDataMessage.getDataLen(), origTransportDataMessage->getDataLen()); - PTF_ASSERT_BUF_COMPARE(newTransportDataMessage.getData(), origTransportDataMessage->getData(), - origTransportDataMessage->getDataLen()); + PTF_ASSERT_EQUAL(newTransportDataMessage.getCounter(), expectedCounterTransport); + PTF_ASSERT_TRUE(wgTransportDataPacket.addLayer(&newTransportDataMessage)); PTF_ASSERT_EQUAL(wgTransportDataPacket.getRawPacket()->getRawDataLen(), bufferLength3); - PTF_ASSERT_BUF_COMPARE(wgTransportDataPacket.getRawPacket()->getRawData(), origBuffer, bufferLength3); delete origTransportDataMessage; } From c89349612521a85ab16c89944f4b7e075d46a9bf Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Thu, 26 Sep 2024 22:50:35 +0900 Subject: [PATCH 34/37] Refactor WireGuardLayer code and comments, add pcap and test code for WireGuardCookieReply Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 163 ++++-------------- Packet++/src/WireGuardLayer.cpp | 17 -- .../PacketExamples/WireGuardCookieReply.dat | 1 + Tests/Packet++Test/TestDefinition.h | 1 + Tests/Packet++Test/Tests/WireGuardTests.cpp | 90 +++++++++- Tests/Packet++Test/main.cpp | 1 + 6 files changed, 117 insertions(+), 156 deletions(-) create mode 100644 Tests/Packet++Test/PacketExamples/WireGuardCookieReply.dat diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index eb96aef720..5d3d81037d 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -21,10 +21,6 @@ namespace pcpp { protected: #pragma pack(push, 1) - /** - * @struct wg_common_header - * Represents the common header for all WireGuard message types - */ struct wg_common_header { /** Message type field */ @@ -33,16 +29,13 @@ namespace pcpp uint8_t reserved[3]; }; #pragma pack(pop) - /** - * Get the basic header common to all WireGuard messages. - * - * @return Pointer to the common header structure. - */ wg_common_header* getBasicHeader() const { return reinterpret_cast(m_Data); } + WireGuardLayer() = default; + public: /** * WireGuard message types @@ -73,14 +66,6 @@ namespace pcpp : Layer(data, dataLen, prevLayer, packet, WireGuard) {} - /** - * Default constructor for creating an empty WireGuardLayer object. - * This constructor can be used when no initial data is provided, - * and the message will be initialized later. - */ - WireGuardLayer() - {} - /** * Checks if the given port numbers are WireGuard ports. * @@ -114,37 +99,27 @@ namespace pcpp static WireGuardLayer* parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); /** - * Get the message type as a human-readable string. - * * @return String representation of the message type. */ std::string getMessageTypeAsString() const; /** - * Get the message type of the WireGuard message. - * * @return The message type as an unsigned 32-bit integer. */ uint8_t getMessageType() const; /** - * Get the reserved field from the WireGuard message. - * * @return The reserved field as a 32-bit integer. */ uint32_t getReserved() const; /** - * Multiple WireGuard messages can be present in a single packet. - * WireGuard does not have a layer that follows its messages, but this method checks for remaining data - * in the packet to determine if another WireGuard message exists. If so, it parses the next message - * as a new WireGuard layer. + * Does nothing for this layer (WireGuard layer is always last) */ - void parseNextLayer() override; + void parseNextLayer() override + {} /** - * Calculates the length of the header based on the message type. - * * @return Size of the header in bytes. */ size_t getHeaderLen() const override; @@ -163,8 +138,6 @@ namespace pcpp std::string toString() const override; /** - * Returns the OSI model layer that this protocol belongs to. - * * @return OSI model layer corresponding to the Network layer */ OsiModelLayer getOsiModelLayer() const override @@ -173,8 +146,6 @@ namespace pcpp } /** - * Get the WireGuard message type in the form of a WireGuardMessageType enum. - * * @return The message type as a WireGuardMessageType enum value. */ virtual WireGuardMessageType getWireGuardMessageType() const @@ -191,10 +162,6 @@ namespace pcpp { private: #pragma pack(push, 1) - /** - * @struct wg_handshake_initiation - * Represents the Handshake Initiation message structure - */ typedef struct wg_handshake_initiation : wg_common_header { /** Sender index */ @@ -211,6 +178,12 @@ namespace pcpp uint8_t mac2[16]; } wg_handshake_initiation; #pragma pack(pop) + + wg_handshake_initiation* getHandshakeInitiationHeader() const + { + return reinterpret_cast(getBasicHeader()); + } + public: /** * A constructor that creates the layer from an existing packet raw data @@ -238,62 +211,38 @@ namespace pcpp const uint8_t mac2[16]); /** - * Get the sender index from the Handshake Initiation message. - * * @return The sender index as a 32-bit integer. */ uint32_t getSenderIndex() const; /** - * Get the initiator's ephemeral public key from the Handshake Initiation message. - * * @return An array containing the initiator's ephemeral public key. */ std::array getInitiatorEphemeral() const; /** - * Get the encrypted initiator's static key from the Handshake Initiation message. - * * @return An array containing the encrypted initiator's static key. */ std::array getEncryptedInitiatorStatic() const; /** - * Get the encrypted timestamp from the Handshake Initiation message. - * * @return An array containing the encrypted timestamp. */ std::array getEncryptedTimestamp() const; /** - * Get the MAC1 field from the Handshake Initiation message. - * * @return An array containing the MAC1 field. */ std::array getMac1() const; /** - * Get the MAC2 field from the Handshake Initiation message. - * * @return An array containing the MAC2 field. */ std::array getMac2() const; - /** - * Get the Handshake Initiation message header. - * - * @return A pointer to the Handshake Initiation message structure. - */ - wg_handshake_initiation* getHandshakeInitiationHeader() const - { - return reinterpret_cast(getBasicHeader()); - } - // implement abstract methods /** - * Returns the message type as HandshakeInitiation. - * * @return WireGuardMessageType enum value indicating HandshakeInitiation. */ WireGuardMessageType getWireGuardMessageType() const override @@ -310,10 +259,6 @@ namespace pcpp { private: #pragma pack(push, 1) - /** - * @struct wg_handshake_response - * Represents the Handshake Response message structure - */ typedef struct wg_handshake_response : wg_common_header { /** Sender index */ @@ -330,6 +275,12 @@ namespace pcpp uint8_t mac2[16]; } wg_handshake_response; #pragma pack(pop) + + wg_handshake_response* getHandshakeResponseHeader() const + { + return reinterpret_cast(getBasicHeader()); + } + public: /** * A constructor that creates the layer from an existing packet raw data @@ -356,62 +307,38 @@ namespace pcpp const uint8_t mac1[16], const uint8_t mac2[16]); /** - * Get the sender index from the Handshake Response message. - * * @return The sender index as a 32-bit unsigned integer. */ uint32_t getSenderIndex() const; /** - * Get the receiver index from the Handshake Response message. - * * @return The receiver index as a 32-bit unsigned integer. */ uint32_t getReceiverIndex() const; /** - * Get the responder's ephemeral public key. - * * @return The responder's ephemeral public key as an array of 32 bytes. */ std::array getResponderEphemeral() const; /** - * Get the encrypted empty field from the Handshake Response message. - * * @return The encrypted empty field as an array of 16 bytes. */ std::array getEncryptedEmpty() const; /** - * Get the MAC1 field from the Handshake Response message. - * * @return The MAC1 field as an array of 16 bytes. */ std::array getMac1() const; /** - * Get the MAC2 field from the Handshake Response message. - * * @return The MAC2 field as an array of 16 bytes. */ std::array getMac2() const; - /** - * Get the Handshake Response message header. - * - * @return A pointer to the Handshake Response message structure. - */ - wg_handshake_response* getHandshakeResponseHeader() const - { - return reinterpret_cast(getBasicHeader()); - } - // implement abstract methods /** - * Get the WireGuard message type for the Handshake Response. - * * @return The message type as a WireGuardMessageType enum value. */ WireGuardMessageType getWireGuardMessageType() const override @@ -428,10 +355,6 @@ namespace pcpp { private: #pragma pack(push, 1) - /** - * @struct wg_cookie_reply - * Represents the Cookie Reply message structure - */ typedef struct wg_cookie_reply : wg_common_header { /** Receiver index */ @@ -442,6 +365,12 @@ namespace pcpp uint8_t encryptedCookie[32]; } wg_cookie_reply; #pragma pack(pop) + + wg_cookie_reply* getCookieReplyHeader() const + { + return reinterpret_cast(getBasicHeader()); + } + public: /** * A constructor that creates the layer from an existing packet raw data @@ -463,41 +392,23 @@ namespace pcpp WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], const uint8_t encryptedCookie[32]); /** - * Get the receiver index from the Cookie Reply message. - * * @return The receiver index as a 32-bit unsigned integer. */ uint32_t getReceiverIndex() const; /** - * Get the nonce field from the Cookie Reply message. - * * @return The nonce field as an array of 24 bytes. */ std::array getNonce() const; /** - * Get the encrypted cookie from the Cookie Reply message. - * * @return The encrypted cookie as an array of 32 bytes. */ std::array getEncryptedCookie() const; - /** - * Get the Cookie Reply message header. - * - * @return A pointer to the Cookie Reply message structure. - */ - wg_cookie_reply* getCookieReplyHeader() const - { - return reinterpret_cast(getBasicHeader()); - } - // implement abstract methods /** - * Get the WireGuard message type for the Cookie Reply. - * * @return The message type as a WireGuardMessageType enum value. */ WireGuardMessageType getWireGuardMessageType() const override @@ -514,10 +425,6 @@ namespace pcpp { private: #pragma pack(push, 1) - /** - * @struct wg_transport_data - * Represents the Transport Data message structure - */ typedef struct wg_transport_data : wg_common_header { /** Receiver index */ @@ -528,6 +435,12 @@ namespace pcpp uint8_t encryptedData[0]; } wg_transport_data; #pragma pack(pop) + + wg_transport_data* getTransportHeader() const + { + return reinterpret_cast(getBasicHeader()); + } + public: /** * A constructor that creates the layer from an existing packet raw data @@ -551,41 +464,23 @@ namespace pcpp size_t encryptedDataLen); /** - * Get the receiver index from the Transport Data message. - * * @return The receiver index as a 32-bit unsigned integer. */ uint32_t getReceiverIndex() const; /** - * Get the counter field from the Transport Data message. - * * @return The counter field as a 64-bit unsigned integer. */ uint64_t getCounter() const; /** - * Get the encrypted data from the Transport Data message. - * * @return A pointer to the encrypted data field. */ const uint8_t* getEncryptedData() const; - /** - * Get the Transport Data message header. - * - * @return A pointer to the Transport Data message structure. - */ - wg_transport_data* getTransportHeader() const - { - return reinterpret_cast(getBasicHeader()); - } - // implement abstract methods /** - * Get the WireGuard message type for the Transport Data message. - * * @return The message type as a WireGuardMessageType enum value. */ WireGuardMessageType getWireGuardMessageType() const override diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index d4c01ccf4a..149836655a 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -2,30 +2,13 @@ #include "UdpLayer.h" #include "PayloadLayer.h" -#include "IPv4Layer.h" -#include "IPv6Layer.h" #include "WireGuardLayer.h" -#include "Logger.h" #include "EndianPortable.h" -#include #include #include namespace pcpp { - void WireGuardLayer::parseNextLayer() - { - size_t headerLen = getHeaderLen(); - if (m_DataLen <= headerLen && headerLen != 0) - m_NextLayer = new PayloadLayer(m_Data, m_DataLen, this, m_Packet); - else - { - m_NextLayer = WireGuardLayer::parseWireGuardLayer(m_Data, m_DataLen, this, m_Packet); - if (!m_NextLayer) - m_NextLayer = new PayloadLayer(m_Data, m_DataLen, this, m_Packet); - } - } - WireGuardLayer* WireGuardLayer::parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) { if (dataLen < sizeof(WireGuardLayer::wg_common_header)) diff --git a/Tests/Packet++Test/PacketExamples/WireGuardCookieReply.dat b/Tests/Packet++Test/PacketExamples/WireGuardCookieReply.dat new file mode 100644 index 0000000000..cf8caaf01e --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/WireGuardCookieReply.dat @@ -0,0 +1 @@ +aabbccddeeff00504311223308004500005c07d000004011a717c0a801010a000001ca6cca6c0048f55503000000ab7df4060100000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000000100000000000000 \ No newline at end of file diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 0c7fca856e..477e956671 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -267,5 +267,6 @@ PTF_TEST_CASE(LdapCreationTest); // Implemented in WireGuardTests.cpp PTF_TEST_CASE(WireGuardHandshakeInitParsingTest); PTF_TEST_CASE(WireGuardHandshakeRespParsingTest); +PTF_TEST_CASE(WireGuardCookieReplyParsingTest); PTF_TEST_CASE(WireGuardTransportDataParsingTest); PTF_TEST_CASE(WireGuardCreationTest); diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 2ab3abb8cf..08cc147769 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -106,6 +106,44 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getMac2() == expectedMac2); } +PTF_TEST_CASE(WireGuardCookieReplyParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardCookieReply.dat"); + + pcpp::Packet wgCookieReplyPacket(&rawPacket1); + + PTF_ASSERT_TRUE(wgCookieReplyPacket.isPacketOfType(pcpp::WireGuard)); + pcpp::WireGuardLayer* wgLayer = wgCookieReplyPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(wgLayer); + + pcpp::WireGuardCookieReplyLayer* wgCookieReplyaLayer = + wgCookieReplyPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(wgCookieReplyaLayer); + + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getMessageTypeAsString(), "Cookie Reply"); + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->toString(), + "WireGuard Layer, " + wgCookieReplyaLayer->getMessageTypeAsString() + " message"); + + PTF_ASSERT_TRUE(wgCookieReplyaLayer->getWireGuardMessageType() == + pcpp::WireGuardLayer::WireGuardMessageType::CookieReply); + + uint32_t receiverIndex = 2877158406; + + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getReceiverIndex(), receiverIndex); + + uint8_t nonce[24] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE(std::memcmp(wgCookieReplyaLayer->getNonce().data(), nonce, sizeof(nonce)) == 0); + uint8_t encryptedCookie[32] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PTF_ASSERT_TRUE( + std::memcmp(wgCookieReplyaLayer->getEncryptedCookie().data(), encryptedCookie, sizeof(encryptedCookie)) == 0); +} + PTF_TEST_CASE(WireGuardTransportDataParsingTest) { timeval time; @@ -154,7 +192,8 @@ PTF_TEST_CASE(WireGuardCreationTest) READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/WireGuardHandshakeInitiation.dat"); READ_FILE_AND_CREATE_PACKET(2, "PacketExamples/WireGuardHandshakeResponse.dat"); - READ_FILE_AND_CREATE_PACKET(3, "PacketExamples/WireGuardTransportData.dat"); + READ_FILE_AND_CREATE_PACKET(3, "PacketExamples/WireGuardCookieReply.dat"); + READ_FILE_AND_CREATE_PACKET(4, "PacketExamples/WireGuardTransportData.dat"); uint8_t origBuffer[1500]; @@ -187,7 +226,15 @@ PTF_TEST_CASE(WireGuardCreationTest) dynamic_cast(wgHandshakeInitPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeInitMessage); PTF_ASSERT_EQUAL(newHandshakeInitMessage.getDataLen(), origHandshakeInitMessage->getDataLen()); + PTF_ASSERT_EQUAL(newHandshakeInitMessage.getSenderIndex(), 818952152); + PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getInitiatorEphemeral().data(), expectedPublicKeyInit, 32) == 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getEncryptedInitiatorStatic().data(), expectedStaticKeyInit, 48) == + 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getEncryptedTimestamp().data(), expectedTimestampInit, 28) == 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getMac1().data(), expectedMac1Init, 16) == 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getMac2().data(), expectedMac2Init, 16) == 0); + PTF_ASSERT_TRUE(wgHandshakeInitPacket.addLayer(&newHandshakeInitMessage)); PTF_ASSERT_EQUAL(wgHandshakeInitPacket.getRawPacket()->getRawDataLen(), bufferLength1); @@ -218,16 +265,49 @@ PTF_TEST_CASE(WireGuardCreationTest) PTF_ASSERT_EQUAL(newHandshakeRespMessage.getDataLen(), origHandshakeRespMessage->getDataLen()); PTF_ASSERT_EQUAL(newHandshakeRespMessage.getSenderIndex(), 2877158406); PTF_ASSERT_EQUAL(newHandshakeRespMessage.getReceiverIndex(), 818952152); + PTF_ASSERT_TRUE( + memcmp(newHandshakeRespMessage.getResponderEphemeral().data(), expectedResponderEphemeralResp, 32) == 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeRespMessage.getEncryptedEmpty().data(), encryptedEmptyDataResp, 16) == 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeRespMessage.getMac1().data(), expectedMac1Resp, 16) == 0); + PTF_ASSERT_TRUE(memcmp(newHandshakeRespMessage.getMac2().data(), expectedMac2Resp, 16) == 0); PTF_ASSERT_TRUE(wgHandshakeRespPacket.addLayer(&newHandshakeRespMessage)); PTF_ASSERT_EQUAL(wgHandshakeRespPacket.getRawPacket()->getRawDataLen(), bufferLength2); delete origHandshakeRespMessage; - // create WireGuard Transport Data message + // create WireGuard Cookie Reply message memcpy(origBuffer, buffer3, bufferLength3); + uint32_t receiverIndex = 2877158406; + uint8_t nonce[24] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t encryptedCookie[32] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + pcpp::WireGuardCookieReplyLayer newCookieReplyMessage(receiverIndex, nonce, encryptedCookie); + pcpp::Packet wgCookieReplyPacket(&rawPacket3); + + pcpp::WireGuardCookieReplyLayer* origCookieReplyMessage = + dynamic_cast(wgCookieReplyPacket.detachLayer(pcpp::WireGuard)); + PTF_ASSERT_NOT_NULL(origCookieReplyMessage); + + PTF_ASSERT_EQUAL(newCookieReplyMessage.getDataLen(), origCookieReplyMessage->getDataLen()); + PTF_ASSERT_EQUAL(newCookieReplyMessage.getReceiverIndex(), receiverIndex); + PTF_ASSERT_TRUE(std::memcmp(newCookieReplyMessage.getNonce().data(), nonce, sizeof(nonce)) == 0); + PTF_ASSERT_TRUE( + std::memcmp(newCookieReplyMessage.getEncryptedCookie().data(), encryptedCookie, sizeof(encryptedCookie)) == 0); + PTF_ASSERT_TRUE(wgCookieReplyPacket.addLayer(&newCookieReplyMessage)); + PTF_ASSERT_EQUAL(wgCookieReplyPacket.getRawPacket()->getRawDataLen(), bufferLength3); + + delete origCookieReplyMessage; + + // create WireGuard Transport Data message + + memcpy(origBuffer, buffer4, bufferLength4); + uint64_t expectedCounterTransport = 0x0000000000000000; uint8_t expectedEncryptedDataTransport[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, 0xc0, 0x4e, 0x27, @@ -241,16 +321,16 @@ PTF_TEST_CASE(WireGuardCreationTest) pcpp::WireGuardTransportDataLayer newTransportDataMessage(2877158406, expectedCounterTransport, expectedEncryptedDataTransport, 112); - pcpp::Packet wgTransportDataPacket(&rawPacket3); + pcpp::Packet wgTransportDataPacket(&rawPacket4); pcpp::WireGuardTransportDataLayer* origTransportDataMessage = dynamic_cast(wgTransportDataPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origTransportDataMessage); PTF_ASSERT_EQUAL(newTransportDataMessage.getDataLen(), origTransportDataMessage->getDataLen()); PTF_ASSERT_EQUAL(newTransportDataMessage.getCounter(), expectedCounterTransport); - + PTF_ASSERT_TRUE(memcmp(newTransportDataMessage.getEncryptedData(), expectedEncryptedDataTransport, 112) == 0); PTF_ASSERT_TRUE(wgTransportDataPacket.addLayer(&newTransportDataMessage)); - PTF_ASSERT_EQUAL(wgTransportDataPacket.getRawPacket()->getRawDataLen(), bufferLength3); + PTF_ASSERT_EQUAL(wgTransportDataPacket.getRawPacket()->getRawDataLen(), bufferLength4); delete origTransportDataMessage; } diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index f4c7e02875..1b6bc08fba 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -336,6 +336,7 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(WireGuardHandshakeInitParsingTest, "wg"); PTF_RUN_TEST(WireGuardHandshakeRespParsingTest, "wg"); + PTF_RUN_TEST(WireGuardCookieReplyParsingTest, "wg"); PTF_RUN_TEST(WireGuardTransportDataParsingTest, "wg"); PTF_RUN_TEST(WireGuardCreationTest, "wg"); From 1be20e1b0f3a17db0907622c2613f24937067c56 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Thu, 26 Sep 2024 23:05:08 +0900 Subject: [PATCH 35/37] lint Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 36 +++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 5d3d81037d..850a3ec5e6 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -21,6 +21,10 @@ namespace pcpp { protected: #pragma pack(push, 1) + /** + * @struct wg_common_header + * Represents the common header for all WireGuard message types + */ struct wg_common_header { /** Message type field */ @@ -29,6 +33,9 @@ namespace pcpp uint8_t reserved[3]; }; #pragma pack(pop) + /** + * @return Pointer to the common header structure. + */ wg_common_header* getBasicHeader() const { return reinterpret_cast(m_Data); @@ -162,6 +169,10 @@ namespace pcpp { private: #pragma pack(push, 1) + /** + * @struct wg_handshake_initiation + * Represents the Handshake Initiation message structure + */ typedef struct wg_handshake_initiation : wg_common_header { /** Sender index */ @@ -179,6 +190,9 @@ namespace pcpp } wg_handshake_initiation; #pragma pack(pop) + /** + * @return A pointer to the Handshake Initiation message structure. + */ wg_handshake_initiation* getHandshakeInitiationHeader() const { return reinterpret_cast(getBasicHeader()); @@ -259,6 +273,10 @@ namespace pcpp { private: #pragma pack(push, 1) + /** + * @struct wg_handshake_response + * Represents the Handshake Response message structure + */ typedef struct wg_handshake_response : wg_common_header { /** Sender index */ @@ -276,6 +294,9 @@ namespace pcpp } wg_handshake_response; #pragma pack(pop) + /** + * @return A pointer to the Handshake Response message structure. + */ wg_handshake_response* getHandshakeResponseHeader() const { return reinterpret_cast(getBasicHeader()); @@ -355,6 +376,10 @@ namespace pcpp { private: #pragma pack(push, 1) + /** + * @struct wg_cookie_reply + * Represents the Cookie Reply message structure + */ typedef struct wg_cookie_reply : wg_common_header { /** Receiver index */ @@ -365,7 +390,9 @@ namespace pcpp uint8_t encryptedCookie[32]; } wg_cookie_reply; #pragma pack(pop) - + /** + * @return A pointer to the Cookie Reply message structure. + */ wg_cookie_reply* getCookieReplyHeader() const { return reinterpret_cast(getBasicHeader()); @@ -425,6 +452,10 @@ namespace pcpp { private: #pragma pack(push, 1) + /** + * @struct wg_transport_data + * Represents the Transport Data message structure + */ typedef struct wg_transport_data : wg_common_header { /** Receiver index */ @@ -436,6 +467,9 @@ namespace pcpp } wg_transport_data; #pragma pack(pop) + /** + * @return A pointer to the Transport Data message structure. + */ wg_transport_data* getTransportHeader() const { return reinterpret_cast(getBasicHeader()); From 306035493bf205afc7e21825511541d860b5411d Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 28 Sep 2024 00:21:41 +0900 Subject: [PATCH 36/37] Refactor WireGuardLayer and Tests Signed-off-by: Dongjun Na --- Packet++/header/WireGuardLayer.h | 17 +-- Packet++/src/WireGuardLayer.cpp | 2 +- .../PacketExamples/WireGuard.pcap | Bin 566 -> 1108 bytes Tests/Packet++Test/Tests/WireGuardTests.cpp | 131 +++++++++++------- 4 files changed, 82 insertions(+), 68 deletions(-) diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 850a3ec5e6..5d5a9dca24 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -33,9 +33,6 @@ namespace pcpp uint8_t reserved[3]; }; #pragma pack(pop) - /** - * @return Pointer to the common header structure. - */ wg_common_header* getBasicHeader() const { return reinterpret_cast(m_Data); @@ -189,10 +186,6 @@ namespace pcpp uint8_t mac2[16]; } wg_handshake_initiation; #pragma pack(pop) - - /** - * @return A pointer to the Handshake Initiation message structure. - */ wg_handshake_initiation* getHandshakeInitiationHeader() const { return reinterpret_cast(getBasicHeader()); @@ -294,9 +287,6 @@ namespace pcpp } wg_handshake_response; #pragma pack(pop) - /** - * @return A pointer to the Handshake Response message structure. - */ wg_handshake_response* getHandshakeResponseHeader() const { return reinterpret_cast(getBasicHeader()); @@ -390,9 +380,7 @@ namespace pcpp uint8_t encryptedCookie[32]; } wg_cookie_reply; #pragma pack(pop) - /** - * @return A pointer to the Cookie Reply message structure. - */ + wg_cookie_reply* getCookieReplyHeader() const { return reinterpret_cast(getBasicHeader()); @@ -467,9 +455,6 @@ namespace pcpp } wg_transport_data; #pragma pack(pop) - /** - * @return A pointer to the Transport Data message structure. - */ wg_transport_data* getTransportHeader() const { return reinterpret_cast(getBasicHeader()); diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 149836655a..573282eee8 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -1,7 +1,6 @@ #define LOG_MODULE PacketLogModuleWireGuardLayer #include "UdpLayer.h" -#include "PayloadLayer.h" #include "WireGuardLayer.h" #include "EndianPortable.h" #include @@ -99,6 +98,7 @@ namespace pcpp msgHdr->messageType = static_cast(WireGuardMessageType::HandshakeInitiation); msgHdr->senderIndex = htobe32(senderIndex); + memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); memcpy(msgHdr->encryptedTimestamp, encryptedTimestamp, 28); diff --git a/Tests/Packet++Test/PacketExamples/WireGuard.pcap b/Tests/Packet++Test/PacketExamples/WireGuard.pcap index 53a32b86b49395bbef5a2dbc6b1f9e14015fc50b..5d21e849cfd67c105950ee6d427642895eda7e7d 100644 GIT binary patch delta 612 zcmaKoy-OTX5Wr{gJmo})L~ zV<`dgkBB4|Vqp=RK)^z-NRc9q;9p>st98cpqX`)p=HoZ>=FObtevkJHlaqya2EfXK zIfDjnAH;y4@J4%z$w-MrxvaIrd=<5I(5|rpkxGs6^;ktQcf+9FNrOOeX_~wq21%q_ zX`;h`H>Kz`y)-7}A5@&gyeVW?C8kLc?`KhCTlhUs#e73YYB?2=YxS@*8)W}u&{DV+ zc%g9P`;kvw^)T#e^TUA%e`O1754+nHby5KY_S%BP= z|C}@Kb9toKR5F2@ej0_^NpX0kzo|D>C(IO;O%gI Y1gpR8{>^8bJZ|(~`x0B83$jn#0o#g~CIA2c delta 67 zcmcb@v5iIH%Hd55nHX3Y5P*e&5y&Y_35xzz$jUIegYg&#h;yMD$jM;p19N0*fgAzm FO#m>c5oG`X diff --git a/Tests/Packet++Test/Tests/WireGuardTests.cpp b/Tests/Packet++Test/Tests/WireGuardTests.cpp index 08cc147769..9858b3445c 100644 --- a/Tests/Packet++Test/Tests/WireGuardTests.cpp +++ b/Tests/Packet++Test/Tests/WireGuardTests.cpp @@ -17,21 +17,24 @@ PTF_TEST_CASE(WireGuardHandshakeInitParsingTest) PTF_ASSERT_TRUE(wgHandShakeInitPacket.isPacketOfType(pcpp::WireGuard)); - pcpp::WireGuardLayer* wgLayer = wgHandShakeInitPacket.getLayerOfType(); + auto wgLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - pcpp::WireGuardHandshakeInitiationLayer* wgHandShakeInitLayer = - wgHandShakeInitPacket.getLayerOfType(); + auto wgHandShakeInitLayer = wgHandShakeInitPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgHandShakeInitLayer); PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getMessageTypeAsString(), "Handshake Initiation"); + + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getMessageType(), 1); + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getReserved(), 0); + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getHeaderLen(), 148); + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->toString(), "WireGuard Layer, " + wgHandShakeInitLayer->getMessageTypeAsString() + " message"); PTF_ASSERT_TRUE(wgHandShakeInitLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeInitiation); - - PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getSenderIndex(), be32toh(818952152)); + PTF_ASSERT_EQUAL(wgHandShakeInitLayer->getSenderIndex(), 0xd837d030); std::array expectedPublicKey = { 0x5f, 0xce, 0xc7, 0xc8, 0xe5, 0xc8, 0xe2, 0xe3, 0xf7, 0x98, 0x9e, 0xef, 0x60, 0xc2, 0x28, 0xd8, 0x23, 0x29, 0xd6, 0x02, 0xb6, 0xb1, @@ -69,22 +72,26 @@ PTF_TEST_CASE(WireGuardHandshakeRespParsingTest) pcpp::Packet wgHandShakeResponsePacket(&rawPacket1); PTF_ASSERT_TRUE(wgHandShakeResponsePacket.isPacketOfType(pcpp::WireGuard)); - pcpp::WireGuardLayer* wgLayer = wgHandShakeResponsePacket.getLayerOfType(); + auto wgLayer = wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - pcpp::WireGuardHandshakeResponseLayer* wgHandShakeResponseLayer = - wgHandShakeResponsePacket.getLayerOfType(); + auto wgHandShakeResponseLayer = wgHandShakeResponsePacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgHandShakeResponseLayer); PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getMessageTypeAsString(), "Handshake Response"); + + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getMessageType(), 2); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getReserved(), 0); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getHeaderLen(), 92); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->toString(), "WireGuard Layer, " + wgHandShakeResponseLayer->getMessageTypeAsString() + " message"); PTF_ASSERT_TRUE(wgHandShakeResponseLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::HandshakeResponse); - PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getSenderIndex(), be32toh(2877158406)); - PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getReceiverIndex(), be32toh(818952152)); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getSenderIndex(), 0x06f47dab); + PTF_ASSERT_EQUAL(wgHandShakeResponseLayer->getReceiverIndex(), 0xd837d030); std::array expectedResponderEphemeral = { 0xb1, 0x8d, 0x55, 0x50, 0xbd, 0x40, 0x42, 0xa3, 0x7a, 0x46, 0x82, 0x3a, 0xc0, 0x8d, 0xb1, 0xec, @@ -116,23 +123,25 @@ PTF_TEST_CASE(WireGuardCookieReplyParsingTest) pcpp::Packet wgCookieReplyPacket(&rawPacket1); PTF_ASSERT_TRUE(wgCookieReplyPacket.isPacketOfType(pcpp::WireGuard)); - pcpp::WireGuardLayer* wgLayer = wgCookieReplyPacket.getLayerOfType(); + auto wgLayer = wgCookieReplyPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - pcpp::WireGuardCookieReplyLayer* wgCookieReplyaLayer = - wgCookieReplyPacket.getLayerOfType(); + auto wgCookieReplyaLayer = wgCookieReplyPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgCookieReplyaLayer); PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getMessageTypeAsString(), "Cookie Reply"); + + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getMessageType(), 3); + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getReserved(), 0); + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getHeaderLen(), 64); + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->toString(), "WireGuard Layer, " + wgCookieReplyaLayer->getMessageTypeAsString() + " message"); PTF_ASSERT_TRUE(wgCookieReplyaLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::CookieReply); - uint32_t receiverIndex = 2877158406; - - PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getReceiverIndex(), receiverIndex); + PTF_ASSERT_EQUAL(wgCookieReplyaLayer->getReceiverIndex(), 0xab7df406); uint8_t nonce[24] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -153,24 +162,27 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) pcpp::Packet wgTransportDataPacket(&rawPacket1); PTF_ASSERT_TRUE(wgTransportDataPacket.isPacketOfType(pcpp::WireGuard)); - pcpp::WireGuardLayer* wgLayer = wgTransportDataPacket.getLayerOfType(); + auto wgLayer = wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgLayer); - pcpp::WireGuardTransportDataLayer* wgTransportDataLayer = - wgTransportDataPacket.getLayerOfType(); + auto wgTransportDataLayer = wgTransportDataPacket.getLayerOfType(); PTF_ASSERT_NOT_NULL(wgTransportDataLayer); PTF_ASSERT_EQUAL(wgTransportDataLayer->getMessageTypeAsString(), "Transport Data"); + + PTF_ASSERT_EQUAL(wgTransportDataLayer->getMessageType(), 4); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getReserved(), 0); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getHeaderLen(), 128); + PTF_ASSERT_EQUAL(wgTransportDataLayer->toString(), "WireGuard Layer, " + wgTransportDataLayer->getMessageTypeAsString() + " message"); PTF_ASSERT_TRUE(wgTransportDataLayer->getWireGuardMessageType() == pcpp::WireGuardLayer::WireGuardMessageType::TransportData); - PTF_ASSERT_EQUAL(wgTransportDataLayer->getReceiverIndex(), be32toh(2877158406)); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getReceiverIndex(), 0x06f47dab); - uint64_t expectedCounter = 0x0000000000000000; - PTF_ASSERT_EQUAL(wgTransportDataLayer->getCounter(), be32toh(expectedCounter)); + PTF_ASSERT_EQUAL(wgTransportDataLayer->getCounter(), 0); uint8_t expectedEncryptedData[112] = { 0xa4, 0xeb, 0xc1, 0x2e, 0xe3, 0xf9, 0x90, 0xda, 0x18, 0x03, 0x3a, 0x07, 0x89, 0xc0, 0x4e, 0x27, 0x00, 0xf6, 0xf5, 0xc2, 0x71, 0xd4, 0x2a, 0xc4, 0xb4, 0xd6, @@ -181,8 +193,8 @@ PTF_TEST_CASE(WireGuardTransportDataParsingTest) 0xbe, 0x03, 0x34, 0x6d, 0x91, 0x2e, 0x91, 0x6d, 0xad, 0x86, 0x25, 0x45, 0x45, 0x47, 0x01, 0x36, 0x4f, 0x2d, 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - PTF_ASSERT_TRUE(std::memcmp(wgTransportDataLayer->getEncryptedData(), expectedEncryptedData, - sizeof(expectedEncryptedData)) == 0); + PTF_ASSERT_BUF_COMPARE(wgTransportDataLayer->getEncryptedData(), expectedEncryptedData, + sizeof(expectedEncryptedData)); } PTF_TEST_CASE(WireGuardCreationTest) @@ -218,26 +230,29 @@ PTF_TEST_CASE(WireGuardCreationTest) uint8_t expectedMac2Init[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(818952152, expectedPublicKeyInit, + pcpp::WireGuardHandshakeInitiationLayer newHandshakeInitMessage(0xd837d030, expectedPublicKeyInit, expectedStaticKeyInit, expectedTimestampInit, expectedMac1Init, expectedMac2Init); pcpp::Packet wgHandshakeInitPacket(&rawPacket1); - pcpp::WireGuardHandshakeInitiationLayer* origHandshakeInitMessage = + auto origHandshakeInitMessage = dynamic_cast(wgHandshakeInitPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeInitMessage); - PTF_ASSERT_EQUAL(newHandshakeInitMessage.getDataLen(), origHandshakeInitMessage->getDataLen()); - PTF_ASSERT_EQUAL(newHandshakeInitMessage.getSenderIndex(), 818952152); - PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getInitiatorEphemeral().data(), expectedPublicKeyInit, 32) == 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getEncryptedInitiatorStatic().data(), expectedStaticKeyInit, 48) == - 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getEncryptedTimestamp().data(), expectedTimestampInit, 28) == 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getMac1().data(), expectedMac1Init, 16) == 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeInitMessage.getMac2().data(), expectedMac2Init, 16) == 0); + PTF_ASSERT_EQUAL(newHandshakeInitMessage.getSenderIndex(), 0xd837d030); + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getInitiatorEphemeral().data(), expectedPublicKeyInit, 32); + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getEncryptedInitiatorStatic().data(), expectedStaticKeyInit, 48); + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getEncryptedTimestamp().data(), expectedTimestampInit, 28); + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getMac1().data(), expectedMac1Init, 16); + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getMac2().data(), expectedMac2Init, 16); PTF_ASSERT_TRUE(wgHandshakeInitPacket.addLayer(&newHandshakeInitMessage)); PTF_ASSERT_EQUAL(wgHandshakeInitPacket.getRawPacket()->getRawDataLen(), bufferLength1); + PTF_ASSERT_EQUAL(newHandshakeInitMessage.getDataLen(), origHandshakeInitMessage->getDataLen()); + + PTF_ASSERT_BUF_COMPARE(newHandshakeInitMessage.getData(), origHandshakeInitMessage->getData(), + origHandshakeInitMessage->getDataLen()); + delete origHandshakeInitMessage; // create WireGuard Handshake Response message @@ -255,52 +270,60 @@ PTF_TEST_CASE(WireGuardCreationTest) uint8_t expectedMac2Resp[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage(2877158406, 818952152, expectedResponderEphemeralResp, - encryptedEmptyDataResp, expectedMac1Resp, - expectedMac2Resp); + pcpp::WireGuardHandshakeResponseLayer newHandshakeRespMessage( + 0x06f47dab, 0xd837d030, expectedResponderEphemeralResp, encryptedEmptyDataResp, expectedMac1Resp, + expectedMac2Resp); pcpp::Packet wgHandshakeRespPacket(&rawPacket2); pcpp::WireGuardHandshakeResponseLayer* origHandshakeRespMessage = dynamic_cast(wgHandshakeRespPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origHandshakeRespMessage); PTF_ASSERT_EQUAL(newHandshakeRespMessage.getDataLen(), origHandshakeRespMessage->getDataLen()); - PTF_ASSERT_EQUAL(newHandshakeRespMessage.getSenderIndex(), 2877158406); - PTF_ASSERT_EQUAL(newHandshakeRespMessage.getReceiverIndex(), 818952152); - PTF_ASSERT_TRUE( - memcmp(newHandshakeRespMessage.getResponderEphemeral().data(), expectedResponderEphemeralResp, 32) == 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeRespMessage.getEncryptedEmpty().data(), encryptedEmptyDataResp, 16) == 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeRespMessage.getMac1().data(), expectedMac1Resp, 16) == 0); - PTF_ASSERT_TRUE(memcmp(newHandshakeRespMessage.getMac2().data(), expectedMac2Resp, 16) == 0); + PTF_ASSERT_EQUAL(newHandshakeRespMessage.getSenderIndex(), 0x06f47dab); + PTF_ASSERT_EQUAL(newHandshakeRespMessage.getReceiverIndex(), 0xd837d030); + PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getResponderEphemeral().data(), expectedResponderEphemeralResp, 32); + PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getEncryptedEmpty().data(), encryptedEmptyDataResp, 16); + PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getMac1().data(), expectedMac1Resp, 16); + PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getMac2().data(), expectedMac2Resp, 16); PTF_ASSERT_TRUE(wgHandshakeRespPacket.addLayer(&newHandshakeRespMessage)); PTF_ASSERT_EQUAL(wgHandshakeRespPacket.getRawPacket()->getRawDataLen(), bufferLength2); + PTF_ASSERT_EQUAL(newHandshakeRespMessage.getDataLen(), origHandshakeRespMessage->getDataLen()); + + PTF_ASSERT_BUF_COMPARE(newHandshakeRespMessage.getData(), origHandshakeRespMessage->getData(), + origHandshakeRespMessage->getDataLen()); + delete origHandshakeRespMessage; // create WireGuard Cookie Reply message memcpy(origBuffer, buffer3, bufferLength3); - uint32_t receiverIndex = 2877158406; uint8_t nonce[24] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t encryptedCookie[32] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - pcpp::WireGuardCookieReplyLayer newCookieReplyMessage(receiverIndex, nonce, encryptedCookie); + pcpp::WireGuardCookieReplyLayer newCookieReplyMessage(0xab7df406, nonce, encryptedCookie); pcpp::Packet wgCookieReplyPacket(&rawPacket3); - pcpp::WireGuardCookieReplyLayer* origCookieReplyMessage = + auto origCookieReplyMessage = dynamic_cast(wgCookieReplyPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origCookieReplyMessage); PTF_ASSERT_EQUAL(newCookieReplyMessage.getDataLen(), origCookieReplyMessage->getDataLen()); - PTF_ASSERT_EQUAL(newCookieReplyMessage.getReceiverIndex(), receiverIndex); + PTF_ASSERT_EQUAL(newCookieReplyMessage.getReceiverIndex(), 0xab7df406); PTF_ASSERT_TRUE(std::memcmp(newCookieReplyMessage.getNonce().data(), nonce, sizeof(nonce)) == 0); PTF_ASSERT_TRUE( std::memcmp(newCookieReplyMessage.getEncryptedCookie().data(), encryptedCookie, sizeof(encryptedCookie)) == 0); PTF_ASSERT_TRUE(wgCookieReplyPacket.addLayer(&newCookieReplyMessage)); + PTF_ASSERT_EQUAL(wgCookieReplyPacket.getRawPacket()->getRawDataLen(), bufferLength3); + PTF_ASSERT_EQUAL(newCookieReplyMessage.getDataLen(), origCookieReplyMessage->getDataLen()); + + PTF_ASSERT_BUF_COMPARE(newCookieReplyMessage.getData(), origCookieReplyMessage->getData(), + origCookieReplyMessage->getDataLen()); delete origCookieReplyMessage; @@ -319,18 +342,24 @@ PTF_TEST_CASE(WireGuardCreationTest) 0x24, 0x86, 0xd7, 0xce, 0xd4, 0xc8, 0x64, 0x2c, 0xe5, 0x47, 0xdd, 0xb2, 0x6e, 0xf6, 0xa4, 0x6b }; - pcpp::WireGuardTransportDataLayer newTransportDataMessage(2877158406, expectedCounterTransport, + pcpp::WireGuardTransportDataLayer newTransportDataMessage(0x06f47dab, expectedCounterTransport, expectedEncryptedDataTransport, 112); pcpp::Packet wgTransportDataPacket(&rawPacket4); - pcpp::WireGuardTransportDataLayer* origTransportDataMessage = + auto origTransportDataMessage = dynamic_cast(wgTransportDataPacket.detachLayer(pcpp::WireGuard)); PTF_ASSERT_NOT_NULL(origTransportDataMessage); PTF_ASSERT_EQUAL(newTransportDataMessage.getDataLen(), origTransportDataMessage->getDataLen()); + PTF_ASSERT_EQUAL(newCookieReplyMessage.getReceiverIndex(), 0xab7df406); PTF_ASSERT_EQUAL(newTransportDataMessage.getCounter(), expectedCounterTransport); - PTF_ASSERT_TRUE(memcmp(newTransportDataMessage.getEncryptedData(), expectedEncryptedDataTransport, 112) == 0); + PTF_ASSERT_BUF_COMPARE(newTransportDataMessage.getEncryptedData(), expectedEncryptedDataTransport, 112); PTF_ASSERT_TRUE(wgTransportDataPacket.addLayer(&newTransportDataMessage)); PTF_ASSERT_EQUAL(wgTransportDataPacket.getRawPacket()->getRawDataLen(), bufferLength4); + PTF_ASSERT_EQUAL(newTransportDataMessage.getDataLen(), origTransportDataMessage->getDataLen()); + + PTF_ASSERT_BUF_COMPARE(newTransportDataMessage.getData(), origTransportDataMessage->getData(), + origTransportDataMessage->getDataLen()); + delete origTransportDataMessage; } From 5416764bbbd28b40a6766a8ec375d53e34ecfa56 Mon Sep 17 00:00:00 2001 From: Dongjun Na Date: Sat, 28 Sep 2024 00:36:32 +0900 Subject: [PATCH 37/37] Refactor Initialize reserved Signed-off-by: Dongjun Na --- Packet++/src/WireGuardLayer.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Packet++/src/WireGuardLayer.cpp b/Packet++/src/WireGuardLayer.cpp index 573282eee8..2f88b6c7ab 100644 --- a/Packet++/src/WireGuardLayer.cpp +++ b/Packet++/src/WireGuardLayer.cpp @@ -94,16 +94,17 @@ namespace pcpp m_Data = new uint8_t[messageLen]; memset(m_Data, 0, messageLen); - wg_handshake_initiation* msgHdr = reinterpret_cast(m_Data); + wg_handshake_initiation* msg = reinterpret_cast(m_Data); - msgHdr->messageType = static_cast(WireGuardMessageType::HandshakeInitiation); - msgHdr->senderIndex = htobe32(senderIndex); + msg->messageType = static_cast(WireGuardMessageType::HandshakeInitiation); + memset(msg->reserved, 0, 3); + msg->senderIndex = htobe32(senderIndex); - memcpy(msgHdr->initiatorEphemeral, initiatorEphemeral, 32); - memcpy(msgHdr->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); - memcpy(msgHdr->encryptedTimestamp, encryptedTimestamp, 28); - memcpy(msgHdr->mac1, mac1, 16); - memcpy(msgHdr->mac2, mac2, 16); + memcpy(msg->initiatorEphemeral, initiatorEphemeral, 32); + memcpy(msg->encryptedInitiatorStatic, encryptedInitiatorStatic, 48); + memcpy(msg->encryptedTimestamp, encryptedTimestamp, 28); + memcpy(msg->mac1, mac1, 16); + memcpy(msg->mac2, mac2, 16); m_Protocol = WireGuard; } @@ -163,6 +164,7 @@ namespace pcpp wg_handshake_response* msg = reinterpret_cast(m_Data); msg->messageType = static_cast(WireGuardMessageType::HandshakeResponse); + memset(msg->reserved, 0, 3); msg->senderIndex = htobe32(senderIndex); msg->receiverIndex = htobe32(receiverIndex); memcpy(msg->responderEphemeral, responderEphemeral, 32); @@ -226,6 +228,7 @@ namespace pcpp wg_cookie_reply* msg = reinterpret_cast(m_Data); msg->messageType = static_cast(WireGuardMessageType::CookieReply); + memset(msg->reserved, 0, 3); msg->receiverIndex = htobe32(receiverIndex); memcpy(msg->nonce, nonce, 24); memcpy(msg->encryptedCookie, encryptedCookie, 32); @@ -267,6 +270,7 @@ namespace pcpp wg_transport_data* msg = reinterpret_cast(m_Data); msg->messageType = static_cast(WireGuardMessageType::TransportData); + memset(msg->reserved, 0, 3); msg->receiverIndex = htobe32(receiverIndex); msg->counter = htobe64(counter); memcpy(m_Data + sizeof(wg_transport_data), encryptedData, encryptedDataLen);