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
95 lines
2.2 KiB
C++
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
|