Merge "Migrate to new open-dice API for Android" into main
diff --git a/keystore2/OWNERS b/keystore2/OWNERS
new file mode 100644
index 0000000..6b1a95b
--- /dev/null
+++ b/keystore2/OWNERS
@@ -0,0 +1,9 @@
+set noparent
+# Bug component: 1084732
+eranm@google.com
+drysdale@google.com
+hasinitg@google.com
+jbires@google.com
+sethmo@google.com
+trong@google.com
+swillden@google.com
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index e27cd1c..6bfd47a 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -144,6 +144,11 @@
 //
 const uint8_t kKeyBlobMagic[7] = {'p', 'K', 'M', 'b', 'l', 'o', 'b'};
 
+// Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set
+// to 9999-12-31T23:59:59Z.
+//
+const uint64_t kUndefinedNotAfter = 253402300799000;
+
 // Prefixes a keyblob returned by e.g. generateKey() with information on whether it
 // originated from the real underlying KeyMaster HAL or from soft-KeyMint.
 //
@@ -260,6 +265,16 @@
     return result;
 }
 
+std::vector<KMV1::KeyParameter>
+extractCombinedParams(const std::vector<KMV1::KeyCharacteristics>& characteristics) {
+    std::vector<KMV1::KeyParameter> result;
+    for (auto characteristic : characteristics) {
+        std::copy(characteristic.authorizations.begin(), characteristic.authorizations.end(),
+                  std::back_inserter(result));
+    }
+    return result;
+}
+
 ScopedAStatus convertErrorCode(KMV1::ErrorCode result) {
     if (result == KMV1::ErrorCode::OK) {
         return ScopedAStatus::ok();
@@ -587,6 +602,15 @@
         LOG(ERROR) << __func__ << " transaction failed. " << result.description();
         return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
     }
+    if (errorCode == KMV1::ErrorCode::OK) {
+        auto params = extractCombinedParams(out_creationResult->keyCharacteristics);
+        auto cert = getCertificate(params, out_creationResult->keyBlob, true /* isWrappedKey */);
+        // importWrappedKey used to not generate a certificate. Ignore the error to preserve
+        // backwards compatibility with clients that can't successfully generate a certificate.
+        if (std::holds_alternative<std::vector<Certificate>>(cert)) {
+            out_creationResult->certificateChain = std::get<std::vector<Certificate>>(cert);
+        }
+    }
     return convertErrorCode(errorCode);
 }
 
@@ -1055,7 +1079,7 @@
 
 static std::variant<keystore::X509_Ptr, KMV1::ErrorCode>
 makeCert(::android::sp<Keymaster> mDevice, const std::vector<KeyParameter>& keyParams,
-         const std::vector<uint8_t>& keyBlob) {
+         const std::vector<uint8_t>& keyBlob, bool isWrappedKey) {
     // Start generating the certificate.
     // Get public key for makeCert.
     KMV1::ErrorCode errorCode;
@@ -1097,15 +1121,21 @@
         serial = *blob;
     }
 
+    // There is no way to specify CERTIFICATE_NOT_BEFORE and CERTIFICATE_NOT_AFTER for wrapped keys.
+    // So we provide default values.
     int64_t activation;
-    if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_BEFORE)) {
+    if (isWrappedKey) {
+        activation = 0;
+    } else if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_BEFORE)) {
         activation = static_cast<int64_t>(*date);
     } else {
         return KMV1::ErrorCode::MISSING_NOT_BEFORE;
     }
 
     int64_t expiration;
-    if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_AFTER)) {
+    if (isWrappedKey) {
+        expiration = kUndefinedNotAfter;
+    } else if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_AFTER)) {
         expiration = static_cast<int64_t>(*date);
     } else {
         return KMV1::ErrorCode::MISSING_NOT_AFTER;
@@ -1235,7 +1265,7 @@
 
 std::variant<std::vector<Certificate>, KMV1::ErrorCode>
 KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
-                              const std::vector<uint8_t>& prefixedKeyBlob) {
+                              const std::vector<uint8_t>& prefixedKeyBlob, bool isWrappedKey) {
     const std::vector<uint8_t>& keyBlob = prefixedKeyBlobRemovePrefix(prefixedKeyBlob);
 
     // There are no certificates for symmetric keys.
@@ -1278,7 +1308,7 @@
     }
 
     // makeCert
-    auto certOrError = makeCert(mDevice, keyParams, keyBlob);
+    auto certOrError = makeCert(mDevice, keyParams, keyBlob, isWrappedKey);
     if (std::holds_alternative<KMV1::ErrorCode>(certOrError)) {
         return std::get<KMV1::ErrorCode>(certOrError);
     }
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 6654c4a..c4bcdaa 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -150,7 +150,8 @@
     // These are public to allow testing code to use them directly.
     // This class should not be used publicly anyway.
     std::variant<std::vector<Certificate>, KMV1_ErrorCode>
-    getCertificate(const std::vector<KeyParameter>& keyParams, const std::vector<uint8_t>& keyBlob);
+    getCertificate(const std::vector<KeyParameter>& keyParams, const std::vector<uint8_t>& keyBlob,
+                   bool isWrappedKey = false);
 
     void setNumFreeSlots(uint8_t numFreeSlots);