Refactor OEMCrypto Unit Tests

Merge from widevine repo of http://go/wvgerrit/21681

This CL refactors some oemcrypto unit tests in preparation for adding
Provisioning 3.0 tests.

- The signature GenerateNonce has changed.  Instead of the caller
  passing in a pointer for the nonce, we store the nonce in a member
  variable of Session.

- GenerateDerivedKeys is being replaced by InstallTestSessionKeys.
  This sets up and calls the appropriate derive keys method.  This
  function is in the test class, instead of the session class so that
  multiple sessions in a class can share the same wrapped rsa key.
  This will be modified for provisioning 3.0 in a future CL.

- Rename tests that require a keybox.  Some tests are specific for
  using a keybox to request a DRM cert. These tests are renamed so we
  can filter them out on devices that use an OEM Cert.  Corresponding
  tests for devices using provisioning 3.0 will be in a future CL.

- Some member variables and methods in the class Session were not
  used.  They are removed.

- Added openssl smart pointer.

- Comments.  I added comments.

- clang format.

Change-Id: Ib579a322858e0ef92652a42167241b35cf85a041
This commit is contained in:
Fred Gylys-Colwell
2016-11-29 15:05:23 -08:00
parent 4cac936b10
commit 0fb76d5c1b
6 changed files with 433 additions and 325 deletions

View File

