Keystore 2.0: Add support for the new CERTIFICATE_* tags.

Test: Keystore CTS tests
Change-Id: Ifbecd4517e8b6fb143283ed3f815aed4812a3c4a
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index 601baf1..93a8b70 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -30,6 +30,8 @@
 #include <keymasterV4_1/Keymaster3.h>
 #include <keymasterV4_1/Keymaster4.h>
 
+#include <chrono>
+
 #include "certificate_utils.h"
 
 using ::aidl::android::hardware::security::keymint::Algorithm;
@@ -50,6 +52,9 @@
 namespace V4_1 = ::android::hardware::keymaster::V4_1;
 namespace KMV1 = ::aidl::android::hardware::security::keymint;
 
+using namespace std::chrono_literals;
+using std::chrono::duration_cast;
+
 // Utility functions
 
 ScopedAStatus convertErrorCode(KMV1::ErrorCode result) {
@@ -579,21 +584,34 @@
     CBS cbs;
     CBS_init(&cbs, key.data(), key.size());
     auto pkey = EVP_parse_public_key(&cbs);
+
     // makeCert
-    // TODO: Get the serial and subject from key params once the tags are added.  Also use new tags
-    // for the two datetime parameters once we get those.
+    std::optional<std::reference_wrapper<const std::vector<uint8_t>>> subject;
+    if (auto blob = getParam(keyParams, KMV1::TAG_CERTIFICATE_SUBJECT)) {
+        subject = *blob;
+    }
+
+    std::optional<std::reference_wrapper<const std::vector<uint8_t>>> serial;
+    if (auto blob = getParam(keyParams, KMV1::TAG_CERTIFICATE_SERIAL)) {
+        serial = *blob;
+    }
 
     uint64_t activation = 0;
-    if (auto date = getParam(keyParams, KMV1::TAG_ACTIVE_DATETIME)) {
+    if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_BEFORE)) {
         activation = *date;
+    } else {
+        return KMV1::ErrorCode::MISSING_NOT_BEFORE;
     }
-    uint64_t expiration = std::numeric_limits<uint64_t>::max();
-    if (auto date = getParam(keyParams, KMV1::TAG_USAGE_EXPIRE_DATETIME)) {
+
+    uint64_t expiration;
+    if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_AFTER)) {
         expiration = *date;
+    } else {
+        return KMV1::ErrorCode::MISSING_NOT_AFTER;
     }
 
     auto certOrError = keystore::makeCert(
-        pkey, 42, "TODO", activation, expiration, false /* intentionally left blank */,
+        pkey, serial, subject, activation, expiration, false /* intentionally left blank */,
         std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */);
     if (std::holds_alternative<keystore::CertUtilsError>(certOrError)) {
         LOG(ERROR) << __func__ << ": Failed to make certificate";
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
index 5fdca91..b36b78a 100644
--- a/keystore2/src/km_compat/km_compat_type_conversion.h
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -734,7 +734,11 @@
         }
         break;
     case KMV1::Tag::RSA_OAEP_MGF_DIGEST:
-        // Does not exist in KM < KeyMint 1.0.
+    case KMV1::Tag::CERTIFICATE_SERIAL:
+    case KMV1::Tag::CERTIFICATE_SUBJECT:
+    case KMV1::Tag::CERTIFICATE_NOT_BEFORE:
+    case KMV1::Tag::CERTIFICATE_NOT_AFTER:
+        // These tags do not exist in KM < KeyMint 1.0.
         break;
     }
     return V4_0::KeyParameter{.tag = V4_0::Tag::INVALID};
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
index d264e7a..097e6d4 100644
--- a/keystore2/src/km_compat/lib.rs
+++ b/keystore2/src/km_compat/lib.rs
@@ -76,6 +76,10 @@
         creation_result
     }
 
+    // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
+    // 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
+    const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;
+
     fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
         let mut kps = vec![
             KeyParameter {
@@ -97,6 +101,14 @@
                 tag: Tag::PURPOSE,
                 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
             },
+            KeyParameter {
+                tag: Tag::CERTIFICATE_NOT_BEFORE,
+                value: KeyParameterValue::DateTime(0),
+            },
+            KeyParameter {
+                tag: Tag::CERTIFICATE_NOT_AFTER,
+                value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
+            },
         ];
         if encrypt {
             kps.push(KeyParameter {