Update entitlement unit tests
This patch updates the entitlement keys in the sample code and in the unit tests to use AES 256.
This commit is contained in:
4
README
4
README
@@ -5,8 +5,8 @@ as well as unit tests and reference code.
|
||||
|
||||
Several versions of OEMCrypto are available on different branches. This is the
|
||||
only file on the master branch. Please use the git checkout command to work
|
||||
with the correct version of OEMCrypto, for example, to see version 13, use the
|
||||
command "git checkout origin/v13".
|
||||
with the correct version of OEMCrypto, for example, to see version 14, use the
|
||||
command "git checkout origin/v14".
|
||||
|
||||
Use "git branch -a" to see a list of all branches.
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ typedef enum OEMCrypto_ProvisioningMethod {
|
||||
#define OEMCrypto_IsSRMUpdateSupported _oecc53
|
||||
#define OEMCrypto_GetCurrentSRMVersion _oecc54
|
||||
#define OEMCrypto_LoadSRM _oecc55
|
||||
#define OEMCrypto_LoadKeys_v13 _oecc56
|
||||
#define OEMCrypto_LoadKeys_V13 _oecc56
|
||||
#define OEMCrypto_RemoveSRM _oecc57
|
||||
#define OEMCrypto_CreateUsageTableHeader _oecc61
|
||||
#define OEMCrypto_LoadUsageTableHeader _oecc62
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "level3_file_system.h"
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
|
||||
namespace wvoec3 {
|
||||
|
||||
@@ -68,7 +69,7 @@ namespace wvoec3 {
|
||||
#define Level3_IsSRMUpdateSupported _lcc53
|
||||
#define Level3_GetCurrentSRMVersion _lcc54
|
||||
#define Level3_LoadSRM _lcc55
|
||||
#define Level3_LoadKeys _lcc56
|
||||
#define Level3_LoadKeys_V13 _lcc56
|
||||
#define Level3_RemoveSRM _lcc57
|
||||
#define Level3_CreateUsageTableHeader _lcc61
|
||||
#define Level3_LoadUsageTableHeader _lcc62
|
||||
@@ -128,7 +129,7 @@ namespace wvoec3 {
|
||||
#define Level3_IsSRMUpdateSupported _oecc53
|
||||
#define Level3_GetCurrentSRMVersion _oecc54
|
||||
#define Level3_LoadSRM _oecc55
|
||||
#define Level3_LoadKeys _oecc56
|
||||
#define Level3_LoadKeys_V13 _oecc56
|
||||
#define Level3_RemoveSRM _oecc57
|
||||
#define Level3_CreateUsageTableHeader _oecc61
|
||||
#define Level3_LoadUsageTableHeader _oecc62
|
||||
@@ -163,12 +164,14 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session,
|
||||
size_t message_length,
|
||||
uint8_t* signature,
|
||||
size_t* signature_length);
|
||||
OEMCryptoResult Level3_LoadKeys(
|
||||
// TODO(srujzs): Change this to LoadKeys once V14 has been implemented for
|
||||
// Level 3.
|
||||
OEMCryptoResult Level3_LoadKeys_V13(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys,
|
||||
size_t num_keys, const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
|
||||
size_t pst_length, const uint8_t* srm_requirement);
|
||||
size_t num_keys, const OEMCrypto_KeyObject_V13* key_array,
|
||||
const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement);
|
||||
OEMCryptoResult Level3_RefreshKeys(OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
# Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
{
|
||||
'target_defaults': {
|
||||
# It seems that if one target uses -fPIC, then all targets will need that
|
||||
# flag or else there will be linking errors. For generating a shared
|
||||
# library, we need position independent code.
|
||||
'cflags': [
|
||||
'-g',
|
||||
'-fPIC',
|
||||
'-std=gnu++98',
|
||||
],
|
||||
'ldflags': [
|
||||
'-fPIC',
|
||||
],
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'oec_mock',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'src/oemcrypto_keybox_testkey.cpp',
|
||||
'src/oemcrypto_engine_device_properties.cpp',
|
||||
],
|
||||
'variables': {
|
||||
'oec_mock_dir': '.',
|
||||
},
|
||||
'includes': [
|
||||
'oec_mock_kernel.gypi',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'oec_mock_shared',
|
||||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'oec_mock'
|
||||
# TODO(joeyparrish or fredgc): circular dependencies. 'wvcdm_sysdep'
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
# Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
# Define oec_mock_dir and include into your oec target.
|
||||
|
||||
{
|
||||
'include_dirs': [
|
||||
'<(oec_mock_dir)/../../core/include', # for lock.h and wvcdm_types.h
|
||||
'<(oec_mock_dir)/../include',
|
||||
'<(oec_mock_dir)/src',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'<(oec_mock_dir)/../../core/include',
|
||||
'<(oec_mock_dir)/../include',
|
||||
'<(oec_mock_dir)/src',
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'<(oec_mock_dir)/src/keys.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_auth_mock.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_engine_mock.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_key_mock.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_keybox_mock.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_mock.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_nonce_table.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_old_usage_table_mock.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_rsa_key_shared.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_session.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_session_key_table.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_usage_table_mock.cpp',
|
||||
'<(oec_mock_dir)/src/wvcrc.cpp',
|
||||
'<(oec_mock_dir)/src/oemcrypto_logging.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(oec_mock_dir)/../../third_party/boringssl/boringssl.gyp:crypto',
|
||||
],
|
||||
}
|
||||
@@ -95,8 +95,8 @@ class EntitlementKey : public Key {
|
||||
const std::vector<uint8_t>& content_key() { return content_key_; }
|
||||
const std::vector<uint8_t>& content_key_id() { return content_key_id_; }
|
||||
const std::vector<uint8_t>& entitlement_key() { return Key::value(); }
|
||||
bool SetContentKey(const std::vector<uint8_t>& content_key,
|
||||
const std::vector<uint8_t>& content_key_id) {
|
||||
bool SetContentKey(const std::vector<uint8_t>& content_key_id,
|
||||
const std::vector<uint8_t>& content_key) {
|
||||
content_key_.assign(content_key.begin(), content_key.end());
|
||||
content_key_id_.assign(content_key_id.begin(), content_key_id.end());
|
||||
return true;
|
||||
|
||||
@@ -73,9 +73,8 @@ class ContentKeysContext : public SessionContextKeys {
|
||||
virtual bool SetContentKey(const KeyId& entitlement_id,
|
||||
const KeyId& content_key_id,
|
||||
const std::vector<uint8_t>& content_key);
|
||||
virtual bool GetEntitlementKey(
|
||||
const KeyId& entitlement_id,
|
||||
const std::vector<uint8_t>** entitlement_key);
|
||||
virtual bool GetEntitlementKey(const KeyId& entitlement_id,
|
||||
const std::vector<uint8_t>** entitlement_key);
|
||||
|
||||
private:
|
||||
SessionKeyTable session_keys_;
|
||||
@@ -105,8 +104,8 @@ bool ContentKeysContext::SetContentKey(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContentKeysContext::GetEntitlementKey(
|
||||
const KeyId& entitlement_id, const std::vector<uint8_t>** key) {
|
||||
bool ContentKeysContext::GetEntitlementKey(const KeyId& entitlement_id,
|
||||
const std::vector<uint8_t>** key) {
|
||||
// Unsupported action for this type.
|
||||
return false;
|
||||
};
|
||||
@@ -314,7 +313,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *mac_key = NULL;
|
||||
const uint8_t* mac_key = NULL;
|
||||
bool using_usage_mac_key_client = false;
|
||||
if (mac_key_client_.size() == wvcdm::MAC_KEY_SIZE) {
|
||||
// If we have a mac key, use it.
|
||||
@@ -333,7 +332,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
|
||||
}
|
||||
|
||||
if (using_usage_mac_key_client &&
|
||||
LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
std::vector<uint8_t> usage_entry_mac_key_client(
|
||||
usage_entry_->mac_key_client(),
|
||||
usage_entry_->mac_key_client() + wvcdm::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
@@ -620,9 +619,9 @@ OEMCryptoResult SessionContext::LoadKeys(
|
||||
key_control_iv.assign(key_array[i].key_control_iv,
|
||||
key_array[i].key_control_iv + wvcdm::KEY_IV_SIZE);
|
||||
|
||||
OEMCryptoResult result = InstallKey(
|
||||
key_id, enc_key_data, key_data_iv, key_control, key_control_iv,
|
||||
second_license);
|
||||
OEMCryptoResult result =
|
||||
InstallKey(key_id, enc_key_data, key_data_iv, key_control,
|
||||
key_control_iv, second_license);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
status = result;
|
||||
break;
|
||||
@@ -683,8 +682,7 @@ OEMCryptoResult SessionContext::LoadKeys(
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::LoadEntitledContentKeys(
|
||||
size_t num_keys,
|
||||
const OEMCrypto_EntitledContentKeyObject* key_array) {
|
||||
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) {
|
||||
if (!key_array) {
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
@@ -694,9 +692,9 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys(
|
||||
for (size_t i = 0; i < num_keys; ++i) {
|
||||
const OEMCrypto_EntitledContentKeyObject* key_data = &key_array[i];
|
||||
std::vector<uint8_t> entitlement_key_id;
|
||||
entitlement_key_id.assign(key_data->entitlement_key_id,
|
||||
key_data->entitlement_key_id +
|
||||
key_data->entitlement_key_id_length);
|
||||
entitlement_key_id.assign(
|
||||
key_data->entitlement_key_id,
|
||||
key_data->entitlement_key_id + key_data->entitlement_key_id_length);
|
||||
|
||||
const std::vector<uint8_t>* entitlement_key = NULL;
|
||||
if (!session_keys_->GetEntitlementKey(entitlement_key_id,
|
||||
@@ -716,12 +714,12 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys(
|
||||
content_key_id.assign(
|
||||
key_data->content_key_id,
|
||||
key_data->content_key_id + key_data->content_key_id_length);
|
||||
if (!DecryptEntitlement(*entitlement_key, iv,
|
||||
encrypted_content_key, &content_key)) {
|
||||
if (!DecryptMessage(*entitlement_key, iv, encrypted_content_key,
|
||||
&content_key)) {
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (!session_keys_->SetContentKey(
|
||||
entitlement_key_id, content_key_id, content_key)) {
|
||||
if (!session_keys_->SetContentKey(entitlement_key_id, content_key_id,
|
||||
content_key)) {
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -732,8 +730,7 @@ OEMCryptoResult SessionContext::InstallKey(
|
||||
const KeyId& key_id, const std::vector<uint8_t>& key_data,
|
||||
const std::vector<uint8_t>& key_data_iv,
|
||||
const std::vector<uint8_t>& key_control,
|
||||
const std::vector<uint8_t>& key_control_iv,
|
||||
bool second_license) {
|
||||
const std::vector<uint8_t>& key_control_iv, bool second_license) {
|
||||
// Decrypt encrypted key_data using derived encryption key and offered iv
|
||||
std::vector<uint8_t> content_key;
|
||||
std::vector<uint8_t> key_control_str;
|
||||
@@ -1339,26 +1336,7 @@ bool SessionContext::DecryptMessage(const std::vector<uint8_t>& key,
|
||||
uint8_t iv_buffer[16];
|
||||
memcpy(iv_buffer, &iv[0], 16);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&message[0], &(decrypted->front()), message.size(), &aes_key,
|
||||
iv_buffer, AES_DECRYPT);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionContext::DecryptEntitlement(
|
||||
const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<uint8_t>& message,
|
||||
std::vector<uint8_t>* decrypted) {
|
||||
if (key.empty() || iv.empty() || message.empty() || !decrypted) {
|
||||
LOGE("[DecryptMessage(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||
return false;
|
||||
}
|
||||
decrypted->resize(message.size());
|
||||
uint8_t iv_buffer[16];
|
||||
memcpy(iv_buffer, &iv[0], 16);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&key[0], 256, &aes_key);
|
||||
AES_set_decrypt_key(&key[0], key.size() * 8, &aes_key);
|
||||
AES_cbc_encrypt(&message[0], &(decrypted->front()), message.size(), &aes_key,
|
||||
iv_buffer, AES_DECRYPT);
|
||||
return true;
|
||||
|
||||
@@ -190,10 +190,6 @@ class SessionContext {
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<uint8_t>& message,
|
||||
std::vector<uint8_t>* decrypted);
|
||||
bool DecryptEntitlement(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<uint8_t>& message,
|
||||
std::vector<uint8_t>* decrypted);
|
||||
// Either verify the nonce or usage entry, as required by the key control
|
||||
// block.
|
||||
OEMCryptoResult CheckNonceOrEntry(const KeyControlBlock& key_control_block);
|
||||
|
||||
52
oem_certificate_generator/README.md
Normal file
52
oem_certificate_generator/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
OEM certificate generation tool
|
||||
===================================================
|
||||
|
||||
## Supports
|
||||
|
||||
- Generating CSR (certificate signing request)
|
||||
- Generating OEM intermediate certificate (for testing)
|
||||
- Generating OEM leaf certificate chain
|
||||
- Erasing file securely
|
||||
- Getting CSR/certificate/certificate chain information
|
||||
|
||||
## Prerequirements
|
||||
|
||||
- Install pip: https://pip.pypa.io/en/stable/installing/
|
||||
- Install python cryptography: https://cryptography.io/en/latest/installation/
|
||||
|
||||
## Usage
|
||||
|
||||
Run `python oem_certificate.py --help` to see available commands.
|
||||
|
||||
The arguments can be partially or fully loaded from a configuration file, for
|
||||
example, if file "location.cfg" is,
|
||||
|
||||
```
|
||||
-C=US
|
||||
-ST=CA
|
||||
-L=Kirkland
|
||||
-O=Some Company
|
||||
-OU=Some Unit
|
||||
```
|
||||
|
||||
A command of
|
||||
|
||||
```bash
|
||||
python oem_certificate.py generate_csr @location.cfg -CN TestDevice1 \
|
||||
--output_csr_file=csr.pem --output_private_key_file=key.der
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```bash
|
||||
python oem_certificate.py generate_csr -CN TestDevice1 -C=US -ST=CA \
|
||||
-L=Kirkland -O='Some Company' -OU='Some Unit' --output_csr_file=csr.pem \
|
||||
--output_private_key_file=key.der.
|
||||
```
|
||||
|
||||
Note that
|
||||
- The arguments in the config file must be one per line;
|
||||
- The arguments should not be quoted in the config file.
|
||||
|
||||
The script uses a default configuration file 'oem_certificate.cfg', which will
|
||||
be loaded automatically if exists.
|
||||
492
oem_certificate_generator/oem_certificate.py
Normal file
492
oem_certificate_generator/oem_certificate.py
Normal file
@@ -0,0 +1,492 @@
|
||||
# Copyright 2017 Google Inc. All Rights Reserved.
|
||||
|
||||
"""OEM certificate generation tool.
|
||||
|
||||
Supports:
|
||||
- Generating CSR (certificate signing request)
|
||||
- Generating OEM intermediate certificate (for testing)
|
||||
- Generating OEM leaf certificate chain
|
||||
- Erasing file securely
|
||||
- Getting CSR/certificate/certificate chain information
|
||||
|
||||
Prerequirements:
|
||||
- Install pip: https://pip.pypa.io/en/stable/installing/
|
||||
- Install python cryptography: https://cryptography.io/en/latest/installation/
|
||||
|
||||
Run 'python oem_certificate.py --help' to see available commands.
|
||||
|
||||
The arguments can be partially or fully loaded from a configuration file, for
|
||||
example, if file "location.cfg" is,
|
||||
|
||||
-C=US
|
||||
-ST=CA
|
||||
-L=Kirkland
|
||||
-O=Some Company
|
||||
-OU=Some Unit
|
||||
|
||||
A command of
|
||||
"python oem_certificate.py generate_csr @location.cfg -CN TestDevice1 "
|
||||
"--output_csr_file=csr.pem --output_private_key_file=key.der",
|
||||
is equivalent to
|
||||
"python oem_certificate.py generate_csr -CN TestDevice1 -C=US -ST=CA "
|
||||
"-L=Kirkland -O='Some Company' -OU='Some Unit' --output_csr_file=csr.pem "
|
||||
"--output_private_key_file=key.der".
|
||||
|
||||
Note that (1) the arguments in the config file must be one per line; (2) the
|
||||
arguments should not be quoted in the config file.
|
||||
|
||||
The script uses a default configuration file 'oem_certificate.cfg', which will
|
||||
be loaded automatically if exists.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat import backends
|
||||
from cryptography.hazmat.backends import openssl
|
||||
from cryptography.hazmat.backends.openssl import backend
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.x509 import oid
|
||||
from pyasn1.codec.der import decoder
|
||||
from pyasn1.codec.der import encoder
|
||||
from pyasn1.type import univ
|
||||
import six
|
||||
|
||||
|
||||
class WidevineSystemId(x509.UnrecognizedExtension):
|
||||
"""Implement WidevineSystemId x509 extension."""
|
||||
|
||||
# oid of Widevine system id.
|
||||
oid = oid.ObjectIdentifier('1.3.6.1.4.1.11129.4.1.1')
|
||||
|
||||
def __init__(self, value):
|
||||
"""Inits from raw bytes."""
|
||||
super(WidevineSystemId, self).__init__(WidevineSystemId.oid, value)
|
||||
|
||||
@classmethod
|
||||
def from_int_value(cls, int_value):
|
||||
"""Construct from integer system id value."""
|
||||
return cls(encoder.encode(univ.Integer(int_value)))
|
||||
|
||||
def int_value(self):
|
||||
"""Return the integer value of the system id."""
|
||||
return int(decoder.decode(self.value)[0])
|
||||
|
||||
|
||||
class X509CertificateChain(object):
|
||||
"""Implement x509 certificate chain object.
|
||||
|
||||
cryptography does not support certificate chain (pkcs7 container) right
|
||||
now, so we have to implement it using low level functions directly.
|
||||
"""
|
||||
|
||||
# Disable pylint on protected-access in class X509CertificateChain.
|
||||
# pylint: disable=protected-access
|
||||
|
||||
def __init__(self, certificates):
|
||||
"""Inits from certificate list."""
|
||||
self._certificates = certificates
|
||||
|
||||
def __iter__(self):
|
||||
"""Iterates through certificates."""
|
||||
return self._certificates.__iter__()
|
||||
|
||||
@classmethod
|
||||
def load_der(cls, certificate_chain_data):
|
||||
"""Load from DER formatted data."""
|
||||
bio = backend._bytes_to_bio(certificate_chain_data)
|
||||
pkcs7 = backend._lib.d2i_PKCS7_bio(bio.bio, backend._ffi.NULL)
|
||||
if pkcs7 == backend._ffi.NULL:
|
||||
raise ValueError('Unable to load certificate chain')
|
||||
pkcs7 = backend._ffi.gc(pkcs7, backend._lib.PKCS7_free)
|
||||
if not backend._lib.PKCS7_type_is_signed(pkcs7):
|
||||
raise ValueError('Invalid certificate chain')
|
||||
|
||||
x509_stack = pkcs7.d.sign.cert
|
||||
certificates = []
|
||||
for i in xrange(backend._lib.sk_X509_num(x509_stack)):
|
||||
x509_value = backend._ffi.gc(
|
||||
backend._lib.X509_dup(backend._lib.sk_X509_value(x509_stack, i)),
|
||||
backend._lib.X509_free)
|
||||
certificates.append(openssl.x509._Certificate(backend, x509_value))
|
||||
return cls(certificates)
|
||||
|
||||
def der_bytes(self):
|
||||
"""Return DER formatted bytes."""
|
||||
x509_stack = backend._ffi.gc(backend._lib.sk_X509_new_null(),
|
||||
backend._lib.sk_X509_free)
|
||||
for certificate in self._certificates:
|
||||
backend._lib.sk_X509_push(x509_stack, certificate._x509)
|
||||
|
||||
pkcs7_partial = 0x4000
|
||||
p7 = backend._lib.PKCS7_sign(backend._ffi.NULL, backend._ffi.NULL,
|
||||
x509_stack, backend._ffi.NULL, pkcs7_partial)
|
||||
p7 = backend._ffi.gc(p7, backend._lib.PKCS7_free)
|
||||
|
||||
bio = backend._create_mem_bio_gc()
|
||||
backend.openssl_assert(backend._lib.i2d_PKCS7_bio(bio, p7) == 1)
|
||||
return backend._read_mem_bio(bio)
|
||||
|
||||
|
||||
def _multiple_of_1024(key_size_str):
|
||||
"""argparse custom type function for key size."""
|
||||
key_size = int(key_size_str)
|
||||
if key_size % 1024:
|
||||
msg = '%r is not multiple of 1024' % key_size_str
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
return key_size
|
||||
|
||||
|
||||
def _valid_date(date_str):
|
||||
"""argparse custom type function dates."""
|
||||
return datetime.datetime.strptime(date_str, '%Y-%m-%d')
|
||||
|
||||
|
||||
def _get_encryption_algorithm(passphrase):
|
||||
"""Convenient function to get the encryption algorithm."""
|
||||
if passphrase:
|
||||
return serialization.BestAvailableEncryption(passphrase)
|
||||
else:
|
||||
return serialization.NoEncryption()
|
||||
|
||||
|
||||
def generate_csr(args):
|
||||
"""Subparser handler for generating certificate signing request."""
|
||||
key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=args.key_size,
|
||||
backend=backends.default_backend())
|
||||
args.output_private_key_file.write(
|
||||
key.private_bytes(
|
||||
encoding=serialization.Encoding.DER,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=_get_encryption_algorithm(args.passphrase)))
|
||||
|
||||
x509_name = [
|
||||
# Provide various details about who we are.
|
||||
x509.NameAttribute(oid.NameOID.COUNTRY_NAME,
|
||||
six.text_type(args.country_name)),
|
||||
x509.NameAttribute(oid.NameOID.STATE_OR_PROVINCE_NAME,
|
||||
six.text_type(args.state_or_province_name)),
|
||||
x509.NameAttribute(oid.NameOID.LOCALITY_NAME,
|
||||
six.text_type(args.locality_name)),
|
||||
x509.NameAttribute(oid.NameOID.ORGANIZATION_NAME,
|
||||
six.text_type(args.organization_name)),
|
||||
x509.NameAttribute(oid.NameOID.ORGANIZATIONAL_UNIT_NAME,
|
||||
six.text_type(args.organizational_unit_name)),
|
||||
]
|
||||
if args.common_name:
|
||||
x509_name.append(x509.NameAttribute(oid.NameOID.COMMON_NAME,
|
||||
six.text_type(args.common_name)))
|
||||
csr = x509.CertificateSigningRequestBuilder().subject_name(
|
||||
x509.Name(x509_name)).sign(key, hashes.SHA256(),
|
||||
backends.default_backend())
|
||||
args.output_csr_file.write(csr.public_bytes(serialization.Encoding.PEM))
|
||||
|
||||
|
||||
def _random_serial_number():
|
||||
"""Utility function to generate random serial number."""
|
||||
return utils.int_from_bytes(os.urandom(16), byteorder='big')
|
||||
|
||||
|
||||
def build_certificate(subject_name, issuer_name, system_id, not_valid_before,
|
||||
valid_duration, public_key, signing_key, ca):
|
||||
"""Utility function to build certificate."""
|
||||
builder = x509.CertificateBuilder()
|
||||
builder = builder.subject_name(subject_name).issuer_name(issuer_name)
|
||||
|
||||
if ca:
|
||||
builder = builder.add_extension(
|
||||
x509.SubjectKeyIdentifier.from_public_key(public_key), critical=False)
|
||||
builder = builder.add_extension(
|
||||
x509.AuthorityKeyIdentifier.from_issuer_public_key(
|
||||
signing_key.public_key()),
|
||||
critical=False)
|
||||
builder = builder.add_extension(
|
||||
x509.BasicConstraints(True, 0), critical=True)
|
||||
if system_id:
|
||||
builder = builder.add_extension(
|
||||
WidevineSystemId.from_int_value(system_id), critical=False)
|
||||
|
||||
builder = builder.not_valid_before(not_valid_before).not_valid_after(
|
||||
not_valid_before + datetime.timedelta(valid_duration)).serial_number(
|
||||
_random_serial_number()).public_key(public_key)
|
||||
return builder.sign(
|
||||
private_key=signing_key,
|
||||
algorithm=hashes.SHA256(),
|
||||
backend=backends.default_backend())
|
||||
|
||||
|
||||
def generate_intermediate_certificate(args):
|
||||
"""Subparser handler for generating intermediate certificate."""
|
||||
root_cert = x509.load_der_x509_certificate(args.root_certificate_file.read(),
|
||||
backends.default_backend())
|
||||
root_private_key = serialization.load_der_private_key(
|
||||
args.root_private_key_file.read(),
|
||||
password=args.root_private_key_passphrase,
|
||||
backend=backends.default_backend())
|
||||
if (root_private_key.public_key().public_numbers() !=
|
||||
root_cert.public_key().public_numbers()):
|
||||
raise ValueError('Root certificate does not match with root private key')
|
||||
csr = x509.load_pem_x509_csr(args.csr_file.read(), backends.default_backend())
|
||||
|
||||
certificate = build_certificate(csr.subject, root_cert.subject,
|
||||
args.system_id, args.not_valid_before,
|
||||
args.valid_duration,
|
||||
csr.public_key(), root_private_key, True)
|
||||
args.output_certificate_file.write(
|
||||
certificate.public_bytes(serialization.Encoding.DER))
|
||||
|
||||
|
||||
def generate_leaf_certificate(args):
|
||||
"""Subparser handler for generating leaf certificate."""
|
||||
intermediate_cert_bytes = args.intermediate_certificate_file.read()
|
||||
intermediate_cert = x509.load_der_x509_certificate(intermediate_cert_bytes,
|
||||
backends.default_backend())
|
||||
intermediate_private_key = serialization.load_der_private_key(
|
||||
args.intermediate_private_key_file.read(),
|
||||
password=args.intermediate_private_key_passphrase,
|
||||
backend=backends.default_backend())
|
||||
if (intermediate_private_key.public_key().public_numbers() !=
|
||||
intermediate_cert.public_key().public_numbers()):
|
||||
raise ValueError(
|
||||
'Intermediate certificate does not match with intermediate private key')
|
||||
|
||||
system_id_raw_bytes = intermediate_cert.extensions.get_extension_for_oid(
|
||||
WidevineSystemId.oid).value.value
|
||||
system_id = WidevineSystemId(system_id_raw_bytes).int_value()
|
||||
|
||||
name_attributes = [
|
||||
x509.NameAttribute(oid.NameOID.COMMON_NAME, u'{0}-leaf'.format(system_id))
|
||||
]
|
||||
name_attributes.extend([
|
||||
attribute for attribute in intermediate_cert.subject
|
||||
if attribute.oid != oid.NameOID.COMMON_NAME
|
||||
])
|
||||
subject_name = x509.Name(name_attributes)
|
||||
|
||||
leaf_private_key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=args.key_size,
|
||||
backend=backends.default_backend())
|
||||
args.output_private_key_file.write(
|
||||
leaf_private_key.private_bytes(
|
||||
encoding=serialization.Encoding.DER,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=_get_encryption_algorithm(args.passphrase)))
|
||||
|
||||
certificate = build_certificate(subject_name, intermediate_cert.subject,
|
||||
system_id, args.not_valid_before,
|
||||
args.valid_duration,
|
||||
leaf_private_key.public_key(),
|
||||
intermediate_private_key, False)
|
||||
args.output_certificate_file.write(
|
||||
X509CertificateChain([certificate, intermediate_cert]).der_bytes())
|
||||
|
||||
|
||||
def secure_erase(args):
|
||||
"""Subparser handler for secure erasing of a file."""
|
||||
length = args.file.tell()
|
||||
for _ in xrange(args.passes):
|
||||
args.file.seek(0)
|
||||
for _ in xrange(length):
|
||||
args.file.write(os.urandom(1))
|
||||
args.file.close()
|
||||
os.remove(args.file.name)
|
||||
|
||||
|
||||
def _certificate_as_string(cert):
|
||||
"""Utility function to format certificate as string."""
|
||||
lines = ['Certificate Subject Name:']
|
||||
lines.extend([' {0}'.format(attribute) for attribute in cert.subject])
|
||||
lines.append('Issuer Name:')
|
||||
lines.extend([' {0}'.format(attribute) for attribute in cert.issuer])
|
||||
lines.append('Key Size: {0.key_size}'.format(cert.public_key()))
|
||||
try:
|
||||
system_id_raw_bytes = cert.extensions.get_extension_for_oid(
|
||||
WidevineSystemId.oid).value.value
|
||||
lines.append('Widevine System Id: {0}'.format(
|
||||
WidevineSystemId(system_id_raw_bytes).int_value()))
|
||||
except x509.ExtensionNotFound:
|
||||
pass
|
||||
lines.append('Not valid before: {0.not_valid_before}'.format(cert))
|
||||
lines.append('Not valid after: {0.not_valid_after}'.format(cert))
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def _csr_as_string(csr):
|
||||
"""Utility function to format csr as string."""
|
||||
lines = ['CSR Subject Name:']
|
||||
lines.extend([' {0}'.format(attribute) for attribute in csr.subject])
|
||||
lines.append('Key Size: {0.key_size}'.format(csr.public_key()))
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def _handle_csr(data):
|
||||
"""Utility function for get_info to parse csr."""
|
||||
return _csr_as_string(
|
||||
x509.load_pem_x509_csr(data, backends.default_backend()))
|
||||
|
||||
|
||||
def _handle_certificate(data):
|
||||
"""Utility function for get_info to parse certificate."""
|
||||
return _certificate_as_string(
|
||||
x509.load_der_x509_certificate(data, backends.default_backend()))
|
||||
|
||||
|
||||
def _handle_certificate_chain(data):
|
||||
"""Utility function for get_info to parse certificate chain."""
|
||||
return '\n\n'.join([
|
||||
_certificate_as_string(certificate)
|
||||
for certificate in X509CertificateChain.load_der(data)
|
||||
])
|
||||
|
||||
|
||||
def get_info(args, out=sys.stdout):
|
||||
"""Subparser handler to get csr or certificate information."""
|
||||
# The input is either a CSR or a certificate, or a certificate chain.
|
||||
# Loop through the corresponding handlers one by one.
|
||||
data = args.file.read()
|
||||
for handler in [_handle_csr, _handle_certificate, _handle_certificate_chain]:
|
||||
try:
|
||||
out.write(handler(data))
|
||||
return
|
||||
except ValueError:
|
||||
pass
|
||||
print('Error occurred. The input file is not a valid CSR, nor certificate, '
|
||||
'nor certificate chain.')
|
||||
|
||||
|
||||
def create_parser():
|
||||
"""Command line parsing."""
|
||||
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# Subparser for certificate signing request generation.
|
||||
parser_csr = subparsers.add_parser(
|
||||
'generate_csr', help='generate certificate signing request')
|
||||
parser_csr.add_argument(
|
||||
'--key_size',
|
||||
type=_multiple_of_1024,
|
||||
default=2048,
|
||||
help='specify RSA key size.')
|
||||
parser_csr.add_argument('-C', '--country_name', required=True)
|
||||
parser_csr.add_argument('-ST', '--state_or_province_name', required=True)
|
||||
parser_csr.add_argument('-L', '--locality_name', required=True)
|
||||
parser_csr.add_argument('-O', '--organization_name', required=True)
|
||||
parser_csr.add_argument('-OU', '--organizational_unit_name', required=True)
|
||||
parser_csr.add_argument('-CN', '--common_name', required=False)
|
||||
parser_csr.add_argument(
|
||||
'--output_csr_file', type=argparse.FileType('wb'), required=True)
|
||||
parser_csr.add_argument(
|
||||
'--output_private_key_file', type=argparse.FileType('wb'), required=True)
|
||||
parser_csr.add_argument(
|
||||
'--passphrase',
|
||||
help=('specify an optional passphrase to encrypt the private key. The '
|
||||
'private key is not encrypted if omitted.'))
|
||||
parser_csr.set_defaults(func=generate_csr)
|
||||
|
||||
# Subparser for intermediate certificate generation.
|
||||
parser_intermediate_cert = subparsers.add_parser(
|
||||
'generate_intermediate_certificate',
|
||||
help=('generate intermediate certificate from csr. This should only be '
|
||||
'used for testing.'))
|
||||
parser_intermediate_cert.add_argument(
|
||||
'--not_valid_before',
|
||||
type=_valid_date,
|
||||
default=datetime.datetime.today(),
|
||||
help='certificate validity start date - format YYYY-MM-DD')
|
||||
parser_intermediate_cert.add_argument(
|
||||
'--valid_duration',
|
||||
type=int,
|
||||
default=3650,
|
||||
help='the certificate will expire after the specified number of days.')
|
||||
parser_intermediate_cert.add_argument('--system_id', type=int, required=True)
|
||||
parser_intermediate_cert.add_argument(
|
||||
'--csr_file', type=argparse.FileType('rb'), required=True)
|
||||
parser_intermediate_cert.add_argument(
|
||||
'--root_certificate_file', type=argparse.FileType('rb'), required=True)
|
||||
parser_intermediate_cert.add_argument(
|
||||
'--root_private_key_file', type=argparse.FileType('rb'), required=True)
|
||||
parser_intermediate_cert.add_argument('--root_private_key_passphrase')
|
||||
parser_intermediate_cert.add_argument(
|
||||
'--output_certificate_file', type=argparse.FileType('wb'), required=True)
|
||||
parser_intermediate_cert.set_defaults(func=generate_intermediate_certificate)
|
||||
|
||||
# Subparser for leaf certificate generation.
|
||||
parser_leaf_cert = subparsers.add_parser(
|
||||
'generate_leaf_certificate', help='generate leaf certificate')
|
||||
parser_leaf_cert.add_argument(
|
||||
'--key_size',
|
||||
type=_multiple_of_1024,
|
||||
default=2048,
|
||||
help='specify RSA key size.')
|
||||
parser_leaf_cert.add_argument(
|
||||
'--not_valid_before',
|
||||
type=_valid_date,
|
||||
default=datetime.datetime.today(),
|
||||
help='certificate validity start date - format YYYY-MM-DD')
|
||||
parser_leaf_cert.add_argument(
|
||||
'--valid_duration',
|
||||
type=int,
|
||||
default=3650,
|
||||
help='the certificate will expire after the specified number of days.')
|
||||
parser_leaf_cert.add_argument(
|
||||
'--intermediate_certificate_file',
|
||||
type=argparse.FileType('rb'),
|
||||
required=True)
|
||||
parser_leaf_cert.add_argument(
|
||||
'--intermediate_private_key_file',
|
||||
type=argparse.FileType('rb'),
|
||||
required=True)
|
||||
parser_leaf_cert.add_argument('--intermediate_private_key_passphrase')
|
||||
parser_leaf_cert.add_argument(
|
||||
'--output_certificate_file', type=argparse.FileType('wb'), required=True)
|
||||
parser_leaf_cert.add_argument(
|
||||
'--output_private_key_file', type=argparse.FileType('wb'), required=True)
|
||||
parser_leaf_cert.add_argument(
|
||||
'--passphrase',
|
||||
help=('specify an optional passphrase to encrypt the private key. The '
|
||||
'private key is not encrypted if omitted.'))
|
||||
parser_leaf_cert.set_defaults(func=generate_leaf_certificate)
|
||||
|
||||
# Subparser for secure file erase.
|
||||
parser_erase = subparsers.add_parser('erase', help='erase a file securely')
|
||||
parser_erase.add_argument(
|
||||
'-F', '--file', type=argparse.FileType('a'), required=True)
|
||||
parser_erase.add_argument(
|
||||
'--passes',
|
||||
type=int,
|
||||
default=3,
|
||||
help=('the file will be overwritten with random patterns for the '
|
||||
'specified number of passes'))
|
||||
parser_erase.set_defaults(func=secure_erase)
|
||||
|
||||
# Subparser to get CSR or certificate or certificate chain metadata.
|
||||
parser_info = subparsers.add_parser(
|
||||
'info', help='get CSR or certificate metadata')
|
||||
parser_info.add_argument(
|
||||
'-F', '--file', type=argparse.FileType('rb'), required=True)
|
||||
parser_info.set_defaults(func=get_info)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
config_file_name = 'oem_certificate.cfg'
|
||||
if os.path.isfile(config_file_name):
|
||||
print 'Load from args default configuration file: ', config_file_name
|
||||
args.append('@' + config_file_name)
|
||||
parser_args = create_parser().parse_args(args)
|
||||
parser_args.func(parser_args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -171,7 +171,6 @@ void DeviceFeatures::PickDerivedKey() {
|
||||
}
|
||||
if (uses_keybox) {
|
||||
// If device uses a keybox, try to load the test keybox.
|
||||
// TODO(jfore): Update to pass in parameters.
|
||||
if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestKeybox(NULL, 0)) {
|
||||
derive_key_method = LOAD_TEST_KEYBOX;
|
||||
} else if (IsTestKeyboxInstalled()) {
|
||||
|
||||
@@ -566,7 +566,7 @@ void Session::FillRefreshMessage(size_t key_count, uint32_t control_bits,
|
||||
encrypted_license().keys[i].key_id_length);
|
||||
if (global_features.api_version == 14) {
|
||||
// For version 14, we require OEMCrypto to handle kc14 for all licenses.
|
||||
memcpy(license_.keys[i].control.verification, "kc14", 4);
|
||||
memcpy(encrypted_license().keys[i].control.verification, "kc14", 4);
|
||||
} else if (global_features.api_version == 13) {
|
||||
// For version 13, we require OEMCrypto to handle kc13 for all licenses.
|
||||
memcpy(encrypted_license().keys[i].control.verification, "kc13", 4);
|
||||
@@ -596,7 +596,8 @@ void Session::EncryptAndSign() {
|
||||
|
||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||
memcpy(iv_buffer, &license_.keys[i].control_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key);
|
||||
AES_set_encrypt_key(&license_.keys[i].key_data[0],
|
||||
license_.keys[i].key_data_length * 8, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
reinterpret_cast<const uint8_t*>(&license_.keys[i].control),
|
||||
reinterpret_cast<uint8_t*>(&encrypted_license().keys[i].control),
|
||||
|
||||
@@ -460,6 +460,220 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo3_3072[] = {
|
||||
0x7f, 0xad, 0x7d, 0xcd, 0x22, 0x06
|
||||
};
|
||||
|
||||
// This is an RSA key where e*d != 1 mod phi. Instead, it uses the carmicahel
|
||||
// totient. That means e*d = 1 mod lambda, where lambda = lcm(p-1, q-1).
|
||||
static const uint8_t kTestKeyRSACarmichael_2048[] = {
|
||||
0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
|
||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
|
||||
0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
|
||||
0x01, 0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a,
|
||||
0x40, 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde,
|
||||
0xa7, 0x1f, 0x3c, 0x2c, 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57, 0x67, 0x5e,
|
||||
0x56, 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, 0x2a, 0xaa, 0x9d, 0xb4,
|
||||
0x4e, 0xfa, 0xa7, 0x6a, 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e, 0x9f, 0xe3,
|
||||
0x34, 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, 0x28, 0xda, 0x3f, 0xce,
|
||||
0x31, 0x7b, 0xfd, 0x06, 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9, 0xaf, 0xfb,
|
||||
0x3e, 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, 0x29, 0xf2, 0x73, 0x9e,
|
||||
0x39, 0xd8, 0xf6, 0x6f, 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e, 0xb5, 0xa4,
|
||||
0xf2, 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, 0xcd, 0x9a, 0x13, 0x8b,
|
||||
0x54, 0x73, 0x54, 0x25, 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67, 0xad, 0xda,
|
||||
0xb3, 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, 0x98, 0x56, 0x57, 0x54,
|
||||
0x71, 0xcd, 0x12, 0x7f, 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b, 0x24, 0x03,
|
||||
0x96, 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, 0xc9, 0x83, 0x06, 0x51,
|
||||
0x5a, 0x88, 0x65, 0x13, 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1, 0x61, 0x5b,
|
||||
0x4c, 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, 0x2d, 0x5f, 0xf8, 0x12,
|
||||
0x7f, 0xa2, 0xfc, 0xbb, 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40, 0xfb, 0x01,
|
||||
0xca, 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, 0x82, 0x46, 0x0b, 0x3a,
|
||||
0x77, 0x8f, 0xc0, 0x72, 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86, 0x5b, 0xed,
|
||||
0x27, 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, 0xd3, 0x5b, 0x3d, 0xdb,
|
||||
0x9c, 0x5e, 0x1b, 0x7b, 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b, 0xbb, 0xbb,
|
||||
0x2c, 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
|
||||
0x82, 0x01, 0x00, 0x0a, 0xf9, 0x4a, 0x19, 0x72, 0x88, 0x1b, 0x4e, 0xd8,
|
||||
0x2f, 0xef, 0x99, 0x93, 0x32, 0xda, 0x51, 0x21, 0x2e, 0x14, 0x06, 0xf4,
|
||||
0xe9, 0x65, 0x1c, 0xf9, 0xd4, 0xcf, 0x1a, 0x51, 0x53, 0xcd, 0x48, 0x33,
|
||||
0x8c, 0x30, 0xed, 0xdd, 0x53, 0x6f, 0x29, 0x82, 0xf9, 0xe0, 0x74, 0xde,
|
||||
0xb1, 0x13, 0x01, 0x88, 0x8f, 0xce, 0x14, 0xc1, 0x3b, 0x90, 0xb7, 0xcc,
|
||||
0x6c, 0xdf, 0x35, 0xa1, 0xf2, 0x1a, 0x3d, 0xbe, 0x19, 0xd7, 0x0a, 0xe4,
|
||||
0x67, 0x75, 0xbb, 0xfa, 0x87, 0xf4, 0x03, 0xb5, 0x7f, 0x69, 0xe4, 0x0b,
|
||||
0x6a, 0xdc, 0x92, 0x82, 0x54, 0x64, 0x1a, 0x94, 0x2d, 0xe4, 0x63, 0x40,
|
||||
0xb2, 0xb4, 0x85, 0x6b, 0xc8, 0x34, 0xba, 0xa2, 0x14, 0x30, 0x47, 0x1a,
|
||||
0xeb, 0x90, 0x62, 0x30, 0x43, 0x44, 0x02, 0xc7, 0x0c, 0x30, 0xc0, 0x7f,
|
||||
0xa9, 0x47, 0xae, 0xde, 0x68, 0x27, 0x92, 0xaa, 0x11, 0x95, 0xf5, 0x6f,
|
||||
0xfc, 0x19, 0x8b, 0x49, 0xa0, 0x77, 0x9d, 0xc6, 0x13, 0x5d, 0x73, 0xff,
|
||||
0x45, 0xa2, 0x4c, 0x3b, 0xf3, 0xe1, 0x2d, 0xd7, 0xc4, 0x70, 0xe2, 0x6c,
|
||||
0x37, 0x99, 0x4c, 0x7a, 0xa9, 0x27, 0xf8, 0x3a, 0xd6, 0xfd, 0xc5, 0xd8,
|
||||
0xfa, 0x2d, 0x0e, 0x71, 0x4b, 0x85, 0x7e, 0xce, 0xcb, 0x1c, 0x79, 0x71,
|
||||
0xbd, 0xff, 0x63, 0x03, 0x6b, 0x58, 0x68, 0xe0, 0x14, 0xca, 0x5e, 0x85,
|
||||
0xfd, 0xd0, 0xb7, 0xe0, 0x68, 0x14, 0xff, 0x2c, 0x82, 0x22, 0x26, 0x8a,
|
||||
0x3f, 0xbf, 0xb0, 0x2a, 0x90, 0xff, 0xc7, 0x72, 0xfc, 0x66, 0x51, 0x3e,
|
||||
0x51, 0x9f, 0x82, 0x68, 0x0e, 0xf3, 0x65, 0x74, 0x88, 0xab, 0xb7, 0xe5,
|
||||
0x97, 0x5f, 0x0f, 0x3e, 0xe5, 0x3a, 0xbc, 0xa4, 0xa1, 0x50, 0xdd, 0x5c,
|
||||
0x94, 0x4b, 0x0c, 0x70, 0x71, 0x48, 0x4e, 0xd0, 0xec, 0x46, 0x8f, 0xdf,
|
||||
0xa2, 0x9a, 0xfe, 0xd8, 0x35, 0x1a, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xcf,
|
||||
0x73, 0x8c, 0xbe, 0x6d, 0x45, 0x2d, 0x0c, 0x0b, 0x5d, 0x5c, 0x6c, 0x75,
|
||||
0x78, 0xcc, 0x35, 0x48, 0xb6, 0x98, 0xf1, 0xb9, 0x64, 0x60, 0x8c, 0x43,
|
||||
0xeb, 0x85, 0xab, 0x04, 0xb6, 0x7d, 0x1b, 0x71, 0x75, 0x06, 0xe2, 0xda,
|
||||
0x84, 0x68, 0x2e, 0x7f, 0x4c, 0xe3, 0x73, 0xb4, 0xde, 0x51, 0x4b, 0xb6,
|
||||
0x51, 0x86, 0x7b, 0xd0, 0xe6, 0x4d, 0xf3, 0xd1, 0xcf, 0x1a, 0xfe, 0x7f,
|
||||
0x3a, 0x83, 0xba, 0xb3, 0xe1, 0xff, 0x54, 0x13, 0x93, 0xd7, 0x9c, 0x27,
|
||||
0x80, 0xb7, 0x1e, 0x64, 0x9e, 0xf7, 0x32, 0x2b, 0x46, 0x29, 0xf7, 0xf8,
|
||||
0x18, 0x6c, 0xf7, 0x4a, 0xbe, 0x4b, 0xee, 0x96, 0x90, 0x8f, 0xa2, 0x16,
|
||||
0x22, 0x6a, 0xcc, 0x48, 0x06, 0x74, 0x63, 0x43, 0x7f, 0x27, 0x22, 0x44,
|
||||
0x3c, 0x2d, 0x3b, 0x62, 0xf1, 0x1c, 0xb4, 0x27, 0x33, 0x85, 0x26, 0x60,
|
||||
0x48, 0x16, 0xcb, 0xef, 0xf8, 0xcd, 0x37, 0x02, 0x81, 0x81, 0x00, 0xce,
|
||||
0x15, 0x43, 0x6e, 0x4b, 0x0f, 0xf9, 0x3f, 0x87, 0xc3, 0x41, 0x45, 0x97,
|
||||
0xb1, 0x49, 0xc2, 0x19, 0x23, 0x87, 0xe4, 0x24, 0x1c, 0x64, 0xe5, 0x28,
|
||||
0xcb, 0x43, 0x10, 0x14, 0x14, 0x0e, 0x19, 0xcb, 0xbb, 0xdb, 0xfd, 0x11,
|
||||
0x9d, 0x17, 0x68, 0x78, 0x6d, 0x61, 0x70, 0x63, 0x3a, 0xa1, 0xb3, 0xf3,
|
||||
0xa7, 0x5b, 0x0e, 0xff, 0xb7, 0x61, 0x11, 0x54, 0x91, 0x99, 0xe5, 0x91,
|
||||
0x32, 0x2d, 0xeb, 0x3f, 0xd8, 0x3e, 0xf7, 0xd4, 0xcb, 0xd2, 0xa3, 0x41,
|
||||
0xc1, 0xee, 0xc6, 0x92, 0x13, 0xeb, 0x7f, 0x42, 0x58, 0xf4, 0xd0, 0xb2,
|
||||
0x74, 0x1d, 0x8e, 0x87, 0x46, 0xcd, 0x14, 0xb8, 0x16, 0xad, 0xb5, 0xbd,
|
||||
0x0d, 0x6c, 0x95, 0x5a, 0x16, 0xbf, 0xe9, 0x53, 0xda, 0xfb, 0xed, 0x83,
|
||||
0x51, 0x67, 0xa9, 0x55, 0xab, 0x54, 0x02, 0x95, 0x20, 0xa6, 0x68, 0x17,
|
||||
0x53, 0xa8, 0xea, 0x43, 0xe5, 0xb0, 0xa3, 0x02, 0x81, 0x80, 0x67, 0x9c,
|
||||
0x32, 0x83, 0x39, 0x57, 0xff, 0x73, 0xb0, 0x89, 0x64, 0x8b, 0xd6, 0xf0,
|
||||
0x0a, 0x2d, 0xe2, 0xaf, 0x30, 0x1c, 0x2a, 0x97, 0xf3, 0x90, 0x9a, 0xab,
|
||||
0x9b, 0x0b, 0x1b, 0x43, 0x79, 0xa0, 0xa7, 0x3d, 0xe7, 0xbe, 0x8d, 0x9c,
|
||||
0xeb, 0xdb, 0xad, 0x40, 0xdd, 0xa9, 0x00, 0x80, 0xb8, 0xe1, 0xb3, 0xa1,
|
||||
0x6c, 0x25, 0x92, 0xe4, 0x33, 0xb2, 0xbe, 0xeb, 0x4d, 0x74, 0x26, 0x5f,
|
||||
0x37, 0x43, 0x9c, 0x6c, 0x17, 0x76, 0x0a, 0x81, 0x20, 0x82, 0xa1, 0x48,
|
||||
0x2c, 0x2d, 0x45, 0xdc, 0x0f, 0x62, 0x43, 0x32, 0xbb, 0xeb, 0x59, 0x41,
|
||||
0xf9, 0xca, 0x58, 0xce, 0x4a, 0x66, 0x53, 0x54, 0xc8, 0x28, 0x10, 0x1e,
|
||||
0x08, 0x71, 0x16, 0xd8, 0x02, 0x71, 0x41, 0x58, 0xd4, 0x56, 0xcc, 0xf5,
|
||||
0xb1, 0x31, 0xa3, 0xed, 0x00, 0x85, 0x09, 0xbf, 0x35, 0x95, 0x41, 0x29,
|
||||
0x40, 0x19, 0x83, 0x35, 0x24, 0x69, 0x02, 0x81, 0x80, 0x55, 0x10, 0x0b,
|
||||
0xcc, 0x3b, 0xa9, 0x75, 0x3d, 0x16, 0xe1, 0xae, 0x50, 0x76, 0x63, 0x94,
|
||||
0x49, 0x4c, 0xad, 0x10, 0xcb, 0x47, 0x68, 0x7c, 0xf0, 0xe5, 0xdc, 0xb8,
|
||||
0x6a, 0xab, 0x8e, 0xf7, 0x9f, 0x08, 0x2c, 0x1b, 0x8a, 0xa2, 0xb9, 0x8f,
|
||||
0xce, 0xec, 0x5e, 0x61, 0xa8, 0xcd, 0x1c, 0x87, 0x60, 0x4a, 0xc3, 0x1a,
|
||||
0x5f, 0xdf, 0x87, 0x26, 0xc6, 0xcb, 0x7c, 0x69, 0xe4, 0x8b, 0x01, 0x06,
|
||||
0x59, 0x22, 0xfa, 0x34, 0x4b, 0x81, 0x87, 0x3c, 0x03, 0x6d, 0x02, 0x0a,
|
||||
0x77, 0xe6, 0x15, 0xd8, 0xcf, 0xa7, 0x68, 0x26, 0x6c, 0xfa, 0x2b, 0xd9,
|
||||
0x83, 0x5a, 0x2d, 0x0c, 0x3b, 0x70, 0x1c, 0xd4, 0x48, 0xbe, 0xa7, 0x0a,
|
||||
0xd9, 0xbe, 0xdc, 0xc3, 0x0c, 0x21, 0x33, 0xb3, 0x66, 0xff, 0x1c, 0x1b,
|
||||
0xc8, 0x96, 0x76, 0xe8, 0x6f, 0x44, 0x74, 0xbc, 0x9b, 0x1c, 0x7d, 0xc8,
|
||||
0xac, 0x21, 0xa8, 0x6e, 0x37, 0x02, 0x81, 0x80, 0x2c, 0x7c, 0xad, 0x1e,
|
||||
0x75, 0xf6, 0x69, 0x1d, 0xe7, 0xa6, 0xca, 0x74, 0x7d, 0x67, 0xc8, 0x65,
|
||||
0x28, 0x66, 0xc4, 0x43, 0xa6, 0xbd, 0x40, 0x57, 0xae, 0xb7, 0x65, 0x2c,
|
||||
0x52, 0xf9, 0xe4, 0xc7, 0x81, 0x7b, 0x56, 0xa3, 0xd2, 0x0d, 0xe8, 0x33,
|
||||
0x70, 0xcf, 0x06, 0x84, 0xb3, 0x4e, 0x44, 0x50, 0x75, 0x61, 0x96, 0x86,
|
||||
0x4b, 0xb6, 0x2b, 0xad, 0xf0, 0xad, 0x57, 0xd0, 0x37, 0x0d, 0x1d, 0x35,
|
||||
0x50, 0xcb, 0x69, 0x22, 0x39, 0x29, 0xb9, 0x3a, 0xd3, 0x29, 0x23, 0x02,
|
||||
0x60, 0xf7, 0xab, 0x30, 0x40, 0xda, 0x8e, 0x4d, 0x45, 0x70, 0x26, 0xf4,
|
||||
0xa2, 0x0d, 0xd0, 0x64, 0x5d, 0x47, 0x3c, 0x18, 0xf4, 0xd4, 0x52, 0x95,
|
||||
0x00, 0xae, 0x84, 0x6b, 0x47, 0xb2, 0x3c, 0x82, 0xd3, 0x72, 0x53, 0xde,
|
||||
0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe, 0x39, 0x28,
|
||||
0x33, 0xe0, 0xdb, 0x03,
|
||||
};
|
||||
|
||||
// This is the same key as above, except the private key was chosen using the
|
||||
// Euler totient.
|
||||
static const uint8_t kTestKeyRSAEuler_2048[] = {
|
||||
0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
|
||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
|
||||
0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
|
||||
0x01, 0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a,
|
||||
0x40, 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde,
|
||||
0xa7, 0x1f, 0x3c, 0x2c, 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57, 0x67, 0x5e,
|
||||
0x56, 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, 0x2a, 0xaa, 0x9d, 0xb4,
|
||||
0x4e, 0xfa, 0xa7, 0x6a, 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e, 0x9f, 0xe3,
|
||||
0x34, 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, 0x28, 0xda, 0x3f, 0xce,
|
||||
0x31, 0x7b, 0xfd, 0x06, 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9, 0xaf, 0xfb,
|
||||
0x3e, 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, 0x29, 0xf2, 0x73, 0x9e,
|
||||
0x39, 0xd8, 0xf6, 0x6f, 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e, 0xb5, 0xa4,
|
||||
0xf2, 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, 0xcd, 0x9a, 0x13, 0x8b,
|
||||
0x54, 0x73, 0x54, 0x25, 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67, 0xad, 0xda,
|
||||
0xb3, 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, 0x98, 0x56, 0x57, 0x54,
|
||||
0x71, 0xcd, 0x12, 0x7f, 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b, 0x24, 0x03,
|
||||
0x96, 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, 0xc9, 0x83, 0x06, 0x51,
|
||||
0x5a, 0x88, 0x65, 0x13, 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1, 0x61, 0x5b,
|
||||
0x4c, 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, 0x2d, 0x5f, 0xf8, 0x12,
|
||||
0x7f, 0xa2, 0xfc, 0xbb, 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40, 0xfb, 0x01,
|
||||
0xca, 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, 0x82, 0x46, 0x0b, 0x3a,
|
||||
0x77, 0x8f, 0xc0, 0x72, 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86, 0x5b, 0xed,
|
||||
0x27, 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, 0xd3, 0x5b, 0x3d, 0xdb,
|
||||
0x9c, 0x5e, 0x1b, 0x7b, 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b, 0xbb, 0xbb,
|
||||
0x2c, 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
|
||||
0x82, 0x01, 0x00, 0x5e, 0x79, 0x65, 0x49, 0xa5, 0x76, 0x79, 0xf9, 0x05,
|
||||
0x45, 0x0f, 0xf4, 0x03, 0xbd, 0xa4, 0x7d, 0x29, 0xd5, 0xde, 0x33, 0x63,
|
||||
0xd8, 0xb8, 0xac, 0x97, 0xeb, 0x3f, 0x5e, 0x55, 0xe8, 0x7d, 0xf3, 0xe7,
|
||||
0x3b, 0x5c, 0x2d, 0x54, 0x67, 0x36, 0xd6, 0x1d, 0x46, 0xf5, 0xca, 0x2d,
|
||||
0x8b, 0x3a, 0x7e, 0xdc, 0x45, 0x38, 0x79, 0x7e, 0x65, 0x71, 0x5f, 0x1c,
|
||||
0x5e, 0x79, 0xb1, 0x40, 0xcd, 0xfe, 0xc5, 0xe1, 0xc1, 0x6b, 0x78, 0x04,
|
||||
0x4e, 0x8e, 0x79, 0xf9, 0x0a, 0xfc, 0x79, 0xb1, 0x5e, 0xb3, 0x60, 0xe3,
|
||||
0x68, 0x7b, 0xc6, 0xef, 0xcb, 0x71, 0x4c, 0xba, 0xa7, 0x79, 0x5c, 0x7a,
|
||||
0x81, 0xd1, 0x71, 0xe7, 0x00, 0x21, 0x13, 0xe2, 0x55, 0x69, 0x0e, 0x75,
|
||||
0xbe, 0x09, 0xc3, 0x4f, 0xa9, 0xc9, 0x68, 0x22, 0x0e, 0x97, 0x8d, 0x89,
|
||||
0x6e, 0xf1, 0xe8, 0x88, 0x7a, 0xd1, 0xd9, 0x09, 0x5d, 0xd3, 0x28, 0x78,
|
||||
0x25, 0x0b, 0x1c, 0x47, 0x73, 0x25, 0xcc, 0x21, 0xb6, 0xda, 0xc6, 0x24,
|
||||
0x5a, 0xd0, 0x37, 0x14, 0x46, 0xc7, 0x94, 0x69, 0xe4, 0x43, 0x6f, 0x47,
|
||||
0xde, 0x00, 0x33, 0x4d, 0x8f, 0x95, 0x72, 0xfa, 0x68, 0x71, 0x17, 0x66,
|
||||
0x12, 0x1a, 0x87, 0x27, 0xf7, 0xef, 0x7e, 0xe0, 0x35, 0x58, 0xf2, 0x4d,
|
||||
0x6f, 0x35, 0x01, 0xaa, 0x96, 0xe2, 0x3d, 0x51, 0x13, 0x86, 0x9c, 0x79,
|
||||
0xd0, 0xb7, 0xb6, 0x64, 0xe8, 0x86, 0x65, 0x50, 0xbf, 0xcc, 0x27, 0x53,
|
||||
0x1f, 0x51, 0xd4, 0xca, 0xbe, 0xf5, 0xdd, 0x77, 0x70, 0x98, 0x0f, 0xee,
|
||||
0xa8, 0x96, 0x07, 0x5f, 0x45, 0x6a, 0x7a, 0x0d, 0x03, 0x9c, 0x4f, 0x29,
|
||||
0xf6, 0x06, 0xf3, 0x5d, 0x58, 0x6c, 0x47, 0xd0, 0x96, 0xa9, 0x03, 0x17,
|
||||
0xbb, 0x4e, 0xc9, 0x21, 0xe0, 0xac, 0xcd, 0x78, 0x78, 0xb2, 0xfe, 0x81,
|
||||
0xb2, 0x51, 0x53, 0xa6, 0x1f, 0x98, 0x45, 0x02, 0x81, 0x81, 0x00, 0xcf,
|
||||
0x73, 0x8c, 0xbe, 0x6d, 0x45, 0x2d, 0x0c, 0x0b, 0x5d, 0x5c, 0x6c, 0x75,
|
||||
0x78, 0xcc, 0x35, 0x48, 0xb6, 0x98, 0xf1, 0xb9, 0x64, 0x60, 0x8c, 0x43,
|
||||
0xeb, 0x85, 0xab, 0x04, 0xb6, 0x7d, 0x1b, 0x71, 0x75, 0x06, 0xe2, 0xda,
|
||||
0x84, 0x68, 0x2e, 0x7f, 0x4c, 0xe3, 0x73, 0xb4, 0xde, 0x51, 0x4b, 0xb6,
|
||||
0x51, 0x86, 0x7b, 0xd0, 0xe6, 0x4d, 0xf3, 0xd1, 0xcf, 0x1a, 0xfe, 0x7f,
|
||||
0x3a, 0x83, 0xba, 0xb3, 0xe1, 0xff, 0x54, 0x13, 0x93, 0xd7, 0x9c, 0x27,
|
||||
0x80, 0xb7, 0x1e, 0x64, 0x9e, 0xf7, 0x32, 0x2b, 0x46, 0x29, 0xf7, 0xf8,
|
||||
0x18, 0x6c, 0xf7, 0x4a, 0xbe, 0x4b, 0xee, 0x96, 0x90, 0x8f, 0xa2, 0x16,
|
||||
0x22, 0x6a, 0xcc, 0x48, 0x06, 0x74, 0x63, 0x43, 0x7f, 0x27, 0x22, 0x44,
|
||||
0x3c, 0x2d, 0x3b, 0x62, 0xf1, 0x1c, 0xb4, 0x27, 0x33, 0x85, 0x26, 0x60,
|
||||
0x48, 0x16, 0xcb, 0xef, 0xf8, 0xcd, 0x37, 0x02, 0x81, 0x81, 0x00, 0xce,
|
||||
0x15, 0x43, 0x6e, 0x4b, 0x0f, 0xf9, 0x3f, 0x87, 0xc3, 0x41, 0x45, 0x97,
|
||||
0xb1, 0x49, 0xc2, 0x19, 0x23, 0x87, 0xe4, 0x24, 0x1c, 0x64, 0xe5, 0x28,
|
||||
0xcb, 0x43, 0x10, 0x14, 0x14, 0x0e, 0x19, 0xcb, 0xbb, 0xdb, 0xfd, 0x11,
|
||||
0x9d, 0x17, 0x68, 0x78, 0x6d, 0x61, 0x70, 0x63, 0x3a, 0xa1, 0xb3, 0xf3,
|
||||
0xa7, 0x5b, 0x0e, 0xff, 0xb7, 0x61, 0x11, 0x54, 0x91, 0x99, 0xe5, 0x91,
|
||||
0x32, 0x2d, 0xeb, 0x3f, 0xd8, 0x3e, 0xf7, 0xd4, 0xcb, 0xd2, 0xa3, 0x41,
|
||||
0xc1, 0xee, 0xc6, 0x92, 0x13, 0xeb, 0x7f, 0x42, 0x58, 0xf4, 0xd0, 0xb2,
|
||||
0x74, 0x1d, 0x8e, 0x87, 0x46, 0xcd, 0x14, 0xb8, 0x16, 0xad, 0xb5, 0xbd,
|
||||
0x0d, 0x6c, 0x95, 0x5a, 0x16, 0xbf, 0xe9, 0x53, 0xda, 0xfb, 0xed, 0x83,
|
||||
0x51, 0x67, 0xa9, 0x55, 0xab, 0x54, 0x02, 0x95, 0x20, 0xa6, 0x68, 0x17,
|
||||
0x53, 0xa8, 0xea, 0x43, 0xe5, 0xb0, 0xa3, 0x02, 0x81, 0x80, 0x67, 0x9c,
|
||||
0x32, 0x83, 0x39, 0x57, 0xff, 0x73, 0xb0, 0x89, 0x64, 0x8b, 0xd6, 0xf0,
|
||||
0x0a, 0x2d, 0xe2, 0xaf, 0x30, 0x1c, 0x2a, 0x97, 0xf3, 0x90, 0x9a, 0xab,
|
||||
0x9b, 0x0b, 0x1b, 0x43, 0x79, 0xa0, 0xa7, 0x3d, 0xe7, 0xbe, 0x8d, 0x9c,
|
||||
0xeb, 0xdb, 0xad, 0x40, 0xdd, 0xa9, 0x00, 0x80, 0xb8, 0xe1, 0xb3, 0xa1,
|
||||
0x6c, 0x25, 0x92, 0xe4, 0x33, 0xb2, 0xbe, 0xeb, 0x4d, 0x74, 0x26, 0x5f,
|
||||
0x37, 0x43, 0x9c, 0x6c, 0x17, 0x76, 0x0a, 0x81, 0x20, 0x82, 0xa1, 0x48,
|
||||
0x2c, 0x2d, 0x45, 0xdc, 0x0f, 0x62, 0x43, 0x32, 0xbb, 0xeb, 0x59, 0x41,
|
||||
0xf9, 0xca, 0x58, 0xce, 0x4a, 0x66, 0x53, 0x54, 0xc8, 0x28, 0x10, 0x1e,
|
||||
0x08, 0x71, 0x16, 0xd8, 0x02, 0x71, 0x41, 0x58, 0xd4, 0x56, 0xcc, 0xf5,
|
||||
0xb1, 0x31, 0xa3, 0xed, 0x00, 0x85, 0x09, 0xbf, 0x35, 0x95, 0x41, 0x29,
|
||||
0x40, 0x19, 0x83, 0x35, 0x24, 0x69, 0x02, 0x81, 0x80, 0x55, 0x10, 0x0b,
|
||||
0xcc, 0x3b, 0xa9, 0x75, 0x3d, 0x16, 0xe1, 0xae, 0x50, 0x76, 0x63, 0x94,
|
||||
0x49, 0x4c, 0xad, 0x10, 0xcb, 0x47, 0x68, 0x7c, 0xf0, 0xe5, 0xdc, 0xb8,
|
||||
0x6a, 0xab, 0x8e, 0xf7, 0x9f, 0x08, 0x2c, 0x1b, 0x8a, 0xa2, 0xb9, 0x8f,
|
||||
0xce, 0xec, 0x5e, 0x61, 0xa8, 0xcd, 0x1c, 0x87, 0x60, 0x4a, 0xc3, 0x1a,
|
||||
0x5f, 0xdf, 0x87, 0x26, 0xc6, 0xcb, 0x7c, 0x69, 0xe4, 0x8b, 0x01, 0x06,
|
||||
0x59, 0x22, 0xfa, 0x34, 0x4b, 0x81, 0x87, 0x3c, 0x03, 0x6d, 0x02, 0x0a,
|
||||
0x77, 0xe6, 0x15, 0xd8, 0xcf, 0xa7, 0x68, 0x26, 0x6c, 0xfa, 0x2b, 0xd9,
|
||||
0x83, 0x5a, 0x2d, 0x0c, 0x3b, 0x70, 0x1c, 0xd4, 0x48, 0xbe, 0xa7, 0x0a,
|
||||
0xd9, 0xbe, 0xdc, 0xc3, 0x0c, 0x21, 0x33, 0xb3, 0x66, 0xff, 0x1c, 0x1b,
|
||||
0xc8, 0x96, 0x76, 0xe8, 0x6f, 0x44, 0x74, 0xbc, 0x9b, 0x1c, 0x7d, 0xc8,
|
||||
0xac, 0x21, 0xa8, 0x6e, 0x37, 0x02, 0x81, 0x80, 0x2c, 0x7c, 0xad, 0x1e,
|
||||
0x75, 0xf6, 0x69, 0x1d, 0xe7, 0xa6, 0xca, 0x74, 0x7d, 0x67, 0xc8, 0x65,
|
||||
0x28, 0x66, 0xc4, 0x43, 0xa6, 0xbd, 0x40, 0x57, 0xae, 0xb7, 0x65, 0x2c,
|
||||
0x52, 0xf9, 0xe4, 0xc7, 0x81, 0x7b, 0x56, 0xa3, 0xd2, 0x0d, 0xe8, 0x33,
|
||||
0x70, 0xcf, 0x06, 0x84, 0xb3, 0x4e, 0x44, 0x50, 0x75, 0x61, 0x96, 0x86,
|
||||
0x4b, 0xb6, 0x2b, 0xad, 0xf0, 0xad, 0x57, 0xd0, 0x37, 0x0d, 0x1d, 0x35,
|
||||
0x50, 0xcb, 0x69, 0x22, 0x39, 0x29, 0xb9, 0x3a, 0xd3, 0x29, 0x23, 0x02,
|
||||
0x60, 0xf7, 0xab, 0x30, 0x40, 0xda, 0x8e, 0x4d, 0x45, 0x70, 0x26, 0xf4,
|
||||
0xa2, 0x0d, 0xd0, 0x64, 0x5d, 0x47, 0x3c, 0x18, 0xf4, 0xd4, 0x52, 0x95,
|
||||
0x00, 0xae, 0x84, 0x6b, 0x47, 0xb2, 0x3c, 0x82, 0xd3, 0x72, 0x53, 0xde,
|
||||
0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe, 0x39, 0x28,
|
||||
0x33, 0xe0, 0xdb, 0x03,
|
||||
};
|
||||
|
||||
} // namespace wvoec
|
||||
|
||||
#endif // CDM_OEC_TEST_DATA_H_
|
||||
|
||||
@@ -2445,6 +2445,24 @@ TEST_F(OEMCryptoLoadsCertificate, TestLargeRSAKey3072) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
}
|
||||
|
||||
// Test an RSA key certificate which has a private key generated using the
|
||||
// Carmichael totient.
|
||||
TEST_F(OEMCryptoLoadsCertificate, TestCarmichaelRSAKey) {
|
||||
encoded_rsa_key_.assign(
|
||||
kTestKeyRSACarmichael_2048,
|
||||
kTestKeyRSACarmichael_2048 + sizeof(kTestKeyRSACarmichael_2048));
|
||||
CreateWrappedRSAKey(kSign_RSASSA_PSS, true);
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0],
|
||||
encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(kDuration, 0, 0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
}
|
||||
|
||||
// Devices that load certificates, should at least support RSA 2048 keys.
|
||||
TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
|
||||
ASSERT_NE(0u,
|
||||
@@ -5265,7 +5283,7 @@ TEST_F(UsageTableDefragTest, ReloadUsageEntryBadData) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
vector<uint8_t> data = s.encrypted_usage_entry();
|
||||
ASSERT_LT(0, data.size());
|
||||
ASSERT_LT(0UL, data.size());
|
||||
data[0] ^= 42;
|
||||
// Error could be signature or verification error.
|
||||
ASSERT_NE(OEMCrypto_SUCCESS,
|
||||
|
||||
Reference in New Issue
Block a user