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 {