Skip to content

Commit 59d56d0

Browse files
hdu-sdlzxBewareMyPower
authored andcommitted
Update OpenSSL API (#509)
(cherry picked from commit 4366ffe)
1 parent 5d73c4b commit 59d56d0

File tree

4 files changed

+123
-34
lines changed

4 files changed

+123
-34
lines changed

lib/MessageCrypto.cc

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5148
MessageCrypto::~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+
91141
bool 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
}

lib/MessageCrypto.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class MessageCrypto {
104104
typedef std::unique_lock<std::mutex> Lock;
105105
std::mutex mutex_;
106106

107-
int dataKeyLen_;
107+
size_t dataKeyLen_;
108108
boost::scoped_array<unsigned char> dataKey_;
109109

110110
int tagLen_;
@@ -125,8 +125,12 @@ class MessageCrypto {
125125

126126
EVP_MD_CTX* mdCtx_;
127127

128-
RSA* loadPublicKey(std::string& pubKeyStr);
129-
RSA* loadPrivateKey(std::string& privateKeyStr);
128+
EVP_PKEY* loadPublicKey(std::string& pubKeyStr);
129+
EVP_PKEY* loadPrivateKey(std::string& privateKeyStr);
130+
bool rsaDecrypt(EVP_PKEY_CTX* ctx, const std::string& in, boost::scoped_array<unsigned char>& out,
131+
size_t& outLen);
132+
bool rsaEncrypt(EVP_PKEY_CTX* ctx, boost::scoped_array<unsigned char>& in, size_t inLen,
133+
boost::scoped_array<unsigned char>& out, size_t& outLen);
130134
bool getDigest(const std::string& keyName, const void* input, unsigned int inputLen,
131135
unsigned char keyDigest[], unsigned int& digestLen);
132136
void removeExpiredDataKey();

lib/auth/athenz/ZTSClient.cc

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ const std::string ZTSClient::getPrincipalToken() const {
226226
const char *unsignedToken = unsignedTokenString.c_str();
227227
unsigned char signature[BUFSIZ] = {};
228228
unsigned char hash[SHA256_DIGEST_LENGTH] = {};
229-
unsigned int siglen;
229+
size_t siglen;
230230
FILE *fp;
231-
RSA *privateKey;
231+
EVP_PKEY *privateKey;
232232

233233
if (privateKeyUri_.scheme == "data") {
234234
if (privateKeyUri_.mediaTypeAndEncodingType != "application/x-pem-file;base64") {
@@ -249,7 +249,7 @@ const std::string ZTSClient::getPrincipalToken() const {
249249
free(decodeStr);
250250
return "";
251251
}
252-
privateKey = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
252+
privateKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
253253
BIO_free(bio);
254254
free(decodeStr);
255255
if (privateKey == NULL) {
@@ -263,7 +263,7 @@ const std::string ZTSClient::getPrincipalToken() const {
263263
return "";
264264
}
265265

266-
privateKey = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
266+
privateKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
267267
fclose(fp);
268268
if (privateKey == NULL) {
269269
LOG_ERROR("Failed to read private key: " << privateKeyUri_.path);
@@ -275,16 +275,38 @@ const std::string ZTSClient::getPrincipalToken() const {
275275
}
276276

277277
SHA256((unsigned char *)unsignedToken, unsignedTokenString.length(), hash);
278-
RSA_sign(NID_sha256, hash, SHA256_DIGEST_LENGTH, signature, &siglen, privateKey);
278+
auto *ctx = EVP_MD_CTX_new();
279+
if (ctx == NULL) {
280+
LOG_ERROR("Failed to create EVP_MD_CTX.");
281+
return "";
282+
}
283+
284+
bool sign = rsaSign(ctx, privateKey, signature, &siglen, hash);
285+
EVP_MD_CTX_free(ctx);
286+
if (!sign) {
287+
LOG_ERROR("Failed to sign with " << privateKeyUri_.path);
288+
return "";
289+
}
279290

280291
std::string principalToken = unsignedTokenString + ";s=" + ybase64Encode(signature, siglen);
281292
LOG_DEBUG("Created signed principal token: " << principalToken);
282293

283-
RSA_free(privateKey);
294+
EVP_PKEY_free(privateKey);
284295

285296
return principalToken;
286297
}
287298

299+
bool ZTSClient::rsaSign(EVP_MD_CTX *ctx, EVP_PKEY *privateKey, unsigned char *signature, size_t *siglen,
300+
unsigned char *hash) const {
301+
if (EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, privateKey) != 1) {
302+
return false;
303+
}
304+
if (EVP_DigestSign(ctx, signature, siglen, hash, SHA256_DIGEST_LENGTH) != 1) {
305+
return false;
306+
}
307+
return true;
308+
}
309+
288310
std::mutex cacheMtx_;
289311
const std::string ZTSClient::getRoleToken() {
290312
RoleToken roleToken;

lib/auth/athenz/ZTSClient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19+
#include <openssl/evp.h>
1920
#include <pulsar/defines.h>
2021

2122
#include <map>
@@ -63,6 +64,8 @@ class PULSAR_PUBLIC ZTSClient {
6364
static UriSt parseUri(const char* uri);
6465
static bool checkRequiredParams(std::map<std::string, std::string>& params,
6566
const std::vector<std::string>& requiredParams);
67+
bool rsaSign(EVP_MD_CTX* ctx, EVP_PKEY* privateKey, unsigned char* signature, size_t* siglen,
68+
unsigned char* hash) const;
6669

6770
friend class ZTSClientWrapper;
6871
};

0 commit comments

Comments
 (0)