in sdk/src/encryption/CipherOpenssl.cc [164:283]
ByteBuffer AsymmetricCipherOpenssl::Encrypt(const ByteBuffer& data)
{
#if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 30000
BIO* bio = NULL;
OSSL_DECODER_CTX* dctx = NULL;
EVP_PKEY* pkey = NULL;
EVP_PKEY_CTX* ctx = NULL;
ByteBuffer enc;
do {
if (data.empty()) {
break;
}
dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, "RSA", EVP_PKEY_PUBLIC_KEY, NULL, NULL);
if (dctx == NULL) {
break;
}
bio = BIO_new(BIO_s_mem());
BIO_puts(bio, PublicKey().c_str());
if (OSSL_DECODER_from_bio(dctx, bio) == 0) {
break;
}
ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
if (ctx == NULL) {
break;
}
if (EVP_PKEY_encrypt_init_ex(ctx, NULL) <= 0) {
break;
}
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
break;
}
size_t enc_len = 0;
if (EVP_PKEY_encrypt(ctx, NULL, &enc_len, (unsigned char*)data.data(), data.size()) <= 0) {
break;
}
enc.resize(enc_len, 0);
if (EVP_PKEY_encrypt(ctx, (unsigned char*)enc.data(), &enc_len, (unsigned char*)data.data(), data.size()) <= 0) {
enc.resize(0);
break;
}
} while (0);
if (bio) {
BIO_free(bio);
}
if (dctx != NULL) {
OSSL_DECODER_CTX_free(dctx);
}
if (pkey) {
EVP_PKEY_free(pkey);
}
if (ctx != NULL) {
EVP_PKEY_CTX_free(ctx);
}
return enc;
#else
RSA* rsa = NULL;
BIO* bio = NULL;
EVP_PKEY* pkey = NULL;
ByteBuffer enc;
do {
if (data.empty()) {
break;
}
bio = BIO_new(BIO_s_mem());
BIO_puts(bio, PublicKey().c_str());
if (strncmp("-----BEGIN RSA", PublicKey().c_str(), 14) == 0) {
rsa = PEM_read_bio_RSAPublicKey(bio, &rsa, NULL, NULL);
}
else {
pkey = PEM_read_bio_PUBKEY(bio, &pkey, NULL, NULL);
rsa = pkey ? EVP_PKEY_get1_RSA(pkey) : NULL;
}
if (rsa == NULL) {
break;
}
int rsa_len = RSA_size(rsa);
enc.resize(rsa_len, 0);
if (RSA_public_encrypt(data.size(), (unsigned char*)data.data(), (unsigned char*)enc.data(), rsa, RSA_PKCS1_PADDING) < 0) {
enc.resize(0);
}
} while (0);
if (bio) {
BIO_free(bio);
}
if (pkey) {
EVP_PKEY_free(pkey);
}
if (rsa) {
RSA_free(rsa);
}
return enc;
#endif
}