1 /*
2  * Copyright 2019, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "VtsAttestationParserSupport.h"
18 
19 #include <aidl/Gtest.h>
20 #include <map>
21 
22 namespace android::hardware::identity::test_utils {
23 
24 using std::endl;
25 using std::map;
26 using std::optional;
27 using std::string;
28 using std::vector;
29 
30 using ::android::sp;
31 using ::android::String16;
32 using ::android::binder::Status;
33 
34 using ::keymaster::ASN1_OBJECT_Ptr;
35 using ::keymaster::AuthorizationSet;
36 using ::keymaster::EVP_PKEY_Ptr;
37 using ::keymaster::kAttestionRecordOid;
38 using ::keymaster::TAG_ATTESTATION_APPLICATION_ID;
39 using ::keymaster::TAG_IDENTITY_CREDENTIAL_KEY;
40 using ::keymaster::TAG_INCLUDE_UNIQUE_ID;
41 using ::keymaster::TypedTag;
42 using ::keymaster::X509_Ptr;
43 
44 using support::certificateChainSplit;
45 
certificateChainToKeymasterChain(const vector<Certificate> & certificates)46 optional<keymaster_cert_chain_t> AttestationCertificateParser::certificateChainToKeymasterChain(
47         const vector<Certificate>& certificates) {
48     if (certificates.size() <= 0) {
49         return {};
50     }
51 
52     keymaster_cert_chain_t kCert;
53     kCert.entry_count = certificates.size();
54     kCert.entries = (keymaster_blob_t*)malloc(sizeof(keymaster_blob_t) * kCert.entry_count);
55 
56     int index = 0;
57     for (const auto& c : certificates) {
58         kCert.entries[index].data_length = c.encodedCertificate.size();
59         uint8_t* data = (uint8_t*)malloc(c.encodedCertificate.size());
60 
61         memcpy(data, c.encodedCertificate.data(), c.encodedCertificate.size());
62         kCert.entries[index].data = (const uint8_t*)data;
63         index++;
64     }
65 
66     return kCert;
67 }
68 
parse()69 bool AttestationCertificateParser::parse() {
70     optional<keymaster_cert_chain_t> cert_chain = certificateChainToKeymasterChain(origCertChain_);
71     if (!cert_chain) {
72         return false;
73     }
74 
75     if (cert_chain.value().entry_count < 3) {
76         return false;
77     }
78 
79     if (!verifyChain(cert_chain.value())) {
80         return false;
81     }
82 
83     if (!verifyAttestationRecord(cert_chain.value().entries[0])) {
84         return false;
85     }
86 
87     keymaster_free_cert_chain(&cert_chain.value());
88     return true;
89 }
90 
getAttestationRecord(X509 * certificate)91 ASN1_OCTET_STRING* AttestationCertificateParser::getAttestationRecord(X509* certificate) {
92     ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1));
93     if (!oid.get()) return nullptr;
94 
95     int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1);
96     if (location == -1) return nullptr;
97 
98     X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
99     if (!attest_rec_ext) return nullptr;
100 
101     ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
102     return attest_rec;
103 }
104 
parseCertBlob(const keymaster_blob_t & blob)105 X509* AttestationCertificateParser::parseCertBlob(const keymaster_blob_t& blob) {
106     const uint8_t* p = blob.data;
107     return d2i_X509(nullptr, &p, blob.data_length);
108 }
109 
verifyAttestationRecord(const keymaster_blob_t & attestation_cert)110 bool AttestationCertificateParser::verifyAttestationRecord(
111         const keymaster_blob_t& attestation_cert) {
112     X509_Ptr cert(parseCertBlob(attestation_cert));
113     if (!cert.get()) {
114         return false;
115     }
116 
117     ASN1_OCTET_STRING* attest_rec = getAttestationRecord(cert.get());
118     if (!attest_rec) {
119         return false;
120     }
121 
122     keymaster_blob_t att_unique_id = {};
123     keymaster_blob_t att_challenge;
124     keymaster_error_t ret = parse_attestation_record(
125             attest_rec->data, attest_rec->length, &att_attestation_version_,
126             &att_attestation_security_level_, &att_keymaster_version_,
127             &att_keymaster_security_level_, &att_challenge, &att_sw_enforced_, &att_hw_enforced_,
128             &att_unique_id);
129     if (ret) {
130         return false;
131     }
132 
133     att_challenge_.assign(att_challenge.data, att_challenge.data + att_challenge.data_length);
134     return true;
135 }
136 
getKeymasterVersion()137 uint32_t AttestationCertificateParser::getKeymasterVersion() {
138     return att_keymaster_version_;
139 }
140 
getAttestationVersion()141 uint32_t AttestationCertificateParser::getAttestationVersion() {
142     return att_attestation_version_;
143 }
144 
getAttestationChallenge()145 vector<uint8_t> AttestationCertificateParser::getAttestationChallenge() {
146     return att_challenge_;
147 }
148 
getKeymasterSecurityLevel()149 keymaster_security_level_t AttestationCertificateParser::getKeymasterSecurityLevel() {
150     return att_keymaster_security_level_;
151 }
152 
getAttestationSecurityLevel()153 keymaster_security_level_t AttestationCertificateParser::getAttestationSecurityLevel() {
154     return att_attestation_security_level_;
155 }
156 
157 // Verify the Attestation certificates are correctly chained.
verifyChain(const keymaster_cert_chain_t & chain)158 bool AttestationCertificateParser::verifyChain(const keymaster_cert_chain_t& chain) {
159     for (size_t i = 0; i < chain.entry_count - 1; ++i) {
160         keymaster_blob_t& key_cert_blob = chain.entries[i];
161         keymaster_blob_t& signing_cert_blob = chain.entries[i + 1];
162 
163         X509_Ptr key_cert(parseCertBlob(key_cert_blob));
164         X509_Ptr signing_cert(parseCertBlob(signing_cert_blob));
165         if (!key_cert.get() || !signing_cert.get()) {
166             return false;
167         }
168 
169         EVP_PKEY_Ptr signing_pubkey(X509_get_pubkey(signing_cert.get()));
170         if (!signing_pubkey.get()) return false;
171 
172         if (X509_verify(key_cert.get(), signing_pubkey.get()) != 1) {
173             return false;
174         }
175 
176         if (i + 1 == chain.entry_count - 1) {
177             // Last entry is self-signed.
178             if (X509_verify(signing_cert.get(), signing_pubkey.get()) != 1) {
179                 return false;
180             }
181         }
182     }
183 
184     return true;
185 }
186 
187 }  // namespace android::hardware::identity::test_utils
188