blob: f35f92b6a48f5dc12e0ae09b6e38c1af3dcf4782 [file] [log] [blame]
Martijn Coenen95194842020-09-24 16:56:46 +02001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <string>
18
19#include <android-base/file.h>
20#include <android-base/logging.h>
21
22#include <fcntl.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25
26#include "CertUtils.h"
27#include "Keymaster.h"
28#include "KeymasterSigningKey.h"
29
30using android::base::ErrnoError;
31using android::base::Error;
32using android::base::ReadFileToString;
33using android::base::Result;
34using android::base::unique_fd;
35
36KeymasterSigningKey::KeymasterSigningKey() {}
37
38Result<KeymasterSigningKey> KeymasterSigningKey::loadFromBlobAndVerify(const std::string& path) {
39 KeymasterSigningKey signingKey;
40
41 auto status = signingKey.initializeFromKeyblob(path);
42
43 if (!status.ok()) {
44 return status.error();
45 }
46
47 return std::move(signingKey);
48}
49
50Result<KeymasterSigningKey> KeymasterSigningKey::createNewKey() {
51 KeymasterSigningKey signingKey;
52
53 auto status = signingKey.createSigningKey();
54
55 if (!status.ok()) {
56 return status.error();
57 }
58
59 return std::move(signingKey);
60}
61
62Result<void> KeymasterSigningKey::createSigningKey() {
63 KeymasterSigningKey signingKey;
64 mKeymaster = Keymaster::getInstance();
65
66 auto keyBlob = mKeymaster->createKey();
67
68 if (!keyBlob.ok()) {
69 return keyBlob.error();
70 }
71
72 mVerifiedKeyBlob.assign(keyBlob->begin(), keyBlob->end());
73
74 return {};
75}
76
77Result<void> KeymasterSigningKey::saveKeyblob(const std::string& path) const {
78 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
79
80 unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags, 0600)));
81 if (fd == -1) {
82 return ErrnoError() << "Error creating key blob file " << path;
83 }
84
85 if (!android::base::WriteFully(fd, mVerifiedKeyBlob.data(), mVerifiedKeyBlob.size())) {
86 return ErrnoError() << "Error writing key blob file " << path;
87 } else {
88 return {};
89 }
90}
91
92Result<std::vector<uint8_t>> KeymasterSigningKey::getPublicKey() const {
93 auto publicKeyX509 = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
94 if (!publicKeyX509.ok()) {
95 return publicKeyX509.error();
96 }
97 return extractPublicKeyFromX509(publicKeyX509.value());
98}
99
100Result<void> KeymasterSigningKey::createX509Cert(const std::string& outPath) const {
101 auto publicKey = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
102
103 if (!publicKey.ok()) {
104 return publicKey.error();
105 }
106
107 auto keymasterSignFunction = [&](const std::string& to_be_signed) {
108 return this->sign(to_be_signed);
109 };
110 createSelfSignedCertificate(*publicKey, keymasterSignFunction, outPath);
111 return {};
112}
113
114Result<void> KeymasterSigningKey::initializeFromKeyblob(const std::string& path) {
115 mKeymaster = Keymaster::getInstance();
116 std::string keyBlobData;
117
118 bool result = ReadFileToString(path, &keyBlobData);
119 if (!result) {
120 return ErrnoError() << "Failed to read " << path;
121 }
122
123 std::vector<uint8_t> keyBlob = {keyBlobData.begin(), keyBlobData.end()};
124
125 auto verifyResult = mKeymaster->verifyKey(keyBlob);
126 if (!verifyResult.ok()) {
127 return Error() << "Failed to verify key: " << verifyResult.error().message();
128 }
129
130 if (*verifyResult == KeymasterVerifyResult::UPGRADE) {
131 auto upgradeResult = mKeymaster->upgradeKey(keyBlob);
132 if (!upgradeResult.ok()) {
133 return Error() << "Failed to upgrade key: " << upgradeResult.error().message();
134 }
135 mVerifiedKeyBlob = *upgradeResult;
136 // Make sure we persist the new blob
137 auto saveResult = saveKeyblob(path);
138 if (!saveResult.ok()) {
139 return Error() << "Failed to store upgraded key";
140 }
141 } else {
142 mVerifiedKeyBlob = keyBlob;
143 }
144
145 return {};
146}
147
148Result<std::string> KeymasterSigningKey::sign(const std::string& message) const {
149 return mKeymaster->sign(mVerifiedKeyBlob, message);
150}