From 0b3ee777176a306d556d5df48f5058a0afe280b9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Dec 2014 21:31:06 -0500 Subject: [PATCH] RSA signatures --- CryptoConst.h | 5 ++- Identity.cpp | 83 +++++++++++++++++++++++++++++++++++++-- Identity.h | 5 ++- Signature.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 186 insertions(+), 13 deletions(-) diff --git a/CryptoConst.h b/CryptoConst.h index 1d722b1e..ba48a35d 100644 --- a/CryptoConst.h +++ b/CryptoConst.h @@ -28,7 +28,10 @@ namespace crypto // DSA #define dsap GetCryptoConstants ().dsap #define dsaq GetCryptoConstants ().dsaq - #define dsag GetCryptoConstants ().dsag + #define dsag GetCryptoConstants ().dsag + + // RSA + const int rsae = 65537; } } diff --git a/Identity.cpp b/Identity.cpp index a616e5eb..714b8f1e 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -68,6 +68,30 @@ namespace data memcpy (excessBuf, signingKey + 128, excessLen); break; } + case SIGNING_KEY_TYPE_RSA_SHA256_2048: + { + memcpy (m_StandardIdentity.signingKey, signingKey, 128); + excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256 - 128 + excessBuf = new uint8_t[excessLen]; + memcpy (excessBuf, signingKey + 128, excessLen); + break; + } + case SIGNING_KEY_TYPE_RSA_SHA384_3072: + { + memcpy (m_StandardIdentity.signingKey, signingKey, 128); + excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384 - 128 + excessBuf = new uint8_t[excessLen]; + memcpy (excessBuf, signingKey + 128, excessLen); + break; + } + case SIGNING_KEY_TYPE_RSA_SHA512_4096: + { + memcpy (m_StandardIdentity.signingKey, signingKey, 128); + excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512 - 128 + excessBuf = new uint8_t[excessLen]; + memcpy (excessBuf, signingKey + 128, excessLen); + break; + } default: LogPrint ("Signing key type ", (int)type, " is not supported"); } @@ -225,6 +249,14 @@ namespace data return 128; } + size_t IdentityEx::GetSigningPrivateKeyLen () const + { + if (!m_Verifier) CreateVerifier (); + if (m_Verifier) + return m_Verifier->GetPrivateKeyLen (); + return GetSignatureLen ()/2; + } + size_t IdentityEx::GetSignatureLen () const { if (!m_Verifier) CreateVerifier (); @@ -283,6 +315,33 @@ namespace data m_Verifier = new i2p::crypto::ECDSAP521Verifier (signingKey); break; } + case SIGNING_KEY_TYPE_RSA_SHA256_2048: + { + uint8_t signingKey[i2p::crypto::RSASHA2562048_KEY_LENGTH]; + memcpy (signingKey, m_StandardIdentity.signingKey, 128); + size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128 + memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types + m_Verifier = new i2p::crypto:: RSASHA2562048Verifier (signingKey); + break; + } + case SIGNING_KEY_TYPE_RSA_SHA384_3072: + { + uint8_t signingKey[i2p::crypto::RSASHA3843072_KEY_LENGTH]; + memcpy (signingKey, m_StandardIdentity.signingKey, 128); + size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128 + memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types + m_Verifier = new i2p::crypto:: RSASHA3843072Verifier (signingKey); + break; + } + case SIGNING_KEY_TYPE_RSA_SHA512_4096: + { + uint8_t signingKey[i2p::crypto::RSASHA5124096_KEY_LENGTH]; + memcpy (signingKey, m_StandardIdentity.signingKey, 128); + size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128 + memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types + m_Verifier = new i2p::crypto:: RSASHA5124096Verifier (signingKey); + break; + } default: LogPrint ("Signing key type ", (int)keyType, " is not supported"); } @@ -322,7 +381,7 @@ namespace data size_t ret = m_Public.FromBuffer (buf, len); memcpy (m_PrivateKey, buf + ret, 256); // private key always 256 ret += 256; - size_t signingPrivateKeySize = m_Public.GetSignatureLen ()/2; // 20 for DSA + size_t signingPrivateKeySize = m_Public.GetSigningPrivateKeyLen (); memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize); ret += signingPrivateKeySize; delete m_Signer; @@ -336,7 +395,7 @@ namespace data size_t ret = m_Public.ToBuffer (buf, len); memcpy (buf + ret, m_PrivateKey, 256); // private key always 256 ret += 256; - size_t signingPrivateKeySize = m_Public.GetSignatureLen ()/2; // 20 for DSA + size_t signingPrivateKeySize = m_Public.GetSigningPrivateKeyLen (); memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize); ret += signingPrivateKeySize; return ret; @@ -386,6 +445,15 @@ namespace data case SIGNING_KEY_TYPE_ECDSA_SHA512_P521: m_Signer = new i2p::crypto::ECDSAP521Signer (m_SigningPrivateKey); break; + case SIGNING_KEY_TYPE_RSA_SHA256_2048: + m_Signer = new i2p::crypto::RSASHA2562048Signer (m_SigningPrivateKey); + break; + case SIGNING_KEY_TYPE_RSA_SHA384_3072: + m_Signer = new i2p::crypto::RSASHA3843072Signer (m_SigningPrivateKey); + break; + case SIGNING_KEY_TYPE_RSA_SHA512_4096: + m_Signer = new i2p::crypto::RSASHA5124096Signer (m_SigningPrivateKey); + break; default: LogPrint ("Signing key type ", (int)m_Public.GetSigningKeyType (), " is not supported"); } @@ -398,7 +466,7 @@ namespace data PrivateKeys keys; auto& rnd = i2p::context.GetRandomNumberGenerator (); // signature - uint8_t signingPublicKey[i2p::crypto::ECDSAP521_KEY_LENGTH]; // 132 bytes is max key size now + uint8_t signingPublicKey[512]; // signing public key is 512 bytes max switch (type) { case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: @@ -410,6 +478,15 @@ namespace data case SIGNING_KEY_TYPE_ECDSA_SHA512_P521: i2p::crypto::CreateECDSAP521RandomKeys (rnd, keys.m_SigningPrivateKey, signingPublicKey); break; + case SIGNING_KEY_TYPE_RSA_SHA256_2048: + i2p::crypto::CreateRSARandomKeys (rnd, i2p::crypto::RSASHA2562048_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey); + break; + case SIGNING_KEY_TYPE_RSA_SHA384_3072: + i2p::crypto::CreateRSARandomKeys (rnd, i2p::crypto::RSASHA3843072_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey); + break; + case SIGNING_KEY_TYPE_RSA_SHA512_4096: + i2p::crypto::CreateRSARandomKeys (rnd, i2p::crypto::RSASHA5124096_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey); + break; default: LogPrint ("Signing key type ", (int)type, " is not supported. Create DSA-SHA1"); return PrivateKeys (i2p::data::CreateRandomKeys ()); // DSA-SHA1 diff --git a/Identity.h b/Identity.h index e4f8bd59..9fed07a1 100644 --- a/Identity.h +++ b/Identity.h @@ -140,6 +140,7 @@ namespace data const IdentHash& GetIdentHash () const { return m_IdentHash; }; size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; }; size_t GetSigningPublicKeyLen () const; + size_t GetSigningPrivateKeyLen () const; size_t GetSignatureLen () const; bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; SigningKeyType GetSigningKeyType () const; @@ -175,7 +176,7 @@ namespace data const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; void Sign (const uint8_t * buf, int len, uint8_t * signature) const; - size_t GetFullLen () const { return m_Public.GetFullLen () + 256 + m_Public.GetSignatureLen ()/2; }; + size_t GetFullLen () const { return m_Public.GetFullLen () + 256 + m_Public.GetSigningPrivateKeyLen (); }; size_t FromBuffer (const uint8_t * buf, size_t len); size_t ToBuffer (uint8_t * buf, size_t len) const; @@ -192,7 +193,7 @@ namespace data IdentityEx m_Public; uint8_t m_PrivateKey[256]; - uint8_t m_SigningPrivateKey[128]; // assume private key doesn't exceed 128 bytes + uint8_t m_SigningPrivateKey[1024]; // assume private key doesn't exceed 1024 bytes i2p::crypto::Signer * m_Signer; }; diff --git a/Signature.h b/Signature.h index f998eb86..90eb06d9 100644 --- a/Signature.h +++ b/Signature.h @@ -22,6 +22,7 @@ namespace crypto virtual bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const = 0; virtual size_t GetPublicKeyLen () const = 0; virtual size_t GetSignatureLen () const = 0; + virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; }; }; class Signer @@ -233,37 +234,128 @@ namespace crypto } // RSA - template + template class RSAVerifier: public Verifier { public: RSAVerifier (const uint8_t * signingKey) { - // TODO + m_PublicKey.Initialize (CryptoPP::Integer (signingKey, keyLen), CryptoPP::Integer (rsae)); } bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { typename CryptoPP::RSASS::Verifier verifier (m_PublicKey); - return verifier.VerifyMessage (buf, len, signature, keyLength); // signature length + return verifier.VerifyMessage (buf, len, signature, keyLen); // signature length } - size_t GetPublicKeyLen () const { return keyLength; } - size_t GetSignatureLen () const { return keyLength; } + size_t GetPublicKeyLen () const { return keyLen; } + size_t GetSignatureLen () const { return keyLen; } + size_t GetPrivateKeyLen () const { return GetSignatureLen ()*2; }; private: CryptoPP::RSA::PublicKey m_PublicKey; }; + + template + class RSASigner: public Signer + { + public: + + RSASigner (const uint8_t * signingPrivateKey, size_t keyLen) + { + m_PrivateKey.Initialize (CryptoPP::Integer (signingPrivateKey, keyLen/2), + rsae, + CryptoPP::Integer (signingPrivateKey + keyLen/2, keyLen/2)); + } + + void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const + { + typename CryptoPP::RSASS::Signer signer (m_PrivateKey); + signer.SignMessage (rnd, buf, len, signature); + } + + private: + + CryptoPP::RSA::PrivateKey m_PrivateKey; + }; + + inline void CreateRSARandomKeys (CryptoPP::RandomNumberGenerator& rnd, + size_t publicKeyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) + { + CryptoPP::RSA::PrivateKey privateKey; + privateKey.Initialize (rnd, publicKeyLen*8, rsae); + privateKey.GetModulus ().Encode (signingPrivateKey, publicKeyLen); + privateKey.GetPrivateExponent ().Encode (signingPrivateKey + publicKeyLen, publicKeyLen); + privateKey.GetModulus ().Encode (signingPublicKey, publicKeyLen); + } + + // RSA_SHA256_2048 - const size_t RSASHA2562048_KEY_LENGTH =256; + const size_t RSASHA2562048_KEY_LENGTH = 256; class RSASHA2562048Verifier: public RSAVerifier { public: - RSASHA2562048Verifier (const uint8_t * signingKey): RSAVerifier (signingKey) {}; + RSASHA2562048Verifier (const uint8_t * signingKey): RSAVerifier (signingKey) + { + } + }; + + class RSASHA2562048Signer: public RSASigner + { + public: + + RSASHA2562048Signer (const uint8_t * signingPrivateKey): + RSASigner (signingPrivateKey, RSASHA2562048_KEY_LENGTH*2) + { + } }; + +// RSA_SHA384_3072 + const size_t RSASHA3843072_KEY_LENGTH = 384; + class RSASHA3843072Verifier: public RSAVerifier + { + public: + + RSASHA3843072Verifier (const uint8_t * signingKey): RSAVerifier (signingKey) + { + } + }; + + class RSASHA3843072Signer: public RSASigner + { + public: + + RSASHA3843072Signer (const uint8_t * signingPrivateKey): + RSASigner (signingPrivateKey, RSASHA3843072_KEY_LENGTH*2) + { + } + }; + +// RSA_SHA512_4096 + const size_t RSASHA5124096_KEY_LENGTH = 512; + class RSASHA5124096Verifier: public RSAVerifier + { + public: + + RSASHA5124096Verifier (const uint8_t * signingKey): RSAVerifier (signingKey) + { + } + }; + + class RSASHA5124096Signer: public RSASigner + { + public: + + RSASHA5124096Signer (const uint8_t * signingPrivateKey): + RSASigner (signingPrivateKey, RSASHA5124096_KEY_LENGTH*2) + { + } + }; + } }