@@ -35,9 +35,6 @@ MessageCrypto::MessageCrypto(const std::string& logCtx, bool keyGenNeeded)
3535 ivLen_(12 ),
3636 iv_(new unsigned char [ivLen_]),
3737 logCtx_(logCtx) {
38- SSL_library_init ();
39- SSL_load_error_strings ();
40-
4138 if (!keyGenNeeded) {
4239 mdCtx_ = EVP_MD_CTX_create ();
4340 EVP_MD_CTX_init (mdCtx_);
@@ -50,17 +47,17 @@ MessageCrypto::MessageCrypto(const std::string& logCtx, bool keyGenNeeded)
5047
5148MessageCrypto::~MessageCrypto () {}
5249
53- RSA * MessageCrypto::loadPublicKey (std::string& pubKeyStr) {
50+ EVP_PKEY * MessageCrypto::loadPublicKey (std::string& pubKeyStr) {
5451 BIO* pubBio = NULL ;
55- RSA * rsaPub = NULL ;
52+ EVP_PKEY * rsaPub = NULL ;
5653
5754 pubBio = BIO_new_mem_buf ((char *)pubKeyStr.c_str (), -1 );
5855 if (pubBio == NULL ) {
5956 LOG_ERROR (logCtx_ << " Failed to get memory for public key" );
6057 return rsaPub;
6158 }
6259
63- rsaPub = PEM_read_bio_RSA_PUBKEY (pubBio, NULL , NULL , NULL );
60+ rsaPub = PEM_read_bio_PUBKEY (pubBio, NULL , NULL , NULL );
6461 if (rsaPub == NULL ) {
6562 LOG_ERROR (logCtx_ << " Failed to load public key" );
6663 }
@@ -69,17 +66,17 @@ RSA* MessageCrypto::loadPublicKey(std::string& pubKeyStr) {
6966 return rsaPub;
7067}
7168
72- RSA * MessageCrypto::loadPrivateKey (std::string& privateKeyStr) {
69+ EVP_PKEY * MessageCrypto::loadPrivateKey (std::string& privateKeyStr) {
7370 BIO* privBio = NULL ;
74- RSA * rsaPriv = NULL ;
71+ EVP_PKEY * rsaPriv = NULL ;
7572
7673 privBio = BIO_new_mem_buf ((char *)privateKeyStr.c_str (), -1 );
7774 if (privBio == NULL ) {
7875 LOG_ERROR (logCtx_ << " Failed to get memory for private key" );
7976 return rsaPriv;
8077 }
8178
82- rsaPriv = PEM_read_bio_RSAPrivateKey (privBio, NULL , NULL , NULL );
79+ rsaPriv = PEM_read_bio_PrivateKey (privBio, NULL , NULL , NULL );
8380 if (rsaPriv == NULL ) {
8481 LOG_ERROR (logCtx_ << " Failed to load private key" );
8582 }
@@ -88,6 +85,59 @@ RSA* MessageCrypto::loadPrivateKey(std::string& privateKeyStr) {
8885 return rsaPriv;
8986}
9087
88+ bool MessageCrypto::rsaDecrypt (EVP_PKEY_CTX* ctx, const std::string& in,
89+ boost::scoped_array<unsigned char >& out, size_t & outLen) {
90+ if (EVP_PKEY_decrypt_init (ctx) <= 0 ) {
91+ LOG_ERROR (logCtx_ << " Failed to initialize decryption" );
92+ return false ;
93+ }
94+ if (EVP_PKEY_CTX_set_rsa_padding (ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ) {
95+ LOG_ERROR (logCtx_ << " Failed to set RSA padding" );
96+ return false ;
97+ }
98+ auto inStr_ = reinterpret_cast <unsigned const char *>(in.c_str ());
99+ size_t rsaSize;
100+ if (EVP_PKEY_decrypt (ctx, NULL , &rsaSize, inStr_, in.size ()) <= 0 ) {
101+ LOG_ERROR (logCtx_ << " Failed to determine decrypt buffer size" );
102+ return false ;
103+ }
104+ if (rsaSize != outLen) {
105+ outLen = rsaSize;
106+ out.reset (new unsigned char [outLen]);
107+ }
108+ if (EVP_PKEY_decrypt (ctx, out.get (), &outLen, inStr_, in.size ()) <= 0 ) {
109+ LOG_ERROR (logCtx_ << " Failed to decrypt." );
110+ return false ;
111+ }
112+ return true ;
113+ }
114+
115+ bool MessageCrypto::rsaEncrypt (EVP_PKEY_CTX* ctx, boost::scoped_array<unsigned char >& in, size_t inLen,
116+ boost::scoped_array<unsigned char >& out, size_t & outLen) {
117+ if (EVP_PKEY_encrypt_init (ctx) <= 0 ) {
118+ LOG_ERROR (logCtx_ << " Failed to initialize encryption" );
119+ return false ;
120+ }
121+ if (EVP_PKEY_CTX_set_rsa_padding (ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ) {
122+ LOG_ERROR (logCtx_ << " Failed to set RSA padding" );
123+ return false ;
124+ }
125+ size_t rsaSize;
126+ if (EVP_PKEY_encrypt (ctx, NULL , &rsaSize, in.get (), inLen) <= 0 ) {
127+ LOG_ERROR (logCtx_ << " Failed to determine encrypt buffer size" );
128+ return false ;
129+ }
130+ if (rsaSize != outLen) {
131+ outLen = rsaSize;
132+ out.reset (new unsigned char [rsaSize]);
133+ }
134+ if (EVP_PKEY_encrypt (ctx, out.get (), &outLen, in.get (), inLen) <= 0 ) {
135+ LOG_ERROR (logCtx_ << " Failed to encrypt." );
136+ return false ;
137+ }
138+ return true ;
139+ }
140+
91141bool MessageCrypto::getDigest (const std::string& keyName, const void * input, unsigned int inputLen,
92142 unsigned char keyDigest[], unsigned int & digestLen) {
93143 if (EVP_DigestInit_ex (mdCtx_, EVP_md5 (), NULL ) != 1 ) {
@@ -181,24 +231,29 @@ Result MessageCrypto::addPublicKeyCipher(const std::string& keyName, const Crypt
181231 return result;
182232 }
183233
184- RSA * pubKey = loadPublicKey (keyInfo.getKey ());
234+ auto * pubKey = loadPublicKey (keyInfo.getKey ());
185235 if (pubKey == NULL ) {
186236 LOG_ERROR (logCtx_ << " Failed to load public key " << keyName);
187237 return ResultCryptoError;
188238 }
189239 LOG_DEBUG (logCtx_ << " Public key " << keyName << " loaded successfully." );
190240
191- int inSize = RSA_size (pubKey);
192- boost::scoped_array<unsigned char > encryptedKey (new unsigned char [inSize]);
193-
194- int outSize =
195- RSA_public_encrypt (dataKeyLen_, dataKey_.get (), encryptedKey.get (), pubKey, RSA_PKCS1_OAEP_PADDING);
196-
197- if (inSize != outSize) {
198- LOG_ERROR (logCtx_ << " Ciphertext is length not matching input key length for key " << keyName);
241+ boost::scoped_array<unsigned char > encryptedKey{nullptr };
242+ size_t encryptedKeyLen{0 };
243+ auto * ctx = EVP_PKEY_CTX_new (pubKey, NULL );
244+ if (!ctx) {
245+ LOG_ERROR (logCtx_ << " Failed to create EVP_PKEY_CTX for " << keyName);
246+ EVP_PKEY_free (pubKey);
247+ return ResultCryptoError;
248+ }
249+ bool encrypted = rsaEncrypt (ctx, dataKey_, dataKeyLen_, encryptedKey, encryptedKeyLen);
250+ EVP_PKEY_CTX_free (ctx);
251+ EVP_PKEY_free (pubKey);
252+ if (!encrypted) {
253+ LOG_ERROR (logCtx_ << " Failed to encrypt with " << keyName);
199254 return ResultCryptoError;
200255 }
201- std::string encryptedKeyStr (reinterpret_cast <char *>(encryptedKey.get ()), inSize );
256+ std::string encryptedKeyStr (reinterpret_cast <char *>(encryptedKey.get ()), encryptedKeyLen );
202257 std::shared_ptr<EncryptionKeyInfo> eki (new EncryptionKeyInfo ());
203258 eki->setKey (encryptedKeyStr);
204259 eki->setMetadata (keyInfo.getMetadata ());
@@ -353,19 +408,24 @@ bool MessageCrypto::decryptDataKey(const proto::EncryptionKeys& encKeys, const C
353408 keyReader.getPrivateKey (keyName, keyMeta, keyInfo);
354409
355410 // Convert key from string to RSA key
356- RSA * privKey = loadPrivateKey (keyInfo.getKey ());
411+ auto * privKey = loadPrivateKey (keyInfo.getKey ());
357412 if (privKey == NULL ) {
358413 LOG_ERROR (logCtx_ << " Failed to load private key " << keyName);
359414 return false ;
360415 }
361416 LOG_DEBUG (logCtx_ << " Private key " << keyName << " loaded successfully." );
362417
363418 // Decrypt data key
364- int outSize = RSA_private_decrypt (encryptedDataKey.size (),
365- reinterpret_cast <unsigned const char *>(encryptedDataKey.c_str ()),
366- dataKey_.get (), privKey, RSA_PKCS1_OAEP_PADDING);
367-
368- if (outSize == -1 ) {
419+ auto * ctx = EVP_PKEY_CTX_new (privKey, NULL );
420+ if (!ctx) {
421+ LOG_ERROR (logCtx_ << " Failed to create EVP_PKEY_CTX for " << keyName);
422+ EVP_PKEY_free (privKey);
423+ return false ;
424+ }
425+ bool decrypted = rsaDecrypt (ctx, encryptedDataKey, dataKey_, dataKeyLen_);
426+ EVP_PKEY_CTX_free (ctx);
427+ EVP_PKEY_free (privKey);
428+ if (!decrypted) {
369429 LOG_ERROR (logCtx_ << " Failed to decrypt AES key for " << keyName);
370430 return false ;
371431 }
0 commit comments