13bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis/* 23bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** 33bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** Copyright 2017, The Android Open Source Project 43bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** 53bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** Licensed under the Apache License, Version 2.0 (the "License"); 63bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** you may not use this file except in compliance with the License. 73bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** You may obtain a copy of the License at 83bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** 93bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** http://www.apache.org/licenses/LICENSE-2.0 103bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** 113bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** Unless required by applicable law or agreed to in writing, software 123bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** distributed under the License is distributed on an "AS IS" BASIS, 133bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** See the License for the specific language governing permissions and 153bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis** limitations under the License. 163bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis*/ 173bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 183bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <keymaster/km_openssl/attestation_utils.h> 193bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 203bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <hardware/keymaster_defs.h> 213bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 223bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <keymaster/authorization_set.h> 233bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <keymaster/attestation_record.h> 243bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <keymaster/km_openssl/asymmetric_key.h> 253bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <keymaster/km_openssl/openssl_utils.h> 263bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <keymaster/km_openssl/openssl_err.h> 273bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 283bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <openssl/x509v3.h> 293bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis#include <openssl/evp.h> 303bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 313bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 323bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisnamespace keymaster { 333bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 343bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisnamespace { 353bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 363bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisconstexpr int kDigitalSignatureKeyUsageBit = 0; 373bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisconstexpr int kKeyEnciphermentKeyUsageBit = 2; 383bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisconstexpr int kDataEnciphermentKeyUsageBit = 3; 393bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisconstexpr int kMaxKeyUsageBit = 8; 403bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 413bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <typename T> T && min(T && a, T && b) { 423bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return (a < b) ? std::forward<T>(a) : std::forward<T>(b); 433bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 443bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 453bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisstruct emptyCert {}; 463bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 473bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis__attribute__((__unused__)) 483bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline keymaster_blob_t certBlobifier(const emptyCert&, bool*){ return {}; } 493bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <size_t N> 503bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline keymaster_blob_t certBlobifier(const uint8_t (&cert)[N], bool* fail){ 513bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_blob_t result = { dup_array(cert), N }; 523bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!result.data) { 533bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *fail = true; 543bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return {}; 553bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 563bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return result; 573bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 583bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline keymaster_blob_t certBlobifier(const keymaster_blob_t& blob, bool* fail){ 593bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (blob.data == nullptr || blob.data_length == 0) return {}; 603bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_blob_t result = { dup_array(blob.data, blob.data_length), blob.data_length }; 613bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!result.data) { 623bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *fail = true; 633bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return {}; 643bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 653bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return result; 663bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 673bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline keymaster_blob_t certBlobifier(keymaster_blob_t&& blob, bool*){ 683bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (blob.data == nullptr || blob.data_length == 0) return {}; 693bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_blob_t result = blob; 703bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis blob = {}; 713bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return result; 723bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 733bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline keymaster_blob_t certBlobifier(X509* certificate, bool* fail){ 743bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis int len = i2d_X509(certificate, nullptr); 753bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (len < 0) { 763bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *fail = true; 773bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return {}; 783bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 793bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 803bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis uint8_t* data = new(std::nothrow) uint8_t[len]; 813bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!data) { 823bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *fail = true; 833bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return {}; 843bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 853bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis uint8_t* p = data; 863bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 873bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis i2d_X509(certificate, &p); 883bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 893bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return { data, (size_t)len }; 903bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 913bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 923bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline bool certCopier(keymaster_blob_t** out, const keymaster_cert_chain_t& chain, 933bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis bool* fail) { 943bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis for (size_t i = 0; i < chain.entry_count; ++i) { 953bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *(*out)++ = certBlobifier(chain.entries[i], fail); 963bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 973bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return *fail; 983bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 993bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1003bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis__attribute__((__unused__)) 1013bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline bool certCopier(keymaster_blob_t** out, keymaster_cert_chain_t&& chain, bool* fail) { 1023bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis for (size_t i = 0; i < chain.entry_count; ++i) { 1033bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *(*out)++ = certBlobifier(std::move(chain.entries[i]), fail); 1043bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 1053bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis delete[] chain.entries; 1063bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis chain.entries = nullptr; 1073bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis chain.entry_count = 0; 1083bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return *fail; 1093bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1103bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <typename CERT> 1113bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline bool certCopier(keymaster_blob_t** out, CERT&& cert, bool* fail) { 1123bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *(*out)++ = certBlobifier(std::forward<CERT>(cert), fail); 1133bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return *fail; 1143bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1153bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1163bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline bool certCopyHelper(keymaster_blob_t**, bool* fail) { 1173bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return *fail; 1183bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1193bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1203bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <typename CERT, typename... CERTS> 1213bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline bool certCopyHelper(keymaster_blob_t** out, bool* fail, CERT&& cert, CERTS&&... certs) { 1223bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis certCopier(out, std::forward<CERT>(cert), fail); 1233bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return certCopyHelper(out, fail, std::forward<CERTS>(certs)...); 1243bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1253bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1263bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1273bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1283bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <typename T> 1293bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline size_t noOfCert(T &&) { return 1; } 1303bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline size_t noOfCert(const keymaster_cert_chain_t& cert_chain) { return cert_chain.entry_count; } 1313bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1323bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline size_t certCount() { return 0; } 1333bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <typename CERT, typename... CERTS> 1343bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisinline size_t certCount(CERT&& cert, CERTS&&... certs) { 1353bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return noOfCert(std::forward<CERT>(cert)) + certCount(std::forward<CERTS>(certs)...); 1363bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1373bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1383bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis/* 1393bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * makeCertChain creates a new keymaster_cert_chain_t from all the certs that get thrown at it 1403bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * in the given order. A cert may be a X509*, uint8_t[], a keymaster_blob_t, an instance of 1413bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * emptyCert, or another keymater_cert_chain_t in which case the certs of the chain are included 1423bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * in the new chain. emptyCert is a placeholder which results in an empty slot at the given 1433bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * position in the newly created certificate chain. E.g., makeCertChain(emptyCert(), someCertChain) 1443bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * allocates enough slots to accommodate all certificates of someCertChain plus one empty slot and 1453bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * copies in someCertChain starting at index 1 so that the slot with index 0 can be used for a new 1463bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * leaf entry. 1473bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * 1483bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * makeCertChain respects move semantics. E.g., makeCertChain(emptyCert(), std::move(someCertChain)) 1493bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * will take possession of secondary resources for the certificate blobs so that someCertChain is 1503bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * empty after the call. Also, because no allocation happens this cannot fail. Note, however, that 1513bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * if another cert is passed to makeCertChain, that needs to be copied and thus requires 1523bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis * allocation, and this allocation fails, all resources - allocated or moved - will be reaped. 1533bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis */ 1543bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskistemplate <typename... CERTS> 1553bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis DanisevskisCertChainPtr makeCertChain(CERTS&&... certs) { 1563bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis CertChainPtr result(new (std::nothrow) keymaster_cert_chain_t); 1573bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!result.get()) return {}; 1583bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis result->entries = new (std::nothrow) keymaster_blob_t[certCount(std::forward<CERTS>(certs)...)]; 1593bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!result->entries) return {}; 1603bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis result->entry_count = certCount(std::forward<CERTS>(certs)...); 1613bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis bool allocation_failed = false; 1623bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_blob_t* entries = result->entries; 1633bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis certCopyHelper(&entries, &allocation_failed, std::forward<CERTS>(certs)...); 1643bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (allocation_failed) return {}; 1653bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return result; 1663bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1673bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1683bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1693bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskiskeymaster_error_t build_attestation_extension(const AuthorizationSet& attest_params, 1703bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AuthorizationSet& tee_enforced, 1713bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AuthorizationSet& sw_enforced, 1723bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AttestationRecordContext& context, 1733bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_EXTENSION_Ptr* extension) { 1743bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_OBJECT_Ptr oid( 1753bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis OBJ_txt2obj(kAttestionRecordOid, 1 /* accept numerical dotted string form only */)); 1763bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!oid.get()) 1773bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 1783bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1793bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis UniquePtr<uint8_t[]> attest_bytes; 1803bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis size_t attest_bytes_len; 1813bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_error_t error = build_attestation_record(attest_params, sw_enforced, tee_enforced, 1823bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis context, &attest_bytes, &attest_bytes_len); 1833bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (error != KM_ERROR_OK) 1843bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return error; 1853bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1863bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_OCTET_STRING_Ptr attest_str(ASN1_OCTET_STRING_new()); 1873bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!attest_str.get() || 1883bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !ASN1_OCTET_STRING_set(attest_str.get(), attest_bytes.get(), attest_bytes_len)) 1893bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 1903bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1913bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis extension->reset( 1923bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */, attest_str.get())); 1933bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!extension->get()) 1943bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 1953bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1963bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_OK; 1973bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 1983bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 1993bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskiskeymaster_error_t add_key_usage_extension(const AuthorizationSet& tee_enforced, 2003bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AuthorizationSet& sw_enforced, 2013bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509* certificate) { 2023bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // Build BIT_STRING with correct contents. 2033bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_BIT_STRING_Ptr key_usage(ASN1_BIT_STRING_new()); 2043bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2053bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis for (size_t i = 0; i <= kMaxKeyUsageBit; ++i) { 2063bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!ASN1_BIT_STRING_set_bit(key_usage.get(), i, 0)) { 2073bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2083bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2093bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2103bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2113bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_SIGN) || 2123bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_VERIFY) || 2133bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_SIGN) || 2143bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_VERIFY)) { 2153bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kDigitalSignatureKeyUsageBit, 1)) { 2163bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2173bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2183bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2193bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2203bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_ENCRYPT) || 2213bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_DECRYPT) || 2223bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_ENCRYPT) || 2233bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_DECRYPT)) { 2243bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kKeyEnciphermentKeyUsageBit, 1) || 2253bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !ASN1_BIT_STRING_set_bit(key_usage.get(), kDataEnciphermentKeyUsageBit, 1)) { 2263bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2273bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2283bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2293bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2303bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // Convert to octets 2313bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis int len = i2d_ASN1_BIT_STRING(key_usage.get(), nullptr); 2323bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (len < 0) { 2333bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2343bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2353bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis UniquePtr<uint8_t[]> asn1_key_usage(new(std::nothrow) uint8_t[len]); 2363bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!asn1_key_usage.get()) { 2373bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_MEMORY_ALLOCATION_FAILED; 2383bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2393bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis uint8_t* p = asn1_key_usage.get(); 2403bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis len = i2d_ASN1_BIT_STRING(key_usage.get(), &p); 2413bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (len < 0) { 2423bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2433bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2443bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2453bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // Build OCTET_STRING 2463bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_OCTET_STRING_Ptr key_usage_str(ASN1_OCTET_STRING_new()); 2473bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!key_usage_str.get() || 2483bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !ASN1_OCTET_STRING_set(key_usage_str.get(), asn1_key_usage.get(), len)) { 2493bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2503bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2513bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2523bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_EXTENSION_Ptr key_usage_extension(X509_EXTENSION_create_by_NID(nullptr, // 2533bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis NID_key_usage, // 2543bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis false /* critical */, 2553bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis key_usage_str.get())); 2563bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!key_usage_extension.get()) { 2573bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2583bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2593bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2603bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!X509_add_ext(certificate, key_usage_extension.get() /* Don't release; copied */, 2613bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis -1 /* insert at end */)) { 2623bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 2633bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2643bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2653bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_OK; 2663bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 2673bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2683bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisbool add_public_key(EVP_PKEY* key, X509* certificate, keymaster_error_t* error) { 2693bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!X509_set_pubkey(certificate, key)) { 2703bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *error = TranslateLastOpenSslError(); 2713bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return false; 2723bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2733bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return true; 2743bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 2753bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2763bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskisbool add_attestation_extension(const AuthorizationSet& attest_params, 2773bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AuthorizationSet& tee_enforced, 2783bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AuthorizationSet& sw_enforced, 2793bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AttestationRecordContext& context, 2803bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509* certificate, 2813bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_error_t* error) { 2823bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_EXTENSION_Ptr attest_extension; 2833bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *error = build_attestation_extension(attest_params, tee_enforced, sw_enforced, context, 2843bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis &attest_extension); 2853bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (*error != KM_ERROR_OK) 2863bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return false; 2873bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2883bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!X509_add_ext(certificate, attest_extension.get() /* Don't release; copied */, 2893bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis -1 /* insert at end */)) { 2903bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *error = TranslateLastOpenSslError(); 2913bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return false; 2923bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 2933bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2943bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return true; 2953bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 2963bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2973bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} // anonymous namespace 2983bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 2993bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskiskeymaster_error_t generate_attestation(const AsymmetricKey& key, 30059c6af81b6b510dd991ab04b8d65f1bab966d0c8Janis Danisevskis const AuthorizationSet& attest_params, const keymaster_cert_chain_t& attestation_chain, 3013bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const keymaster_key_blob_t& attestation_signing_key, 3023bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const AttestationRecordContext& context, CertChainPtr* cert_chain_out) { 3033bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3043bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!cert_chain_out) 3053bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_UNEXPECTED_NULL_POINTER; 3063bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3073bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis keymaster_algorithm_t sign_algorithm; 30859c6af81b6b510dd991ab04b8d65f1bab966d0c8Janis Danisevskis if ((!key.sw_enforced().GetTagValue(TAG_ALGORITHM, &sign_algorithm) && 30959c6af81b6b510dd991ab04b8d65f1bab966d0c8Janis Danisevskis !key.hw_enforced().GetTagValue(TAG_ALGORITHM, &sign_algorithm))) 3103bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_UNKNOWN_ERROR; 3113bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3123bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis EVP_PKEY_Ptr pkey(EVP_PKEY_new()); 3133bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!key.InternalToEvp(pkey.get())) 3143bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3153bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3163bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_Ptr certificate(X509_new()); 3173bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!certificate.get()) 3183bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3193bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3203bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!X509_set_version(certificate.get(), 2 /* version 3, but zero-based */)) 3213bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3223bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3233bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_INTEGER_Ptr serialNumber(ASN1_INTEGER_new()); 3243bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!serialNumber.get() || !ASN1_INTEGER_set(serialNumber.get(), 1) || 3253bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !X509_set_serialNumber(certificate.get(), serialNumber.get() /* Don't release; copied */)) 3263bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3273bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3283bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_NAME_Ptr subjectName(X509_NAME_new()); 3293bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!subjectName.get() || 3303bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !X509_NAME_add_entry_by_txt(subjectName.get(), "CN", MBSTRING_ASC, 3313bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis reinterpret_cast<const uint8_t*>("Android Keystore Key"), 3323bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis -1 /* len */, -1 /* loc */, 0 /* set */) || 3333bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !X509_set_subject_name(certificate.get(), subjectName.get() /* Don't release; copied */)) 3343bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3353bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3363bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_TIME_Ptr notBefore(ASN1_TIME_new()); 3373bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis uint64_t activeDateTime = 0; 3383bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis key.authorizations().GetTagValue(TAG_ACTIVE_DATETIME, &activeDateTime); 3393bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!notBefore.get() || !ASN1_TIME_set(notBefore.get(), activeDateTime / 1000) || 3403bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !X509_set_notBefore(certificate.get(), notBefore.get() /* Don't release; copied */)) 3413bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3423bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3433bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis ASN1_TIME_Ptr notAfter(ASN1_TIME_new()); 3443bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis uint64_t usageExpireDateTime = UINT64_MAX; 3453bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis key.authorizations().GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &usageExpireDateTime); 3463bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // TODO(swillden): When trusty can use the C++ standard library change the calculation of 3473bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // notAfterTime to use std::numeric_limits<time_t>::max(), rather than assuming that time_t is 3483bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // 32 bits. 3493bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis time_t notAfterTime = min(static_cast<uint64_t>(UINT32_MAX), usageExpireDateTime / 1000); 3503bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!notAfter.get() || !ASN1_TIME_set(notAfter.get(), notAfterTime) || 3513bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !X509_set_notAfter(certificate.get(), notAfter.get() /* Don't release; copied */)) 3523bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3533bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 35459c6af81b6b510dd991ab04b8d65f1bab966d0c8Janis Danisevskis keymaster_error_t error = add_key_usage_extension(key.hw_enforced(), key.sw_enforced(), certificate.get()); 3553bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (error != KM_ERROR_OK) { 3563bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return error; 3573bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 3583bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3593bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // We have established above that it is one of the two. So if it is not RSA its EC. 3603bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis int evp_key_type = (sign_algorithm == KM_ALGORITHM_RSA) ? EVP_PKEY_RSA : EVP_PKEY_EC; 3613bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3623bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const uint8_t* key_material = attestation_signing_key.key_material; 3633bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis EVP_PKEY_Ptr sign_key( 3643bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis d2i_PrivateKey(evp_key_type, nullptr, 3653bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const_cast<const uint8_t**>(&key_material), 3663bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis attestation_signing_key.key_material_size)); 3673bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!sign_key.get()) return TranslateLastOpenSslError(); 3683bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3693bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!add_public_key(pkey.get(), certificate.get(), &error) || 37059c6af81b6b510dd991ab04b8d65f1bab966d0c8Janis Danisevskis !add_attestation_extension(attest_params, key.hw_enforced(), key.sw_enforced(), 3713bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis context, certificate.get(), &error)) 3723bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return error; 3733bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3743bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (attestation_chain.entry_count < 1) { 3753bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // the attestation chain must have at least the cert for the key that signs the new cert. 3763bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_UNKNOWN_ERROR; 3773bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 3783bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3793bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const uint8_t* p = attestation_chain.entries[0].data; 3803bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_Ptr signing_cert(d2i_X509(nullptr, &p, attestation_chain.entries[0].data_length)); 3813bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!signing_cert.get()) { 3823bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3833bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 3843bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3853bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis // Set issuer to subject of batch certificate. 3863bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_NAME* issuerSubject = X509_get_subject_name(signing_cert.get()); 3873bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!issuerSubject) { 3883bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_UNKNOWN_ERROR; 3893bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 3903bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!X509_set_issuer_name(certificate.get(), issuerSubject)) { 3913bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 3923bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 3933bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 3943bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis UniquePtr<X509V3_CTX> x509v3_ctx(new(std::nothrow) X509V3_CTX); 3953bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!x509v3_ctx.get()) 3963bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_MEMORY_ALLOCATION_FAILED; 3973bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *x509v3_ctx = {}; 3983bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509V3_set_ctx(x509v3_ctx.get(), signing_cert.get(), certificate.get(), nullptr /* req */, 3993bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis nullptr /* crl */, 0 /* flags */); 4003bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 4013bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis X509_EXTENSION_Ptr auth_key_id(X509V3_EXT_nconf_nid(nullptr /* conf */, x509v3_ctx.get(), 4023bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis NID_authority_key_identifier, 4033bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis const_cast<char*>("keyid:always"))); 4043bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!auth_key_id.get() || 4053bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis !X509_add_ext(certificate.get(), auth_key_id.get() /* Don't release; copied */, 4063bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis -1 /* insert at end */)) { 4073bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 4083bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis } 4093bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 4103bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!X509_sign(certificate.get(), sign_key.get(), EVP_sha256())) 4113bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return TranslateLastOpenSslError(); 4123bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 4133bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis *cert_chain_out = makeCertChain(certificate.get(), attestation_chain); 4143bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis if (!cert_chain_out->get()) 4153bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_MEMORY_ALLOCATION_FAILED; 4163bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis return KM_ERROR_OK; 4173bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} 4183bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 4193bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis 4203bfda165bb8a2b91dfe039c92f96cd50aa3d8c2eJanis Danisevskis} // namespace keymaster 421