diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index bb82b58e..a9309412 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -52,30 +52,7 @@ namespace crypto } #endif -#if OPENSSL_EDDSA - EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) - { - m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); - // TODO: check public key - m_MDCtx = EVP_MD_CTX_create (); - EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - } - - EDDSA25519Signer::~EDDSA25519Signer () - { - EVP_MD_CTX_destroy (m_MDCtx); - EVP_PKEY_free (m_Pkey); - } - - void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const - { - size_t l = 64; - EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, NULL); - EVP_DigestSign (m_MDCtx, signature, &l, buf, len); - } - -#else - EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) + EDDSA25519SignerCompat::EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) { // expand key Ed25519::ExpandPrivateKey (signingPrivateKey, m_ExpandedPrivateKey); @@ -95,14 +72,56 @@ namespace crypto BN_CTX_free (ctx); } - EDDSA25519Signer::~EDDSA25519Signer () + EDDSA25519SignerCompat::~EDDSA25519SignerCompat () { } - void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const + void EDDSA25519SignerCompat::Sign (const uint8_t * buf, int len, uint8_t * signature) const { GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); } + +#if OPENSSL_EDDSA + EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): + m_Fallback (nullptr) + { + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); + uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; + size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; + EVP_PKEY_get_raw_public_key (pkey, publicKey, &len); + if (memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) + { + LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); + EVP_PKEY_free (m_Pkey); + m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); + } + else + { + m_MDCtx = EVP_MD_CTX_create (); + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + } + } + + EDDSA25519Signer::~EDDSA25519Signer () + { + if (m_Fallback) delete m_Fallback; + else + { + EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); + } + } + + void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const + { + if (m_Fallback) return m_Fallback->Sign (buf, len, signature); + else + { + size_t l = 64; + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, NULL); + EVP_DigestSign (m_MDCtx, signature, &l, buf, len); + } + } #endif } } diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 7f5a53b9..b645a3c3 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -385,6 +385,24 @@ namespace crypto #endif }; + class EDDSA25519SignerCompat: public Signer + { + public: + + EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); + // we pass signingPublicKey to check if it matches private key + ~EDDSA25519SignerCompat (); + + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; + const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation + + private: + + uint8_t m_ExpandedPrivateKey[64]; + uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; + }; + +#if OPENSSL_EDDSA class EDDSA25519Signer: public Signer { public: @@ -394,20 +412,18 @@ namespace crypto ~EDDSA25519Signer (); void Sign (const uint8_t * buf, int len, uint8_t * signature) const; -#if !OPENSSL_EDDSA - const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation -#endif private: -#if OPENSSL_EDDSA EVP_PKEY * m_Pkey; - EVP_MD_CTX * m_MDCtx; -#else - uint8_t m_ExpandedPrivateKey[64]; - uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; -#endif + EVP_MD_CTX * m_MDCtx; + EDDSA25519SignerCompat * m_Fallback; }; +#else + typedef EDDSA25519SignerCompat EDDSA25519Signer; + +#endif + inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { #if OPENSSL_EDDSA