mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Restructured p2p message signing keys.
This commit is contained in:
@@ -154,7 +154,6 @@ p2p::proposal create_stage0_proposal()
|
||||
// The proposal we are going to emit in stage 0.
|
||||
p2p::proposal stg_prop;
|
||||
stg_prop.time = ctx.time_now;
|
||||
stg_prop.timestamp = ctx.time_now;
|
||||
ctx.novel_proposal_time = ctx.time_now;
|
||||
stg_prop.stage = 0;
|
||||
stg_prop.lcl = ctx.lcl;
|
||||
@@ -200,7 +199,6 @@ p2p::proposal create_stage123_proposal(vote_counter &votes)
|
||||
{
|
||||
// The proposal to be emited at the end of this stage.
|
||||
p2p::proposal stg_prop;
|
||||
stg_prop.timestamp = ctx.time_now;
|
||||
stg_prop.stage = ctx.stage;
|
||||
|
||||
// we always vote for our current lcl regardless of what other peers are saying
|
||||
|
||||
@@ -6,8 +6,10 @@ include "message_content.fbs";
|
||||
namespace p2p;
|
||||
|
||||
table Container { //root type for message
|
||||
version: uint16;
|
||||
signature:[ubyte];
|
||||
version:uint16;
|
||||
timestamp:uint64;
|
||||
pubkey:[ubyte];
|
||||
signature:[ubyte]; // signature of the message content
|
||||
content:[ubyte]; // message content: byte array of proposal,npl,etc
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,10 @@ struct Container;
|
||||
struct Container FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_VERSION = 4,
|
||||
VT_SIGNATURE = 6,
|
||||
VT_CONTENT = 8
|
||||
VT_TIMESTAMP = 6,
|
||||
VT_PUBKEY = 8,
|
||||
VT_SIGNATURE = 10,
|
||||
VT_CONTENT = 12
|
||||
};
|
||||
uint16_t version() const {
|
||||
return GetField<uint16_t>(VT_VERSION, 0);
|
||||
@@ -24,6 +26,18 @@ struct Container FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
bool mutate_version(uint16_t _version) {
|
||||
return SetField<uint16_t>(VT_VERSION, _version, 0);
|
||||
}
|
||||
uint64_t timestamp() const {
|
||||
return GetField<uint64_t>(VT_TIMESTAMP, 0);
|
||||
}
|
||||
bool mutate_timestamp(uint64_t _timestamp) {
|
||||
return SetField<uint64_t>(VT_TIMESTAMP, _timestamp, 0);
|
||||
}
|
||||
const flatbuffers::Vector<uint8_t> *pubkey() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_PUBKEY);
|
||||
}
|
||||
flatbuffers::Vector<uint8_t> *mutable_pubkey() {
|
||||
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_PUBKEY);
|
||||
}
|
||||
const flatbuffers::Vector<uint8_t> *signature() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_SIGNATURE);
|
||||
}
|
||||
@@ -39,6 +53,9 @@ struct Container FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<uint16_t>(verifier, VT_VERSION) &&
|
||||
VerifyField<uint64_t>(verifier, VT_TIMESTAMP) &&
|
||||
VerifyOffset(verifier, VT_PUBKEY) &&
|
||||
verifier.VerifyVector(pubkey()) &&
|
||||
VerifyOffset(verifier, VT_SIGNATURE) &&
|
||||
verifier.VerifyVector(signature()) &&
|
||||
VerifyOffset(verifier, VT_CONTENT) &&
|
||||
@@ -53,6 +70,12 @@ struct ContainerBuilder {
|
||||
void add_version(uint16_t version) {
|
||||
fbb_.AddElement<uint16_t>(Container::VT_VERSION, version, 0);
|
||||
}
|
||||
void add_timestamp(uint64_t timestamp) {
|
||||
fbb_.AddElement<uint64_t>(Container::VT_TIMESTAMP, timestamp, 0);
|
||||
}
|
||||
void add_pubkey(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pubkey) {
|
||||
fbb_.AddOffset(Container::VT_PUBKEY, pubkey);
|
||||
}
|
||||
void add_signature(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> signature) {
|
||||
fbb_.AddOffset(Container::VT_SIGNATURE, signature);
|
||||
}
|
||||
@@ -74,11 +97,15 @@ struct ContainerBuilder {
|
||||
inline flatbuffers::Offset<Container> CreateContainer(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint16_t version = 0,
|
||||
uint64_t timestamp = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pubkey = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> signature = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> content = 0) {
|
||||
ContainerBuilder builder_(_fbb);
|
||||
builder_.add_timestamp(timestamp);
|
||||
builder_.add_content(content);
|
||||
builder_.add_signature(signature);
|
||||
builder_.add_pubkey(pubkey);
|
||||
builder_.add_version(version);
|
||||
return builder_.Finish();
|
||||
}
|
||||
@@ -86,13 +113,18 @@ inline flatbuffers::Offset<Container> CreateContainer(
|
||||
inline flatbuffers::Offset<Container> CreateContainerDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint16_t version = 0,
|
||||
uint64_t timestamp = 0,
|
||||
const std::vector<uint8_t> *pubkey = nullptr,
|
||||
const std::vector<uint8_t> *signature = nullptr,
|
||||
const std::vector<uint8_t> *content = nullptr) {
|
||||
auto pubkey__ = pubkey ? _fbb.CreateVector<uint8_t>(*pubkey) : 0;
|
||||
auto signature__ = signature ? _fbb.CreateVector<uint8_t>(*signature) : 0;
|
||||
auto content__ = content ? _fbb.CreateVector<uint8_t>(*content) : 0;
|
||||
return p2p::CreateContainer(
|
||||
_fbb,
|
||||
version,
|
||||
timestamp,
|
||||
pubkey__,
|
||||
signature__,
|
||||
content__);
|
||||
}
|
||||
|
||||
@@ -27,15 +27,13 @@ table Content {
|
||||
}
|
||||
|
||||
table Proposal_Message { //Proposal type message schema
|
||||
pubkey:[ubyte];
|
||||
timestamp:uint64;
|
||||
stage: int8;
|
||||
time:uint64;
|
||||
lcl:[ubyte];
|
||||
users: [ByteArray];
|
||||
raw_inputs: [RawInputList]; //stage 0 inputs (hash and raw value)
|
||||
hash_inputs:[ByteArray]; //stage > 0 inputs (hash of stage 0 inputs)
|
||||
raw_outputs: [RawOutput]; //stage 0 outputs (hash and raw value)
|
||||
raw_outputs: [RawOutput]; //stage 0 outputs (hash and raw value)
|
||||
hash_outputs:[ByteArray]; //stage > 0 outputs (hash of stage 0 outputs)
|
||||
state: State;
|
||||
}
|
||||
|
||||
@@ -411,30 +411,16 @@ inline flatbuffers::Offset<Content> CreateContent(
|
||||
|
||||
struct Proposal_Message FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_PUBKEY = 4,
|
||||
VT_TIMESTAMP = 6,
|
||||
VT_STAGE = 8,
|
||||
VT_TIME = 10,
|
||||
VT_LCL = 12,
|
||||
VT_USERS = 14,
|
||||
VT_RAW_INPUTS = 16,
|
||||
VT_HASH_INPUTS = 18,
|
||||
VT_RAW_OUTPUTS = 20,
|
||||
VT_HASH_OUTPUTS = 22,
|
||||
VT_STATE = 24
|
||||
VT_STAGE = 4,
|
||||
VT_TIME = 6,
|
||||
VT_LCL = 8,
|
||||
VT_USERS = 10,
|
||||
VT_RAW_INPUTS = 12,
|
||||
VT_HASH_INPUTS = 14,
|
||||
VT_RAW_OUTPUTS = 16,
|
||||
VT_HASH_OUTPUTS = 18,
|
||||
VT_STATE = 20
|
||||
};
|
||||
const flatbuffers::Vector<uint8_t> *pubkey() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_PUBKEY);
|
||||
}
|
||||
flatbuffers::Vector<uint8_t> *mutable_pubkey() {
|
||||
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_PUBKEY);
|
||||
}
|
||||
uint64_t timestamp() const {
|
||||
return GetField<uint64_t>(VT_TIMESTAMP, 0);
|
||||
}
|
||||
bool mutate_timestamp(uint64_t _timestamp) {
|
||||
return SetField<uint64_t>(VT_TIMESTAMP, _timestamp, 0);
|
||||
}
|
||||
int8_t stage() const {
|
||||
return GetField<int8_t>(VT_STAGE, 0);
|
||||
}
|
||||
@@ -491,9 +477,6 @@ struct Proposal_Message FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyOffset(verifier, VT_PUBKEY) &&
|
||||
verifier.VerifyVector(pubkey()) &&
|
||||
VerifyField<uint64_t>(verifier, VT_TIMESTAMP) &&
|
||||
VerifyField<int8_t>(verifier, VT_STAGE) &&
|
||||
VerifyField<uint64_t>(verifier, VT_TIME) &&
|
||||
VerifyOffset(verifier, VT_LCL) &&
|
||||
@@ -522,12 +505,6 @@ struct Proposal_Message FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct Proposal_MessageBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_pubkey(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pubkey) {
|
||||
fbb_.AddOffset(Proposal_Message::VT_PUBKEY, pubkey);
|
||||
}
|
||||
void add_timestamp(uint64_t timestamp) {
|
||||
fbb_.AddElement<uint64_t>(Proposal_Message::VT_TIMESTAMP, timestamp, 0);
|
||||
}
|
||||
void add_stage(int8_t stage) {
|
||||
fbb_.AddElement<int8_t>(Proposal_Message::VT_STAGE, stage, 0);
|
||||
}
|
||||
@@ -569,8 +546,6 @@ struct Proposal_MessageBuilder {
|
||||
|
||||
inline flatbuffers::Offset<Proposal_Message> CreateProposal_Message(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pubkey = 0,
|
||||
uint64_t timestamp = 0,
|
||||
int8_t stage = 0,
|
||||
uint64_t time = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> lcl = 0,
|
||||
@@ -582,7 +557,6 @@ inline flatbuffers::Offset<Proposal_Message> CreateProposal_Message(
|
||||
flatbuffers::Offset<State> state = 0) {
|
||||
Proposal_MessageBuilder builder_(_fbb);
|
||||
builder_.add_time(time);
|
||||
builder_.add_timestamp(timestamp);
|
||||
builder_.add_state(state);
|
||||
builder_.add_hash_outputs(hash_outputs);
|
||||
builder_.add_raw_outputs(raw_outputs);
|
||||
@@ -590,15 +564,12 @@ inline flatbuffers::Offset<Proposal_Message> CreateProposal_Message(
|
||||
builder_.add_raw_inputs(raw_inputs);
|
||||
builder_.add_users(users);
|
||||
builder_.add_lcl(lcl);
|
||||
builder_.add_pubkey(pubkey);
|
||||
builder_.add_stage(stage);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Proposal_Message> CreateProposal_MessageDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const std::vector<uint8_t> *pubkey = nullptr,
|
||||
uint64_t timestamp = 0,
|
||||
int8_t stage = 0,
|
||||
uint64_t time = 0,
|
||||
const std::vector<uint8_t> *lcl = nullptr,
|
||||
@@ -608,7 +579,6 @@ inline flatbuffers::Offset<Proposal_Message> CreateProposal_MessageDirect(
|
||||
const std::vector<flatbuffers::Offset<RawOutput>> *raw_outputs = nullptr,
|
||||
const std::vector<flatbuffers::Offset<ByteArray>> *hash_outputs = nullptr,
|
||||
flatbuffers::Offset<State> state = 0) {
|
||||
auto pubkey__ = pubkey ? _fbb.CreateVector<uint8_t>(*pubkey) : 0;
|
||||
auto lcl__ = lcl ? _fbb.CreateVector<uint8_t>(*lcl) : 0;
|
||||
auto users__ = users ? _fbb.CreateVector<flatbuffers::Offset<ByteArray>>(*users) : 0;
|
||||
auto raw_inputs__ = raw_inputs ? _fbb.CreateVector<flatbuffers::Offset<RawInputList>>(*raw_inputs) : 0;
|
||||
@@ -617,8 +587,6 @@ inline flatbuffers::Offset<Proposal_Message> CreateProposal_MessageDirect(
|
||||
auto hash_outputs__ = hash_outputs ? _fbb.CreateVector<flatbuffers::Offset<ByteArray>>(*hash_outputs) : 0;
|
||||
return p2p::CreateProposal_Message(
|
||||
_fbb,
|
||||
pubkey__,
|
||||
timestamp,
|
||||
stage,
|
||||
time,
|
||||
lcl__,
|
||||
|
||||
@@ -48,26 +48,87 @@ int validate_and_extract_container(const Container **container_ref, std::string_
|
||||
//Verify container message using flatbuffer verifier
|
||||
if (!VerifyContainerBuffer(container_verifier))
|
||||
{
|
||||
LOG_DBG << "Flatbuffer verify: Bad container.";
|
||||
LOG_DBG << "Flatbuffer verify: Bad peer message container.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Get message container
|
||||
const Container *container = GetContainer(container_buf_ptr);
|
||||
|
||||
//Validation are prioritzed base on expensiveness of validation.
|
||||
//i.e - signature validation is done at the end.
|
||||
|
||||
//check protocol version of message whether it is greater than minimum supported protocol version.
|
||||
const uint16_t version = container->version();
|
||||
if (version < util::MIN_PEERMSG_VERSION)
|
||||
{
|
||||
LOG_DBG << "Recieved message is from unsupported protocol version (" << version << ")";
|
||||
LOG_DBG << "Peer message is from unsupported protocol version (" << version << ").";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t time_now = util::get_epoch_milliseconds();
|
||||
|
||||
//check message timestamp.
|
||||
if (container->timestamp() < (time_now - conf::cfg.roundtime * 4))
|
||||
{
|
||||
LOG_DBG << "Peer message is too old.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// After signature is verified, get message hash and see wheteher
|
||||
// message is already recieved -> abandon if duplicate.
|
||||
// auto messageHash = crypto::sha_512_hash(message, "PEERMSG", 7);
|
||||
|
||||
// if (recent_peer_msghash.count(messageHash) == 0)
|
||||
// {
|
||||
// recent_peer_msghash.try_emplace(std::move(messageHash), timestamp);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LOG_DBG << "Duplicate message";
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
//Assign container and content out params.
|
||||
*container_ref = container;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the container message signing keys to see if the message is from a trusted source (UNL).
|
||||
* @return 0 on successful verification. -1 for failure.
|
||||
*/
|
||||
int validate_container_trust(const Container *container)
|
||||
{
|
||||
std::string_view msg_pubkey = flatbuff_bytes_to_sv(container->pubkey());
|
||||
std::string_view msg_sig = flatbuff_bytes_to_sv(container->signature());
|
||||
|
||||
if (msg_pubkey.empty() || msg_sig.empty())
|
||||
{
|
||||
LOG_DBG << "Peer message key pair incomplete. Trust verification failed.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//validate if the message is not from a node of current node's unl list.
|
||||
if (!conf::cfg.unl.count(std::string(msg_pubkey)))
|
||||
{
|
||||
LOG_DBG << "Peer message pubkey verification failed. Not in UNL.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//verify message signature.
|
||||
//this is performed towards end since this is bit expensive
|
||||
std::string_view msg_content = flatbuff_bytes_to_sv(container->content());
|
||||
|
||||
if (crypto::verify(msg_content, msg_sig, msg_pubkey) != 0)
|
||||
{
|
||||
LOG_DBG << "Peer message signature verification failed.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the Content message structure and outputs faltbuffer Content pointer to access the given buffer.
|
||||
*
|
||||
@@ -94,81 +155,17 @@ int validate_and_extract_content(const Content **content_ref, const uint8_t *con
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the incoming p2p message content on several criteria.
|
||||
*
|
||||
* @param message Message content data buffer.
|
||||
* @param signature Binary message signature.
|
||||
* @param pubkey Binary public key of message originating node.
|
||||
* @param timestamp Message timestamp.
|
||||
* @param version Message protocol version.
|
||||
* @return 0 on successful validation. -1 for failure.
|
||||
*/
|
||||
int validate_content_message(std::string_view message, std::string_view signature, std::string_view pubkey, int64_t timestamp)
|
||||
{
|
||||
//Validation are prioritzed base on expensiveness of validation.
|
||||
//i.e - signature validation is done at the end.
|
||||
|
||||
int64_t time_now = util::get_epoch_milliseconds();
|
||||
|
||||
// validate if the message is not from a node of current node's unl list.
|
||||
if (!conf::cfg.unl.count(pubkey.data()))
|
||||
{
|
||||
LOG_DBG << "pubkey verification failed";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check message timestamp. < timestamp now - 4* round time.
|
||||
/*todo:this might change to check only current stage related. (Base on how consensus algorithm implementation take shape)
|
||||
check message stage is for valid stage(node's current consensus stage - 1)
|
||||
*/
|
||||
if (timestamp < (time_now - conf::cfg.roundtime * 4))
|
||||
{
|
||||
LOG_DBG << "Recieved message from peer is old";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//verify message signature.
|
||||
//this should be the last validation since this is bit expensive
|
||||
auto signature_verified = crypto::verify(message, signature, pubkey);
|
||||
|
||||
if (signature_verified != 0)
|
||||
{
|
||||
LOG_DBG << "Signature verification failed";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// After signature is verified, get message hash and see wheteher
|
||||
// message is already recieved -> abandon if duplicate.
|
||||
// auto messageHash = crypto::sha_512_hash(message, "PEERMSG", 7);
|
||||
|
||||
// if (recent_peer_msghash.count(messageHash) == 0)
|
||||
// {
|
||||
// recent_peer_msghash.try_emplace(std::move(messageHash), timestamp);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LOG_DBG << "Duplicate message";
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a proposal stuct from the given proposal message.
|
||||
* @param The Flatbuffer poporal received from the peer.
|
||||
* @return A proposal struct representing the message.
|
||||
*/
|
||||
const proposal create_proposal_from_msg(const Proposal_Message &msg)
|
||||
const proposal create_proposal_from_msg(const Proposal_Message &msg, const flatbuffers::Vector<uint8_t> *pubkey)
|
||||
{
|
||||
proposal p;
|
||||
|
||||
if (msg.pubkey())
|
||||
p.pubkey = flatbuff_bytes_to_sv(msg.pubkey());
|
||||
|
||||
p.pubkey = flatbuff_bytes_to_sv(pubkey);
|
||||
p.time = msg.time();
|
||||
p.timestamp = msg.timestamp();
|
||||
p.stage = msg.stage();
|
||||
|
||||
if (msg.lcl())
|
||||
@@ -208,8 +205,6 @@ void create_msg_from_proposal(flatbuffers::FlatBufferBuilder &container_builder,
|
||||
flatbuffers::Offset<Proposal_Message> proposal =
|
||||
CreateProposal_Message(
|
||||
builder,
|
||||
sv_to_flatbuff_bytes(builder, conf::cfg.pubkey),
|
||||
p.timestamp,
|
||||
p.stage,
|
||||
p.time,
|
||||
sv_to_flatbuff_bytes(builder, p.lcl),
|
||||
@@ -224,7 +219,7 @@ void create_msg_from_proposal(flatbuffers::FlatBufferBuilder &container_builder,
|
||||
|
||||
// Now that we have built the content message,
|
||||
// we need to sign it and place it inside a container message.
|
||||
create_containermsg_from_content(container_builder, builder);
|
||||
create_containermsg_from_content(container_builder, builder, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,9 +227,10 @@ void create_msg_from_proposal(flatbuffers::FlatBufferBuilder &container_builder,
|
||||
* @param container_builder The Flatbuffer builder to which the final container message should be written to.
|
||||
* @param content_builder The Flatbuffer builder containing the content message that should be placed
|
||||
* inside the container message.
|
||||
* @param sign Whether to sign the message content.
|
||||
*/
|
||||
void create_containermsg_from_content(
|
||||
flatbuffers::FlatBufferBuilder &container_builder, const flatbuffers::FlatBufferBuilder &content_builder)
|
||||
flatbuffers::FlatBufferBuilder &container_builder, const flatbuffers::FlatBufferBuilder &content_builder, bool sign)
|
||||
{
|
||||
uint8_t *content_buf = content_builder.GetBufferPointer();
|
||||
flatbuffers::uoffset_t content_size = content_builder.GetSize();
|
||||
@@ -242,14 +238,24 @@ void create_containermsg_from_content(
|
||||
// Create container message content from serialised content from previous step.
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> content = container_builder.CreateVector(content_buf, content_size);
|
||||
|
||||
// Sign message content with this node's private key.
|
||||
std::string_view content_to_sign(reinterpret_cast<const char *>(content_buf), content_size);
|
||||
std::string sig = crypto::sign(content_to_sign, conf::cfg.seckey);
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pubkey_offset = 0;
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> sig_offset = 0;
|
||||
|
||||
if (sign)
|
||||
{
|
||||
// Sign message content with this node's private key.
|
||||
std::string_view content_to_sign(reinterpret_cast<const char *>(content_buf), content_size);
|
||||
|
||||
sig_offset = sv_to_flatbuff_bytes(container_builder, crypto::sign(content_to_sign, conf::cfg.seckey));
|
||||
pubkey_offset = sv_to_flatbuff_bytes(container_builder, conf::cfg.pubkey);
|
||||
}
|
||||
|
||||
flatbuffers::Offset<Container> container_message = CreateContainer(
|
||||
container_builder,
|
||||
util::PEERMSG_VERSION,
|
||||
sv_to_flatbuff_bytes(container_builder, sig), //signature field
|
||||
util::get_epoch_milliseconds(),
|
||||
pubkey_offset,
|
||||
sig_offset,
|
||||
content);
|
||||
|
||||
// Finish building message container to get serialised message.
|
||||
|
||||
@@ -17,18 +17,18 @@ namespace p2p
|
||||
|
||||
int validate_and_extract_container(const Container **container_ref, std::string_view container_buf);
|
||||
|
||||
int validate_container_trust(const Container *container);
|
||||
|
||||
int validate_and_extract_content(const Content **content_ref, const uint8_t *content_ptr, flatbuffers::uoffset_t content_size);
|
||||
|
||||
int validate_content_message(std::string_view message, std::string_view signature, std::string_view pubkey, int64_t timestamp);
|
||||
|
||||
const proposal create_proposal_from_msg(const Proposal_Message &msg);
|
||||
const proposal create_proposal_from_msg(const Proposal_Message &msg, const flatbuffers::Vector<uint8_t> *pubkey);
|
||||
|
||||
//---Message creation helpers---//
|
||||
|
||||
void create_msg_from_proposal(flatbuffers::FlatBufferBuilder &container_builder, const proposal &p);
|
||||
|
||||
void create_containermsg_from_content(
|
||||
flatbuffers::FlatBufferBuilder &container_builder, const flatbuffers::FlatBufferBuilder &content_builder);
|
||||
flatbuffers::FlatBufferBuilder &container_builder, const flatbuffers::FlatBufferBuilder &content_builder, bool sign);
|
||||
|
||||
//---Conversion helpers from flatbuffers data types to std data types---//
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace p2p
|
||||
{
|
||||
|
||||
|
||||
peer_outbound_message::peer_outbound_message(
|
||||
std::shared_ptr<flatbuffers::FlatBufferBuilder> _fbbuilder_ptr)
|
||||
{
|
||||
@@ -82,24 +82,17 @@ void peer_session_handler::on_message(sock::socket_session<peer_outbound_message
|
||||
|
||||
if (content_message_type == Message_Proposal_Message) //message is a proposal message
|
||||
{
|
||||
const Proposal_Message *proposalmsg = content->message_as_Proposal_Message();
|
||||
|
||||
//validate message for malleability, timeliness, signature and prune recieving messages.
|
||||
bool val_result = validate_content_message(
|
||||
flatbuff_bytes_to_sv(content_ptr, content_size),
|
||||
flatbuff_bytes_to_sv(container->signature()),
|
||||
flatbuff_bytes_to_sv(proposalmsg->pubkey()),
|
||||
proposalmsg->timestamp());
|
||||
// We only trust proposals coming from trusted peers.
|
||||
if (validate_container_trust(container) != 0)
|
||||
{
|
||||
LOG_DBG << "Proposal rejected due to trust failure.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (val_result == 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(collected_msgs.proposals_mutex);
|
||||
collected_msgs.proposals.push_back(create_proposal_from_msg(*proposalmsg));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DBG << "Message content field validation failed";
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(collected_msgs.proposals_mutex); // Insert proposal with lock.
|
||||
|
||||
collected_msgs.proposals.push_back(
|
||||
create_proposal_from_msg(*content->message_as_Proposal_Message(), container->pubkey()));
|
||||
}
|
||||
else if (content_message_type == Message_Npl_Message) //message is a NPL message
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user