Ref T730, namespace for BlackCore::Afv

* added namespace
* removed some *.pri files and added files to blackcore.pro
* added copyright etc.
This commit is contained in:
Klaus Basan
2019-09-19 00:56:54 +02:00
committed by Mat Sutcliffe
parent d064da13b5
commit 384aa3ce19
46 changed files with 2985 additions and 2916 deletions

View File

@@ -1,128 +1,146 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include "cryptodtochannel.h"
CryptoDtoChannel::CryptoDtoChannel(QString channelTag, const QByteArray &aeadReceiveKey, const QByteArray &aeadTransmitKey, int receiveSequenceHistorySize)
namespace BlackCore
{
ChannelTag = channelTag;
m_aeadReceiveKey = aeadReceiveKey;
m_aeadTransmitKey = aeadTransmitKey;
receiveSequenceSizeMaxSize = receiveSequenceHistorySize;
if (receiveSequenceSizeMaxSize < 1)
receiveSequenceSizeMaxSize = 1;
receiveSequenceHistory = new uint[receiveSequenceSizeMaxSize];
receiveSequenceHistoryDepth = 0;
}
CryptoDtoChannel::CryptoDtoChannel(CryptoDtoChannelConfigDto channelConfig, int receiveSequenceHistorySize)
{
ChannelTag = channelConfig.channelTag;
m_aeadReceiveKey = channelConfig.aeadReceiveKey;
m_aeadTransmitKey = channelConfig.aeadTransmitKey;
hmacKey = channelConfig.hmacKey;
receiveSequenceSizeMaxSize = receiveSequenceHistorySize;
if (receiveSequenceSizeMaxSize < 1)
receiveSequenceSizeMaxSize = 1;
receiveSequenceHistory = new uint[receiveSequenceSizeMaxSize];
receiveSequenceHistoryDepth = 0;
}
QByteArray CryptoDtoChannel::getTransmitKey(CryptoDtoMode mode)
{
switch (mode)
namespace Afv
{
case CryptoDtoMode::AEAD_ChaCha20Poly1305: return m_aeadTransmitKey;
case CryptoDtoMode::Undefined:
case CryptoDtoMode::None:
qFatal("GetTransmitKey called with wrong argument.");
}
return {};
}
QByteArray CryptoDtoChannel::getTransmitKey(CryptoDtoMode mode, uint &sequenceToSend)
{
sequenceToSend = transmitSequence;
transmitSequence++;
LastTransmitUtc = QDateTime::currentDateTimeUtc();
switch (mode)
{
case CryptoDtoMode::AEAD_ChaCha20Poly1305: return m_aeadTransmitKey;
case CryptoDtoMode::Undefined:
case CryptoDtoMode::None:
qFatal("GetTransmitKey called with wrong argument.");
}
return {};
}
QString CryptoDtoChannel::getChannelTag() const
{
return ChannelTag;
}
QByteArray CryptoDtoChannel::getReceiveKey(CryptoDtoMode mode)
{
switch (mode)
{
case CryptoDtoMode::AEAD_ChaCha20Poly1305: return m_aeadReceiveKey;
case CryptoDtoMode::Undefined:
case CryptoDtoMode::None:
qFatal("getReceiveKey called with wrong argument.");
}
return {};
}
bool CryptoDtoChannel::checkReceivedSequence(uint sequenceReceived)
{
if (contains(sequenceReceived))
{
// Duplication or replay attack
return false;
}
if (receiveSequenceHistoryDepth < receiveSequenceSizeMaxSize) //If the buffer has been filled...
{
receiveSequenceHistory[receiveSequenceHistoryDepth++] = sequenceReceived;
}
else
{
int minIndex;
uint minValue = getMin(minIndex);
if (sequenceReceived < minValue) { return false; } // Possible replay attack
receiveSequenceHistory[minIndex] = sequenceReceived;
}
LastReceiveUtc = QDateTime::currentDateTimeUtc();
return true;
}
bool CryptoDtoChannel::contains(uint sequence)
{
for (int i = 0; i < receiveSequenceHistoryDepth; i++)
{
if (receiveSequenceHistory[i] == sequence)
return true;
}
return false;
}
uint CryptoDtoChannel::getMin(int &minIndex)
{
uint minValue = std::numeric_limits<uint>::max();
minIndex = -1;
int index = -1;
for (int i = 0; i < receiveSequenceHistoryDepth; i++)
{
index++;
if (receiveSequenceHistory[i] <= minValue)
namespace Crypto
{
minValue = receiveSequenceHistory[i];
minIndex = index;
}
}
return minValue;
}
CryptoDtoChannel::CryptoDtoChannel(QString channelTag, const QByteArray &aeadReceiveKey, const QByteArray &aeadTransmitKey, int receiveSequenceHistorySize)
{
ChannelTag = channelTag;
m_aeadReceiveKey = aeadReceiveKey;
m_aeadTransmitKey = aeadTransmitKey;
receiveSequenceSizeMaxSize = receiveSequenceHistorySize;
if (receiveSequenceSizeMaxSize < 1)
receiveSequenceSizeMaxSize = 1;
receiveSequenceHistory = new uint[receiveSequenceSizeMaxSize];
receiveSequenceHistoryDepth = 0;
}
CryptoDtoChannel::CryptoDtoChannel(CryptoDtoChannelConfigDto channelConfig, int receiveSequenceHistorySize)
{
ChannelTag = channelConfig.channelTag;
m_aeadReceiveKey = channelConfig.aeadReceiveKey;
m_aeadTransmitKey = channelConfig.aeadTransmitKey;
hmacKey = channelConfig.hmacKey;
receiveSequenceSizeMaxSize = receiveSequenceHistorySize;
if (receiveSequenceSizeMaxSize < 1)
receiveSequenceSizeMaxSize = 1;
receiveSequenceHistory = new uint[receiveSequenceSizeMaxSize];
receiveSequenceHistoryDepth = 0;
}
QByteArray CryptoDtoChannel::getTransmitKey(CryptoDtoMode mode)
{
switch (mode)
{
case CryptoDtoMode::AEAD_ChaCha20Poly1305: return m_aeadTransmitKey;
case CryptoDtoMode::Undefined:
case CryptoDtoMode::None:
qFatal("GetTransmitKey called with wrong argument.");
}
return {};
}
QByteArray CryptoDtoChannel::getTransmitKey(CryptoDtoMode mode, uint &sequenceToSend)
{
sequenceToSend = transmitSequence;
transmitSequence++;
LastTransmitUtc = QDateTime::currentDateTimeUtc();
switch (mode)
{
case CryptoDtoMode::AEAD_ChaCha20Poly1305: return m_aeadTransmitKey;
case CryptoDtoMode::Undefined:
case CryptoDtoMode::None:
qFatal("GetTransmitKey called with wrong argument.");
}
return {};
}
QString CryptoDtoChannel::getChannelTag() const
{
return ChannelTag;
}
QByteArray CryptoDtoChannel::getReceiveKey(CryptoDtoMode mode)
{
switch (mode)
{
case CryptoDtoMode::AEAD_ChaCha20Poly1305: return m_aeadReceiveKey;
case CryptoDtoMode::Undefined:
case CryptoDtoMode::None:
qFatal("getReceiveKey called with wrong argument.");
}
return {};
}
bool CryptoDtoChannel::checkReceivedSequence(uint sequenceReceived)
{
if (contains(sequenceReceived))
{
// Duplication or replay attack
return false;
}
if (receiveSequenceHistoryDepth < receiveSequenceSizeMaxSize) //If the buffer has been filled...
{
receiveSequenceHistory[receiveSequenceHistoryDepth++] = sequenceReceived;
}
else
{
int minIndex;
uint minValue = getMin(minIndex);
if (sequenceReceived < minValue) { return false; } // Possible replay attack
receiveSequenceHistory[minIndex] = sequenceReceived;
}
LastReceiveUtc = QDateTime::currentDateTimeUtc();
return true;
}
bool CryptoDtoChannel::contains(uint sequence)
{
for (int i = 0; i < receiveSequenceHistoryDepth; i++)
{
if (receiveSequenceHistory[i] == sequence)
return true;
}
return false;
}
uint CryptoDtoChannel::getMin(int &minIndex)
{
uint minValue = std::numeric_limits<uint>::max();
minIndex = -1;
int index = -1;
for (int i = 0; i < receiveSequenceHistoryDepth; i++)
{
index++;
if (receiveSequenceHistory[i] <= minValue)
{
minValue = receiveSequenceHistory[i];
minIndex = index;
}
}
return minValue;
}
} // ns
} // ns
} // ns

