19#include <packager/media/base/rsa_key.h>
26#include <absl/log/check.h>
27#include <absl/log/log.h>
28#include <mbedtls/ctr_drbg.h>
29#include <mbedtls/entropy.h>
30#include <mbedtls/error.h>
31#include <mbedtls/md.h>
32#include <mbedtls/pk.h>
33#include <mbedtls/rsa.h>
37const size_t kPssSaltLength = 20u;
39std::string mbedtls_strerr(
int rv) {
41 std::string output(mbedtls_high_level_strerr(rv));
46 const char* low_level_error = mbedtls_low_level_strerr(rv);
47 if (low_level_error) {
49 output += low_level_error;
55std::string sha1(
const std::string& message) {
56 const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
59 std::string hash(mbedtls_md_get_size(md_info), 0);
61 mbedtls_md(md_info,
reinterpret_cast<const uint8_t*
>(message.data()),
62 message.size(),
reinterpret_cast<uint8_t*
>(hash.data())));
72RsaPrivateKey::RsaPrivateKey() {
73 mbedtls_pk_init(&pk_context_);
74 mbedtls_entropy_init(&entropy_context_);
75 mbedtls_ctr_drbg_init(&prng_context_);
78RsaPrivateKey::~RsaPrivateKey() {
79 mbedtls_pk_free(&pk_context_);
80 mbedtls_entropy_free(&entropy_context_);
81 mbedtls_ctr_drbg_free(&prng_context_);
86 if (!key->Deserialize(serialized_key)) {
92bool RsaPrivateKey::Deserialize(
const std::string& serialized_key) {
93 const mbedtls_pk_info_t* pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
96 CHECK_EQ(mbedtls_ctr_drbg_seed(&prng_context_, mbedtls_entropy_func,
97 &entropy_context_, NULL,
101 int rv = mbedtls_pk_parse_key(
102 &pk_context_,
reinterpret_cast<const uint8_t*
>(serialized_key.data()),
103 serialized_key.size(),
105 0, mbedtls_ctr_drbg_random, &prng_context_);
107 LOG(ERROR) <<
"RSA private key failed to load: " << mbedtls_strerr(rv);
112 mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pk_context_);
113 rv = mbedtls_rsa_set_padding(rsa_context, MBEDTLS_RSA_PKCS_V21,
116 LOG(ERROR) <<
"RSA private key failed to set padding: "
117 << mbedtls_strerr(rv);
125 std::string* decrypted_message) {
126 DCHECK(decrypted_message);
128 mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pk_context_);
130 size_t rsa_size = mbedtls_rsa_get_len(rsa_context);
131 if (encrypted_message.size() != rsa_size) {
132 LOG(ERROR) <<
"Encrypted RSA message has the wrong size (expected "
133 << rsa_size <<
", actual " << encrypted_message.size() <<
").";
136 decrypted_message->resize(encrypted_message.size());
138 size_t decrypted_size = 0;
139 int rv = mbedtls_rsa_rsaes_oaep_decrypt(
140 rsa_context, mbedtls_ctr_drbg_random, &prng_context_,
143 reinterpret_cast<const uint8_t*
>(encrypted_message.data()),
144 reinterpret_cast<uint8_t*
>(decrypted_message->data()),
145 decrypted_message->size());
148 LOG(ERROR) <<
"RSA private decrypt failure: " << mbedtls_strerr(rv);
151 decrypted_message->resize(decrypted_size);
156 std::string* signature) {
158 if (message.empty()) {
159 LOG(ERROR) <<
"Message to be signed is empty.";
163 mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pk_context_);
165 size_t rsa_size = mbedtls_rsa_get_len(rsa_context);
166 signature->resize(rsa_size);
168 std::string hash = sha1(message);
169 int rv = mbedtls_rsa_rsassa_pss_sign_ext(
170 rsa_context, mbedtls_ctr_drbg_random, &prng_context_, MBEDTLS_MD_SHA1,
171 static_cast<unsigned int>(hash.size()),
172 reinterpret_cast<const uint8_t*
>(hash.data()), kPssSaltLength,
173 reinterpret_cast<uint8_t*
>(signature->data()));
176 LOG(ERROR) <<
"RSA sign failure: " << mbedtls_strerr(rv);
182RsaPublicKey::RsaPublicKey() {
183 mbedtls_pk_init(&pk_context_);
184 mbedtls_entropy_init(&entropy_context_);
185 mbedtls_ctr_drbg_init(&prng_context_);
188RsaPublicKey::~RsaPublicKey() {
189 mbedtls_pk_free(&pk_context_);
190 mbedtls_entropy_free(&entropy_context_);
191 mbedtls_ctr_drbg_free(&prng_context_);
196 if (!key->Deserialize(serialized_key)) {
199 return key.release();
202bool RsaPublicKey::Deserialize(
const std::string& serialized_key) {
203 const mbedtls_pk_info_t* pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
206 CHECK_EQ(mbedtls_ctr_drbg_seed(&prng_context_, mbedtls_entropy_func,
207 &entropy_context_, NULL,
211 int rv = mbedtls_pk_parse_public_key(
212 &pk_context_,
reinterpret_cast<const uint8_t*
>(serialized_key.data()),
213 serialized_key.size());
215 LOG(ERROR) <<
"RSA public key failed to load: " << mbedtls_strerr(rv);
220 mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pk_context_);
221 rv = mbedtls_rsa_set_padding(rsa_context, MBEDTLS_RSA_PKCS_V21,
224 LOG(ERROR) <<
"RSA public key failed to set padding: "
225 << mbedtls_strerr(rv);
233 std::string* encrypted_message) {
234 DCHECK(encrypted_message);
235 if (clear_message.empty()) {
236 LOG(ERROR) <<
"Message to be encrypted is empty.";
240 mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pk_context_);
242 size_t rsa_size = mbedtls_rsa_get_len(rsa_context);
243 encrypted_message->resize(rsa_size);
245 int rv = mbedtls_rsa_rsaes_oaep_encrypt(
246 rsa_context, mbedtls_ctr_drbg_random, &prng_context_,
248 0, clear_message.size(),
249 reinterpret_cast<const uint8_t*
>(clear_message.data()),
250 reinterpret_cast<uint8_t*
>(encrypted_message->data()));
253 LOG(ERROR) <<
"RSA public encrypt failure: " << mbedtls_strerr(rv);
260 const std::string& signature) {
261 if (message.empty()) {
262 LOG(ERROR) <<
"Signed message is empty.";
266 mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pk_context_);
268 size_t rsa_size = mbedtls_rsa_get_len(rsa_context);
269 if (signature.size() != rsa_size) {
270 LOG(ERROR) <<
"Message signature is of the wrong size (expected "
271 << rsa_size <<
", actual " << signature.size() <<
").";
276 std::string hash = sha1(message);
277 int rv = mbedtls_rsa_rsassa_pss_verify_ext(
278 rsa_context, MBEDTLS_MD_SHA1,
static_cast<unsigned int>(hash.size()),
279 reinterpret_cast<const uint8_t*
>(hash.data()), MBEDTLS_MD_SHA1,
280 kPssSaltLength,
reinterpret_cast<const uint8_t*
>(signature.data()));
283 LOG(ERROR) <<
"RSA signature verification failed: " << mbedtls_strerr(rv);
All the methods that are virtual are virtual for mocking.