diff options
author | Shawn Willden <swillden@google.com> | 2016-01-11 08:55:50 -0700 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2016-01-27 20:12:44 -0700 |
commit | fc3cafd487e69c84d83444e1d129d0ab131c4e3d (patch) | |
tree | ab373f7deac7342c6a2cc38a4084e22526fc3c3c | |
parent | d3ee550ac91a5c21343d9885a0e231281057e916 (diff) | |
download | keymaster-fc3cafd487e69c84d83444e1d129d0ab131c4e3d.tar.gz |
Add attestation support to SoftKeymaster.
Bug: 22914603
Change-Id: I7650f1b691665bce3024556c2ea38e122c9cb2cf
-rw-r--r-- | android_keymaster_test.cpp | 126 | ||||
-rw-r--r-- | android_keymaster_test_utils.cpp | 9 | ||||
-rw-r--r-- | android_keymaster_test_utils.h | 5 | ||||
-rw-r--r-- | asymmetric_key.cpp | 2 | ||||
-rw-r--r-- | include/keymaster/android_keymaster_utils.h | 18 | ||||
-rw-r--r-- | include/keymaster/soft_keymaster_device.h | 4 | ||||
-rw-r--r-- | soft_keymaster_context.cpp | 166 | ||||
-rw-r--r-- | soft_keymaster_device.cpp | 50 |
8 files changed, 269 insertions, 111 deletions
diff --git a/android_keymaster_test.cpp b/android_keymaster_test.cpp index 0d8933e..5d4bb3d 100644 --- a/android_keymaster_test.cpp +++ b/android_keymaster_test.cpp @@ -28,14 +28,16 @@ #include <keymaster/softkeymaster.h> #include "android_keymaster_test_utils.h" +#include "attestation_record.h" #include "keymaster0_engine.h" #include "openssl_utils.h" using std::ifstream; using std::istreambuf_iterator; +using std::ofstream; using std::string; -using std::vector; using std::unique_ptr; +using std::vector; extern "C" { int __android_log_print(int prio, const char* tag, const char* fmt); @@ -3444,6 +3446,128 @@ TEST_P(Keymaster0AdapterTest, OldHwKeymaster0RsaBlobGetCharacteristics) { EXPECT_EQ(1, GetParam()->keymaster0_calls()); } +typedef Keymaster2Test AttestationTest; +INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, AttestationTest, test_params); + +static X509* parse_cert_blob(const keymaster_blob_t& blob) { + const uint8_t* p = blob.data; + return d2i_X509(nullptr, &p, blob.data_length); +} + +static bool verify_chain(const keymaster_cert_chain_t& chain) { + for (size_t i = 0; i < chain.entry_count - 1; ++i) { + keymaster_blob_t& key_cert_blob = chain.entries[i]; + keymaster_blob_t& signing_cert_blob = chain.entries[i + 1]; + + X509_Ptr key_cert(parse_cert_blob(key_cert_blob)); + X509_Ptr signing_cert(parse_cert_blob(signing_cert_blob)); + EXPECT_TRUE(!!key_cert.get() && !!signing_cert.get()); + if (!key_cert.get() || !signing_cert.get()) + return false; + + EVP_PKEY_Ptr signing_pubkey(X509_get_pubkey(signing_cert.get())); + EXPECT_TRUE(!!signing_pubkey.get()); + if (!signing_pubkey.get()) + return false; + + EXPECT_EQ(1, X509_verify(key_cert.get(), signing_pubkey.get())) + << "Verification of certificate " << i << " failed"; + } + + return true; +} + +// Extract attestation record from cert. Returned object is still part of cert; don't free it +// separately. +static ASN1_OCTET_STRING* get_attestation_record(X509* certificate) { + ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */)); + EXPECT_TRUE(!!oid.get()); + if (!oid.get()) + return nullptr; + + int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */); + EXPECT_NE(-1, location); + if (location == -1) + return nullptr; + + X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location); + EXPECT_TRUE(!!attest_rec_ext); + if (!attest_rec_ext) + return nullptr; + + ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext); + EXPECT_TRUE(!!attest_rec); + return attest_rec; +} + +static bool verify_attestation_record(AuthorizationSet expected_sw_enforced, + AuthorizationSet expected_tee_enforced, + const keymaster_blob_t& attestation_cert) { + + X509_Ptr cert(parse_cert_blob(attestation_cert)); + EXPECT_TRUE(!!cert.get()); + if (!cert.get()) + return false; + + ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); + EXPECT_TRUE(!!attest_rec); + if (!attest_rec) + return false; + + AuthorizationSet att_sw_enforced; + AuthorizationSet att_tee_enforced; + EXPECT_EQ(KM_ERROR_OK, parse_attestation_record(attest_rec->data, attest_rec->length, + &att_sw_enforced, &att_tee_enforced)); + + // Add TAG_USER_ID to the attestation sw-enforced list, because user IDs are not included in + // attestations, since they're meaningless off-device. + uint32_t user_id; + if (expected_sw_enforced.GetTagValue(TAG_USER_ID, &user_id)) + att_sw_enforced.push_back(TAG_USER_ID, user_id); + if (expected_tee_enforced.GetTagValue(TAG_USER_ID, &user_id)) + att_tee_enforced.push_back(TAG_USER_ID, user_id); + + att_sw_enforced.Sort(); + expected_sw_enforced.Sort(); + EXPECT_EQ(expected_sw_enforced, att_sw_enforced); + + att_tee_enforced.Sort(); + expected_tee_enforced.Sort(); + EXPECT_EQ(expected_tee_enforced, att_tee_enforced); + + return true; +} + +TEST_P(AttestationTest, RsaSignedWithRsa) { + ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder() + .RsaSigningKey(256, 3) + .Digest(KM_DIGEST_NONE) + .Padding(KM_PAD_NONE))); + + keymaster_cert_chain_t cert_chain; + EXPECT_EQ(KM_ERROR_OK, AttestKey(KM_ALGORITHM_RSA, &cert_chain)); + EXPECT_EQ(3U, cert_chain.entry_count); + EXPECT_TRUE(verify_chain(cert_chain)); + EXPECT_TRUE(verify_attestation_record(sw_enforced(), hw_enforced(), cert_chain.entries[0])); + + keymaster_free_cert_chain(&cert_chain); +} + +TEST_P(AttestationTest, RsaSignedWithEc) { + ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder() + .RsaSigningKey(256, 3) + .Digest(KM_DIGEST_NONE) + .Padding(KM_PAD_NONE))); + + keymaster_cert_chain_t cert_chain; + EXPECT_EQ(KM_ERROR_OK, AttestKey(KM_ALGORITHM_EC, &cert_chain)); + EXPECT_EQ(3U, cert_chain.entry_count); + EXPECT_TRUE(verify_chain(cert_chain)); + EXPECT_TRUE(verify_attestation_record(sw_enforced(), hw_enforced(), cert_chain.entries[0])); + + keymaster_free_cert_chain(&cert_chain); +} + TEST(SoftKeymasterWrapperTest, CheckKeymaster2Device) { // Make a good fake device, and wrap it. SoftKeymasterDevice* good_fake(new SoftKeymasterDevice(new TestKeymasterContext)); diff --git a/android_keymaster_test_utils.cpp b/android_keymaster_test_utils.cpp index f62dd66..bfe68ff 100644 --- a/android_keymaster_test_utils.cpp +++ b/android_keymaster_test_utils.cpp @@ -328,6 +328,15 @@ keymaster_error_t Keymaster2Test::AbortOperation() { return device()->abort(device(), op_handle_); } +keymaster_error_t Keymaster2Test::AttestKey(keymaster_algorithm_t algorithm, + keymaster_cert_chain_t* cert_chain) { + AuthorizationSet attest_params( + AuthorizationSetBuilder().Authorization(TAG_ALGORITHM, algorithm)); + attest_params.push_back(UserAuthParams()); + attest_params.push_back(ClientParams()); + return device()->attest_key(device(), &blob_, &attest_params, cert_chain); +} + string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message) { EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, client_params(), NULL /* output_params */)); diff --git a/android_keymaster_test_utils.h b/android_keymaster_test_utils.h index d1acec0..cba1467 100644 --- a/android_keymaster_test_utils.h +++ b/android_keymaster_test_utils.h @@ -144,7 +144,7 @@ inline std::string make_string(const uint8_t* data, size_t length) { return std::string(reinterpret_cast<const char*>(data), length); } -template <size_t N> std::string make_string(const uint8_t(&a)[N]) { +template <size_t N> std::string make_string(const uint8_t (&a)[N]) { return make_string(a, N); } @@ -208,6 +208,8 @@ class Keymaster2Test : public testing::TestWithParam<InstanceCreatorPtr> { keymaster_error_t AbortOperation(); + keymaster_error_t AttestKey(keymaster_algorithm_t algorithm, keymaster_cert_chain_t* chain); + keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor); std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message); @@ -450,7 +452,6 @@ struct Keymaster0CountingWrapper : public keymaster0_device_t { int counter_; }; - /** * This function takes a keymaster1_device_t and wraps it in an adapter that supports only * KM_DIGEST_SHA_2_256. diff --git a/asymmetric_key.cpp b/asymmetric_key.cpp index d3a0f31..e0af5a5 100644 --- a/asymmetric_key.cpp +++ b/asymmetric_key.cpp @@ -224,7 +224,7 @@ keymaster_error_t AsymmetricKey::GenerateAttestation(const KeymasterContext& con return TranslateLastOpenSslError(); keymaster_error_t error = KM_ERROR_OK; - EVP_PKEY_Ptr sign_key(context.AttestationKey(KM_ALGORITHM_RSA, &error)); + EVP_PKEY_Ptr sign_key(context.AttestationKey(sign_algorithm, &error)); if (!sign_key.get() || // !add_public_key(pkey.get(), certificate.get(), &error) || diff --git a/include/keymaster/android_keymaster_utils.h b/include/keymaster/android_keymaster_utils.h index 3ce56cc..c190e04 100644 --- a/include/keymaster/android_keymaster_utils.h +++ b/include/keymaster/android_keymaster_utils.h @@ -50,14 +50,14 @@ inline int64_t java_time(time_t time) { /** * Return the size in bytes of the array \p a. */ -template <typename T, size_t N> inline size_t array_size(const T(&a)[N]) { +template <typename T, size_t N> inline size_t array_size(const T (&a)[N]) { return sizeof(a); } /** * Return the number of elements in array \p a. */ -template <typename T, size_t N> inline size_t array_length(const T(&)[N]) { +template <typename T, size_t N> inline size_t array_length(const T (&)[N]) { return N; } @@ -78,7 +78,7 @@ template <typename T> inline T* dup_array(const T* a, size_t n) { * responsibility. Note that the dup is necessarily returned as a pointer, so size is lost. Call * array_length() on the original array to discover the size. */ -template <typename T, size_t N> inline T* dup_array(const T(&a)[N]) { +template <typename T, size_t N> inline T* dup_array(const T (&a)[N]) { return dup_array(a, N); } @@ -91,7 +91,7 @@ uint8_t* dup_buffer(const void* buf, size_t size); /** * Copy the contents of array \p arr to \p dest. */ -template <typename T, size_t N> inline void copy_array(const T(&arr)[N], T* dest) { +template <typename T, size_t N> inline void copy_array(const T (&arr)[N], T* dest) { for (size_t i = 0; i < N; ++i) dest[i] = arr[i]; } @@ -101,7 +101,7 @@ template <typename T, size_t N> inline void copy_array(const T(&arr)[N], T* dest * early-exit, meaning that it should not be used in contexts where timing analysis attacks could be * a concern. */ -template <typename T, size_t N> inline bool array_contains(const T(&a)[N], T val) { +template <typename T, size_t N> inline bool array_contains(const T (&a)[N], T val) { for (size_t i = 0; i < N; ++i) { if (a[i] == val) { return true; @@ -144,10 +144,9 @@ class Eraser { template <typename T> explicit Eraser(T* t); template <typename T> - explicit Eraser(T& t) - : buf_(reinterpret_cast<uint8_t*>(&t)), size_(sizeof(t)) {} + explicit Eraser(T& t) : buf_(reinterpret_cast<uint8_t*>(&t)), size_(sizeof(t)) {} - template <size_t N> explicit Eraser(uint8_t(&arr)[N]) : buf_(arr), size_(N) {} + template <size_t N> explicit Eraser(uint8_t (&arr)[N]) : buf_(arr), size_(N) {} Eraser(void* buf, size_t size) : buf_(static_cast<uint8_t*>(buf)), size_(size) {} ~Eraser() { memset_s(buf_, 0, size_); } @@ -176,6 +175,9 @@ template <typename T> class ArrayWrapper { T* begin_; T* end_; }; +template <typename T> ArrayWrapper<T> array_range(T* begin, size_t length) { + return ArrayWrapper<T>(begin, length); +} /** * Convert any unsigned integer from network to host order. We implement this here rather than diff --git a/include/keymaster/soft_keymaster_device.h b/include/keymaster/soft_keymaster_device.h index c39b326..e9e325d 100644 --- a/include/keymaster/soft_keymaster_device.h +++ b/include/keymaster/soft_keymaster_device.h @@ -200,6 +200,10 @@ class SoftKeymasterDevice { const keymaster_blob_t* client_id, const keymaster_blob_t* app_data, keymaster_blob_t* export_data); + static keymaster_error_t attest_key(const keymaster2_device_t* dev, + const keymaster_key_blob_t* key_to_attest, + const keymaster_key_param_set_t* attest_params, + keymaster_cert_chain_t* cert_chain); static keymaster_error_t delete_key(const keymaster2_device_t* dev, const keymaster_key_blob_t* key); static keymaster_error_t delete_all_keys(const keymaster2_device_t* dev); diff --git a/soft_keymaster_context.cpp b/soft_keymaster_context.cpp index bde7ae1..ab68760 100644 --- a/soft_keymaster_context.cpp +++ b/soft_keymaster_context.cpp @@ -182,29 +182,19 @@ static uint8_t kRsaAttestRootCert[] = { }; static uint8_t kEcAttestKey[] = { - 0x30, 0x82, 0x01, 0x13, 0x02, 0x01, 0x01, 0x04, 0x20, 0xb4, 0x42, 0xdb, 0x79, 0x76, 0xd2, 0xc7, - 0x4d, 0x17, 0x15, 0x88, 0xf0, 0x7b, 0x6d, 0x94, 0x27, 0x9e, 0xd3, 0x46, 0x17, 0x54, 0x74, 0xbf, - 0x58, 0xfb, 0xaf, 0x51, 0x2c, 0x8c, 0x2f, 0x1e, 0x23, 0xa0, 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x02, - 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, - 0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x41, 0x04, 0x79, 0xbe, 0x66, 0x7e, 0xf9, - 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, - 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98, 0x48, 0x3a, 0xda, 0x77, 0x26, - 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, - 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, 0x02, 0x21, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, - 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, 0x02, 0x01, - 0x01, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x18, 0x4c, 0x18, 0x2d, 0x52, 0xa5, 0x0f, 0x38, 0x7f, - 0xeb, 0x12, 0xe3, 0x6b, 0x8e, 0x64, 0x18, 0x36, 0x28, 0xc1, 0x0d, 0xb7, 0x03, 0x70, 0xde, 0x6f, - 0x02, 0x12, 0x40, 0xa9, 0x5e, 0x9a, 0xb8, 0x3b, 0x7c, 0x0e, 0x75, 0xfd, 0x19, 0x32, 0x4c, 0xd0, - 0x11, 0x3d, 0x7b, 0xeb, 0x29, 0xdf, 0xa9, 0x01, 0xb7, 0x40, 0xac, 0xac, 0x56, 0x7e, 0xcf, 0x5a, - 0x01, 0x1f, 0xa5, 0xc4, 0x98, 0x15, 0x7a, + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x21, 0xe0, 0x86, 0x43, 0x2a, 0x15, 0x19, 0x84, 0x59, + 0xcf, 0x36, 0x3a, 0x50, 0xfc, 0x14, 0xc9, 0xda, 0xad, 0xf9, 0x35, 0xf5, 0x27, 0xc2, 0xdf, 0xd7, + 0x1e, 0x4d, 0x6d, 0xbc, 0x42, 0xe5, 0x44, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xeb, 0x9e, 0x79, 0xf8, 0x42, 0x63, 0x59, + 0xac, 0xcb, 0x2a, 0x91, 0x4c, 0x89, 0x86, 0xcc, 0x70, 0xad, 0x90, 0x66, 0x93, 0x82, 0xa9, 0x73, + 0x26, 0x13, 0xfe, 0xac, 0xcb, 0xf8, 0x21, 0x27, 0x4c, 0x21, 0x74, 0x97, 0x4a, 0x2a, 0xfe, 0xa5, + 0xb9, 0x4d, 0x7f, 0x66, 0xd4, 0xe0, 0x65, 0x10, 0x66, 0x35, 0xbc, 0x53, 0xb7, 0xa0, 0xa3, 0xa6, + 0x71, 0x58, 0x3e, 0xdb, 0x3e, 0x11, 0xae, 0x10, 0x14, }; static uint8_t kEcAttestCert[] = { - 0x30, 0x82, 0x03, 0x17, 0x30, 0x82, 0x02, 0xbc, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, - 0x00, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0x98, + 0x30, 0x82, 0x02, 0x78, 0x30, 0x82, 0x02, 0x1e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, + 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, @@ -212,52 +202,42 @@ static uint8_t kEcAttestCert[] = { 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x41, 0x6e, - 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x53, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x31, - 0x30, 0x34, 0x31, 0x33, 0x32, 0x33, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x31, 0x30, - 0x31, 0x31, 0x33, 0x32, 0x33, 0x30, 0x30, 0x5a, 0x30, 0x81, 0x89, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x31, 0x31, 0x30, 0x30, 0x34, 0x36, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x31, 0x30, + 0x38, 0x30, 0x30, 0x34, 0x36, 0x30, 0x39, 0x5a, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, - 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x33, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x30, 0x81, 0xf5, 0x30, 0x81, 0xae, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, - 0x3d, 0x02, 0x01, 0x30, 0x81, 0xa2, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, - 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, - 0x41, 0x04, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, - 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, - 0x17, 0x98, 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, - 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, - 0xd4, 0xb8, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, - 0x8c, 0xd0, 0x36, 0x41, 0x41, 0x02, 0x01, 0x01, 0x03, 0x42, 0x00, 0x04, 0x18, 0x4c, 0x18, 0x2d, - 0x52, 0xa5, 0x0f, 0x38, 0x7f, 0xeb, 0x12, 0xe3, 0x6b, 0x8e, 0x64, 0x18, 0x36, 0x28, 0xc1, 0x0d, - 0xb7, 0x03, 0x70, 0xde, 0x6f, 0x02, 0x12, 0x40, 0xa9, 0x5e, 0x9a, 0xb8, 0x3b, 0x7c, 0x0e, 0x75, - 0xfd, 0x19, 0x32, 0x4c, 0xd0, 0x11, 0x3d, 0x7b, 0xeb, 0x29, 0xdf, 0xa9, 0x01, 0xb7, 0x40, 0xac, - 0xac, 0x56, 0x7e, 0xcf, 0x5a, 0x01, 0x1f, 0xa5, 0xc4, 0x98, 0x15, 0x7a, 0xa3, 0x66, 0x30, 0x64, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x49, 0xcf, 0x1a, 0xa4, 0x97, - 0x9e, 0xc0, 0x07, 0xcd, 0x92, 0x83, 0x82, 0xf1, 0x4f, 0xfa, 0x14, 0xfb, 0xe8, 0xf8, 0x50, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xf5, 0x93, 0x69, 0xf0, - 0x54, 0xc1, 0x52, 0x5d, 0x1f, 0x59, 0x49, 0xd4, 0xd8, 0x72, 0x1c, 0xae, 0x89, 0x4e, 0x6b, 0x09, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, - 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, - 0x03, 0x02, 0x02, 0x84, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, - 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x99, 0xa7, 0x1b, 0xc2, 0x26, 0x64, 0xda, 0x14, - 0xb2, 0x9e, 0x5f, 0x6d, 0x87, 0x75, 0x52, 0x32, 0x97, 0xe8, 0x5f, 0x7f, 0x3e, 0x23, 0xcd, 0x74, - 0xc7, 0x50, 0x36, 0x54, 0x5a, 0xe3, 0x94, 0x42, 0x02, 0x21, 0x00, 0x82, 0xf4, 0xa9, 0x9d, 0x2a, - 0x9b, 0x05, 0xee, 0x8f, 0xcb, 0x33, 0x10, 0x27, 0xf7, 0x40, 0xbe, 0x62, 0xce, 0x38, 0x6d, 0x0b, - 0xe5, 0x19, 0x2f, 0x0e, 0x36, 0xb3, 0x6d, 0x10, 0x8d, 0x42, 0xa2, + 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x32, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xeb, 0x9e, + 0x79, 0xf8, 0x42, 0x63, 0x59, 0xac, 0xcb, 0x2a, 0x91, 0x4c, 0x89, 0x86, 0xcc, 0x70, 0xad, 0x90, + 0x66, 0x93, 0x82, 0xa9, 0x73, 0x26, 0x13, 0xfe, 0xac, 0xcb, 0xf8, 0x21, 0x27, 0x4c, 0x21, 0x74, + 0x97, 0x4a, 0x2a, 0xfe, 0xa5, 0xb9, 0x4d, 0x7f, 0x66, 0xd4, 0xe0, 0x65, 0x10, 0x66, 0x35, 0xbc, + 0x53, 0xb7, 0xa0, 0xa3, 0xa6, 0x71, 0x58, 0x3e, 0xdb, 0x3e, 0x11, 0xae, 0x10, 0x14, 0xa3, 0x66, + 0x30, 0x64, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3f, 0xfc, 0xac, + 0xd6, 0x1a, 0xb1, 0x3a, 0x9e, 0x81, 0x20, 0xb8, 0xd5, 0x25, 0x1c, 0xc5, 0x65, 0xbb, 0x1e, 0x91, + 0xa9, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc8, 0xad, + 0xe9, 0x77, 0x4c, 0x45, 0xc3, 0xa3, 0xcf, 0x0d, 0x16, 0x10, 0xe4, 0x79, 0x43, 0x3a, 0x21, 0x5a, + 0x30, 0xcf, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x4b, 0x8a, 0x9b, 0x7b, 0xee, 0x82, 0xbc, + 0xc0, 0x33, 0x87, 0xae, 0x2f, 0xc0, 0x89, 0x98, 0xb4, 0xdd, 0xc3, 0x8d, 0xab, 0x27, 0x2a, 0x45, + 0x9f, 0x69, 0x0c, 0xc7, 0xc3, 0x92, 0xd4, 0x0f, 0x8e, 0x02, 0x21, 0x00, 0xee, 0xda, 0x01, 0x5d, + 0xb6, 0xf4, 0x32, 0xe9, 0xd4, 0x84, 0x3b, 0x62, 0x4c, 0x94, 0x04, 0xef, 0x3a, 0x7c, 0xcc, 0xbd, + 0x5e, 0xfb, 0x22, 0xbb, 0xe7, 0xfe, 0xb9, 0x77, 0x3f, 0x59, 0x3f, 0xfb, }; static uint8_t kEcAttestRootCert[] = { - 0x30, 0x82, 0x03, 0x29, 0x30, 0x82, 0x02, 0xcf, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, - 0x98, 0xd8, 0x96, 0x30, 0x3d, 0xbc, 0x29, 0xae, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x30, 0x82, 0x02, 0x8b, 0x30, 0x82, 0x02, 0x32, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, + 0xa2, 0x05, 0x9e, 0xd1, 0x0e, 0x43, 0x5b, 0x57, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, @@ -265,11 +245,11 @@ static uint8_t kEcAttestRootCert[] = { 0x77, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x53, 0x6f, 0x66, - 0x74, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, + 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, - 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x31, 0x30, 0x34, 0x31, 0x33, 0x32, 0x31, 0x30, 0x37, 0x5a, - 0x17, 0x0d, 0x33, 0x35, 0x31, 0x32, 0x33, 0x30, 0x31, 0x33, 0x32, 0x31, 0x30, 0x37, 0x5a, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x31, 0x31, 0x31, 0x30, 0x30, 0x34, 0x33, 0x35, 0x30, 0x5a, + 0x17, 0x0d, 0x33, 0x36, 0x30, 0x31, 0x30, 0x36, 0x30, 0x30, 0x34, 0x33, 0x35, 0x30, 0x5a, 0x30, 0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, @@ -277,36 +257,26 @@ static uint8_t kEcAttestRootCert[] = { 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, - 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x4b, 0x65, 0x79, 0x6d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x81, 0xf5, 0x30, 0x81, 0xae, - 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x30, 0x81, 0xa2, 0x02, 0x01, 0x01, 0x30, - 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x30, 0x06, 0x04, - 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x41, 0x04, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, - 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, - 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98, 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, - 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, - 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, - 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, 0x02, 0x01, 0x01, 0x03, 0x42, - 0x00, 0x04, 0x20, 0xf2, 0x5a, 0xc7, 0x49, 0x9b, 0xf1, 0x84, 0xf3, 0x34, 0x96, 0xc9, 0x3c, 0x73, - 0x00, 0xf2, 0x3c, 0x2e, 0xa2, 0xec, 0x0e, 0x99, 0x83, 0x5d, 0x9a, 0x22, 0x49, 0x14, 0xef, 0x8f, - 0x5f, 0xc4, 0xff, 0xfa, 0x12, 0x7c, 0xc4, 0xa9, 0x9d, 0x6d, 0xa3, 0x3c, 0x09, 0xbe, 0xed, 0x7d, - 0x2d, 0xb5, 0xa4, 0x5e, 0xac, 0x1e, 0x7b, 0xc6, 0xa4, 0x81, 0x5d, 0xf3, 0x8b, 0x43, 0x6d, 0x4c, - 0x31, 0xbc, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0xf5, 0x93, 0x69, 0xf0, 0x54, 0xc1, 0x52, 0x5d, 0x1f, 0x59, 0x49, 0xd4, 0xd8, 0x72, 0x1c, - 0xae, 0x89, 0x4e, 0x6b, 0x09, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xf5, 0x93, 0x69, 0xf0, 0x54, 0xc1, 0x52, 0x5d, 0x1f, 0x59, 0x49, 0xd4, 0xd8, 0x72, - 0x1c, 0xae, 0x89, 0x4e, 0x6b, 0x09, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, - 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x71, 0xa3, 0x49, 0xbb, 0x57, 0xe1, - 0x0a, 0xd0, 0x8c, 0x5f, 0xed, 0x89, 0x30, 0xcf, 0xdb, 0x33, 0x3c, 0xed, 0xb9, 0xe0, 0x46, 0x11, - 0x2a, 0x73, 0xa7, 0x59, 0x53, 0xe4, 0x70, 0x18, 0xd4, 0xc2, 0x02, 0x21, 0x00, 0xb7, 0x0b, 0xf4, - 0x65, 0x8b, 0x1c, 0xbe, 0x53, 0x04, 0x9e, 0x9a, 0x16, 0x28, 0x55, 0xa9, 0x55, 0x48, 0xda, 0x28, - 0x2c, 0x3e, 0x4f, 0x68, 0xaa, 0xb4, 0x6e, 0xfe, 0x27, 0x4c, 0xeb, 0x78, 0x47, + 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, + 0x07, 0x03, 0x42, 0x00, 0x04, 0xee, 0x5d, 0x5e, 0xc7, 0xe1, 0xc0, 0xdb, 0x6d, 0x03, 0xa6, 0x7e, + 0xe6, 0xb6, 0x1b, 0xec, 0x4d, 0x6a, 0x5d, 0x6a, 0x68, 0x2e, 0x0f, 0xff, 0x7f, 0x49, 0x0e, 0x7d, + 0x77, 0x1f, 0x44, 0x22, 0x6d, 0xbd, 0xb1, 0xaf, 0xfa, 0x16, 0xcb, 0xc7, 0xad, 0xc5, 0x77, 0xd2, + 0x56, 0x9c, 0xaa, 0xb7, 0xb0, 0x2d, 0x54, 0x01, 0x5d, 0x3e, 0x43, 0x2b, 0x2a, 0x8e, 0xd7, 0x4e, + 0xec, 0x48, 0x75, 0x41, 0xa4, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xc8, 0xad, 0xe9, 0x77, 0x4c, 0x45, 0xc3, 0xa3, 0xcf, 0x0d, 0x16, 0x10, + 0xe4, 0x79, 0x43, 0x3a, 0x21, 0x5a, 0x30, 0xcf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0xc8, 0xad, 0xe9, 0x77, 0x4c, 0x45, 0xc3, 0xa3, 0xcf, 0x0d, 0x16, + 0x10, 0xe4, 0x79, 0x43, 0x3a, 0x21, 0x5a, 0x30, 0xcf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x35, 0x21, 0xa3, + 0xef, 0x8b, 0x34, 0x46, 0x1e, 0x9c, 0xd5, 0x60, 0xf3, 0x1d, 0x58, 0x89, 0x20, 0x6a, 0xdc, 0xa3, + 0x65, 0x41, 0xf6, 0x0d, 0x9e, 0xce, 0x8a, 0x19, 0x8c, 0x66, 0x48, 0x60, 0x7b, 0x02, 0x20, 0x4d, + 0x0b, 0xf3, 0x51, 0xd9, 0x30, 0x7c, 0x7d, 0x5b, 0xda, 0x35, 0x34, 0x1d, 0xa8, 0x47, 0x1b, 0x63, + 0xa5, 0x85, 0x65, 0x3c, 0xad, 0x4f, 0x24, 0xa7, 0xe7, 0x4d, 0xaf, 0x41, 0x7d, 0xf1, 0xbf, }; size_t kCertificateChainLength = 2; @@ -733,7 +703,7 @@ keymaster_cert_chain_t* SoftKeymasterContext::AttestationChain(keymaster_algorit if (!chain->entries) return nullptr; - memset(&chain->entries, 0, sizeof(chain->entries[0]) * kCertificateChainLength); + memset(chain->entries, 0, sizeof(chain->entries[0]) * kCertificateChainLength); chain->entry_count = kCertificateChainLength; size_t entry = 0; @@ -748,19 +718,21 @@ keymaster_cert_chain_t* SoftKeymasterContext::AttestationChain(keymaster_algorit chain->entries[entry].data = dup_array(kRsaAttestRootCert); if (!chain->entries[entry].data) return nullptr; - chain->entries[entry++].data_length = array_length(kRsaAttestRootCert); + chain->entries[entry].data_length = array_length(kRsaAttestRootCert); + entry++; break; case KM_ALGORITHM_EC: chain->entries[entry].data = dup_array(kEcAttestCert); if (!chain->entries[entry].data) return nullptr; - chain->entries[entry++].data_length = array_length(kEcAttestCert); + chain->entries[entry].data_length = array_length(kEcAttestCert); + entry++; chain->entries[entry].data = dup_array(kEcAttestRootCert); if (!chain->entries[entry].data) return nullptr; - chain->entries[entry++].data_length = array_length(kEcAttestRootCert); - + chain->entries[entry].data_length = array_length(kEcAttestRootCert); + entry++; break; default: diff --git a/soft_keymaster_device.cpp b/soft_keymaster_device.cpp index cff3ebb..cbeaec7 100644 --- a/soft_keymaster_device.cpp +++ b/soft_keymaster_device.cpp @@ -280,8 +280,8 @@ void SoftKeymasterDevice::initialize_device_struct(uint32_t flags) { km2_device_.get_key_characteristics = get_key_characteristics; km2_device_.import_key = import_key; km2_device_.export_key = export_key; - km2_device_.agree_key = nullptr; // TODO(swillden) Implement ECDH - km2_device_.attest_key = nullptr; // TODO(swillden) Implement attestation + km2_device_.agree_key = nullptr; // TODO(swillden) Implement ECDH + km2_device_.attest_key = attest_key; km2_device_.upgrade_key = nullptr; // TODO(swillden) Implement upgrade km2_device_.delete_key = delete_key; km2_device_.delete_all_keys = delete_all_keys; @@ -978,6 +978,52 @@ keymaster_error_t SoftKeymasterDevice::export_key(const keymaster2_device_t* dev } /* static */ +keymaster_error_t SoftKeymasterDevice::attest_key(const keymaster2_device_t* dev, + const keymaster_key_blob_t* key_to_attest, + const keymaster_key_param_set_t* attest_params, + keymaster_cert_chain_t* cert_chain) { + if (!dev || !key_to_attest || !attest_params || !cert_chain) + return KM_ERROR_UNEXPECTED_NULL_POINTER; + + cert_chain->entry_count = 0; + cert_chain->entries = nullptr; + + AttestKeyRequest request; + request.SetKeyMaterial(*key_to_attest); + request.attest_params.Reinitialize(*attest_params); + + AttestKeyResponse response; + convert_device(dev)->impl_->AttestKey(request, &response); + if (response.error != KM_ERROR_OK) + return response.error; + + // Allocate and clear storage for cert_chain. + keymaster_cert_chain_t& rsp_chain = response.certificate_chain; + cert_chain->entries = reinterpret_cast<keymaster_blob_t*>( + malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries))); + if (!cert_chain->entries) + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + cert_chain->entry_count = rsp_chain.entry_count; + for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count)) + entry = {}; + + // Copy cert_chain contents + size_t i = 0; + for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) { + cert_chain->entries[i].data = reinterpret_cast<uint8_t*>(malloc(entry.data_length)); + if (!cert_chain->entries[i].data) { + keymaster_free_cert_chain(cert_chain); + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + } + cert_chain->entries[i].data_length = entry.data_length; + memcpy(const_cast<uint8_t*>(cert_chain->entries[i].data), entry.data, entry.data_length); + ++i; + } + + return KM_ERROR_OK; +} + +/* static */ keymaster_error_t SoftKeymasterDevice::delete_key(const keymaster1_device_t* dev, const keymaster_key_blob_t* key) { if (!dev || !key || !key->key_material) |