View File

@@ -1,5 +1,15 @@
#ifndef CRYPTODTOCHANNEL_H
#define CRYPTODTOCHANNEL_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKCORE_AFV_CRYPTO_CRYPTODTOCHANNEL_H
#define BLACKCORE_AFV_CRYPTO_CRYPTODTOCHANNEL_H
#include "blackcore/afv/dto.h"
#include "cryptodtomode.h"
@@ -9,39 +19,51 @@
#include <limits>
class CryptoDtoChannel
namespace BlackCore
{
public:
namespace Afv
{
namespace Crypto
{
//! Crypto channel
class CryptoDtoChannel
{
public:
//! Ctor
CryptoDtoChannel(QString channelTag, const QByteArray &aeadReceiveKey, const QByteArray &aeadTransmitKey, int receiveSequenceHistorySize = 10);
CryptoDtoChannel(QString channelTag, const QByteArray &aeadReceiveKey, const QByteArray &aeadTransmitKey, int receiveSequenceHistorySize = 10);
CryptoDtoChannel(CryptoDtoChannelConfigDto channelConfig, int receiveSequenceHistorySize = 10);
//! Ctor
CryptoDtoChannel(CryptoDtoChannelConfigDto channelConfig, int receiveSequenceHistorySize = 10);
QByteArray getTransmitKey(CryptoDtoMode mode);
QByteArray getTransmitKey(CryptoDtoMode mode, uint &sequenceToSend);
QString getChannelTag() const;
QByteArray getReceiveKey(CryptoDtoMode mode);
QByteArray getTransmitKey(CryptoDtoMode mode);
QByteArray getTransmitKey(CryptoDtoMode mode, uint &sequenceToSend);
QString getChannelTag() const;
QByteArray getReceiveKey(CryptoDtoMode mode);
bool checkReceivedSequence(uint sequenceReceived);
bool checkReceivedSequence(uint sequenceReceived);
private:
bool contains(uint sequence);
uint getMin(int &minIndex);
private:
bool contains(uint sequence);
uint getMin(int &minIndex);
QByteArray m_aeadTransmitKey;
uint transmitSequence = 0;
QByteArray m_aeadTransmitKey;
uint transmitSequence = 0;
QByteArray m_aeadReceiveKey;
QByteArray m_aeadReceiveKey;
uint *receiveSequenceHistory;
int receiveSequenceHistoryDepth;
int receiveSequenceSizeMaxSize;
uint *receiveSequenceHistory;
int receiveSequenceHistoryDepth;
int receiveSequenceSizeMaxSize;
QByteArray hmacKey;
QByteArray hmacKey;
QString ChannelTag;
QDateTime LastTransmitUtc;
QDateTime LastReceiveUtc;
};
QString ChannelTag;
QDateTime LastTransmitUtc;
QDateTime LastReceiveUtc;
};
} // ns
} // ns
} // ns
#endif // CRYPTODTOCHANNEL_H
#endif // guard

