base for packet encryption
This commit is contained in:
parent
523c86237c
commit
e5c0418760
5 changed files with 87 additions and 67 deletions
|
@ -49,7 +49,6 @@ add_executable(M2-PT-DRP
|
||||||
source/behavior/tasks/client/ClientTask.cpp
|
source/behavior/tasks/client/ClientTask.cpp
|
||||||
source/behavior/tasks/client/ClientTask.hpp
|
source/behavior/tasks/client/ClientTask.hpp
|
||||||
source/Context.hpp
|
source/Context.hpp
|
||||||
source/utils/CacheMap.hpp
|
|
||||||
source/packets/search/SearchPacketData.hpp
|
source/packets/search/SearchPacketData.hpp
|
||||||
source/packets/base/PacketContent.cpp
|
source/packets/base/PacketContent.cpp
|
||||||
source/packets/base/PacketContent.hpp
|
source/packets/base/PacketContent.hpp
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Packet.hpp"
|
#include "Packet.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "SecurityMode.hpp"
|
#include "SecurityMode.hpp"
|
||||||
|
|
||||||
|
@ -49,23 +50,50 @@ GenericPacketContent decryptPacketContentAes(const GenericPacket& packet) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
PacketContent Packet::getContent() const {
|
inline Packet::Packet(
|
||||||
// TODO(Faraphel): implement RSA and AES
|
const Context& context,
|
||||||
// additional "context" argument to hold cryptographic keys ?
|
const std::uint8_t channel,
|
||||||
|
SecurityMode securityMode,
|
||||||
|
const PacketContent& content
|
||||||
|
) {
|
||||||
|
this->channel = channel;
|
||||||
|
this->securityMode = static_cast<std::uint8_t>(securityMode);
|
||||||
|
|
||||||
|
switch (securityMode) {
|
||||||
|
case SecurityMode::PLAIN:
|
||||||
|
this->content = static_cast<auto>(content);
|
||||||
|
break;
|
||||||
|
case SecurityMode::RSA:
|
||||||
|
this->content = encryptRsa(context, content);
|
||||||
|
break;
|
||||||
|
case SecurityMode::AES:
|
||||||
|
this->content = encryptAes(context, content);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("Invalid security mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PacketContent Packet::getContent(
|
||||||
|
const Context& context,
|
||||||
|
const sockaddr_storage& address,
|
||||||
|
socklen_t addressLength
|
||||||
|
) const {
|
||||||
|
PacketContent content {};
|
||||||
|
|
||||||
switch (static_cast<SecurityMode>(this->securityMode)) {
|
switch (static_cast<SecurityMode>(this->securityMode)) {
|
||||||
case SecurityMode::PLAIN:
|
case SecurityMode::PLAIN:
|
||||||
return this->_content;
|
std::memcpy(&content, &this->content, sizeof(PacketContent));
|
||||||
|
return content;
|
||||||
case SecurityMode::AES:
|
|
||||||
// return decryptPacketContentAes(packet);
|
|
||||||
throw std::runtime_error("Not implemented.");
|
|
||||||
|
|
||||||
case SecurityMode::RSA:
|
case SecurityMode::RSA:
|
||||||
throw std::runtime_error("Not implemented.");
|
content = decryptRsa(context, this->content, address, addressLength);
|
||||||
|
return content;
|
||||||
|
case SecurityMode::AES:
|
||||||
|
content = decryptAes(context, this->content);
|
||||||
|
return content;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Unsupported security mode.");
|
throw std::invalid_argument("Invalid security mode.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "Context.hpp"
|
||||||
#include "PacketContent.hpp"
|
#include "PacketContent.hpp"
|
||||||
|
#include "SecurityMode.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace drp::packet::base {
|
namespace drp::packet::base {
|
||||||
|
@ -14,15 +16,26 @@ namespace drp::packet::base {
|
||||||
* @param channel the channel of the packet. Two system can be created inside a same network by using different
|
* @param channel the channel of the packet. Two system can be created inside a same network by using different
|
||||||
* channels value. "0" is used for "broadcast" message across networks.
|
* channels value. "0" is used for "broadcast" message across networks.
|
||||||
* @param securityMode the type of security used in the packet.
|
* @param securityMode the type of security used in the packet.
|
||||||
* @param _content the content of the packet. It is encrypted accordingly to the securityMode.
|
* @param content the content of the packet. It is encrypted accordingly to the securityMode.
|
||||||
*/
|
*/
|
||||||
struct Packet {
|
class Packet {
|
||||||
|
public:
|
||||||
|
explicit Packet(
|
||||||
|
const Context& context,
|
||||||
|
std::uint8_t channel,
|
||||||
|
SecurityMode securityMode,
|
||||||
|
const PacketContent& content
|
||||||
|
);
|
||||||
|
[[nodiscard]] PacketContent getContent(
|
||||||
|
const Context& context,
|
||||||
|
const sockaddr_storage& address,
|
||||||
|
socklen_t addressLength
|
||||||
|
) const;
|
||||||
|
|
||||||
|
private:
|
||||||
std::uint8_t channel;
|
std::uint8_t channel;
|
||||||
std::uint8_t securityMode;
|
std::uint8_t securityMode;
|
||||||
PacketContent _content;
|
std::array<std::uint8_t, sizeof(PacketContent)> content;
|
||||||
|
|
||||||
[[nodiscard]] PacketContent getContent() const;
|
|
||||||
void setContent(const PacketContent& content);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#include "PacketContent.hpp"
|
#include "PacketContent.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
|
#include "Context.hpp"
|
||||||
#include "Packet.hpp"
|
#include "Packet.hpp"
|
||||||
#include "SecurityMode.hpp"
|
#include "SecurityMode.hpp"
|
||||||
|
|
||||||
|
@ -9,22 +12,34 @@
|
||||||
namespace drp::packet::base {
|
namespace drp::packet::base {
|
||||||
|
|
||||||
|
|
||||||
void Packet::setContent(const PacketContent &content) {
|
void PacketContent::encryptRsa(const std::array<std::uint8_t, 2048>& publicKey) {
|
||||||
// TODO(Faraphel): implement RSA and AES
|
BIO* bioPublicKey = BIO_new_mem_buf(publicKey.data(), static_cast<int>(publicKey.size()));
|
||||||
switch (static_cast<SecurityMode>(this->securityMode)) {
|
EVP_PKEY* evpPublicKey = PEM_read_bio_PUBKEY(bioPublicKey, nullptr, nullptr, nullptr);
|
||||||
case SecurityMode::PLAIN:
|
|
||||||
this->_content = content;
|
|
||||||
return;
|
|
||||||
|
|
||||||
case SecurityMode::AES:
|
const std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> evpContext(
|
||||||
throw std::runtime_error("Not implemented.");
|
EVP_PKEY_CTX_new(evpPublicKey, nullptr),
|
||||||
|
EVP_PKEY_CTX_free
|
||||||
|
);
|
||||||
|
if (evpContext == nullptr)
|
||||||
|
throw std::runtime_error("Failed to create EVP_PKEY_CTX");
|
||||||
|
|
||||||
case SecurityMode::RSA:
|
if (EVP_PKEY_encrypt_init(evpContext.get()) <= 0)
|
||||||
throw std::runtime_error("Not implemented.");
|
throw std::runtime_error("Failed to initialize EVP_PKEY_CTX");
|
||||||
|
|
||||||
|
if (EVP_PKEY_CTX_set_rsa_padding(evpContext.get(), RSA_PKCS1_PADDING) <= 0)
|
||||||
|
throw std::runtime_error("Failed to set RSA_PKCS1_PADDING");
|
||||||
|
|
||||||
|
std::vector<std::uint8_t> cipher(EVP_PKEY_size(evpPublicKey));
|
||||||
|
std::size_t cipherLength;
|
||||||
|
EVP_PKEY_encrypt(
|
||||||
|
evpContext.get(),
|
||||||
|
cipher.data(),
|
||||||
|
&cipherLength,
|
||||||
|
this,
|
||||||
|
sizeof(*this)
|
||||||
|
);
|
||||||
|
cipher.resize(cipherLength);
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Unsupported security mode.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
namespace drp::util {
|
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Value, int limit, class Comparator = std::less<Value>>
|
|
||||||
class CacheMap : std::map<Key, Value> {
|
|
||||||
public:
|
|
||||||
void cache() {
|
|
||||||
// check if the limit have been reached.
|
|
||||||
if (this->size() <= limit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// apply the comparator on all the value to find the minimum.
|
|
||||||
auto minimum = this->begin();
|
|
||||||
for (const auto& it : this)
|
|
||||||
if (Comparator()(it.second, minimum))
|
|
||||||
minimum = it;
|
|
||||||
|
|
||||||
// delete this lowest value.
|
|
||||||
this->erase(minimum);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value& operator[](const Key& key) {
|
|
||||||
const auto& value = std::map<Key, Value>::operator[](key);
|
|
||||||
this->cache();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue