From e780dbf0d02341e0dd96ac2f06fdd8155077af36 Mon Sep 17 00:00:00 2001 From: Andrew Scull Date: Thu, 31 Aug 2023 19:28:36 +0000 Subject: [PATCH] Test the format of patch level device info On top of checking that the patch level are a UINT, also check that they follow the YYYYMM or YYYYMMDD format in the CSR v3 as is required by the server validation logic. This check is not applied in the factory as the value might not yet be correctly provisioned. Bug: 269813991 Test: atest VtsHalRemotelyProvisionedComponentTargetTest Change-Id: I5c62ba176dae390ea0a387bba6cb975226e3873a --- .../keymint/support/remote_prov_utils.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index c9c3e4d4ae..780c3d2041 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -420,6 +421,36 @@ std::string checkMapEntry(bool isFactory, const cppbor::Map& devInfo, cppbor::Ma return entryName + " has an invalid value.\n"; } +std::string checkMapPatchLevelEntry(bool isFactory, const cppbor::Map& devInfo, + const std::string& entryName) { + std::string error = checkMapEntry(isFactory, devInfo, cppbor::UINT, entryName); + if (!error.empty()) { + return error; + } + + if (isFactory) { + return ""; + } + + const std::unique_ptr& val = devInfo.get(entryName); + std::string dateString = std::to_string(val->asUint()->unsignedValue()); + if (dateString.size() == 6) { + dateString += "01"; + } + if (dateString.size() != 8) { + return entryName + " should in the format YYYYMMDD or YYYYMM\n"; + } + + std::tm t; + std::istringstream ss(dateString); + ss >> std::get_time(&t, "%Y%m%d"); + if (!ss) { + return entryName + " should in the format YYYYMMDD or YYYYMM\n"; + } + + return ""; +} + bool isTeeDeviceInfo(const cppbor::Map& devInfo) { return devInfo.get("security_level") && devInfo.get("security_level")->asTstr() && devInfo.get("security_level")->asTstr()->value() == "tee"; @@ -520,6 +551,10 @@ ErrMsgOr> parseAndValidateDeviceInfo( error += "Err: Unrecognized key entry: <" + key->asTstr()->value() + ">,\n"; } } + // Checks that only apply to v3. + error += checkMapPatchLevelEntry(isFactory, *parsed, "system_patch_level"); + error += checkMapPatchLevelEntry(isFactory, *parsed, "boot_patch_level"); + error += checkMapPatchLevelEntry(isFactory, *parsed, "vendor_patch_level"); FALLTHROUGH_INTENDED; case 2: for (const auto& entry : kAttestationIdEntrySet) {