Verified Commit 3bacbd1a authored by Sean Coughlin's avatar Sean Coughlin

Merge pull request #1034

8e7bf420 Identity: fix compiler size-compare error (oneiric)
c8e9e7e7 Tests: RouterProfile: profiling unit-tests (oneiric)
c3eb5e57 IdentityEx: remove dead code (oneiric)
294c3c01 NTCP: adjust Phase3 sizes for Ed25519 (oneiric)
f2693fd2 Identity: enumerate signing and crypto key types (oneiric)
27a4752a Identity: enumerate Identity sizes (oneiric)
91b65f43 RouterInfo: remove arbitrary IdentityEx buffer size (oneiric)
e8bb1cad Tunnel: check router profile before deref (oneiric)
1616a39c Tests: DSA: static data for verification tests (oneiric)
92ddebfb Datagram: remove DSA signing type (oneiric)
64374a9e IdentityEx: replace raw DSA lengths (oneiric)
088218b9 Crypto: add DSA and RSASHA5124096 lengths (oneiric)
c0d26405 Crypto: remove unnecessary signatures (oneiric)
cfde514d Benchmark: remove unnecessary signature benchmarks (oneiric)
b785f537 IdentityEx: remove unneeded signature key types (oneiric)
parents 603df4ca 8e7bf420
Pipeline #44690692 passed with stage
in 6 minutes and 53 seconds
......@@ -50,11 +50,12 @@ bool AddressBookStorage::GetAddress(
return false;
file.seekg(0, std::ios::end);
const std::size_t len = file.tellg();
if (len < kovri::core::DEFAULT_IDENTITY_SIZE) {
LOG(error)
<< "AddressBookStorage: file " << filename << " is too short. " << len;
return false;
}
if (len < kovri::core::IdentitySizes::Default)
{
LOG(error) << "AddressBookStorage: file " << filename << " is too short. "
<< len;
return false;
}
file.seekg(0, std::ios::beg);
auto buf = std::make_unique<std::uint8_t[]>(len);
file.read(reinterpret_cast<char *>(buf.get()), len);
......
......@@ -114,14 +114,7 @@ void DatagramDestination::SendDatagramTo(
std::uint8_t* buf1 = signature + signature_len;
std::size_t header_len = identity_len + signature_len;
memcpy(buf1, payload, len);
if (m_Owner.GetIdentity().GetSigningKeyType()
== kovri::core::SIGNING_KEY_TYPE_DSA_SHA1) {
std::uint8_t hash[32];
kovri::core::SHA256().CalculateDigest(hash, buf1, len);
m_Owner.Sign(hash, 32, signature);
} else {
m_Owner.Sign(buf1, len, signature);
}
m_Owner.Sign(buf1, len, signature);
std::unique_ptr<kovri::core::I2NPMessage> msg
= CreateDataMessage(buf, len + header_len, from_port, to_port);
std::shared_ptr<const kovri::core::LeaseSet> remote
......@@ -193,7 +186,7 @@ void DatagramDestination::HandleDatagram(
const std::uint8_t* signature = buf + identity_len;
std::size_t header_len = identity_len + identity.GetSignatureLen();
bool verified = false;
if (identity.GetSigningKeyType() == kovri::core::SIGNING_KEY_TYPE_DSA_SHA1) {
if (identity.GetSigningKeyType() == kovri::core::SigningKeyType::DsaSha1) {
std::uint8_t hash[32];
kovri::core::SHA256().CalculateDigest(hash, buf + header_len, len - header_len);
verified = identity.Verify(hash, 32, signature);
......
......@@ -245,8 +245,8 @@ std::shared_ptr<ClientDestination> ClientContext::LoadLocalDestination(
}
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination(
bool is_public,
kovri::core::SigningKeyType sig_type,
const bool is_public,
const std::map<std::string, std::string>* params) {
kovri::core::PrivateKeys keys =
kovri::core::PrivateKeys::CreateRandomKeys(sig_type);
......@@ -275,7 +275,7 @@ void ClientContext::DeleteLocalDestination(
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination(
const kovri::core::PrivateKeys& keys,
bool is_public,
const bool is_public,
const std::map<std::string, std::string>* params) {
auto it = m_Destinations.find(keys.GetPublic().GetIdentHash());
if (it != m_Destinations.end()) {
......
......@@ -74,14 +74,15 @@ class ClientContext {
// Non-public
std::shared_ptr<ClientDestination> CreateNewLocalDestination(
bool is_public = false,
kovri::core::SigningKeyType sig_type = kovri::core::DEFAULT_CLIENT_SIGNING_KEY_TYPE,
kovri::core::SigningKeyType sig_type =
kovri::core::SigningKeyType::DefaultClient,
const bool is_public = false,
const std::map<std::string, std::string>* params = nullptr); // transient
// Public
std::shared_ptr<ClientDestination> CreateNewLocalDestination(
const kovri::core::PrivateKeys& keys,
bool is_public = true,
const bool is_public = true,
const std::map<std::string, std::string>* params = nullptr);
void DeleteLocalDestination(
......
......@@ -285,12 +285,17 @@ bool SU3::PrepareStream() {
// File format version offset (spec defines it as 0, so we don't need it)
m_Stream.Seekg(Offset::version, std::ios::cur);
// Prepare signature type
m_Stream.Read(&m_Data->signature_type, Size::signature_type);
boost::endian::big_to_native_inplace(m_Data->signature_type);
if (m_Data->signature_type != kovri::core::SIGNING_KEY_TYPE_RSA_SHA512_4096) { // Temporary (see #160)
LOG(error) << "SU3: signature type not supported";
return false;
}
std::uint16_t signature_type = 0xFFFF;
m_Stream.Read(&signature_type, Size::signature_type);
boost::endian::big_to_native_inplace(signature_type);
if (signature_type
!= kovri::core::GetType(kovri::core::SigningKeyType::RsaSha5124096))
{ // Temporary (see #160)
LOG(error) << "SU3: signature type not supported";
return false;
}
else
m_Data->signature_type = kovri::core::SigningKeyType::RsaSha5124096;
// Prepare signature length
m_Stream.Read(&m_Data->signature_length, Size::signature_length);
boost::endian::big_to_native_inplace(m_Data->signature_length);
......@@ -415,7 +420,7 @@ bool SU3::VerifySignature() {
}
// Verify hash of content data and signature
switch (m_Data->signature_type) {
case kovri::core::SIGNING_KEY_TYPE_RSA_SHA512_4096: {
case kovri::core::SigningKeyType::RsaSha5124096: {
kovri::core::RSASHA5124096RawVerifier verifier(signing_key_it->second);
verifier.Update(m_Data->content.data(), m_Data->content.size());
if (!verifier.Verify(m_Data->signature.data())) {
......@@ -429,8 +434,9 @@ bool SU3::VerifySignature() {
// tested during stream preparation. We'll leave this here
// because it will eventually be useful.
default:
LOG(error)
<< "SU3: signature type " << m_Data->signature_type << " is not supported";
LOG(error) << "SU3: signature type "
<< kovri::core::GetType(m_Data->signature_type)
<< " is not supported";
return false;
}
LOG(debug) << "SU3: verification successful";
......
This diff is collapsed.
......@@ -49,9 +49,32 @@ namespace core {
*
*/
const std::size_t DSA_PUBLIC_KEY_LENGTH = 128;
const std::size_t DSA_SIGNATURE_LENGTH = 40;
const std::size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH / 2;
namespace crypto
{
namespace PkLen
{
enum
{
DSA = 128,
};
} // namespace PkLen
namespace SkLen
{
enum
{
DSA = 20,
};
} // namespace SkLen
namespace SigLen
{
enum
{
DSA = 40,
};
} // namespace SigLen
} // namespace crypto
/// @class DSAVerifier
class DSAVerifier : public Verifier {
......@@ -66,15 +89,15 @@ class DSAVerifier : public Verifier {
const std::uint8_t* signature) const;
std::size_t GetPublicKeyLen() const {
return DSA_PUBLIC_KEY_LENGTH;
return crypto::PkLen::DSA;
}
std::size_t GetSignatureLen() const {
return DSA_SIGNATURE_LENGTH;
return crypto::SigLen::DSA;
}
std::size_t GetPrivateKeyLen() const {
return DSA_PRIVATE_KEY_LENGTH;
return crypto::SkLen::DSA;
}
private:
......@@ -82,367 +105,38 @@ class DSAVerifier : public Verifier {
std::unique_ptr<DSAVerifierImpl> m_DSAVerifierPimpl;
};
/// @class DSASigner
class DSASigner : public Signer {
public:
explicit DSASigner(
const std::uint8_t* private_signing_key);
~DSASigner();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class DSASignerImpl;
std::unique_ptr<DSASignerImpl> m_DSASignerPimpl;
};
void CreateDSARandomKeys(
std::uint8_t* private_signing_key,
std::uint8_t* public_signing_key);
/**
*
* ECDSAP256
*
*/
const std::size_t ECDSAP256_KEY_LENGTH = 64;
/// @class ECDSAP256Verifier
class ECDSAP256Verifier : public Verifier {
public:
ECDSAP256Verifier(
const std::uint8_t* signing_key);
~ECDSAP256Verifier();
bool Verify(
const std::uint8_t* buf,
std::size_t len,
const std::uint8_t* signature) const;
std::size_t GetPublicKeyLen() const {
return ECDSAP256_KEY_LENGTH;
}
std::size_t GetSignatureLen() const {
return ECDSAP256_KEY_LENGTH;
}
std::size_t GetPrivateKeyLen() const {
return ECDSAP256_KEY_LENGTH / 2;
}
private:
class ECDSAP256VerifierImpl;
std::unique_ptr<ECDSAP256VerifierImpl> m_ECDSAP256VerifierPimpl;
};
/// @class ECDSAP256Signer
class ECDSAP256Signer : public Signer {
public:
explicit ECDSAP256Signer(
const std::uint8_t* private_signing_key);
~ECDSAP256Signer();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class ECDSAP256SignerImpl;
std::unique_ptr<ECDSAP256SignerImpl> m_ECDSAP256SignerPimpl;
};
void CreateECDSAP256RandomKeys(
std::uint8_t* private_signing_key,
std::uint8_t* public_signing_key);
/**
*
* ECDSAP384
*
*/
const std::size_t ECDSAP384_KEY_LENGTH = 96;
/// @class ECDSAP384Verifier
class ECDSAP384Verifier : public Verifier {
public:
ECDSAP384Verifier(
const std::uint8_t* signing_key);
~ECDSAP384Verifier();
bool Verify(
const std::uint8_t* buf,
std::size_t len,
const std::uint8_t* signature) const;
std::size_t GetPublicKeyLen() const {
return ECDSAP384_KEY_LENGTH;
}
std::size_t GetSignatureLen() const {
return ECDSAP384_KEY_LENGTH;
}
std::size_t GetPrivateKeyLen() const {
return ECDSAP384_KEY_LENGTH / 2;
}
private:
class ECDSAP384VerifierImpl;
std::unique_ptr<ECDSAP384VerifierImpl> m_ECDSAP384VerifierPimpl;
};
/// @class ECDSAP384Signer
class ECDSAP384Signer : public Signer {
public:
explicit ECDSAP384Signer(
const uint8_t* private_signing_key);
~ECDSAP384Signer();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class ECDSAP384SignerImpl;
std::unique_ptr<ECDSAP384SignerImpl> m_ECDSAP384SignerPimpl;
};
void CreateECDSAP384RandomKeys(
std::uint8_t* private_signing_key,
std::uint8_t* public_signing_key);
/**
*
* ECDSAP521
*
*/
const std::size_t ECDSAP521_KEY_LENGTH = 132;
/// @class ECDSAP521Verifier
class ECDSAP521Verifier : public Verifier {
public:
ECDSAP521Verifier(
const std::uint8_t* signing_key);
~ECDSAP521Verifier();
bool Verify(
const std::uint8_t* buf,
std::size_t len,
const std::uint8_t* signature) const;
std::size_t GetPublicKeyLen() const {
return ECDSAP521_KEY_LENGTH;
}
std::size_t GetSignatureLen() const {
return ECDSAP521_KEY_LENGTH;
}
std::size_t GetPrivateKeyLen() const {
return ECDSAP521_KEY_LENGTH / 2;
}
private:
class ECDSAP521VerifierImpl;
std::unique_ptr<ECDSAP521VerifierImpl> m_ECDSAP521VerifierPimpl;
};
/// @class ECDSAP521Signer
class ECDSAP521Signer : public Signer {
public:
explicit ECDSAP521Signer(
const uint8_t* private_signing_key);
~ECDSAP521Signer();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class ECDSAP521SignerImpl;
std::unique_ptr<ECDSAP521SignerImpl> m_ECDSAP521SignerPimpl;
};
void CreateECDSAP521RandomKeys(
std::uint8_t* private_signing_key,
std::uint8_t* public_signing_key);
/**
*
* RSASHA2562048
*
*/
const std::size_t RSASHA2562048_KEY_LENGTH = 256;
/// @class RSASHA2562048Verifier
class RSASHA2562048Verifier : public Verifier {
public:
explicit RSASHA2562048Verifier(
const std::uint8_t* signing_key);
~RSASHA2562048Verifier();
std::size_t GetPublicKeyLen() const {
return RSASHA2562048_KEY_LENGTH;
}
std::size_t GetSignatureLen() const {
return RSASHA2562048_KEY_LENGTH;
}
std::size_t GetPrivateKeyLen() const {
return RSASHA2562048_KEY_LENGTH * 2;
}
bool Verify(
const std::uint8_t* buf,
std::size_t len,
const std::uint8_t* signature) const;
private:
class RSASHA2562048VerifierImpl;
std::unique_ptr<RSASHA2562048VerifierImpl> m_RSASHA2562048VerifierPimpl;
};
/// @class RSASHA2562048Signer
class RSASHA2562048Signer : public Signer {
public:
explicit RSASHA2562048Signer(
const std::uint8_t* private_signing_key);
~RSASHA2562048Signer();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class RSASHA2562048SignerImpl;
std::unique_ptr<RSASHA2562048SignerImpl> m_RSASHA2562048SignerPimpl;
};
/**
*
* RSASHA3843072
*
*/
const std::size_t RSASHA3843072_KEY_LENGTH = 384;
/// @class RSASHA3843072Verifier
class RSASHA3843072Verifier : public Verifier {
public:
explicit RSASHA3843072Verifier(
const std::uint8_t* signing_key);
~RSASHA3843072Verifier();
std::size_t GetPublicKeyLen() const {
return RSASHA3843072_KEY_LENGTH;
}
std::size_t GetSignatureLen() const {
return RSASHA3843072_KEY_LENGTH;
}
std::size_t GetPrivateKeyLen() const {
return RSASHA3843072_KEY_LENGTH * 2;
}
bool Verify(
const std::uint8_t* buf,
std::size_t len,
const std::uint8_t* signature) const;
private:
class RSASHA3843072VerifierImpl;
std::unique_ptr<RSASHA3843072VerifierImpl> m_RSASHA3843072VerifierPimpl;
};
/// @class RSASHA3843072Signer
class RSASHA3843072Signer : public Signer {
public:
explicit RSASHA3843072Signer(
const std::uint8_t* private_signing_key);
~RSASHA3843072Signer();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class RSASHA3843072SignerImpl;
std::unique_ptr<RSASHA3843072SignerImpl> m_RSASHA3843072SignerPimpl;
};
/**
*
* RSASHA5124096
*
*/
const std::size_t RSASHA5124096_KEY_LENGTH = 512;
/// @class RSASHA5124096Verifier
class RSASHA5124096Verifier : public Verifier {
public:
explicit RSASHA5124096Verifier(
const std::uint8_t* signing_key);
~RSASHA5124096Verifier();
std::size_t GetPublicKeyLen() const {
return RSASHA5124096_KEY_LENGTH;
}
std::size_t GetSignatureLen() const {
return RSASHA5124096_KEY_LENGTH;
}
std::size_t GetPrivateKeyLen() const {
return RSASHA5124096_KEY_LENGTH * 2;
}
bool Verify(
const std::uint8_t* buf,
std::size_t len,
const std::uint8_t* signature) const;
private:
class RSASHA5124096VerifierImpl;
std::unique_ptr<RSASHA5124096VerifierImpl> m_RSASHA5124096VerifierPimpl;
namespace crypto
{
namespace PkLen
{
enum
{
RSASHA5124096 = 512,
};
} // namespace PkLen
/// @class RSASHA5124096Signer
class RSASHA5124096Signer : public Signer {
public:
explicit RSASHA5124096Signer(
const std::uint8_t* private_signing_key);
~RSASHA5124096Signer();
void Sign(
const std::uint8_t* buf,
std::size_t len,
std::uint8_t* signature) const;
private:
class RSASHA5124096SignerImpl;
std::unique_ptr<RSASHA5124096SignerImpl> m_RSASHA5124096SignerPimpl;
namespace SkLen
{
enum
{
RSASHA5124096 = 1024,
};
} // namespace SkLen
void CreateRSARandomKeys(
std::size_t public_key_length,
std::uint8_t* private_signing_key,
std::uint8_t* public_signing_key);
namespace SigLen
{
enum
{
RSASHA5124096 = 512,
};
} // namespace SigLen
} // namespace crypto
/**
*
......
......@@ -103,7 +103,7 @@ void RouterContext::Initialize(const boost::program_options::variables_map& map)
{
LOG(debug) << "RouterContext: creating router keys";
m_Keys = core::PrivateKeys::CreateRandomKeys(
core::DEFAULT_ROUTER_SIGNING_KEY_TYPE);
core::SigningKeyType::DefaultRouter);
LOG(debug) << "RouterContext: writing router keys";
core::OutputFileStream keys(keys_path, std::ofstream::binary);
......
This diff is collapsed.
......@@ -58,6 +58,28 @@ inline std::string GetB32Address(
return ident.ToBase32().append(".b32.i2p");
}
enum IdentitySizes : std::uint16_t
{
Default = 387,
Extended = Default + 4,
};
enum struct SigningKeyType : std::uint16_t
{
DsaSha1 = 0,
RsaSha5124096 = 6,
EdDsaSha512Ed25519 = 7,
DefaultClient = EdDsaSha512Ed25519,
DefaultRouter = EdDsaSha512Ed25519,
Unsupported = 0xFFFF,
};
enum struct CryptoKeyType : std::uint16_t
{
ElGamal = 0,
Unsupported = 0xFFFF,
};
#pragma pack(1)
struct Keys {
std::uint8_t private_key[256];
......@@ -105,25 +127,6 @@ struct Identity {
#pragma pack()
Keys CreateRandomKeys();
const std::size_t DEFAULT_IDENTITY_SIZE = sizeof(Identity); // 387 bytes
const std::uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0;
const std::uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0;
const std::uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1;
const std::uint16_t SIGNING_KEY_TYPE_ECDSA_SHA384_P384 = 2;
const std::uint16_t SIGNING_KEY_TYPE_ECDSA_SHA512_P521 = 3;
const std::uint16_t SIGNING_KEY_TYPE_RSA_SHA256_2048 = 4;
const std::uint16_t SIGNING_KEY_TYPE_RSA_SHA384_3072 = 5;
const std::uint16_t SIGNING_KEY_TYPE_RSA_SHA512_4096 = 6;
const std::uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 = 7;
// TODO(anonimal): review/implement to bump client type to EdDSA-SHA512-Ed25519
const std::uint16_t DEFAULT_CLIENT_SIGNING_KEY_TYPE = SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
const std::uint16_t DEFAULT_ROUTER_SIGNING_KEY_TYPE = SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519;
typedef std::uint16_t SigningKeyType;
typedef std::uint16_t CryptoKeyType;
/// @brief SigningKeyType to human readable string
/// @param type of the signature key
/// @returns human readable string for the key type, empty string if unknown
......@@ -137,7 +140,7 @@ class IdentityEx {
IdentityEx(
const std::uint8_t* public_key,
const std::uint8_t* signing_key,
SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1);
SigningKeyType type = SigningKeyType::EdDsaSha512Ed25519);
IdentityEx(
const std::uint8_t* buf,
......@@ -178,7 +181,7 @@ class IdentityEx {
}
std::size_t GetFullLen() const {
return m_ExtendedLen + DEFAULT_IDENTITY_SIZE;
return m_ExtendedLen + IdentitySizes::Default;
}
std::size_t GetSigningPublicKeyLen() const;
......@@ -261,7 +264,7 @@ class PrivateKeys { // for eepsites
std::size_t len) const;
static PrivateKeys CreateRandomKeys(
SigningKeyType type = DEFAULT_CLIENT_SIGNING_KEY_TYPE);
SigningKeyType type = SigningKeyType::DefaultClient);
private:
void CreateSigner();
......
......@@ -728,14 +728,10 @@ void RouterInfo::CreateRouterInfo(
LOG(debug) << "RouterInfo: " << __func__;
// Write ident
// TODO(anonimal): this max size is arbitrary. Realistically,
// we'll only need a max with 387 + 4 for EdDSA-Ed25519 routers
// which is a majority of the network. Note: do not set that size
// until we remove implementing other signatures.
std::array<std::uint8_t, 1024> ident {{}};
auto ident_len =
private_keys.GetPublic().ToBuffer(ident.data(), ident.size());
router_info.Write(ident.data(), ident_len);
const auto ident_len = private_keys.GetPublic().GetFullLen();
auto ident_buf = std::make_unique<std::uint8_t[]>(ident_len);
private_keys.GetPublic().ToBuffer(ident_buf.get(), ident_len);
router_info.Write(ident_buf.get(), ident_len);
// Set published timestamp
SetTimestamp(core::GetMillisecondsSinceEpoch());
......
......@@ -67,7 +67,7 @@ struct RouterInfoTraits
/// @brief Router Info size constants
enum Size : std::uint16_t
{
MinBuffer = core::DSA_SIGNATURE_LENGTH, // TODO(unassigned): see #498
MinBuffer = crypto::SigLen::DSA,
MaxBuffer = 2048, // TODO(anonimal): review if arbitrary
MinUnsignedBuffer = 399, // Minimum RouterInfo length w/o signature, see spec
// TODO(unassigned): algorithm to dynamically determine cost
......
......@@ -242,7 +242,8 @@ bool RouterProfile::IsBad() {
std::shared_ptr<RouterProfile> GetRouterProfile(
const IdentHash& ident_hash) {
auto profile = std::make_shared<RouterProfile>(ident_hash);
profile->Load(); // if possible
if (profile) // sanity check if make_shared failed
profile->Load(); // if possible
return profile;
}
......
......@@ -286,14 +286,14 @@ class NTCPSession
// The padding is as necessary to a multiple of 16 bytes for the entire unencrypted contents.
Phase3AliceRI = 2,
Phase3AliceTS = 4,
Phase3Padding = 15,
Phase3Signature = 40,
Phase3Padding = 3,
Phase3Signature = 64,