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
This commit is contained in:
parent
a0a2d5da84
commit
0aeee3d632
1 changed files with 54 additions and 18 deletions
|
@ -37,19 +37,36 @@ bool LoadKeyToKeyring(key_serial_t keyring_id, const char* desc, const char* dat
|
|||
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 @@ void LoadKeyFromVerifiedPartitions(key_serial_t keyring_id) {
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue