Files
android/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp
Fred Gylys-Colwell 3164194908 Move keybox and root certificate handling into new class.
Merge from Widevine repo of http://go/wvgerrit/22804

Create a class, AuthenticationRoot, to encapsulate the objects and
logic for managing either keyboxes or certificates as the device's
root of trust.

Currently the class provides the existing keybox-related functions
needed by oemcrypto's CryptoEngine. It will be extended to provide
both keybox and certificate related functions, and the logic to
determine whether keybox or certificate based authentication should
be performed.

Change-Id: I792d1bfc8e9a81bbfd2baec20e3b3d182f0392f7
2017-01-20 16:57:32 -08:00

95 lines
2.2 KiB
C++

// Copyright 2013 Google Inc. All Rights Reserved.
//
// Mock implementation of OEMCrypto APIs
//
#include "oemcrypto_rsa_key_shared.h"
#include <assert.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include "oemcrypto_logging.h"
namespace {
void dump_openssl_error() {
while (unsigned long err = ERR_get_error()) {
char buffer[120];
LOGE("openssl error -- %lu -- %s",
err, ERR_error_string(err, buffer));
}
}
} // namespace
namespace wvoec_mock {
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();
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;
}
key_owned_ = true;
}
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;
}
}
} // namespace wvoec_mock