From ec33bbe2949010e1ed377b9dcc1ace56a0126bfe Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 29 Apr 2014 11:04:54 +0200 Subject: Moved cRsaPrivateKey to PolarSSL++, rewritten using existing objects. --- src/PolarSSL++/CMakeLists.txt | 2 + src/PolarSSL++/CtrDrbgContext.h | 8 +- src/PolarSSL++/RsaPrivateKey.cpp | 173 +++++++++++++++++++++++++++++++++++++++ src/PolarSSL++/RsaPrivateKey.h | 59 +++++++++++++ 4 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 src/PolarSSL++/RsaPrivateKey.cpp create mode 100644 src/PolarSSL++/RsaPrivateKey.h (limited to 'src/PolarSSL++') diff --git a/src/PolarSSL++/CMakeLists.txt b/src/PolarSSL++/CMakeLists.txt index 0493baba4..ebdd52de5 100644 --- a/src/PolarSSL++/CMakeLists.txt +++ b/src/PolarSSL++/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES "CallbackSslContext.cpp" "CtrDrbgContext.cpp" "EntropyContext.cpp" + "RsaPrivateKey.cpp" "SslContext.cpp" "X509Cert.cpp" ) @@ -20,6 +21,7 @@ set(HEADERS "CallbackSslContext.h" "CtrDrbgContext.h" "EntropyContext.h" + "RsaPrivateKey.h" "SslContext.h" "X509Cert.h" ) diff --git a/src/PolarSSL++/CtrDrbgContext.h b/src/PolarSSL++/CtrDrbgContext.h index e9a1e17e2..817222a53 100644 --- a/src/PolarSSL++/CtrDrbgContext.h +++ b/src/PolarSSL++/CtrDrbgContext.h @@ -25,6 +25,7 @@ class cEntropyContext; class cCtrDrbgContext { friend class cSslContext; + friend class cRsaPrivateKey; public: /** Constructs the context with a new entropy context. */ @@ -41,9 +42,6 @@ public: /** Returns true if the object is valid (has been initialized properly) */ bool IsValid(void) const { return m_IsValid; } - /** Returns the internal context ptr. Only use in PolarSSL API calls. */ - OBSOLETE ctr_drbg_context * Get(void) { return &m_CtrDrbg; } - protected: /** The entropy source used for generating the random */ SharedPtr m_EntropyContext; @@ -53,6 +51,10 @@ protected: /** Set to true if the object is valid (has been initialized properly) */ bool m_IsValid; + + + /** Returns the internal context ptr. Only use in PolarSSL API calls. */ + ctr_drbg_context * GetInternal(void) { return &m_CtrDrbg; } } ; diff --git a/src/PolarSSL++/RsaPrivateKey.cpp b/src/PolarSSL++/RsaPrivateKey.cpp new file mode 100644 index 000000000..d042139cf --- /dev/null +++ b/src/PolarSSL++/RsaPrivateKey.cpp @@ -0,0 +1,173 @@ + +// RsaPrivateKey.cpp + +#include "Globals.h" +#include "RsaPrivateKey.h" +#include "CtrDrbgContext.h" +#include "polarssl/pk.h" + + + + + + +cRsaPrivateKey::cRsaPrivateKey(void) +{ + rsa_init(&m_Rsa, RSA_PKCS_V15, 0); +} + + + + + +cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other) +{ + rsa_init(&m_Rsa, RSA_PKCS_V15, 0); + rsa_copy(&m_Rsa, &a_Other.m_Rsa); +} + + + + + +cRsaPrivateKey::~cRsaPrivateKey() +{ + rsa_free(&m_Rsa); +} + + + + + +bool cRsaPrivateKey::Generate(unsigned a_KeySizeBits) +{ + if (rsa_gen_key(&m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), a_KeySizeBits, 65537) != 0) + { + // Key generation failed + return false; + } + + return true; +} + + + + + +AString cRsaPrivateKey::GetPubKeyDER(void) +{ + class cPubKey + { + public: + cPubKey(rsa_context * a_Rsa) : + m_IsValid(false) + { + pk_init(&m_Key); + if (pk_init_ctx(&m_Key, pk_info_from_type(POLARSSL_PK_RSA)) != 0) + { + ASSERT(!"Cannot init PrivKey context"); + return; + } + if (rsa_copy(pk_rsa(m_Key), a_Rsa) != 0) + { + ASSERT(!"Cannot copy PrivKey to PK context"); + return; + } + m_IsValid = true; + } + + ~cPubKey() + { + if (m_IsValid) + { + pk_free(&m_Key); + } + } + + operator pk_context * (void) { return &m_Key; } + + protected: + bool m_IsValid; + pk_context m_Key; + } PkCtx(&m_Rsa); + + unsigned char buf[3000]; + int res = pk_write_pubkey_der(PkCtx, buf, sizeof(buf)); + if (res < 0) + { + return AString(); + } + return AString((const char *)(buf + sizeof(buf) - res), (size_t)res); +} + + + + + +int cRsaPrivateKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength) +{ + if (a_EncryptedLength < m_Rsa.len) + { + LOGD("%s: Invalid a_EncryptedLength: got %u, exp at least %u", + __FUNCTION__, (unsigned)a_EncryptedLength, (unsigned)(m_Rsa.len) + ); + ASSERT(!"Invalid a_DecryptedMaxLength!"); + return -1; + } + if (a_DecryptedMaxLength < m_Rsa.len) + { + LOGD("%s: Invalid a_DecryptedMaxLength: got %u, exp at least %u", + __FUNCTION__, (unsigned)a_EncryptedLength, (unsigned)(m_Rsa.len) + ); + ASSERT(!"Invalid a_DecryptedMaxLength!"); + return -1; + } + size_t DecryptedLength; + int res = rsa_pkcs1_decrypt( + &m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), RSA_PRIVATE, &DecryptedLength, + a_EncryptedData, a_DecryptedData, a_DecryptedMaxLength + ); + if (res != 0) + { + return -1; + } + return (int)DecryptedLength; +} + + + + + +int cRsaPrivateKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength) +{ + if (a_EncryptedMaxLength < m_Rsa.len) + { + LOGD("%s: Invalid a_EncryptedMaxLength: got %u, exp at least %u", + __FUNCTION__, (unsigned)a_EncryptedMaxLength, (unsigned)(m_Rsa.len) + ); + ASSERT(!"Invalid a_DecryptedMaxLength!"); + return -1; + } + if (a_PlainLength < m_Rsa.len) + { + LOGD("%s: Invalid a_PlainLength: got %u, exp at least %u", + __FUNCTION__, (unsigned)a_PlainLength, (unsigned)(m_Rsa.len) + ); + ASSERT(!"Invalid a_PlainLength!"); + return -1; + } + int res = rsa_pkcs1_encrypt( + &m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), RSA_PRIVATE, + a_PlainLength, a_PlainData, a_EncryptedData + ); + if (res != 0) + { + return -1; + } + return (int)m_Rsa.len; +} + + + + + diff --git a/src/PolarSSL++/RsaPrivateKey.h b/src/PolarSSL++/RsaPrivateKey.h new file mode 100644 index 000000000..ffacde11b --- /dev/null +++ b/src/PolarSSL++/RsaPrivateKey.h @@ -0,0 +1,59 @@ + +// RsaPrivateKey.h + +// Declares the cRsaPrivateKey class representing a private key for RSA operations. + + + + + +#pragma once + +#include "CtrDrbgContext.h" +#include "polarssl/rsa.h" + + + + + +/** Encapsulates an RSA private key used in PKI cryptography */ +class cRsaPrivateKey +{ +public: + /** Creates a new empty object, the key is not assigned */ + cRsaPrivateKey(void); + + /** Deep-copies the key from a_Other */ + cRsaPrivateKey(const cRsaPrivateKey & a_Other); + + ~cRsaPrivateKey(); + + /** Generates a new key within this object, with the specified size in bits. + Returns true on success, false on failure. */ + bool Generate(unsigned a_KeySizeBits = 1024); + + /** Returns the public key part encoded in ASN1 DER encoding */ + AString GetPubKeyDER(void); + + /** Decrypts the data using RSAES-PKCS#1 algorithm. + Both a_EncryptedData and a_DecryptedData must be at least bytes large. + Returns the number of bytes decrypted, or negative number for error. */ + int Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength); + + /** Encrypts the data using RSAES-PKCS#1 algorithm. + Both a_EncryptedData and a_DecryptedData must be at least bytes large. + Returns the number of bytes decrypted, or negative number for error. */ + int Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength); + +protected: + /** The PolarSSL key context */ + rsa_context m_Rsa; + + /** The random generator used for generating the key and encryption / decryption */ + cCtrDrbgContext m_CtrDrbg; +} ; + + + + + -- cgit v1.2.3