@@ -33,6 +33,7 @@ class WvGenericOperationsTest : public testing::Test {
virtual void SetUp() {
::testing::Test::SetUp();
// TODO(fredgc or gmorgan): This should be updated for provisioning 3.0
// Load test keybox. This keybox will be used by any CryptoSession
// created by the CDM under test.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestKeybox());
@@ -72,7 +73,8 @@ class WvGenericOperationsTest : public testing::Test {
void OecSessionSetup(uint32_t oec_session_id) {
buffer_size_ = 160;
oec_util_session_.SetSessionId(oec_session_id);
oec_util_session_.GenerateTestSessionKeys();
// TODO(fredgc or gmorgan): This should be updated for provisioning 3.0
oec_util_session_.GenerateDerivedKeysFromKeybox();
MakeFourKeys();
}
@@ -202,7 +204,8 @@ TEST_F(WvGenericOperationsTest, NormalSessionOpenClose) {
TEST_F(WvGenericOperationsTest, GenerateSessionKeys) {
wvoec::Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.GenerateTestSessionKeys());
// TODO(fredgc or gmorgan): This should be updated for provisioning 3.0
ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromKeybox());
ASSERT_NO_FATAL_FAILURE(s.close());
}

View File

@@ -9,8 +9,10 @@
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <stdint.h>
#include <gtest/gtest.h>
@@ -18,13 +20,14 @@
#include <string>
#include <vector>
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_device_features.h"
#include "oec_test_data.h"
#include "oemcrypto_key_mock.h"
#include "OEMCryptoCENC.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
#include "wv_keybox.h"
using namespace std;
@@ -69,6 +72,23 @@ void dump_openssl_error() {
}
}
template <typename T, void (*func)(T*)>
class openssl_ptr {
public:
explicit openssl_ptr(T* p = NULL) : ptr_(p) {}
~openssl_ptr() {
if (ptr_) func(ptr_);
}
T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; }
T* get() const { return ptr_; }
bool NotNull() { return ptr_; }
private:
T* ptr_;
CORE_DISALLOW_COPY_AND_ASSIGN(openssl_ptr);
};
Session::Session()
: open_(false),
forced_session_id_(false),
@@ -113,8 +133,8 @@ void Session::close() {
open_ = false;
}
void Session::GenerateNonce(uint32_t* nonce, int* error_counter) {
if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), nonce)) {
void Session::GenerateNonce(int* error_counter) {
if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), &nonce_)) {
return;
}
if (error_counter) {
@@ -122,7 +142,7 @@ void Session::GenerateNonce(uint32_t* nonce, int* error_counter) {
} else {
sleep(1); // wait a second, then try again.
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GenerateNonce(session_id(), nonce));
OEMCrypto_GenerateNonce(session_id(), &nonce_));
}
}
@@ -148,7 +168,7 @@ void Session::FillDefaultContext(vector<uint8_t>* mac_context,
}
void Session::GenerateDerivedKeysFromKeybox() {
GenerateNonce(&nonce_);
GenerateNonce();
vector<uint8_t> mac_context;
vector<uint8_t> enc_context;
FillDefaultContext(&mac_context, &enc_context);
@@ -168,10 +188,11 @@ void Session::GenerateDerivedKeysFromKeybox() {
void Session::GenerateDerivedKeysFromSessionKey() {
// Uses test certificate.
GenerateNonce(&nonce_);
GenerateNonce();
vector<uint8_t> session_key;
vector<uint8_t> enc_session_key;
PreparePublicKey();
ASSERT_TRUE(GenerateRSASessionKey(&enc_session_key));
ASSERT_TRUE(GenerateRSASessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context;
vector<uint8_t> enc_context;
FillDefaultContext(&mac_context, &enc_context);
@@ -190,14 +211,6 @@ void Session::GenerateDerivedKeysFromSessionKey() {
enc_key_ = wvcdm::a2b_hex("CB477D09014D72C9B8DCE76C33EA43B3");
}
void Session::GenerateTestSessionKeys() {
if (global_features.derive_key_method == DeviceFeatures::LOAD_TEST_RSA_KEY) {
GenerateDerivedKeysFromSessionKey();
} else {
GenerateDerivedKeysFromKeybox();
}
}
void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
uint8_t* pst_ptr = NULL;
if (pst.length() > 0) {
@@ -236,9 +249,11 @@ void Session::VerifyTestKeys() {
// control duration and bits stored in network byte order. For printing
// we change to host byte order.
ASSERT_EQ((htonl_fnc(license_.keys[i].control.duration)),
(htonl_fnc(block.duration))) << "For key " << i;
(htonl_fnc(block.duration)))
<< "For key " << i;
ASSERT_EQ(htonl_fnc(license_.keys[i].control.control_bits),
htonl_fnc(block.control_bits)) << "For key " << i;
htonl_fnc(block.control_bits))
<< "For key " << i;
}
}
}
@@ -278,8 +293,8 @@ void Session::SetKeyId(int index, const string& key_id) {
void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
uint32_t nonce, const std::string& pst) {
EXPECT_EQ(1, RAND_pseudo_bytes(license_.mac_key_iv,
sizeof(license_.mac_key_iv)));
EXPECT_EQ(
1, RAND_pseudo_bytes(license_.mac_key_iv, sizeof(license_.mac_key_iv)));
EXPECT_EQ(1, RAND_pseudo_bytes(license_.mac_keys, sizeof(license_.mac_keys)));
for (unsigned int i = 0; i < num_keys_; i++) {
memset(license_.keys[i].key_id, 0, kTestKeyIdMaxLength);
@@ -353,8 +368,10 @@ void Session::EncryptAndSign() {
FillKeyArray(encrypted_license(), key_array_);
}
void Session::EncryptMessage(RSAPrivateKeyMessage* data,
RSAPrivateKeyMessage* encrypted) {
void Session::EncryptProvisioningMessage(
RSAPrivateKeyMessage* data, RSAPrivateKeyMessage* encrypted,
const vector<uint8_t>& encryption_key) {
ASSERT_EQ(encryption_key.size(), wvcdm::KEY_SIZE);
*encrypted = *data;
size_t padding = wvcdm::KEY_SIZE - (data->rsa_key_length % wvcdm::KEY_SIZE);
memset(data->rsa_key + data->rsa_key_length, static_cast<uint8_t>(padding),
@@ -363,7 +380,7 @@ void Session::EncryptMessage(RSAPrivateKeyMessage* data,
uint8_t iv_buffer[16];
memcpy(iv_buffer, &data->rsa_key_iv[0], wvcdm::KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_set_encrypt_key(&encryption_key[0], 128, &aes_key);
AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0],
encrypted->rsa_key_length, &aes_key, iv_buffer, AES_ENCRYPT);
}
@@ -385,17 +402,15 @@ void Session::ClientSignMessage(const vector<uint8_t>& data,
&(data.front()), data.size(), &(signature->front()), &md_len);
}
// This verifies the signature computed by OEMCrypto using the client mac keys.
// This is used when a device requests a license renewal. It is also used for
// a license request authenticated by a keybox. The first use case is needed
// for devices with a keybox or without.
void Session::VerifyClientSignature(size_t data_length) {
// In the real world, a message should be signed by the client and
// verified by the server. This simulates that.
vector<uint8_t> data(data_length);
for(int i=0; i < data.size(); i++) data[i] = i % 0xFF;
for (int i = 0; i < data.size(); i++) data[i] = i % 0xFF;
OEMCryptoResult sts;
size_t gen_signature_length = 0;
sts = OEMCrypto_GenerateSignature(session_id(), &data[0], data.size(),
NULL, &gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), &data[0], data.size(), NULL,
&gen_signature_length);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
ASSERT_EQ(static_cast<size_t>(32), gen_signature_length);
vector<uint8_t> gen_signature(gen_signature_length);
@@ -520,36 +535,9 @@ void Session::MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
size_t message_size,
std::vector<uint8_t>* signature,
uint32_t allowed_schemes,
const vector<uint8_t>& rsa_key) {
// Dummy context for testing signature generation.
vector<uint8_t> context = wvcdm::a2b_hex(
"0a4c08001248000000020000101907d9ffde13aa95c122678053362136bdf840"
"8f8276e4c2d87ec52b61aa1b9f646e58734930acebe899b3e464189a14a87202"
"fb02574e70640bd22ef44b2d7e3912250a230a14080112100915007caa9b5931"
"b76a3a85f046523e10011a09393837363534333231180120002a0c3138383637"
"38373430350000");
OEMCryptoResult sts;
// Generate signature
size_t gen_signature_length = 0;
sts = OEMCrypto_GenerateSignature(session_id(), &context[0], context.size(),
NULL, &gen_signature_length);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
ASSERT_EQ(static_cast<size_t>(32), gen_signature_length);
vector<uint8_t> gen_signature(gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), &context[0], context.size(),
&gen_signature[0], &gen_signature_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
std::vector<uint8_t> expected_signature;
ClientSignMessage(context, &expected_signature);
ASSERT_EQ(expected_signature, gen_signature);
// Rewrap Canned Response
// In the real world, the signature above would just have been used to
// contact the certificate provisioning server to get this response.
const vector<uint8_t>& rsa_key,
const vector<uint8_t>* encryption_key) {
if (encryption_key == NULL) encryption_key = &enc_key_;
struct RSAPrivateKeyMessage message;
if (allowed_schemes != kSign_RSASSA_PSS) {
uint32_t algorithm_n = htonl(allowed_schemes);
@@ -564,7 +552,7 @@ void Session::MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
EXPECT_EQ(1, RAND_pseudo_bytes(message.rsa_key_iv, wvcdm::KEY_IV_SIZE));
message.nonce = nonce_;
EncryptMessage(&message, encrypted);
EncryptProvisioningMessage(&message, encrypted, *encryption_key);
ServerSignBuffer(reinterpret_cast<const uint8_t*>(encrypted), message_size,
signature);
}
@@ -601,35 +589,29 @@ void Session::PreparePublicKey(const uint8_t* rsa_key, size_t rsa_key_length) {
rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048);
}
uint8_t* p = const_cast<uint8_t*>(rsa_key);
BIO* bio = BIO_new_mem_buf(p, rsa_key_length);
ASSERT_TRUE(NULL != bio);
PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL);
ASSERT_TRUE(NULL != pkcs8_pki);
EVP_PKEY* evp = NULL;
evp = EVP_PKCS82PKEY(pkcs8_pki);
ASSERT_TRUE(NULL != evp);
openssl_ptr<BIO, BIO_vfree> bio(BIO_new_mem_buf(p, rsa_key_length));
ASSERT_TRUE(bio.NotNull());
openssl_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8_pki(
d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL));
ASSERT_TRUE(pkcs8_pki.NotNull());
openssl_ptr<EVP_PKEY, EVP_PKEY_free> evp(EVP_PKCS82PKEY(pkcs8_pki.get()));
ASSERT_TRUE(evp.NotNull());
if (public_rsa_) RSA_free(public_rsa_);
public_rsa_ = EVP_PKEY_get1_RSA(evp);
EVP_PKEY_free(evp);
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
BIO_free(bio);
public_rsa_ = EVP_PKEY_get1_RSA(evp.get());
if (!public_rsa_) {
cout << "d2i_RSAPrivateKey failed. ";
dump_openssl_error();
ASSERT_TRUE(false);
FAIL() << "Could not parse public RSA key.";
}
switch (RSA_check_key(public_rsa_)) {
case 1: // valid.
ASSERT_TRUE(true);
return;
case 0: // not valid.
cout << "[rsa key not valid] ";
dump_openssl_error();
ASSERT_TRUE(false);
FAIL() << "[rsa key not valid] ";
default: // -1 == check failed.
cout << "[error checking rsa key] ";
dump_openssl_error();
ASSERT_TRUE(false);
FAIL() << "[error checking rsa key] ";
}
}
@@ -693,14 +675,12 @@ void Session::VerifyRSASignature(const vector<uint8_t>& message,
EXPECT_EQ(static_cast<size_t>(RSA_size(public_rsa_)), signature_length)
<< "Signature size is wrong. " << signature_length << ", should be "
<< RSA_size(public_rsa_) << "\n";
if (padding_scheme == kSign_RSASSA_PSS) {
EVP_PKEY* pkey = EVP_PKEY_new();
ASSERT_TRUE(EVP_PKEY_set1_RSA(pkey, public_rsa_) == 1);
openssl_ptr<EVP_PKEY, EVP_PKEY_free> pkey(EVP_PKEY_new());
ASSERT_EQ(1, EVP_PKEY_set1_RSA(pkey.get(), public_rsa_));
const bool ok = VerifyPSSSignature(pkey, &message[0], message.size(),
const bool ok = VerifyPSSSignature(pkey.get(), &message[0], message.size(),
signature, signature_length);
EVP_PKEY_free(pkey);
EXPECT_TRUE(ok) << "PSS signature check failed.";
} else if (padding_scheme == kSign_PKCS1_Block1) {
vector<uint8_t> padded_digest(signature_length);
@@ -717,20 +697,20 @@ void Session::VerifyRSASignature(const vector<uint8_t>& message,
}
}
bool Session::GenerateRSASessionKey(vector<uint8_t>* enc_session_key) {
bool Session::GenerateRSASessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* enc_session_key) {
if (!public_rsa_) {
cout << "No public RSA key loaded in test code.\n";
return false;
}
vector<uint8_t> session_key =
wvcdm::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1");
*session_key = wvcdm::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1");
enc_session_key->assign(RSA_size(public_rsa_), 0);
int status = RSA_public_encrypt(session_key.size(), &session_key[0],
int status = RSA_public_encrypt(session_key->size(), &(session_key->front()),
&(enc_session_key->front()), public_rsa_,
RSA_PKCS1_OAEP_PADDING);
int size = static_cast<int>(RSA_size(public_rsa_));
if (status != size) {
cout << "GenerateRSASessionKey error encrypting session key. ";
cout << "GenerateRSASessionKey error encrypting session key.\n";
dump_openssl_error();
return false;
}
@@ -744,21 +724,6 @@ void Session::InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key) {
GenerateDerivedKeysFromSessionKey();
}
void Session::DisallowDeriveKeys() {
GenerateNonce(&nonce_);
vector<uint8_t> enc_session_key;
PreparePublicKey();
ASSERT_TRUE(GenerateRSASessionKey(&enc_session_key));
vector<uint8_t> mac_context;
vector<uint8_t> enc_context;
FillDefaultContext(&mac_context, &enc_context);
ASSERT_NE(OEMCrypto_SUCCESS,
OEMCrypto_DeriveKeysFromSessionKey(
session_id(), &enc_session_key[0], enc_session_key.size(),
&mac_context[0], mac_context.size(), &enc_context[0],
enc_context.size()));
}
void Session::GenerateReport(const std::string& pst, bool expect_success,
Session* other) {
if (other) { // If other is specified, copy mac keys.

View File

@@ -66,10 +66,10 @@ const size_t kTestKeyIdMaxLength = 16;
// Most content will use a key id that is 16 bytes long.
const int kDefaultKeyIdLength = 16;
const size_t kMaxTestRSAKeyLength = 2000; // Rough estimate.
const size_t kMaxPSTLength = 255; // In specification.
const size_t kMaxMessageSize = 8 * 1024; // In specification.
const size_t kMaxDecryptSize = 100 * 1024; // In specification.
const size_t kMaxTestRSAKeyLength = 2000; // Rough estimate.
const size_t kMaxPSTLength = 255; // In specification.
const size_t kMaxMessageSize = 8 * 1024; // In specification.
const size_t kMaxDecryptSize = 100 * 1024; // In specification.
typedef struct {
uint8_t key_id[kTestKeyIdMaxLength];
@@ -92,6 +92,8 @@ struct MessageData {
uint8_t pst[kMaxPSTLength];
};
// This structure will be signed to simulate a provisioning response from the
// server.
struct RSAPrivateKeyMessage {
uint8_t rsa_key[kMaxTestRSAKeyLength];
uint8_t rsa_key_iv[wvcdm::KEY_IV_SIZE];
@@ -116,84 +118,166 @@ class Session {
Session();
~Session();
// Returns the most recently generated nonce.
// Valid after call to GenerateNonce.
uint32_t get_nonce() { return nonce_; }
// Valid after call to open().
uint32_t session_id() { return (uint32_t)session_id_; }
// Call OEMCrypto_OpenSession, with GTest ASSERTs.
void open();
// Call OEMCrypto_CloseSession, with GTest ASSERTs.
void close();
// Artifically set session id without calling OEMCrypto_OpenSession. This is
// used in core/test/generic_crypto_unittest.cpp.
void SetSessionId(uint32_t session_id);
uint32_t GetOecSessionId() { return session_id_; }
void GenerateNonce(uint32_t* nonce, int* error_counter = NULL);
// Generates one nonce. If error_counter is null, this will sleep 1 second
// and try again if a nonce flood has been detected. If error_counter is
// not null, it will be incremented when a nonce flood is detected.
void GenerateNonce(int* error_counter = NULL);
// Fill the vectors with test context which generate known mac and enc keys.
void FillDefaultContext(vector<uint8_t>* mac_context,
vector<uint8_t>* enc_context);
// Generate known mac and enc keys using OEMCrypto_GenerateDerivedKeys and
// also fill out enc_key_, mac_key_server_, and mac_key_client_.
void GenerateDerivedKeysFromKeybox();
// Generate known mac and enc keys using OEMCrypto_DeriveKeysFromSessionKey
// and also fill out enc_key_, mac_key_server_, and mac_key_client_.
void GenerateDerivedKeysFromSessionKey();
void GenerateTestSessionKeys();
// Loads and verifies the keys in the message pointed to by message_ptr()
// using OEMCrypto_LoadKeys. This message should have already been created
// by FillSimpleMessage, modified if needed, and then encrypted and signed by
// the server's mac key in EncryptAndSign.
void LoadTestKeys(const std::string& pst = "", bool new_mac_keys = true);
// This uses OEMCrypto_QueryKeyControl to check that the keys in OEMCrypto
// have the correct key control data.
void VerifyTestKeys();
// This creates a refresh key or license renewal message, signs it with the
// server's mac key, and calls OEMCrypto_RefreshKeys.
void RefreshTestKeys(const size_t key_count, uint32_t control_bits,
uint32_t nonce, OEMCryptoResult expected_result);
// This sets the key id in the current message data to the specified string.
// This is used to test with different key id lengths.
void SetKeyId(int index, const string& key_id);
// This fills the data structure license_ with key information. This data
// can be modified, and then should be encrypted and signed in EncryptAndSign
// before being loaded in LoadTestKeys.
void FillSimpleMessage(uint32_t duration, uint32_t control, uint32_t nonce,
const std::string& pst = "");
// Like FillSimpleMessage, this fills encrypted_license_ with data. The name
// is a little misleading: the license renewal message is not encrypted, it
// is just signed. The signature is computed in RefreshTestKeys, above.
void FillRefreshMessage(size_t key_count, uint32_t control_bits,
uint32_t nonce);
// This copies data from license_ to encrypted_license_, and then encrypts
// each field in the key array appropriately. It then signes the buffer with
// the server mac keys. It then fills out the key_array_ so that pointers in
// that array point to the locations in the encrypted message.
void EncryptAndSign();
void EncryptMessage(RSAPrivateKeyMessage* data,
RSAPrivateKeyMessage* encrypted);
// This encrypts an RSAPrivateKeyMessage with encryption_key so that it may be
// loaded with OEMCrypto_RewrapDeviceRSAKey.
void EncryptProvisioningMessage(RSAPrivateKeyMessage* data,
RSAPrivateKeyMessage* encrypted,
const vector<uint8_t>& encryption_key);
// Sign the buffer with server's mac key.
void ServerSignBuffer(const uint8_t* data, size_t data_length,
std::vector<uint8_t>* signature);
// Sign the buffer with client's known mac key. Known test keys must be
// installed first.
void ClientSignMessage(const vector<uint8_t>& data,
std::vector<uint8_t>* signature);
// This checks the signature generated by OEMCrypto_GenerateSignature against
// that generaged by ClientSignMessage.
void VerifyClientSignature(size_t data_length = 400);
// Set the pointers in key_array[*] to point values inside data. This is
// needed to satisfy range checks in OEMCrypto_LoadKeys.
void FillKeyArray(const MessageData& data, OEMCrypto_KeyObject* key_array);
// As in FillKeyArray but for the license renewal message passed to
// OEMCrypto_RefreshKeys.
void FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array,
size_t key_count);
// Encrypt a block of data using CTR mode.
void EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const uint8_t* starting_iv, vector<uint8_t>* out_buffer);
// Encrypt some data and pass to OEMCrypto_DecryptCENC to verify decryption.
void TestDecryptCTR(bool select_key_first = true,
OEMCryptoResult expected_result = OEMCrypto_SUCCESS,
int key_index = 0);
// Creates RSAPrivateKeyMessage for the specified rsa_key, encrypts it with
// the specified encryption key, and then signs it with the server's mac key.
// If encryption_key is null, use the session's enc_key_.
void MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
size_t message_size, std::vector<uint8_t>* signature,
uint32_t allowed_schemes,
const vector<uint8_t>& rsa_key);
const vector<uint8_t>& rsa_key,
const vector<uint8_t>* encryption_key = NULL);
// Calls OEMCrypto_RewrapDeviceRSAKey with the given provisioning response
// message.
void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
size_t message_size, const std::vector<uint8_t>& signature,
vector<uint8_t>* wrapped_key, bool force);
// Loads the specified RSA public key into public_rsa_. If rsa_key is null,
// the default test key is loaded.
void PreparePublicKey(const uint8_t* rsa_key = NULL,
size_t rsa_key_length = 0);
// Verifies the given signature is from the given message and RSA key, pkey.
static bool VerifyPSSSignature(EVP_PKEY* pkey, const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length);
// Verify that the message was signed by the private key associated with
// |public_rsa_| using the specified padding scheme.
void VerifyRSASignature(const vector<uint8_t>& message,
const uint8_t* signature, size_t signature_length,
RSA_Padding_Scheme padding_scheme);
bool GenerateRSASessionKey(vector<uint8_t>* enc_session_key);
// Encrypts a known session key with public_rsa_ for use in future calls to
// OEMCrypto_DeriveKeysFromSessionKey or OEMCrypto_RewrapDeviceRSAKey30.
// The unencrypted session key is stored in session_key.
bool GenerateRSASessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* enc_session_key);
// Loads the specified wrapped_rsa_key into OEMCrypto, and then runs
// GenerateDerivedKeysFromSessionKey to install known encryption and mac keys.
void InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key);
void DisallowDeriveKeys();
// Generates a usage report for the specified pst. If expect_success is true,
// the report's signature is verified, and several fields are given sanity
// checks. If other is not null, then the mac keys are copied from other in
// order to verify signatures.
void GenerateReport(const std::string& pst, bool expect_success = true,
Session* other = 0);
// Returns a pointer to the usage report generated by the previous call to
// GenerateReport.
OEMCrypto_PST_Report* pst_report();
// Creates a signed delete usage table entry message and calls
// OEMCrypto_DeleteUsageEntry on it.
void DeleteEntry(const std::string& pst);
// Calls OEMCrypto_ForceDeleteUsageEntry to delete a usage table entry without
// a signed message.
void ForceDeleteEntry(const std::string& pst);
// The unencrypted license response or license renewal response.
MessageData& license() { return license_; }
// The encrypted license response or license renewal response.
MessageData& encrypted_license() { return padded_message_; }
// A pointer to the buffer holding encrypted_license.
const uint8_t* message_ptr();
// An array of key objects for use in LoadKeys.
OEMCrypto_KeyObject* key_array() { return key_array_; }
// The last signature generated with the server's mac key.
std::vector<uint8_t>& signature() { return signature_; }
// Set the number of keys to use in the license(), encrypted_license()
// and key_array().
void set_num_keys(int num_keys) { num_keys_ = num_keys; }
// The current number of keys to use in the license(), encrypted_license()
// and key_array().
int num_keys() const { return num_keys_; }
// Set the size of the buffer used the encrypted license.
// Must be between sizeof(MessageData) and kMaxMessageSize.
void set_message_size(size_t size);
// The size of the encrypted message.
size_t message_size() { return message_size_; }
private:

File diff suppressed because it is too large Load Diff

View File

@@ -54,9 +54,9 @@ TEST_F(OEMCryptoAndroidLMPTest, RewrapDeviceRSAKeyImplemented) {
}
TEST_F(OEMCryptoAndroidLMPTest, RSASignatureImplemented) {
ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_GenerateRSASignature(0, NULL, 0, NULL, NULL,
kSign_RSASSA_PSS));
ASSERT_NE(
OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_GenerateRSASignature(0, NULL, 0, NULL, NULL, kSign_RSASSA_PSS));
}
TEST_F(OEMCryptoAndroidLMPTest, GenericCryptoImplemented) {
@@ -66,12 +66,12 @@ TEST_F(OEMCryptoAndroidLMPTest, GenericCryptoImplemented) {
ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_Generic_Decrypt(0, NULL, 0, NULL,
OEMCrypto_AES_CBC_128_NO_PADDING, NULL));
ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_Generic_Sign(0, NULL, 0,
OEMCrypto_HMAC_SHA256, NULL, NULL));
ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_Generic_Verify(0, NULL, 0,
OEMCrypto_HMAC_SHA256, NULL, 0));
ASSERT_NE(
OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_Generic_Sign(0, NULL, 0, OEMCrypto_HMAC_SHA256, NULL, NULL));
ASSERT_NE(
OEMCrypto_ERROR_NOT_IMPLEMENTED,
OEMCrypto_Generic_Verify(0, NULL, 0, OEMCrypto_HMAC_SHA256, NULL, 0));
}
TEST_F(OEMCryptoAndroidLMPTest, SupportsUsageTable) {

View File

@@ -1,9 +1,9 @@
#include <gtest/gtest.h>
#include <iostream>
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_device_features.h"
#include "OEMCryptoCENC.h"
#include "properties.h"
static void acknowledge_cast() {
@@ -20,7 +20,7 @@ int main(int argc, char** argv) {
bool is_cast_receiver = false;
bool force_load_test_keybox = false;
bool filter_tests = true;
for(int i=0; i < argc; i++) {
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], "--cast")) {
acknowledge_cast();
is_cast_receiver = true;
@@ -29,15 +29,15 @@ int main(int argc, char** argv) {
force_load_test_keybox = true;
}
if (!strcmp(argv[i], "--no_filter")) {
filter_tests = false;
filter_tests = false;
}
}
wvoec::global_features.Initialize(is_cast_receiver, force_load_test_keybox);
// If the user requests --no_filter, we don't change the filter, otherwise, we
// filter out features that are not supported.
if (filter_tests) {
::testing::GTEST_FLAG(filter)
= wvoec::global_features.RestrictFilter(::testing::GTEST_FLAG(filter));
::testing::GTEST_FLAG(filter) =
wvoec::global_features.RestrictFilter(::testing::GTEST_FLAG(filter));
}
return RUN_ALL_TESTS();
}