Implement provisioning 3.0 functionality in oemcrypto mock
Merge from widevine repo of http://go/wvgerrit/21684 This CL adds provisioning 3.0 functionality to the OEMCrypto reference implementation. Change-Id: I60c1fd88f246d443e0ae59ad56862c2ea9d95445
This commit is contained in:
@@ -242,12 +242,71 @@ void SessionKeyTable::UpdateDuration(const KeyControlBlock& control) {
|
||||
}
|
||||
}
|
||||
|
||||
void RSA_shared_ptr::reset() {
|
||||
if (rsa_key_ && key_owned_) {
|
||||
RSA_free(rsa_key_);
|
||||
}
|
||||
key_owned_ = false;
|
||||
rsa_key_ = NULL;
|
||||
}
|
||||
|
||||
bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) {
|
||||
assert(buffer != NULL);
|
||||
reset();
|
||||
key_owned_ = true;
|
||||
uint8_t* pkcs8_rsa_key = const_cast<uint8_t*>(buffer);
|
||||
BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length);
|
||||
if (bio == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]");
|
||||
return false;
|
||||
}
|
||||
bool success = true;
|
||||
PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL);
|
||||
if (pkcs8_pki == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL]");
|
||||
success = false;
|
||||
}
|
||||
EVP_PKEY* evp = NULL;
|
||||
if (success) {
|
||||
evp = EVP_PKCS82PKEY(pkcs8_pki);
|
||||
if (evp == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned NULL]");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
rsa_key_ = EVP_PKEY_get1_RSA(evp);
|
||||
if (rsa_key_ == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (evp != NULL) {
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
if (pkcs8_pki != NULL) {
|
||||
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
|
||||
}
|
||||
BIO_free(bio);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
switch (RSA_check_key(rsa_key_)) {
|
||||
case 1: // valid.
|
||||
return true;
|
||||
case 0: // not valid.
|
||||
LOGE("[LoadPkcs8RsaKey(): rsa key not valid]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
default: // -1 == check failed.
|
||||
LOGE("[LoadPkcs8RsaKey(): error checking rsa key]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SessionContext::~SessionContext() {
|
||||
if (usage_entry_) usage_entry_->set_session(NULL);
|
||||
if (rsa_key_ && rsa_key_ != ce_->rsa_key()) {
|
||||
RSA_free(rsa_key_);
|
||||
rsa_key_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal utility function to derive key using CMAC-128
|
||||
@@ -339,20 +398,20 @@ bool SessionContext::DeriveKeys(const std::vector<uint8_t>& master_key,
|
||||
bool SessionContext::RSADeriveKeys(const std::vector<uint8_t>& enc_session_key,
|
||||
const std::vector<uint8_t>& mac_key_context,
|
||||
const std::vector<uint8_t>& enc_key_context) {
|
||||
if (!rsa_key_) {
|
||||
if (!rsa_key()) {
|
||||
LOGE("[RSADeriveKeys(): no RSA key set]");
|
||||
return false;
|
||||
}
|
||||
if (enc_session_key.size() != static_cast<size_t>(RSA_size(rsa_key_))) {
|
||||
if (enc_session_key.size() != static_cast<size_t>(RSA_size(rsa_key()))) {
|
||||
LOGE("[RSADeriveKeys(): encrypted session key wrong size:%zu, expected %d]",
|
||||
enc_session_key.size(), RSA_size(rsa_key_));
|
||||
enc_session_key.size(), RSA_size(rsa_key()));
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
}
|
||||
session_key_.resize(RSA_size(rsa_key_));
|
||||
session_key_.resize(RSA_size(rsa_key()));
|
||||
int decrypted_size = RSA_private_decrypt(enc_session_key.size(),
|
||||
&enc_session_key[0],
|
||||
&session_key_[0], rsa_key_,
|
||||
&session_key_[0], rsa_key(),
|
||||
RSA_PKCS1_OAEP_PADDING);
|
||||
if (-1 == decrypted_size) {
|
||||
LOGE("[RSADeriveKeys(): error decrypting session key.]");
|
||||
@@ -402,11 +461,11 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
|
||||
}
|
||||
|
||||
size_t SessionContext::RSASignatureSize() {
|
||||
if (!rsa_key_) {
|
||||
if (!rsa_key()) {
|
||||
LOGE("[GenerateRSASignature(): no RSA key set]");
|
||||
return 0;
|
||||
}
|
||||
return static_cast<size_t>(RSA_size(rsa_key_));
|
||||
return static_cast<size_t>(RSA_size(rsa_key()));
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::GenerateRSASignature(
|
||||
@@ -417,19 +476,18 @@ OEMCryptoResult SessionContext::GenerateRSASignature(
|
||||
LOGE("[GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
if (!rsa_key_) {
|
||||
if (!rsa_key()) {
|
||||
LOGE("[GenerateRSASignature(): no RSA key set]");
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
if (*signature_length < static_cast<size_t>(RSA_size(rsa_key_))) {
|
||||
*signature_length = RSA_size(rsa_key_);
|
||||
if (*signature_length < static_cast<size_t>(RSA_size(rsa_key()))) {
|
||||
*signature_length = RSA_size(rsa_key());
|
||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
if ((padding_scheme & allowed_schemes_) != padding_scheme) {
|
||||
LOGE("[GenerateRSASignature(): padding_scheme not allowed]");
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
|
||||
// This is the standard padding scheme used for license requests.
|
||||
if (padding_scheme == kSign_RSASSA_PSS) {
|
||||
// Hash the message using SHA1.
|
||||
@@ -442,7 +500,7 @@ OEMCryptoResult SessionContext::GenerateRSASignature(
|
||||
|
||||
// Add PSS padding.
|
||||
std::vector<uint8_t> padded_digest(*signature_length);
|
||||
int status = RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, &padded_digest[0],
|
||||
int status = RSA_padding_add_PKCS1_PSS_mgf1(rsa_key(), &padded_digest[0],
|
||||
hash, EVP_sha1(), NULL,
|
||||
kPssSaltLength);
|
||||
if (status == -1) {
|
||||
@@ -453,7 +511,7 @@ OEMCryptoResult SessionContext::GenerateRSASignature(
|
||||
|
||||
// Encrypt PSS padded digest.
|
||||
status = RSA_private_encrypt(*signature_length, &padded_digest[0], signature,
|
||||
rsa_key_, RSA_NO_PADDING);
|
||||
rsa_key(), RSA_NO_PADDING);
|
||||
if (status == -1) {
|
||||
LOGE("[GeneratRSASignature(): error in private encrypt.]");
|
||||
dump_openssl_error();
|
||||
@@ -467,7 +525,7 @@ OEMCryptoResult SessionContext::GenerateRSASignature(
|
||||
}
|
||||
// Pad the message with PKCS1 padding, and then encrypt.
|
||||
size_t status = RSA_private_encrypt(message_length, message, signature,
|
||||
rsa_key_, RSA_PKCS1_PADDING);
|
||||
rsa_key(), RSA_PKCS1_PADDING);
|
||||
if (status != *signature_length) {
|
||||
LOGE("[GeneratRSASignature(): error in RSA private encrypt. status=%d]", status);
|
||||
dump_openssl_error();
|
||||
@@ -711,6 +769,29 @@ bool SessionContext::InstallKey(const KeyId& key_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionContext::InstallRSAEncryptedKey(const uint8_t *encrypted_message_key,
|
||||
size_t encrypted_message_key_length) {
|
||||
encryption_key_.resize(RSA_size(rsa_key()));
|
||||
int decrypted_size = RSA_private_decrypt( encrypted_message_key_length,
|
||||
encrypted_message_key,
|
||||
&encryption_key_[0], rsa_key(),
|
||||
RSA_PKCS1_OAEP_PADDING);
|
||||
if (-1 == decrypted_size) {
|
||||
LOGE("[RSADeriveKeys(): error decrypting session key.]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
}
|
||||
encryption_key_.resize(decrypted_size);
|
||||
if (decrypted_size != static_cast<int>(wvcdm::KEY_SIZE)) {
|
||||
LOGE("[RSADeriveKeys(): error. session key is wrong size: %d.]",
|
||||
decrypted_size);
|
||||
dump_openssl_error();
|
||||
encryption_key_.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::RefreshKey(
|
||||
const KeyId& key_id, const std::vector<uint8_t>& key_control,
|
||||
const std::vector<uint8_t>& key_control_iv) {
|
||||
@@ -790,7 +871,7 @@ bool SessionContext::DecryptRSAKey(const uint8_t* enc_rsa_key,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* pkcs8_rsa_key) {
|
||||
// Decrypt rsa key with keybox.
|
||||
uint8_t iv_buffer[ wvcdm::KEY_IV_SIZE];
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&encryption_key_[0], 128, &aes_key);
|
||||
@@ -804,7 +885,7 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* enc_rsa_key) {
|
||||
// Encrypt rsa key with keybox.
|
||||
uint8_t iv_buffer[ wvcdm::KEY_IV_SIZE];
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&encryption_key_[0], 128, &aes_key);
|
||||
@@ -813,79 +894,22 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
|
||||
size_t rsa_key_length,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length) {
|
||||
// Validate message signature
|
||||
if (!ValidateMessage(message, message_length, signature, signature_length)) {
|
||||
LOGE("[LoadRSAKey(): Could not verify signature]");
|
||||
return false;
|
||||
}
|
||||
if (rsa_key_) {
|
||||
RSA_free(rsa_key_);
|
||||
rsa_key_ = NULL;
|
||||
}
|
||||
bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
size_t rsa_key_length) {
|
||||
rsa_key_.reset();
|
||||
if (rsa_key_length < 8) {
|
||||
LOGE("[LoadRSAKey(): Very Short Buffer]");
|
||||
return false;
|
||||
}
|
||||
if( (memcmp(pkcs8_rsa_key, "SIGN", 4) == 0) ) {
|
||||
uint32_t *schemes_n = (uint32_t *)(pkcs8_rsa_key + 4);
|
||||
if ((memcmp(pkcs8_rsa_key, "SIGN", 4) == 0)) {
|
||||
uint32_t* schemes_n = (uint32_t*)(pkcs8_rsa_key + 4);
|
||||
allowed_schemes_ = htonl(*schemes_n);
|
||||
pkcs8_rsa_key += 8;
|
||||
rsa_key_length -= 8;
|
||||
} else {
|
||||
allowed_schemes_ = kSign_RSASSA_PSS;
|
||||
}
|
||||
BIO *bio = BIO_new_mem_buf(pkcs8_rsa_key, rsa_key_length);
|
||||
if ( bio == NULL ) {
|
||||
LOGE("[LoadRSAKey(): Could not allocate bio buffer]");
|
||||
return false;
|
||||
}
|
||||
bool success = true;
|
||||
PKCS8_PRIV_KEY_INFO *pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL);
|
||||
if (pkcs8_pki == NULL) {
|
||||
LOGE("d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL.");
|
||||
success = false;
|
||||
}
|
||||
EVP_PKEY *evp = NULL;
|
||||
if (success) {
|
||||
evp = EVP_PKCS82PKEY(pkcs8_pki);
|
||||
if (evp == NULL) {
|
||||
LOGE("EVP_PKCS82PKEY returned NULL.");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
rsa_key_ = EVP_PKEY_get1_RSA(evp);
|
||||
if (rsa_key_ == NULL) {
|
||||
LOGE("PrivateKeyInfo did not contain an RSA key.");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (evp != NULL) {
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
if (pkcs8_pki != NULL) {
|
||||
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
|
||||
}
|
||||
BIO_free(bio);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
switch (RSA_check_key(rsa_key_)) {
|
||||
case 1: // valid.
|
||||
return true;
|
||||
case 0: // not valid.
|
||||
LOGE("[LoadRSAKey(): rsa key not valid]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
default: // -1 == check failed.
|
||||
LOGE("[LoadRSAKey(): error checking rsa key]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
}
|
||||
return rsa_key_.LoadPkcs8RsaKey(pkcs8_rsa_key, rsa_key_length);
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
@@ -921,11 +945,11 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if ( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
|
||||
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
|
||||
LOGE("[Generic_Encrypt(): algorithm bad.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if ( buffer_length % AES_BLOCK_SIZE != 0 ) {
|
||||
if (buffer_length % AES_BLOCK_SIZE != 0) {
|
||||
LOGE("[Generic_Encrypt(): buffers size bad.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
@@ -935,7 +959,7 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Encrypt(): FAILURE]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
uint8_t iv_buffer[ wvcdm::KEY_IV_SIZE];
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv, wvcdm::KEY_IV_SIZE);
|
||||
AES_cbc_encrypt(in_buffer, out_buffer, buffer_length,
|
||||
&aes_key, iv_buffer, AES_ENCRYPT);
|
||||
@@ -981,11 +1005,11 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if ( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
|
||||
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
|
||||
LOGE("[Generic_Decrypt(): bad algorithm.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if ( buffer_length % AES_BLOCK_SIZE != 0 ) {
|
||||
if (buffer_length % AES_BLOCK_SIZE != 0) {
|
||||
LOGE("[Generic_Decrypt(): bad buffer size.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
@@ -995,7 +1019,7 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Decrypt(): FAILURE]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
uint8_t iv_buffer[ wvcdm::KEY_IV_SIZE];
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv, wvcdm::KEY_IV_SIZE);
|
||||
AES_cbc_encrypt(in_buffer, out_buffer, buffer_length,
|
||||
&aes_key, iv_buffer, AES_DECRYPT);
|
||||
@@ -1039,7 +1063,7 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if( algorithm != OEMCrypto_HMAC_SHA256 ) {
|
||||
if (algorithm != OEMCrypto_HMAC_SHA256) {
|
||||
LOGE("[Generic_Sign(): bad algorithm.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
@@ -1089,7 +1113,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if ( algorithm != OEMCrypto_HMAC_SHA256 ) {
|
||||
if (algorithm != OEMCrypto_HMAC_SHA256) {
|
||||
LOGE("[Generic_Verify(): bad algorithm.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
@@ -1190,21 +1214,20 @@ bool SessionContext::IsUsageEntryValid() {
|
||||
void SessionContext::ReleaseUsageEntry() { usage_entry_ = NULL; }
|
||||
|
||||
CryptoEngine::CryptoEngine(wvcdm::FileSystem* file_system)
|
||||
: current_session_(NULL),
|
||||
use_test_keybox_(false),
|
||||
: use_test_keybox_(false),
|
||||
file_system_(file_system),
|
||||
usage_table_(new UsageTable(this)),
|
||||
rsa_key_(NULL) {
|
||||
usage_table_(new UsageTable(this)) {
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
if (!supports_keybox() && !LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize)) {
|
||||
if ((provisioning_method() == OEMCrypto_DrmCertificate) &&
|
||||
!rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize)) {
|
||||
// This error message is OK in unit tests which use test certificate.
|
||||
LOGE("FATAL ERROR: Platform uses a baked-in certificate instead of a "
|
||||
"keybox, but the certificate could not be loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
CryptoEngine::~CryptoEngine() {
|
||||
current_session_ = NULL;
|
||||
sessions_.clear();
|
||||
if (usage_table_) delete usage_table_;
|
||||
}
|
||||
@@ -1214,19 +1237,15 @@ void CryptoEngine::Terminate() {}
|
||||
KeyboxError CryptoEngine::ValidateKeybox() { return keybox().Validate(); }
|
||||
|
||||
bool CryptoEngine::LoadTestRSAKey() {
|
||||
if (rsa_key_) {
|
||||
RSA_free(rsa_key_);
|
||||
rsa_key_ = NULL;
|
||||
}
|
||||
return LoadPkcs8RsaKey(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||
return rsa_key_.LoadPkcs8RsaKey(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||
}
|
||||
|
||||
SessionId CryptoEngine::CreateSession() {
|
||||
wvcdm::AutoLock lock(session_table_lock_);
|
||||
static int unique_id = 1;
|
||||
SessionId sid = (SessionId)++unique_id;
|
||||
SessionContext* sctx = new SessionContext(this, sid, this->rsa_key_);
|
||||
SessionContext* sctx = new SessionContext(this, sid, rsa_key_);
|
||||
sessions_[sid] = sctx;
|
||||
return sid;
|
||||
}
|
||||
@@ -1252,59 +1271,6 @@ SessionContext* CryptoEngine::FindSession(SessionId sid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CryptoEngine::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) {
|
||||
assert(buffer != NULL);
|
||||
uint8_t* pkcs8_rsa_key = const_cast<uint8_t*>(buffer);
|
||||
BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length);
|
||||
if (bio == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]");
|
||||
return false;
|
||||
}
|
||||
bool success = true;
|
||||
PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL);
|
||||
if (pkcs8_pki == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL]");
|
||||
success = false;
|
||||
}
|
||||
EVP_PKEY* evp = NULL;
|
||||
if (success) {
|
||||
evp = EVP_PKCS82PKEY(pkcs8_pki);
|
||||
if (evp == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned NULL]");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
rsa_key_ = EVP_PKEY_get1_RSA(evp);
|
||||
if (rsa_key_ == NULL) {
|
||||
LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (evp != NULL) {
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
if (pkcs8_pki != NULL) {
|
||||
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
|
||||
}
|
||||
BIO_free(bio);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
switch (RSA_check_key(rsa_key_)) {
|
||||
case 1: // valid.
|
||||
return true;
|
||||
case 0: // not valid.
|
||||
LOGE("[LoadPkcs8RsaKey(): rsa key not valid]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
default: // -1 == check failed.
|
||||
LOGE("[LoadPkcs8RsaKey(): error checking rsa key]");
|
||||
dump_openssl_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal utility function to decrypt the message
|
||||
bool SessionContext::DecryptMessage(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv,
|
||||
|
||||
Reference in New Issue
Block a user