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 #define LOG_TAG "Util"
18 
19 #include "Util.h"
20 
21 #include <android-base/logging.h>
22 
23 #include <aidl/Gtest.h>
24 #include <android-base/stringprintf.h>
25 #include <keymaster/km_openssl/openssl_utils.h>
26 #include <keymasterV4_1/attestation_record.h>
27 #include <charconv>
28 
29 #include <map>
30 
31 namespace android::hardware::identity::test_utils {
32 
33 using std::endl;
34 using std::map;
35 using std::optional;
36 using std::string;
37 using std::vector;
38 
39 using ::android::sp;
40 using ::android::String16;
41 using ::android::base::StringPrintf;
42 using ::android::binder::Status;
43 using ::keymaster::X509_Ptr;
44 
setupWritableCredential(sp<IWritableIdentityCredential> & writableCredential,sp<IIdentityCredentialStore> & credentialStore,bool testCredential)45 bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
46                              sp<IIdentityCredentialStore>& credentialStore, bool testCredential) {
47     if (credentialStore == nullptr) {
48         return false;
49     }
50 
51     string docType = "org.iso.18013-5.2019.mdl";
52     Status result = credentialStore->createCredential(docType, testCredential, &writableCredential);
53 
54     if (result.isOk() && writableCredential != nullptr) {
55         return true;
56     } else {
57         return false;
58     }
59 }
60 
generateReaderCertificate(string serialDecimal)61 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal) {
62     vector<uint8_t> privKey;
63     return generateReaderCertificate(serialDecimal, &privKey);
64 }
65 
generateReaderCertificate(string serialDecimal,vector<uint8_t> * outReaderPrivateKey)66 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
67                                                     vector<uint8_t>* outReaderPrivateKey) {
68     optional<vector<uint8_t>> readerKeyPKCS8 = support::createEcKeyPair();
69     if (!readerKeyPKCS8) {
70         return {};
71     }
72 
73     optional<vector<uint8_t>> readerPublicKey =
74             support::ecKeyPairGetPublicKey(readerKeyPKCS8.value());
75     optional<vector<uint8_t>> readerKey = support::ecKeyPairGetPrivateKey(readerKeyPKCS8.value());
76     if (!readerPublicKey || !readerKey) {
77         return {};
78     }
79 
80     if (outReaderPrivateKey == nullptr) {
81         return {};
82     }
83 
84     *outReaderPrivateKey = readerKey.value();
85 
86     string issuer = "Android Open Source Project";
87     string subject = "Android IdentityCredential VTS Test";
88     time_t validityNotBefore = time(nullptr);
89     time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
90 
91     return support::ecPublicKeyGenerateCertificate(readerPublicKey.value(), readerKey.value(),
92                                                    serialDecimal, issuer, subject,
93                                                    validityNotBefore, validityNotAfter, {});
94 }
95 
addAccessControlProfiles(sp<IWritableIdentityCredential> & writableCredential,const vector<TestProfile> & testProfiles)96 optional<vector<SecureAccessControlProfile>> addAccessControlProfiles(
97         sp<IWritableIdentityCredential>& writableCredential,
98         const vector<TestProfile>& testProfiles) {
99     Status result;
100 
101     vector<SecureAccessControlProfile> secureProfiles;
102 
103     for (const auto& testProfile : testProfiles) {
104         SecureAccessControlProfile profile;
105         Certificate cert;
106         cert.encodedCertificate = testProfile.readerCertificate;
107         int64_t secureUserId = testProfile.userAuthenticationRequired ? 66 : 0;
108         result = writableCredential->addAccessControlProfile(
109                 testProfile.id, cert, testProfile.userAuthenticationRequired,
110                 testProfile.timeoutMillis, secureUserId, &profile);
111 
112         // Don't use assert so all errors can be outputed.  Then return
113         // instead of exit even on errors so caller can decide.
114         EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
115                                    << "test profile id = " << testProfile.id << endl;
116         EXPECT_EQ(testProfile.id, profile.id);
117         EXPECT_EQ(testProfile.readerCertificate, profile.readerCertificate.encodedCertificate);
118         EXPECT_EQ(testProfile.userAuthenticationRequired, profile.userAuthenticationRequired);
119         EXPECT_EQ(testProfile.timeoutMillis, profile.timeoutMillis);
120         EXPECT_EQ(support::kAesGcmTagSize + support::kAesGcmIvSize, profile.mac.size());
121 
122         if (!result.isOk() || testProfile.id != profile.id ||
123             testProfile.readerCertificate != profile.readerCertificate.encodedCertificate ||
124             testProfile.userAuthenticationRequired != profile.userAuthenticationRequired ||
125             testProfile.timeoutMillis != profile.timeoutMillis ||
126             support::kAesGcmTagSize + support::kAesGcmIvSize != profile.mac.size()) {
127             return {};
128         }
129 
130         secureProfiles.push_back(profile);
131     }
132 
133     return secureProfiles;
134 }
135 
136 // Most test expects this function to pass. So we will print out additional
137 // value if failed so more debug data can be provided.
addEntry(sp<IWritableIdentityCredential> & writableCredential,const TestEntryData & entry,int dataChunkSize,map<const TestEntryData *,vector<vector<uint8_t>>> & encryptedBlobs,bool expectSuccess)138 bool addEntry(sp<IWritableIdentityCredential>& writableCredential, const TestEntryData& entry,
139               int dataChunkSize, map<const TestEntryData*, vector<vector<uint8_t>>>& encryptedBlobs,
140               bool expectSuccess) {
141     Status result;
142     vector<vector<uint8_t>> chunks = support::chunkVector(entry.valueCbor, dataChunkSize);
143 
144     result = writableCredential->beginAddEntry(entry.profileIds, entry.nameSpace, entry.name,
145                                                entry.valueCbor.size());
146 
147     if (expectSuccess) {
148         EXPECT_TRUE(result.isOk())
149                 << result.exceptionCode() << "; " << result.exceptionMessage() << endl
150                 << "entry name = " << entry.name << ", name space=" << entry.nameSpace << endl;
151     }
152 
153     if (!result.isOk()) {
154         return false;
155     }
156 
157     vector<vector<uint8_t>> encryptedChunks;
158     for (const auto& chunk : chunks) {
159         vector<uint8_t> encryptedContent;
160         result = writableCredential->addEntryValue(chunk, &encryptedContent);
161         if (expectSuccess) {
162             EXPECT_TRUE(result.isOk())
163                     << result.exceptionCode() << "; " << result.exceptionMessage() << endl
164                     << "entry name = " << entry.name << ", name space = " << entry.nameSpace
165                     << endl;
166 
167             EXPECT_GT(encryptedContent.size(), 0u) << "entry name = " << entry.name
168                                                    << ", name space = " << entry.nameSpace << endl;
169         }
170 
171         if (!result.isOk() || encryptedContent.size() <= 0u) {
172             return false;
173         }
174 
175         encryptedChunks.push_back(encryptedContent);
176     }
177 
178     encryptedBlobs[&entry] = encryptedChunks;
179     return true;
180 }
181 
setImageData(vector<uint8_t> & image)182 void setImageData(vector<uint8_t>& image) {
183     image.resize(256 * 1024 - 10);
184     for (size_t n = 0; n < image.size(); n++) {
185         image[n] = (uint8_t)n;
186     }
187 }
188 
x509NameToRfc2253String(X509_NAME * name)189 string x509NameToRfc2253String(X509_NAME* name) {
190     char* buf;
191     size_t bufSize;
192     BIO* bio;
193 
194     bio = BIO_new(BIO_s_mem());
195     X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
196     bufSize = BIO_get_mem_data(bio, &buf);
197     string ret = string(buf, bufSize);
198     BIO_free(bio);
199 
200     return ret;
201 }
202 
parseDigits(const char ** s,int numDigits)203 int parseDigits(const char** s, int numDigits) {
204     int result;
205     auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
206     if (ec != std::errc()) {
207         LOG(ERROR) << "Error parsing " << numDigits << " digits "
208                    << " from " << s;
209         return 0;
210     }
211     *s += numDigits;
212     return result;
213 }
214 
parseAsn1Time(const ASN1_TIME * asn1Time,time_t * outTime)215 bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
216     struct tm tm;
217 
218     memset(&tm, '\0', sizeof(tm));
219     const char* timeStr = (const char*)asn1Time->data;
220     const char* s = timeStr;
221     if (asn1Time->type == V_ASN1_UTCTIME) {
222         tm.tm_year = parseDigits(&s, 2);
223         if (tm.tm_year < 70) {
224             tm.tm_year += 100;
225         }
226     } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
227         tm.tm_year = parseDigits(&s, 4) - 1900;
228         tm.tm_year -= 1900;
229     } else {
230         LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
231         return false;
232     }
233     tm.tm_mon = parseDigits(&s, 2) - 1;
234     tm.tm_mday = parseDigits(&s, 2);
235     tm.tm_hour = parseDigits(&s, 2);
236     tm.tm_min = parseDigits(&s, 2);
237     tm.tm_sec = parseDigits(&s, 2);
238     // This may need to be updated if someone create certificates using +/- instead of Z.
239     //
240     if (*s != 'Z') {
241         LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
242         return false;
243     }
244 
245     time_t t = timegm(&tm);
246     if (t == -1) {
247         LOG(ERROR) << "Error converting broken-down time to time_t";
248         return false;
249     }
250     *outTime = t;
251     return true;
252 }
253 
validateAttestationCertificate(const vector<Certificate> & credentialKeyCertChain,const vector<uint8_t> & expectedChallenge,const vector<uint8_t> & expectedAppId,bool isTestCredential)254 void validateAttestationCertificate(const vector<Certificate>& credentialKeyCertChain,
255                                     const vector<uint8_t>& expectedChallenge,
256                                     const vector<uint8_t>& expectedAppId, bool isTestCredential) {
257     ASSERT_GE(credentialKeyCertChain.size(), 2);
258 
259     vector<uint8_t> certBytes = credentialKeyCertChain[0].encodedCertificate;
260     const uint8_t* certData = certBytes.data();
261     X509_Ptr cert = X509_Ptr(d2i_X509(nullptr, &certData, certBytes.size()));
262 
263     vector<uint8_t> batchCertBytes = credentialKeyCertChain[1].encodedCertificate;
264     const uint8_t* batchCertData = batchCertBytes.data();
265     X509_Ptr batchCert = X509_Ptr(d2i_X509(nullptr, &batchCertData, batchCertBytes.size()));
266 
267     // First get some values from the batch certificate which is checked
268     // against the top-level certificate (subject, notAfter)
269     //
270 
271     X509_NAME* batchSubject = X509_get_subject_name(batchCert.get());
272     ASSERT_NE(nullptr, batchSubject);
273     time_t batchNotAfter;
274     ASSERT_TRUE(parseAsn1Time(X509_get0_notAfter(batchCert.get()), &batchNotAfter));
275 
276     // Check all the requirements from IWritableIdentityCredential::getAttestationCertificate()...
277     //
278 
279     //  - version: INTEGER 2 (means v3 certificate).
280     EXPECT_EQ(2, X509_get_version(cert.get()));
281 
282     //  - serialNumber: INTEGER 1 (fixed value: same on all certs).
283     EXPECT_EQ(1, ASN1_INTEGER_get(X509_get_serialNumber(cert.get())));
284 
285     //  - signature: must be set to ECDSA.
286     EXPECT_EQ(NID_ecdsa_with_SHA256, X509_get_signature_nid(cert.get()));
287 
288     //  - subject: CN shall be set to "Android Identity Credential Key". (fixed value:
289     //    same on all certs)
290     X509_NAME* subject = X509_get_subject_name(cert.get());
291     ASSERT_NE(nullptr, subject);
292     EXPECT_EQ("CN=Android Identity Credential Key", x509NameToRfc2253String(subject));
293 
294     //  - issuer: Same as the subject field of the batch attestation key.
295     X509_NAME* issuer = X509_get_issuer_name(cert.get());
296     ASSERT_NE(nullptr, issuer);
297     EXPECT_EQ(x509NameToRfc2253String(batchSubject), x509NameToRfc2253String(issuer));
298 
299     //  - validity: Should be from current time and expire at the same time as the
300     //    attestation batch certificate used.
301     //
302     //  Allow for 10 seconds drift to account for the time drift between Secure HW
303     //  and this environment plus the difference between when the certificate was
304     //  created and until now
305     //
306     time_t notBefore;
307     ASSERT_TRUE(parseAsn1Time(X509_get0_notBefore(cert.get()), &notBefore));
308     uint64_t now = time(nullptr);
309     int64_t diffSecs = now - notBefore;
310     int64_t allowDriftSecs = 10;
311     EXPECT_LE(-allowDriftSecs, diffSecs);
312     EXPECT_GE(allowDriftSecs, diffSecs);
313 
314     time_t notAfter;
315     ASSERT_TRUE(parseAsn1Time(X509_get0_notAfter(cert.get()), &notAfter));
316     EXPECT_EQ(notAfter, batchNotAfter);
317 
318     auto [err, attRec] = keymaster::V4_1::parse_attestation_record(certBytes);
319     ASSERT_EQ(keymaster::V4_1::ErrorCode::OK, err);
320 
321     //  - subjectPublicKeyInfo: must contain attested public key.
322 
323     //  - The attestationVersion field in the attestation extension must be at least 3.
324     EXPECT_GE(attRec.attestation_version, 3);
325 
326     //  - The attestationSecurityLevel field must be set to either Software (0),
327     //    TrustedEnvironment (1), or StrongBox (2) depending on how attestation is
328     //    implemented.
329     EXPECT_GE(attRec.attestation_security_level,
330               keymaster::V4_0::SecurityLevel::TRUSTED_ENVIRONMENT);
331 
332     //  - The keymasterVersion field in the attestation extension must be set to the.
333     //    same value as used for Android Keystore keys.
334     //
335     // Nothing to check here...
336 
337     //  - The keymasterSecurityLevel field in the attestation extension must be set to
338     //    either Software (0), TrustedEnvironment (1), or StrongBox (2) depending on how
339     //    the Trusted Application backing the HAL implementation is implemented.
340     EXPECT_GE(attRec.keymaster_security_level, keymaster::V4_0::SecurityLevel::TRUSTED_ENVIRONMENT);
341 
342     //  - The attestationChallenge field must be set to the passed-in challenge.
343     EXPECT_EQ(expectedChallenge.size(), attRec.attestation_challenge.size());
344     EXPECT_TRUE(memcmp(expectedChallenge.data(), attRec.attestation_challenge.data(),
345                        attRec.attestation_challenge.size()) == 0);
346 
347     //  - The uniqueId field must be empty.
348     EXPECT_EQ(attRec.unique_id.size(), 0);
349 
350     //  - The softwareEnforced field in the attestation extension must include
351     //    Tag::ATTESTATION_APPLICATION_ID which must be set to the bytes of the passed-in
352     //    attestationApplicationId.
353     EXPECT_TRUE(attRec.software_enforced.Contains(keymaster::V4_0::TAG_ATTESTATION_APPLICATION_ID,
354                                                   expectedAppId));
355 
356     //  - The teeEnforced field in the attestation extension must include
357     //
358     //    - Tag::IDENTITY_CREDENTIAL_KEY which indicates that the key is an Identity
359     //      Credential key (which can only sign/MAC very specific messages) and not an Android
360     //      Keystore key (which can be used to sign/MAC anything). This must not be set
361     //      for test credentials.
362     bool hasIcKeyTag =
363             attRec.hardware_enforced.Contains(static_cast<android::hardware::keymaster::V4_0::Tag>(
364                     keymaster::V4_1::Tag::IDENTITY_CREDENTIAL_KEY));
365     if (isTestCredential) {
366         EXPECT_FALSE(hasIcKeyTag);
367     } else {
368         EXPECT_TRUE(hasIcKeyTag);
369     }
370 
371     //    - Tag::PURPOSE must be set to SIGN
372     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_PURPOSE,
373                                                   keymaster::V4_0::KeyPurpose::SIGN));
374 
375     //    - Tag::KEY_SIZE must be set to the appropriate key size, in bits (e.g. 256)
376     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_KEY_SIZE, 256));
377 
378     //    - Tag::ALGORITHM must be set to EC
379     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_ALGORITHM,
380                                                   keymaster::V4_0::Algorithm::EC));
381 
382     //    - Tag::NO_AUTH_REQUIRED must be set
383     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_NO_AUTH_REQUIRED));
384 
385     //    - Tag::DIGEST must be include SHA_2_256
386     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_DIGEST,
387                                                   keymaster::V4_0::Digest::SHA_2_256));
388 
389     //    - Tag::EC_CURVE must be set to P_256
390     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_EC_CURVE,
391                                                   keymaster::V4_0::EcCurve::P_256));
392 
393     //    - Tag::ROOT_OF_TRUST must be set
394     //
395     EXPECT_GE(attRec.root_of_trust.security_level,
396               keymaster::V4_0::SecurityLevel::TRUSTED_ENVIRONMENT);
397 
398     //    - Tag::OS_VERSION and Tag::OS_PATCHLEVEL must be set
399     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_OS_VERSION));
400     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_OS_PATCHLEVEL));
401 
402     // TODO: we could retrieve osVersion and osPatchLevel from Android itself and compare it
403     // with what was reported in the certificate.
404 }
405 
verifyAuthKeyCertificate(const vector<uint8_t> & authKeyCertChain)406 void verifyAuthKeyCertificate(const vector<uint8_t>& authKeyCertChain) {
407     const uint8_t* data = authKeyCertChain.data();
408     auto cert = X509_Ptr(d2i_X509(nullptr, &data, authKeyCertChain.size()));
409 
410     //  - version: INTEGER 2 (means v3 certificate).
411     EXPECT_EQ(X509_get_version(cert.get()), 2);
412 
413     //  - serialNumber: INTEGER 1 (fixed value: same on all certs).
414     EXPECT_EQ(ASN1_INTEGER_get(X509_get_serialNumber(cert.get())), 1);
415 
416     //  - signature: must be set to ECDSA.
417     EXPECT_EQ(X509_get_signature_nid(cert.get()), NID_ecdsa_with_SHA256);
418 
419     //  - subject: CN shall be set to "Android Identity Credential Authentication Key". (fixed
420     //    value: same on all certs)
421     X509_NAME* subject = X509_get_subject_name(cert.get());
422     ASSERT_NE(subject, nullptr);
423     EXPECT_EQ(x509NameToRfc2253String(subject),
424               "CN=Android Identity Credential Authentication Key");
425 
426     //  - issuer: CN shall be set to "Android Identity Credential Key". (fixed value:
427     //    same on all certs)
428     X509_NAME* issuer = X509_get_issuer_name(cert.get());
429     ASSERT_NE(issuer, nullptr);
430     EXPECT_EQ(x509NameToRfc2253String(issuer), "CN=Android Identity Credential Key");
431 
432     //  - subjectPublicKeyInfo: must contain attested public key.
433 
434     //  - validity: should be from current time and one year in the future (365 days).
435     time_t notBefore, notAfter;
436     ASSERT_TRUE(parseAsn1Time(X509_get0_notAfter(cert.get()), &notAfter));
437     ASSERT_TRUE(parseAsn1Time(X509_get0_notBefore(cert.get()), &notBefore));
438 
439     //  Allow for 10 seconds drift to account for the time drift between Secure HW
440     //  and this environment plus the difference between when the certificate was
441     //  created and until now
442     //
443     uint64_t now = time(nullptr);
444     int64_t diffSecs = now - notBefore;
445     int64_t allowDriftSecs = 10;
446     EXPECT_LE(-allowDriftSecs, diffSecs);
447     EXPECT_GE(allowDriftSecs, diffSecs);
448     constexpr uint64_t kSecsInOneYear = 365 * 24 * 60 * 60;
449     EXPECT_EQ(notBefore + kSecsInOneYear, notAfter);
450 }
451 
buildRequestNamespaces(const vector<TestEntryData> entries)452 vector<RequestNamespace> buildRequestNamespaces(const vector<TestEntryData> entries) {
453     vector<RequestNamespace> ret;
454     RequestNamespace curNs;
455     for (const TestEntryData& testEntry : entries) {
456         if (testEntry.nameSpace != curNs.namespaceName) {
457             if (curNs.namespaceName.size() > 0) {
458                 ret.push_back(curNs);
459             }
460             curNs.namespaceName = testEntry.nameSpace;
461             curNs.items.clear();
462         }
463 
464         RequestDataItem item;
465         item.name = testEntry.name;
466         item.size = testEntry.valueCbor.size();
467         item.accessControlProfileIds = testEntry.profileIds;
468         curNs.items.push_back(item);
469     }
470     if (curNs.namespaceName.size() > 0) {
471         ret.push_back(curNs);
472     }
473     return ret;
474 }
475 
476 }  // namespace android::hardware::identity::test_utils
477