View File

@@ -1,17 +1,37 @@
#ifndef CRYPTODTOHEADERDTO_H
#define CRYPTODTOHEADERDTO_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKCORE_AFV_CRYPTO_CRYPTODTOHEADERDTO_H
#define BLACKCORE_AFV_CRYPTO_CRYPTODTOHEADERDTO_H
#include "cryptodtomode.h"
#include "msgpack.hpp"
#include <QString>
#include <cstdint>
struct CryptoDtoHeaderDto
namespace BlackCore
{
std::string ChannelTag;
uint64_t Sequence;
CryptoDtoMode Mode;
MSGPACK_DEFINE(ChannelTag, Sequence, Mode)
};
namespace Afv
{
namespace Crypto
{
//! DTO header
struct CryptoDtoHeaderDto
{
std::string ChannelTag;
uint64_t Sequence;
CryptoDtoMode Mode;
MSGPACK_DEFINE(ChannelTag, Sequence, Mode)
};
} // ns
} // ns
} // ns
#endif // CRYPTODTOHEADERDTO_H
#endif // gaurd

View File

@@ -1,8 +1,19 @@
#ifndef CRYPTODTOMODE_H
#define CRYPTODTOMODE_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKCORE_AFV_CRYPTO_CRYPTODTOMODE_H
#define BLACKCORE_AFV_CRYPTO_CRYPTODTOMODE_H
#include "msgpack.hpp"
//! DTO mode
enum class CryptoDtoMode
{
Undefined = 0,
@@ -12,4 +23,4 @@ enum class CryptoDtoMode
MSGPACK_ADD_ENUM(CryptoDtoMode);
#endif // CRYPTODTOMODE_H
#endif // guard

View File

@@ -1,72 +1,87 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
#include "cryptodtoserializer.h"
CryptoDtoSerializer::CryptoDtoSerializer()
namespace BlackCore
{
}
CryptoDtoSerializer::Deserializer CryptoDtoSerializer::deserialize(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback)
{
return Deserializer(channel, bytes, loopback);
}
CryptoDtoSerializer::Deserializer::Deserializer(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback)
{
QByteArray data(bytes);
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
buffer.read((char *)&headerLength, sizeof(headerLength));
QByteArray headerBuffer = buffer.read(headerLength);
msgpack::object_handle oh = msgpack::unpack(headerBuffer.data(), headerBuffer.size());
header = oh.get().as<CryptoDtoHeaderDto>();
if(header.Mode == CryptoDtoMode::AEAD_ChaCha20Poly1305)
namespace Afv
{
int aeLength = buffer.size() - (2 + headerLength);
const QByteArray aePayloadBuffer = buffer.read(aeLength);
const QByteArray adBuffer = data.left(2 + headerLength);
QByteArray nonce;
nonce.fill(0, crypto_aead_chacha20poly1305_IETF_NPUBBYTES);
QBuffer nonceBuffer(&nonce);
nonceBuffer.open(QIODevice::WriteOnly);
uint32_t id = 0;
nonceBuffer.write(reinterpret_cast<const char *>(&id), sizeof(id));
nonceBuffer.write(reinterpret_cast<const char *>(&header.Sequence), sizeof(header.Sequence));
nonceBuffer.close();
QByteArray decryptedPayload;
unsigned long long mlen = 500;
decryptedPayload.fill(0, mlen);
QByteArray key;
if (loopback) { key = channel.getTransmitKey(CryptoDtoMode::AEAD_ChaCha20Poly1305); }
else { key = channel.getReceiveKey(CryptoDtoMode::AEAD_ChaCha20Poly1305); }
int result = crypto_aead_chacha20poly1305_ietf_decrypt(reinterpret_cast<unsigned char *>(decryptedPayload.data()), &mlen, nullptr,
reinterpret_cast<const unsigned char *>(aePayloadBuffer.constData()), aePayloadBuffer.size(),
reinterpret_cast<const unsigned char *>(adBuffer.constData()), adBuffer.size(),
reinterpret_cast<const unsigned char *>(nonce.constData()),
reinterpret_cast<const unsigned char *>(key.constData()));
if (result == 0)
namespace Crypto
{
decryptedPayload.resize(mlen);
CryptoDtoSerializer::CryptoDtoSerializer() { }
// Fix this:
// if (! channel.checkReceivedSequence(header.Sequence)) { }
CryptoDtoSerializer::Deserializer CryptoDtoSerializer::deserialize(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback)
{
return Deserializer(channel, bytes, loopback);
}
QBuffer decryptedPayloadBuffer(&decryptedPayload);
decryptedPayloadBuffer.open(QIODevice::ReadOnly);
decryptedPayloadBuffer.read((char *)&dtoNameLength, sizeof(dtoNameLength));
dtoNameBuffer = decryptedPayloadBuffer.read(dtoNameLength);
CryptoDtoSerializer::Deserializer::Deserializer(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback)
{
QByteArray data(bytes);
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
decryptedPayloadBuffer.read((char *)&dataLength, sizeof(dataLength));
dataBuffer = decryptedPayloadBuffer.read(dataLength);
verified = true;
}
}
}
buffer.read((char *)&headerLength, sizeof(headerLength));
QByteArray headerBuffer = buffer.read(headerLength);
msgpack::object_handle oh = msgpack::unpack(headerBuffer.data(), headerBuffer.size());
header = oh.get().as<CryptoDtoHeaderDto>();
if (header.Mode == CryptoDtoMode::AEAD_ChaCha20Poly1305)
{
int aeLength = buffer.size() - (2 + headerLength);
const QByteArray aePayloadBuffer = buffer.read(aeLength);
const QByteArray adBuffer = data.left(2 + headerLength);
QByteArray nonce;
nonce.fill(0, crypto_aead_chacha20poly1305_IETF_NPUBBYTES);
QBuffer nonceBuffer(&nonce);
nonceBuffer.open(QIODevice::WriteOnly);
uint32_t id = 0;
nonceBuffer.write(reinterpret_cast<const char *>(&id), sizeof(id));
nonceBuffer.write(reinterpret_cast<const char *>(&header.Sequence), sizeof(header.Sequence));
nonceBuffer.close();
QByteArray decryptedPayload;
unsigned long long mlen = 500;
decryptedPayload.fill(0, mlen);
QByteArray key;
if (loopback) { key = channel.getTransmitKey(CryptoDtoMode::AEAD_ChaCha20Poly1305); }
else { key = channel.getReceiveKey(CryptoDtoMode::AEAD_ChaCha20Poly1305); }
int result = crypto_aead_chacha20poly1305_ietf_decrypt(reinterpret_cast<unsigned char *>(decryptedPayload.data()), &mlen, nullptr,
reinterpret_cast<const unsigned char *>(aePayloadBuffer.constData()), aePayloadBuffer.size(),
reinterpret_cast<const unsigned char *>(adBuffer.constData()), adBuffer.size(),
reinterpret_cast<const unsigned char *>(nonce.constData()),
reinterpret_cast<const unsigned char *>(key.constData()));
if (result == 0)
{
decryptedPayload.resize(mlen);
// Fix this:
// if (! channel.checkReceivedSequence(header.Sequence)) { }
QBuffer decryptedPayloadBuffer(&decryptedPayload);
decryptedPayloadBuffer.open(QIODevice::ReadOnly);
decryptedPayloadBuffer.read((char *)&dtoNameLength, sizeof(dtoNameLength));
dtoNameBuffer = decryptedPayloadBuffer.read(dtoNameLength);
decryptedPayloadBuffer.read((char *)&dataLength, sizeof(dataLength));
dataBuffer = decryptedPayloadBuffer.read(dataLength);
verified = true;
}
}
}
} // ns
} // ns
} // ns

