Split fsverity_init in multiple phases.
Soon we'll have a need for multiple fs-verity keys in the keyring; we
need a central place to manage the keys, as well as restrict the
keyring. fsverity_init makes most sense for this.
Allow fsverity_init to be called in 3 different ways:
--load-verified-keys: loads preloaded keys from trusted partitions
--load-extra-key: loads an additional key passed in from stdin; the key
name is given as an argument.
--lock: locks the keyring, and prevents new keys from being loaded
Bug: 165630556
Test: boot, cat /proc/keys/
Change-Id: I758e49a5c4229edc531d01ac2e8873a22a1da73e
diff --git a/fsverity_init/fsverity_init.cpp b/fsverity_init/fsverity_init.cpp
index 4ed25cd..b81fb22 100644
--- a/fsverity_init/fsverity_init.cpp
+++ b/fsverity_init/fsverity_init.cpp
@@ -37,19 +37,36 @@
return true;
}
+void LoadKeyFromStdin(key_serial_t keyring_id, const char* keyname) {
+ std::string content;
+ if (!android::base::ReadFdToString(STDIN_FILENO, &content)) {
+ LOG(ERROR) << "Failed to read key from stdin";
+ return;
+ }
+ if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
+ LOG(ERROR) << "Failed to load key from stdin";
+ }
+}
+
+void LoadKeyFromFile(key_serial_t keyring_id, const char* keyname, const std::string& path) {
+ std::string content;
+ if (!android::base::ReadFileToString(path, &content)) {
+ LOG(ERROR) << "Failed to read key from " << path;
+ return;
+ }
+ if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
+ LOG(ERROR) << "Failed to load key from " << path;
+ }
+}
+
void LoadKeyFromDirectory(key_serial_t keyring_id, const char* keyname, const char* dir) {
if (!std::filesystem::exists(dir)) {
return;
}
for (const auto& entry : std::filesystem::directory_iterator(dir)) {
if (!android::base::EndsWithIgnoreCase(entry.path().c_str(), ".der")) continue;
- std::string content;
- if (!android::base::ReadFileToString(entry.path(), &content)) {
- continue;
- }
- if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
- LOG(ERROR) << "Failed to load key from " << entry.path();
- }
+
+ LoadKeyFromFile(keyring_id, keyname, entry.path());
}
}
@@ -60,25 +77,44 @@
LoadKeyFromDirectory(keyring_id, "fsv_product", "/product/etc/security/fsverity");
}
-int main(int /*argc*/, const char** /*argv*/) {
+int main(int argc, const char** argv) {
+ if (argc < 2) {
+ LOG(ERROR) << "Not enough arguments";
+ return -1;
+ }
+
key_serial_t keyring_id = android::GetKeyringId(".fs-verity");
if (keyring_id < 0) {
LOG(ERROR) << "Failed to find .fs-verity keyring id";
return -1;
}
- // Requires files backed by fs-verity to be verified with a key in .fs-verity
- // keyring.
- if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
- PLOG(ERROR) << "Failed to enforce fs-verity signature";
- }
+ const std::string_view command = argv[1];
- LoadKeyFromVerifiedPartitions(keyring_id);
-
- if (!android::base::GetBoolProperty("ro.debuggable", false)) {
- if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
- PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
+ if (command == "--load-verified-keys") {
+ LoadKeyFromVerifiedPartitions(keyring_id);
+ } else if (command == "--load-extra-key") {
+ if (argc != 3) {
+ LOG(ERROR) << "--load-extra-key requires <key_name> argument.";
+ return -1;
}
+ LoadKeyFromStdin(keyring_id, argv[2]);
+ } else if (command == "--lock") {
+ // Requires files backed by fs-verity to be verified with a key in .fs-verity
+ // keyring.
+ if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
+ PLOG(ERROR) << "Failed to enforce fs-verity signature";
+ }
+
+ if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+ if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
+ PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
+ }
+ }
+ } else {
+ LOG(ERROR) << "Unknown argument(s).";
+ return -1;
}
+
return 0;
}