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 <KeyMintAidlTestBase.h>
24 #include <aidl/Gtest.h>
25 #include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
26 #include <android-base/stringprintf.h>
27 #include <keymaster/km_openssl/openssl_utils.h>
28 #include <keymasterV4_1/attestation_record.h>
29 #include <keymint_support/openssl_utils.h>
30 #include <openssl/evp.h>
31 
32 #include <charconv>
33 #include <map>
34 
35 namespace android::hardware::identity::test_utils {
36 
37 using std::endl;
38 using std::map;
39 using std::optional;
40 using std::string;
41 using std::vector;
42 
43 using ::aidl::android::hardware::security::keymint::test::check_maced_pubkey;
44 using ::aidl::android::hardware::security::keymint::test::p256_pub_key;
45 using ::android::sp;
46 using ::android::String16;
47 using ::android::base::StringPrintf;
48 using ::android::binder::Status;
49 using ::android::hardware::security::keymint::MacedPublicKey;
50 using ::keymaster::X509_Ptr;
51 
setupWritableCredential(sp<IWritableIdentityCredential> & writableCredential,sp<IIdentityCredentialStore> & credentialStore,bool testCredential)52 bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
53                              sp<IIdentityCredentialStore>& credentialStore, bool testCredential) {
54     if (credentialStore == nullptr) {
55         return false;
56     }
57 
58     string docType = "org.iso.18013-5.2019.mdl";
59     Status result = credentialStore->createCredential(docType, testCredential, &writableCredential);
60 
61     if (result.isOk() && writableCredential != nullptr) {
62         return true;
63     } else {
64         return false;
65     }
66 }
67 
createFakeRemotelyProvisionedCertificateChain(const MacedPublicKey & macedPublicKey)68 optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
69         const MacedPublicKey& macedPublicKey) {
70     // The helper library uses the NDK symbols, so play a little trickery here to convert
71     // the data into the proper type so we can reuse the helper function to get the pubkey.
72     ::aidl::android::hardware::security::keymint::MacedPublicKey ndkMacedPublicKey;
73     ndkMacedPublicKey.macedKey = macedPublicKey.macedKey;
74 
75     vector<uint8_t> publicKeyBits;
76     check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/false, &publicKeyBits);
77 
78     ::aidl::android::hardware::security::keymint::EVP_PKEY_Ptr publicKey;
79     p256_pub_key(publicKeyBits, &publicKey);
80 
81     // Generate an arbitrary root key for our chain
82     bssl::UniquePtr<EC_KEY> ecRootKey(EC_KEY_new());
83     bssl::UniquePtr<EVP_PKEY> rootKey(EVP_PKEY_new());
84     if (ecRootKey.get() == nullptr || rootKey.get() == nullptr) {
85         LOG(ERROR) << "Memory allocation failed";
86         return {};
87     }
88 
89     bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
90     if (group.get() == nullptr) {
91         LOG(ERROR) << "Error creating EC group by curve name";
92         return {};
93     }
94 
95     if (EC_KEY_set_group(ecRootKey.get(), group.get()) != 1 ||
96         EC_KEY_generate_key(ecRootKey.get()) != 1 || EC_KEY_check_key(ecRootKey.get()) < 0) {
97         LOG(ERROR) << "Error generating key";
98         return {};
99     }
100 
101     if (EVP_PKEY_set1_EC_KEY(rootKey.get(), ecRootKey.get()) != 1) {
102         LOG(ERROR) << "Error getting private key";
103         return {};
104     }
105 
106     // The VTS test does not fully validate the chain, so we're ok without the proper CA extensions.
107     map<string, vector<uint8_t>> extensions;
108 
109     // Now make a self-signed cert
110     optional<vector<uint8_t>> root = support::ecPublicKeyGenerateCertificate(
111             rootKey.get(), rootKey.get(),
112             /*serialDecimal=*/"31415",
113             /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
114             /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
115             /*validityNotBefore=*/time(nullptr),
116             /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
117     if (!root) {
118         LOG(ERROR) << "Error generating root cert";
119         return std::nullopt;
120     }
121 
122     // Now sign a CA cert so that we have a chain that's good enough to satisfy
123     // the VTS tests.
124     optional<vector<uint8_t>> intermediate = support::ecPublicKeyGenerateCertificate(
125             publicKey.get(), rootKey.get(),
126             /*serialDecimal=*/"42",
127             /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
128             /*subject=*/"Android IdentityCredential VTS Test Attestation Certificate",
129             /*validityNotBefore=*/time(nullptr),
130             /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
131     if (!intermediate) {
132         LOG(ERROR) << "Error generating intermediate cert";
133         return std::nullopt;
134     }
135 
136     return vector<vector<uint8_t>>{std::move(*intermediate), std::move(*root)};
137 }
138 
generateReaderCertificate(string serialDecimal)139 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal) {
140     vector<uint8_t> privKey;
141     return generateReaderCertificate(serialDecimal, &privKey);
142 }
143 
generateReaderCertificate(string serialDecimal,vector<uint8_t> * outReaderPrivateKey)144 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
145                                                     vector<uint8_t>* outReaderPrivateKey) {
146     optional<vector<uint8_t>> readerKeyPKCS8 = support::createEcKeyPair();
147     if (!readerKeyPKCS8) {
148         return {};
149     }
150 
151     optional<vector<uint8_t>> readerPublicKey =
152             support::ecKeyPairGetPublicKey(readerKeyPKCS8.value());
153     optional<vector<uint8_t>> readerKey = support::ecKeyPairGetPrivateKey(readerKeyPKCS8.value());
154     if (!readerPublicKey || !readerKey) {
155         return {};
156     }
157 
158     if (outReaderPrivateKey == nullptr) {
159         return {};
160     }
161 
162     *outReaderPrivateKey = readerKey.value();
163 
164     string issuer = "Android Open Source Project";
165     string subject = "Android IdentityCredential VTS Test";
166     time_t validityNotBefore = time(nullptr);
167     time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
168 
169     return support::ecPublicKeyGenerateCertificate(readerPublicKey.value(), readerKey.value(),
170                                                    serialDecimal, issuer, subject,
171                                                    validityNotBefore, validityNotAfter, {});
172 }
173 
addAccessControlProfiles(sp<IWritableIdentityCredential> & writableCredential,const vector<TestProfile> & testProfiles)174 optional<vector<SecureAccessControlProfile>> addAccessControlProfiles(
175         sp<IWritableIdentityCredential>& writableCredential,
176         const vector<TestProfile>& testProfiles) {
177     Status result;
178 
179     vector<SecureAccessControlProfile> secureProfiles;
180 
181     for (const auto& testProfile : testProfiles) {
182         SecureAccessControlProfile profile;
183         Certificate cert;
184         cert.encodedCertificate = testProfile.readerCertificate;
185         int64_t secureUserId = testProfile.userAuthenticationRequired ? 66 : 0;
186         result = writableCredential->addAccessControlProfile(
187                 testProfile.id, cert, testProfile.userAuthenticationRequired,
188                 testProfile.timeoutMillis, secureUserId, &profile);
189 
190         // Don't use assert so all errors can be outputed.  Then return
191         // instead of exit even on errors so caller can decide.
192         EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
193                                    << "test profile id = " << testProfile.id << endl;
194         EXPECT_EQ(testProfile.id, profile.id);
195         EXPECT_EQ(testProfile.readerCertificate, profile.readerCertificate.encodedCertificate);
196         EXPECT_EQ(testProfile.userAuthenticationRequired, profile.userAuthenticationRequired);
197         EXPECT_EQ(testProfile.timeoutMillis, profile.timeoutMillis);
198         EXPECT_EQ(support::kAesGcmTagSize + support::kAesGcmIvSize, profile.mac.size());
199 
200         if (!result.isOk() || testProfile.id != profile.id ||
201             testProfile.readerCertificate != profile.readerCertificate.encodedCertificate ||
202             testProfile.userAuthenticationRequired != profile.userAuthenticationRequired ||
203             testProfile.timeoutMillis != profile.timeoutMillis ||
204             support::kAesGcmTagSize + support::kAesGcmIvSize != profile.mac.size()) {
205             return {};
206         }
207 
208         secureProfiles.push_back(profile);
209     }
210 
211     return secureProfiles;
212 }
213 
214 // Most test expects this function to pass. So we will print out additional
215 // 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)216 bool addEntry(sp<IWritableIdentityCredential>& writableCredential, const TestEntryData& entry,
217               int dataChunkSize, map<const TestEntryData*, vector<vector<uint8_t>>>& encryptedBlobs,
218               bool expectSuccess) {
219     Status result;
220     vector<vector<uint8_t>> chunks = support::chunkVector(entry.valueCbor, dataChunkSize);
221 
222     result = writableCredential->beginAddEntry(entry.profileIds, entry.nameSpace, entry.name,
223                                                entry.valueCbor.size());
224 
225     if (expectSuccess) {
226         EXPECT_TRUE(result.isOk())
227                 << result.exceptionCode() << "; " << result.exceptionMessage() << endl
228                 << "entry name = " << entry.name << ", name space=" << entry.nameSpace << endl;
229     }
230 
231     if (!result.isOk()) {
232         return false;
233     }
234 
235     vector<vector<uint8_t>> encryptedChunks;
236     for (const auto& chunk : chunks) {
237         vector<uint8_t> encryptedContent;
238         result = writableCredential->addEntryValue(chunk, &encryptedContent);
239         if (expectSuccess) {
240             EXPECT_TRUE(result.isOk())
241                     << result.exceptionCode() << "; " << result.exceptionMessage() << endl
242                     << "entry name = " << entry.name << ", name space = " << entry.nameSpace
243                     << endl;
244 
245             EXPECT_GT(encryptedContent.size(), 0u) << "entry name = " << entry.name
246                                                    << ", name space = " << entry.nameSpace << endl;
247         }
248 
249         if (!result.isOk() || encryptedContent.size() <= 0u) {
250             return false;
251         }
252 
253         encryptedChunks.push_back(encryptedContent);
254     }
255 
256     encryptedBlobs[&entry] = encryptedChunks;
257     return true;
258 }
259 
setImageData(vector<uint8_t> & image)260 void setImageData(vector<uint8_t>& image) {
261     image.resize(256 * 1024 - 10);
262     for (size_t n = 0; n < image.size(); n++) {
263         image[n] = (uint8_t)n;
264     }
265 }
266 
x509NameToRfc2253String(X509_NAME * name)267 string x509NameToRfc2253String(X509_NAME* name) {
268     char* buf;
269     size_t bufSize;
270     BIO* bio;
271 
272     bio = BIO_new(BIO_s_mem());
273     X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
274     bufSize = BIO_get_mem_data(bio, &buf);
275     string ret = string(buf, bufSize);
276     BIO_free(bio);
277 
278     return ret;
279 }
280 
parseDigits(const char ** s,int numDigits)281 int parseDigits(const char** s, int numDigits) {
282     int result;
283     auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
284     if (ec != std::errc()) {
285         LOG(ERROR) << "Error parsing " << numDigits << " digits "
286                    << " from " << s;
287         return 0;
288     }
289     *s += numDigits;
290     return result;
291 }
292 
parseAsn1Time(const ASN1_TIME * asn1Time,time_t * outTime)293 bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
294     struct tm tm;
295 
296     memset(&tm, '\0', sizeof(tm));
297     const char* timeStr = (const char*)asn1Time->data;
298     const char* s = timeStr;
299     if (asn1Time->type == V_ASN1_UTCTIME) {
300         tm.tm_year = parseDigits(&s, 2);
301         if (tm.tm_year < 70) {
302             tm.tm_year += 100;
303         }
304     } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
305         tm.tm_year = parseDigits(&s, 4) - 1900;
306         tm.tm_year -= 1900;
307     } else {
308         LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
309         return false;
310     }
311     tm.tm_mon = parseDigits(&s, 2) - 1;
312     tm.tm_mday = parseDigits(&s, 2);
313     tm.tm_hour = parseDigits(&s, 2);
314     tm.tm_min = parseDigits(&s, 2);
315     tm.tm_sec = parseDigits(&s, 2);
316     // This may need to be updated if someone create certificates using +/- instead of Z.
317     //
318     if (*s != 'Z') {
319         LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
320         return false;
321     }
322 
323     time_t t = timegm(&tm);
324     if (t == -1) {
325         LOG(ERROR) << "Error converting broken-down time to time_t";
326         return false;
327     }
328     *outTime = t;
329     return true;
330 }
331 
validateAttestationCertificate(const vector<Certificate> & credentialKeyCertChain,const vector<uint8_t> & expectedChallenge,const vector<uint8_t> & expectedAppId,bool isTestCredential)332 void validateAttestationCertificate(const vector<Certificate>& credentialKeyCertChain,
333                                     const vector<uint8_t>& expectedChallenge,
334                                     const vector<uint8_t>& expectedAppId, bool isTestCredential) {
335     ASSERT_GE(credentialKeyCertChain.size(), 2);
336 
337     vector<uint8_t> certBytes = credentialKeyCertChain[0].encodedCertificate;
338     const uint8_t* certData = certBytes.data();
339     X509_Ptr cert = X509_Ptr(d2i_X509(nullptr, &certData, certBytes.size()));
340 
341     vector<uint8_t> batchCertBytes = credentialKeyCertChain[1].encodedCertificate;
342     const uint8_t* batchCertData = batchCertBytes.data();
343     X509_Ptr batchCert = X509_Ptr(d2i_X509(nullptr, &batchCertData, batchCertBytes.size()));
344 
345     // First get some values from the batch certificate which is checked
346     // against the top-level certificate (subject, notAfter)
347     //
348 
349     X509_NAME* batchSubject = X509_get_subject_name(batchCert.get());
350     ASSERT_NE(nullptr, batchSubject);
351     time_t batchNotAfter;
352     ASSERT_TRUE(parseAsn1Time(X509_get0_notAfter(batchCert.get()), &batchNotAfter));
353 
354     // Check all the requirements from IWritableIdentityCredential::getAttestationCertificate()...
355     //
356 
357     //  - version: INTEGER 2 (means v3 certificate).
358     EXPECT_EQ(2, X509_get_version(cert.get()));
359 
360     //  - serialNumber: INTEGER 1 (fixed value: same on all certs).
361     EXPECT_EQ(1, ASN1_INTEGER_get(X509_get_serialNumber(cert.get())));
362 
363     //  - signature: must be set to ECDSA.
364     EXPECT_EQ(NID_ecdsa_with_SHA256, X509_get_signature_nid(cert.get()));
365 
366     //  - subject: CN shall be set to "Android Identity Credential Key". (fixed value:
367     //    same on all certs)
368     X509_NAME* subject = X509_get_subject_name(cert.get());
369     ASSERT_NE(nullptr, subject);
370     EXPECT_EQ("CN=Android Identity Credential Key", x509NameToRfc2253String(subject));
371 
372     //  - issuer: Same as the subject field of the batch attestation key.
373     X509_NAME* issuer = X509_get_issuer_name(cert.get());
374     ASSERT_NE(nullptr, issuer);
375     EXPECT_EQ(x509NameToRfc2253String(batchSubject), x509NameToRfc2253String(issuer));
376 
377     //  - validity: Should be from current time and expire at the same time as the
378     //    attestation batch certificate used.
379     //
380     //  Allow for 10 seconds drift to account for the time drift between Secure HW
381     //  and this environment plus the difference between when the certificate was
382     //  created and until now
383     //
384     time_t notBefore;
385     ASSERT_TRUE(parseAsn1Time(X509_get0_notBefore(cert.get()), &notBefore));
386     uint64_t now = time(nullptr);
387     int64_t diffSecs = now - notBefore;
388     int64_t allowDriftSecs = 10;
389     EXPECT_LE(-allowDriftSecs, diffSecs);
390     EXPECT_GE(allowDriftSecs, diffSecs);
391 
392     time_t notAfter;
393     ASSERT_TRUE(parseAsn1Time(X509_get0_notAfter(cert.get()), &notAfter));
394     EXPECT_EQ(notAfter, batchNotAfter);
395 
396     auto [err, attRec] = keymaster::V4_1::parse_attestation_record(certBytes);
397     ASSERT_EQ(keymaster::V4_1::ErrorCode::OK, err);
398 
399     //  - subjectPublicKeyInfo: must contain attested public key.
400 
401     //  - The attestationVersion field in the attestation extension must be at least 3.
402     EXPECT_GE(attRec.attestation_version, 3);
403 
404     //  - The attestationSecurityLevel field must be set to either Software (0),
405     //    TrustedEnvironment (1), or StrongBox (2) depending on how attestation is
406     //    implemented.
407     EXPECT_GE(attRec.attestation_security_level,
408               keymaster::V4_0::SecurityLevel::TRUSTED_ENVIRONMENT);
409 
410     //  - The keymasterVersion field in the attestation extension must be set to the.
411     //    same value as used for Android Keystore keys.
412     //
413     // Nothing to check here...
414 
415     //  - The keymasterSecurityLevel field in the attestation extension must be set to
416     //    either Software (0), TrustedEnvironment (1), or StrongBox (2) depending on how
417     //    the Trusted Application backing the HAL implementation is implemented.
418     EXPECT_GE(attRec.keymaster_security_level, keymaster::V4_0::SecurityLevel::TRUSTED_ENVIRONMENT);
419 
420     //  - The attestationChallenge field must be set to the passed-in challenge.
421     EXPECT_EQ(expectedChallenge.size(), attRec.attestation_challenge.size());
422     EXPECT_TRUE(memcmp(expectedChallenge.data(), attRec.attestation_challenge.data(),
423                        attRec.attestation_challenge.size()) == 0);
424 
425     //  - The uniqueId field must be empty.
426     EXPECT_EQ(attRec.unique_id.size(), 0);
427 
428     //  - The softwareEnforced field in the attestation extension must include
429     //    Tag::ATTESTATION_APPLICATION_ID which must be set to the bytes of the passed-in
430     //    attestationApplicationId.
431     EXPECT_TRUE(attRec.software_enforced.Contains(keymaster::V4_0::TAG_ATTESTATION_APPLICATION_ID,
432                                                   expectedAppId));
433 
434     //  - The teeEnforced field in the attestation extension must include
435     //
436     //    - Tag::IDENTITY_CREDENTIAL_KEY which indicates that the key is an Identity
437     //      Credential key (which can only sign/MAC very specific messages) and not an Android
438     //      Keystore key (which can be used to sign/MAC anything). This must not be set
439     //      for test credentials.
440     bool hasIcKeyTag =
441             attRec.hardware_enforced.Contains(static_cast<android::hardware::keymaster::V4_0::Tag>(
442                     keymaster::V4_1::Tag::IDENTITY_CREDENTIAL_KEY));
443     if (isTestCredential) {
444         EXPECT_FALSE(hasIcKeyTag);
445     } else {
446         EXPECT_TRUE(hasIcKeyTag);
447     }
448 
449     //    - Tag::PURPOSE must be set to SIGN
450     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_PURPOSE,
451                                                   keymaster::V4_0::KeyPurpose::SIGN));
452 
453     //    - Tag::KEY_SIZE must be set to the appropriate key size, in bits (e.g. 256)
454     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_KEY_SIZE, 256));
455 
456     //    - Tag::ALGORITHM must be set to EC
457     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_ALGORITHM,
458                                                   keymaster::V4_0::Algorithm::EC));
459 
460     //    - Tag::NO_AUTH_REQUIRED must be set
461     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_NO_AUTH_REQUIRED));
462 
463     //    - Tag::DIGEST must be include SHA_2_256
464     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_DIGEST,
465                                                   keymaster::V4_0::Digest::SHA_2_256));
466 
467     //    - Tag::EC_CURVE must be set to P_256
468     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_EC_CURVE,
469                                                   keymaster::V4_0::EcCurve::P_256));
470 
471     //    - Tag::ROOT_OF_TRUST must be set
472     //
473     EXPECT_GE(attRec.root_of_trust.security_level,
474               keymaster::V4_0::SecurityLevel::TRUSTED_ENVIRONMENT);
475 
476     //    - Tag::OS_VERSION and Tag::OS_PATCHLEVEL must be set
477     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_OS_VERSION));
478     EXPECT_TRUE(attRec.hardware_enforced.Contains(keymaster::V4_0::TAG_OS_PATCHLEVEL));
479 
480     // TODO: we could retrieve osVersion and osPatchLevel from Android itself and compare it
481     // with what was reported in the certificate.
482 }
483 
verifyAuthKeyCertificate(const vector<uint8_t> & authKeyCertChain)484 void verifyAuthKeyCertificate(const vector<uint8_t>& authKeyCertChain) {
485     const uint8_t* data = authKeyCertChain.data();
486     auto cert = X509_Ptr(d2i_X509(nullptr, &data, authKeyCertChain.size()));
487 
488     //  - version: INTEGER 2 (means v3 certificate).
489     EXPECT_EQ(X509_get_version(cert.get()), 2);
490 
491     //  - serialNumber: INTEGER 1 (fixed value: same on all certs).
492     EXPECT_EQ(ASN1_INTEGER_get(X509_get_serialNumber(cert.get())), 1);
493 
494     //  - signature: must be set to ECDSA.
495     EXPECT_EQ(X509_get_signature_nid(cert.get()), NID_ecdsa_with_SHA256);
496 
497     //  - subject: CN shall be set to "Android Identity Credential Authentication Key". (fixed
498     //    value: same on all certs)
499     X509_NAME* subject = X509_get_subject_name(cert.get());
500     ASSERT_NE(subject, nullptr);
501     EXPECT_EQ(x509NameToRfc2253String(subject),
502               "CN=Android Identity Credential Authentication Key");
503 
504     //  - issuer: CN shall be set to "Android Identity Credential Key". (fixed value:
505     //    same on all certs)
506     X509_NAME* issuer = X509_get_issuer_name(cert.get());
507     ASSERT_NE(issuer, nullptr);
508     EXPECT_EQ(x509NameToRfc2253String(issuer), "CN=Android Identity Credential Key");
509 
510     //  - subjectPublicKeyInfo: must contain attested public key.
511 
512     //  - validity: should be from current time and one year in the future (365 days).
513     time_t notBefore, notAfter;
514     ASSERT_TRUE(parseAsn1Time(X509_get0_notAfter(cert.get()), &notAfter));
515     ASSERT_TRUE(parseAsn1Time(X509_get0_notBefore(cert.get()), &notBefore));
516 
517     //  Allow for 10 seconds drift to account for the time drift between Secure HW
518     //  and this environment plus the difference between when the certificate was
519     //  created and until now
520     //
521     uint64_t now = time(nullptr);
522     int64_t diffSecs = now - notBefore;
523     int64_t allowDriftSecs = 10;
524     EXPECT_LE(-allowDriftSecs, diffSecs);
525     EXPECT_GE(allowDriftSecs, diffSecs);
526 
527     // The AIDL spec used to call for "one year in the future (365
528     // days)" but was updated to say "current time and 31536000
529     // seconds in the future (approximately 365 days)" to clarify that
530     // this was the original intention.
531     //
532     // However a number of implementations interpreted this as a
533     // "literal year" which started causing problems in March 2023
534     // because 2024 is a leap year. Since the extra day doesn't really
535     // matter (the validity period is specified in the MSO anyway and
536     // that's what RPs use), we allow both interpretations.
537     //
538     // For simplicity, we just require that that notAfter is after
539     // 31536000 and which also covers the case if there's a leap-day
540     // and possible leap-seconds.
541     //
542     constexpr uint64_t kSecsIn365Days = 365 * 24 * 60 * 60;
543     EXPECT_LE(notBefore + kSecsIn365Days, notAfter);
544 }
545 
buildRequestNamespaces(const vector<TestEntryData> entries)546 vector<RequestNamespace> buildRequestNamespaces(const vector<TestEntryData> entries) {
547     vector<RequestNamespace> ret;
548     RequestNamespace curNs;
549     for (const TestEntryData& testEntry : entries) {
550         if (testEntry.nameSpace != curNs.namespaceName) {
551             if (curNs.namespaceName.size() > 0) {
552                 ret.push_back(curNs);
553             }
554             curNs.namespaceName = testEntry.nameSpace;
555             curNs.items.clear();
556         }
557 
558         RequestDataItem item;
559         item.name = testEntry.name;
560         item.size = testEntry.valueCbor.size();
561         item.accessControlProfileIds = testEntry.profileIds;
562         curNs.items.push_back(item);
563     }
564     if (curNs.namespaceName.size() > 0) {
565         ret.push_back(curNs);
566     }
567     return ret;
568 }
569 
570 }  // namespace android::hardware::identity::test_utils
571