View File

@@ -1,5 +1,15 @@
#ifndef CRYPTODTOSERIALIZER_H
#define CRYPTODTOSERIALIZER_H
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKCORE_AFV_CRYPTO_CRYPTODTO_SERIALIZER_H
#define BLACKCORE_AFV_CRYPTO_CRYPTODTO_SERIALIZER_H
#include "cryptodtochannel.h"
#include "cryptodtomode.h"
@@ -10,123 +20,133 @@
#include <QBuffer>
#include <QtDebug>
extern QHash<QByteArray, QByteArray> gShortDtoNames;
class CryptoDtoSerializer
namespace BlackCore
{
public:
CryptoDtoSerializer();
template<typename T>
static QByteArray Serialize(const QString &channelTag, CryptoDtoMode mode, const QByteArray &transmitKey, uint sequenceToBeSent, T dto)
namespace Afv
{
const CryptoDtoHeaderDto header = { channelTag.toStdString(), sequenceToBeSent, mode };
QBuffer headerBuffer;
headerBuffer.open(QIODevice::WriteOnly);
msgpack::pack(headerBuffer, header);
headerBuffer.close();
const quint16 headerLength = static_cast<quint16>(headerBuffer.buffer().size());
const QByteArray dtoNameBuffer = T::getDtoName();
const QByteArray dtoShortName = T::getShortDtoName();
const quint16 dtoNameLength = static_cast<quint16>(dtoShortName.size());
QBuffer dtoBuffer;
dtoBuffer.open(QIODevice::WriteOnly);
msgpack::pack(dtoBuffer, dto);
dtoBuffer.close();
const quint16 dtoLength = static_cast<quint16>(dtoBuffer.buffer().size());
if(header.Mode == CryptoDtoMode::AEAD_ChaCha20Poly1305)
namespace Crypto
{
QBuffer aePayloadBuffer;
aePayloadBuffer.open(QIODevice::WriteOnly);
aePayloadBuffer.write(reinterpret_cast<const char *>(&dtoNameLength), sizeof(dtoNameLength));
aePayloadBuffer.write(dtoShortName);
aePayloadBuffer.write(reinterpret_cast<const char *>(&dtoLength), sizeof(dtoLength));
aePayloadBuffer.write(dtoBuffer.buffer());
aePayloadBuffer.close();
extern QHash<QByteArray, QByteArray> gShortDtoNames;
QBuffer adPayloadBuffer;
adPayloadBuffer.open(QIODevice::WriteOnly);
adPayloadBuffer.write(reinterpret_cast<const char *>(&headerLength), sizeof(headerLength));
adPayloadBuffer.write(headerBuffer.buffer());
adPayloadBuffer.close();
QByteArray nonce;
nonce.fill(0, crypto_aead_chacha20poly1305_IETF_NPUBBYTES);
QBuffer nonceBuffer(&nonce);
nonceBuffer.open(QIODevice::WriteOnly);
uint32_t id = 0;
nonceBuffer.write(reinterpret_cast<const char *>(&id), sizeof(id));
nonceBuffer.write(reinterpret_cast<const char *>(&header.Sequence), sizeof(header.Sequence));
nonceBuffer.close();
unsigned long long clen;
QByteArray aeadPayload;
aeadPayload.fill(0, static_cast<int>(aePayloadBuffer.size() + crypto_aead_chacha20poly1305_IETF_ABYTES));
int result = crypto_aead_chacha20poly1305_ietf_encrypt(reinterpret_cast<unsigned char*>(aeadPayload.data()),
&clen,
reinterpret_cast<const unsigned char*>(aePayloadBuffer.buffer().constData()), aePayloadBuffer.size(),
reinterpret_cast<const unsigned char*>(adPayloadBuffer.buffer().constData()), adPayloadBuffer.size(),
nullptr,
reinterpret_cast<const unsigned char*>(nonce.constData()),
reinterpret_cast<const unsigned char*>(transmitKey.constData()));
if (result != 0) { return {}; }
QBuffer packetBuffer;
packetBuffer.open(QIODevice::WriteOnly);
packetBuffer.write(reinterpret_cast<const char *>(&headerLength), sizeof(headerLength));
packetBuffer.write(headerBuffer.buffer());
packetBuffer.write(aeadPayload);
packetBuffer.close();
return packetBuffer.buffer();
}
return {};
}
template<typename T>
static QByteArray Serialize(CryptoDtoChannel &channel, CryptoDtoMode mode, T dto)
{
uint sequenceToSend = 0;
QByteArray transmitKey = channel.getTransmitKey(mode, sequenceToSend);
return Serialize(channel.getChannelTag(), mode, transmitKey, sequenceToSend++, dto);
}
struct Deserializer
{
Deserializer(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback);
template<typename T>
T getDto()
{
if (! verified) return {};
if (dtoNameBuffer == T::getDtoName() || dtoNameBuffer == T::getShortDtoName())
//! Crypto serializer
class CryptoDtoSerializer
{
msgpack::object_handle oh2 = msgpack::unpack(dataBuffer.data(), dataBuffer.size());
msgpack::object obj = oh2.get();
T dto = obj.as<T>();
return dto;
}
return {};
}
public:
CryptoDtoSerializer();
quint16 headerLength;
CryptoDtoHeaderDto header;
template<typename T>
static QByteArray Serialize(const QString &channelTag, CryptoDtoMode mode, const QByteArray &transmitKey, uint sequenceToBeSent, T dto)
{
const CryptoDtoHeaderDto header = { channelTag.toStdString(), sequenceToBeSent, mode };
quint16 dtoNameLength;
QByteArray dtoNameBuffer;
QBuffer headerBuffer;
headerBuffer.open(QIODevice::WriteOnly);
msgpack::pack(headerBuffer, header);
headerBuffer.close();
const quint16 headerLength = static_cast<quint16>(headerBuffer.buffer().size());
quint16 dataLength;
QByteArray dataBuffer;
const QByteArray dtoNameBuffer = T::getDtoName();
const QByteArray dtoShortName = T::getShortDtoName();
const quint16 dtoNameLength = static_cast<quint16>(dtoShortName.size());
bool verified = false;
};
QBuffer dtoBuffer;
dtoBuffer.open(QIODevice::WriteOnly);
msgpack::pack(dtoBuffer, dto);
dtoBuffer.close();
const quint16 dtoLength = static_cast<quint16>(dtoBuffer.buffer().size());
static Deserializer deserialize(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback);
};
if (header.Mode == CryptoDtoMode::AEAD_ChaCha20Poly1305)
{
QBuffer aePayloadBuffer;
aePayloadBuffer.open(QIODevice::WriteOnly);
aePayloadBuffer.write(reinterpret_cast<const char *>(&dtoNameLength), sizeof(dtoNameLength));
aePayloadBuffer.write(dtoShortName);
aePayloadBuffer.write(reinterpret_cast<const char *>(&dtoLength), sizeof(dtoLength));
aePayloadBuffer.write(dtoBuffer.buffer());
aePayloadBuffer.close();
#endif // CRYPTODTOSERIALIZER_H
QBuffer adPayloadBuffer;
adPayloadBuffer.open(QIODevice::WriteOnly);
adPayloadBuffer.write(reinterpret_cast<const char *>(&headerLength), sizeof(headerLength));
adPayloadBuffer.write(headerBuffer.buffer());
adPayloadBuffer.close();
QByteArray nonce;
nonce.fill(0, crypto_aead_chacha20poly1305_IETF_NPUBBYTES);
QBuffer nonceBuffer(&nonce);
nonceBuffer.open(QIODevice::WriteOnly);
uint32_t id = 0;
nonceBuffer.write(reinterpret_cast<const char *>(&id), sizeof(id));
nonceBuffer.write(reinterpret_cast<const char *>(&header.Sequence), sizeof(header.Sequence));
nonceBuffer.close();
unsigned long long clen;
QByteArray aeadPayload;
aeadPayload.fill(0, static_cast<int>(aePayloadBuffer.size() + crypto_aead_chacha20poly1305_IETF_ABYTES));
int result = crypto_aead_chacha20poly1305_ietf_encrypt(reinterpret_cast<unsigned char *>(aeadPayload.data()),
&clen,
reinterpret_cast<const unsigned char *>(aePayloadBuffer.buffer().constData()), aePayloadBuffer.size(),
reinterpret_cast<const unsigned char *>(adPayloadBuffer.buffer().constData()), adPayloadBuffer.size(),
nullptr,
reinterpret_cast<const unsigned char *>(nonce.constData()),
reinterpret_cast<const unsigned char *>(transmitKey.constData()));
if (result != 0) { return {}; }
QBuffer packetBuffer;
packetBuffer.open(QIODevice::WriteOnly);
packetBuffer.write(reinterpret_cast<const char *>(&headerLength), sizeof(headerLength));
packetBuffer.write(headerBuffer.buffer());
packetBuffer.write(aeadPayload);
packetBuffer.close();
return packetBuffer.buffer();
}
return {};
}
template<typename T>
static QByteArray Serialize(CryptoDtoChannel &channel, CryptoDtoMode mode, T dto)
{
uint sequenceToSend = 0;
QByteArray transmitKey = channel.getTransmitKey(mode, sequenceToSend);
return Serialize(channel.getChannelTag(), mode, transmitKey, sequenceToSend++, dto);
}
struct Deserializer
{
Deserializer(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback);
template<typename T>
T getDto()
{
if (! verified) return {};
if (dtoNameBuffer == T::getDtoName() || dtoNameBuffer == T::getShortDtoName())
{
msgpack::object_handle oh2 = msgpack::unpack(dataBuffer.data(), dataBuffer.size());
msgpack::object obj = oh2.get();
T dto = obj.as<T>();
return dto;
}
return {};
}
quint16 headerLength;
CryptoDtoHeaderDto header;
quint16 dtoNameLength;
QByteArray dtoNameBuffer;
quint16 dataLength;
QByteArray dataBuffer;
bool verified = false;
};
static Deserializer deserialize(CryptoDtoChannel &channel, const QByteArray &bytes, bool loopback);
};
} // ns
} // ns
} // ns
#endif // guard