rsa_{de,en}crypt_pkcs1_oaep
GitOrigin-RevId: 86e293dfc69bb861674e0034d509381a0ded2a1e
This commit is contained in:
parent
d3be8e7baa
commit
5cd79ae8ec
@ -15,11 +15,14 @@
|
||||
|
||||
#if TD_HAVE_OPENSSL
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#endif
|
||||
|
||||
#if TD_HAVE_ZLIB
|
||||
@ -554,4 +557,67 @@ uint64 crc64(Slice data) {
|
||||
return crc64_partial(data, static_cast<uint64>(-1)) ^ static_cast<uint64>(-1);
|
||||
}
|
||||
|
||||
Result<BufferSlice> rsa_encrypt_pkcs1_oaep(Slice public_key, Slice data) {
|
||||
BIO *mem_bio = BIO_new_mem_buf(public_key.data(), narrow_cast<int>(public_key.size()));
|
||||
SCOPE_EXIT {
|
||||
BIO_vfree(mem_bio);
|
||||
};
|
||||
|
||||
EVP_PKEY *pkey = PEM_read_bio_PUBKEY(mem_bio, nullptr, nullptr, nullptr);
|
||||
if (!pkey) {
|
||||
return Status::Error("Cannot read public key");
|
||||
}
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr);
|
||||
if (!ctx) {
|
||||
return Status::Error("Cannot create EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_encrypt_init(ctx) <= 0) {
|
||||
return Status::Error("Cannot init EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
||||
return Status::Error("Cannot set RSA_PKCS1_OAEP padding in EVP_PKEY_CTX");
|
||||
}
|
||||
size_t outlen;
|
||||
if (EVP_PKEY_encrypt(ctx, nullptr, &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot calculate encrypted length");
|
||||
}
|
||||
BufferSlice res(outlen);
|
||||
if (EVP_PKEY_encrypt(ctx, res.as_slice().ubegin(), &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return Status::Error("Cannot encrypt");
|
||||
}
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
Result<BufferSlice> rsa_decrypt_pkcs1_oaep(Slice private_key, Slice data) {
|
||||
BIO *mem_bio = BIO_new_mem_buf(private_key.data(), narrow_cast<int>(private_key.size()));
|
||||
SCOPE_EXIT {
|
||||
BIO_vfree(mem_bio);
|
||||
};
|
||||
|
||||
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(mem_bio, nullptr, nullptr, nullptr);
|
||||
if (!pkey) {
|
||||
return Status::Error("Cannot read private key");
|
||||
}
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr);
|
||||
if (!ctx) {
|
||||
return Status::Error("Cannot create EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
|
||||
return Status::Error("Cannot init EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
||||
return Status::Error("Cannot set RSA_PKCS1_OAEP padding in EVP_PKEY_CTX");
|
||||
}
|
||||
size_t outlen;
|
||||
if (EVP_PKEY_decrypt(ctx, nullptr, &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot calculate decrypted length");
|
||||
}
|
||||
BufferSlice res(outlen);
|
||||
if (EVP_PKEY_decrypt(ctx, res.as_slice().ubegin(), &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot decrypt");
|
||||
}
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
@ -81,6 +83,10 @@ void md5(Slice input, MutableSlice output);
|
||||
void pbkdf2_sha256(Slice password, Slice salt, int iteration_count, MutableSlice dest);
|
||||
void hmac_sha256(Slice key, Slice message, MutableSlice dest);
|
||||
|
||||
// Interface may be improved
|
||||
Result<BufferSlice> rsa_encrypt_pkcs1_oaep(Slice public_key, Slice data);
|
||||
Result<BufferSlice> rsa_decrypt_pkcs1_oaep(Slice public_key, Slice data);
|
||||
|
||||
void init_openssl_threads();
|
||||
#endif
|
||||
|
||||
|
@ -164,3 +164,53 @@ TEST(Crypto, crc64) {
|
||||
ASSERT_EQ(answers[i], td::crc64(strings[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static td::Slice rsa_private_key = R"ABCD(
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDeYT5/prmLEa2Q
|
||||
tZND+UwTmif8kl2VlXaMCjj1k1lJJq8BqS8cVM2vPnOPzFoiC2LYykhm4kk7goCC
|
||||
ZH6wez9yakg28fcq0Ycv0x8DL1K+VKHJuwIhVfQs//IY1/cBOrMESc+NQowPbv1t
|
||||
TIFxBO2gebnpLuseht8ix7XtpGC4qAaHN2aEvT2cRsnA76TAK1RVxf1OYGUFBDzY
|
||||
318WpVZfVIjcQ7K9+eU6b2Yb84VLlvJXw3e1rvw+fBzx2EjpD4zhXy11YppWDyV6
|
||||
HEb2hs3cGS/LbHfHvdcSfil2omaJP97MDEEY2HFxjR/E5CEf2suvPzX4XS3RE+S3
|
||||
2aEJaaQbAgMBAAECggEAKo3XRNwls0wNt5xXcvF4smOUdUuY5u/0AHZQUgYBVvM1
|
||||
GA9E+ZnsxjUgLgs/0DX3k16aHj39H4sohksuxxy+lmlqKkGBN8tioC85RwW+Qre1
|
||||
QgIsNS7ai+XqcQCavrx51z88nV53qNhnXIwAVR1JT6Ubg1i8G1pZxrEKyk/jRlJd
|
||||
mGjf6vjitH//PPkghPJ/D42k93YRcy+duOgqYDQpLZp8DiEGfYrX10B1H7HrWLV+
|
||||
Wp5KO1YXtKgQUplj6kYy72bVajbxYTvzgjaaKsh74jBO0uT3tHTtXG0dcKGb0VR/
|
||||
cqP/1H/lC9bAnAqAGefNusGJQZIElvTsrpIQXOeZsQKBgQD2W04S+FjqYYFjnEFX
|
||||
6eL4it01afs5M3/C6CcI5JQtN6p+Na4NCSILol33xwhakn87zqdADHawBYQVQ8Uw
|
||||
dPurl805wfkzN3AbfdDmtx0IJ8vK4HFpktRjfpwBVhlVtm1doAYFqqsuCF2vWW1t
|
||||
mM2YOSq4AnRHCeBb/P6kRIW0MwKBgQDnFawKKqiC4tuyBOkkEhexlm7x9he0md7D
|
||||
3Z2hc3Bmdcq1niw4wBq3HUxGLReGCcSr5epKSQwkunlTn5ZSC6Rmbe4zxsGIwbb3
|
||||
5W3342swBaoxEIuBokBvZ/xUOXVwiqKj+S/NzVkZcnT6K9V/HnUCQR+JBbQxFQaX
|
||||
iiezcjKoeQKBgCIVUcDoIQ0UPl10ocmy7xbpx177calhSZzCl5vwW9vBptHdRV5C
|
||||
VDZ92ThNjgdR205/8b23u7fwm2yBusdQd/0ufFMwVfTTB6yWBI/W56pYLya7VJWB
|
||||
nebB/n1k1w53tbvNRugDy7kLqUJ4Qd521ILp7dIVbNbjM+omH2jEnibnAoGBAIM5
|
||||
a1jaoJay/M86uqohHBNcuePtO8jzF+1iDAGC7HFCsrov+CzB6mnR2V6AfLtBEM4M
|
||||
4d8NXDf/LKawGUy+D72a74m3dG+UkbJ0Nt5t5pB+pwb1vkL/QFgDVOb/OhGOqI01
|
||||
FFBqLA6nUIZAHhzxzsBY+u90rb6xkey8J49faiUBAoGAaMgOgEvQB5H19ZL5tMkl
|
||||
A/DKtTz/NFzN4Zw/vNPVb7eNn4jg9M25d9xqvL4acOa+nuV3nLHbcUWE1/7STXw1
|
||||
gT58CvoEmD1AiP95nup+HKHENJ1DWMgF5MDfVQwGCvWP5/Qy89ybr0eG8HjbldbN
|
||||
MpSmzz2wOz152oGdOd3syT4=
|
||||
-----END PRIVATE KEY-----
|
||||
)ABCD";
|
||||
|
||||
static td::Slice rsa_public_key = R"ABCD(
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3mE+f6a5ixGtkLWTQ/lM
|
||||
E5on/JJdlZV2jAo49ZNZSSavAakvHFTNrz5zj8xaIgti2MpIZuJJO4KAgmR+sHs/
|
||||
cmpINvH3KtGHL9MfAy9SvlShybsCIVX0LP/yGNf3ATqzBEnPjUKMD279bUyBcQTt
|
||||
oHm56S7rHobfIse17aRguKgGhzdmhL09nEbJwO+kwCtUVcX9TmBlBQQ82N9fFqVW
|
||||
X1SI3EOyvfnlOm9mG/OFS5byV8N3ta78Pnwc8dhI6Q+M4V8tdWKaVg8lehxG9obN
|
||||
3Bkvy2x3x73XEn4pdqJmiT/ezAxBGNhxcY0fxOQhH9rLrz81+F0t0RPkt9mhCWmk
|
||||
GwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
)ABCD";
|
||||
|
||||
TEST(Crypto, rsa) {
|
||||
auto value = td::rand_string('a', 'z', 200);
|
||||
auto encrypted_value = td::rsa_encrypt_pkcs1_oaep(rsa_public_key, value).move_as_ok();
|
||||
auto decrypted_value = td::rsa_decrypt_pkcs1_oaep(rsa_private_key, encrypted_value.as_slice()).move_as_ok();
|
||||
ASSERT_TRUE(decrypted_value.as_slice().truncate(value.size()) == value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user