On-device signing binary.

This is a first version of the on-device signing binary, that will be
used to sign ART compilation artifacts on an ART mainline module update.

The following basic functionality is implemented:
1) Creating a signing key (though not an early-boot key yet, because
those are broken on cuttlefish)
2) Creating an X.509 certificate from that key
3) Adding said certificate to the fs-verity keychain
4) Verify existing artifacts are in fs-verity (and delete them if
they're not)
5) Call odrefresh --check to have ART verify the artifacts are fresh and
correct
6) Call odrefresh --compile if they're not
7) Add generated output files to fs-verity

Important things left to do (not an exhaustive list):
1) Verify the key characteristics (eg, early-boot key)
2) Add a "manifest" file that records the signed files and their root
hashes; this will prevent us from accepting any random fs-verity file
3) Add a property or other signal to tell Zygote "we think these
artifacts are safe to use"
4) Migrate to keystore2 (once available)

Bug: 165630556
Test: Run odsign as root
Change-Id: I8aa09914d76f20f30c2093961271202fe7add711
diff --git a/ondevice-signing/KeymasterSigningKey.cpp b/ondevice-signing/KeymasterSigningKey.cpp
new file mode 100644
index 0000000..f35f92b
--- /dev/null
+++ b/ondevice-signing/KeymasterSigningKey.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "CertUtils.h"
+#include "Keymaster.h"
+#include "KeymasterSigningKey.h"
+
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::ReadFileToString;
+using android::base::Result;
+using android::base::unique_fd;
+
+KeymasterSigningKey::KeymasterSigningKey() {}
+
+Result<KeymasterSigningKey> KeymasterSigningKey::loadFromBlobAndVerify(const std::string& path) {
+    KeymasterSigningKey signingKey;
+
+    auto status = signingKey.initializeFromKeyblob(path);
+
+    if (!status.ok()) {
+        return status.error();
+    }
+
+    return std::move(signingKey);
+}
+
+Result<KeymasterSigningKey> KeymasterSigningKey::createNewKey() {
+    KeymasterSigningKey signingKey;
+
+    auto status = signingKey.createSigningKey();
+
+    if (!status.ok()) {
+        return status.error();
+    }
+
+    return std::move(signingKey);
+}
+
+Result<void> KeymasterSigningKey::createSigningKey() {
+    KeymasterSigningKey signingKey;
+    mKeymaster = Keymaster::getInstance();
+
+    auto keyBlob = mKeymaster->createKey();
+
+    if (!keyBlob.ok()) {
+        return keyBlob.error();
+    }
+
+    mVerifiedKeyBlob.assign(keyBlob->begin(), keyBlob->end());
+
+    return {};
+}
+
+Result<void> KeymasterSigningKey::saveKeyblob(const std::string& path) const {
+    int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
+
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags, 0600)));
+    if (fd == -1) {
+        return ErrnoError() << "Error creating key blob file " << path;
+    }
+
+    if (!android::base::WriteFully(fd, mVerifiedKeyBlob.data(), mVerifiedKeyBlob.size())) {
+        return ErrnoError() << "Error writing key blob file " << path;
+    } else {
+        return {};
+    }
+}
+
+Result<std::vector<uint8_t>> KeymasterSigningKey::getPublicKey() const {
+    auto publicKeyX509 = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
+    if (!publicKeyX509.ok()) {
+        return publicKeyX509.error();
+    }
+    return extractPublicKeyFromX509(publicKeyX509.value());
+}
+
+Result<void> KeymasterSigningKey::createX509Cert(const std::string& outPath) const {
+    auto publicKey = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
+
+    if (!publicKey.ok()) {
+        return publicKey.error();
+    }
+
+    auto keymasterSignFunction = [&](const std::string& to_be_signed) {
+        return this->sign(to_be_signed);
+    };
+    createSelfSignedCertificate(*publicKey, keymasterSignFunction, outPath);
+    return {};
+}
+
+Result<void> KeymasterSigningKey::initializeFromKeyblob(const std::string& path) {
+    mKeymaster = Keymaster::getInstance();
+    std::string keyBlobData;
+
+    bool result = ReadFileToString(path, &keyBlobData);
+    if (!result) {
+        return ErrnoError() << "Failed to read " << path;
+    }
+
+    std::vector<uint8_t> keyBlob = {keyBlobData.begin(), keyBlobData.end()};
+
+    auto verifyResult = mKeymaster->verifyKey(keyBlob);
+    if (!verifyResult.ok()) {
+        return Error() << "Failed to verify key: " << verifyResult.error().message();
+    }
+
+    if (*verifyResult == KeymasterVerifyResult::UPGRADE) {
+        auto upgradeResult = mKeymaster->upgradeKey(keyBlob);
+        if (!upgradeResult.ok()) {
+            return Error() << "Failed to upgrade key: " << upgradeResult.error().message();
+        }
+        mVerifiedKeyBlob = *upgradeResult;
+        // Make sure we persist the new blob
+        auto saveResult = saveKeyblob(path);
+        if (!saveResult.ok()) {
+            return Error() << "Failed to store upgraded key";
+        }
+    } else {
+        mVerifiedKeyBlob = keyBlob;
+    }
+
+    return {};
+}
+
+Result<std::string> KeymasterSigningKey::sign(const std::string& message) const {
+    return mKeymaster->sign(mVerifiedKeyBlob, message);
+}