blob: dc3ef8a11fc45b89ae3db41d982fbd5153b56482 [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
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010036const std::string kSigningKeyBlob = "/data/misc/odsign/key.blob";
37
Martijn Coenen95194842020-09-24 16:56:46 +020038KeymasterSigningKey::KeymasterSigningKey() {}
39
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010040Result<std::unique_ptr<KeymasterSigningKey>>
41KeymasterSigningKey::loadFromBlobAndVerify(const std::string& path) {
42 auto signingKey = std::make_unique<KeymasterSigningKey>();
Martijn Coenen95194842020-09-24 16:56:46 +020043
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010044 auto status = signingKey->initializeFromKeyblob(path);
Martijn Coenen95194842020-09-24 16:56:46 +020045
46 if (!status.ok()) {
47 return status.error();
48 }
49
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010050 return signingKey;
Martijn Coenen95194842020-09-24 16:56:46 +020051}
52
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010053Result<void> KeymasterSigningKey::saveKeyblob(const std::string& path) const {
54 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
Martijn Coenen95194842020-09-24 16:56:46 +020055
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010056 unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags, 0600)));
57 if (fd == -1) {
58 return ErrnoError() << "Error creating key blob file " << path;
Martijn Coenen95194842020-09-24 16:56:46 +020059 }
60
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010061 if (!android::base::WriteFully(fd, mVerifiedKeyBlob.data(), mVerifiedKeyBlob.size())) {
62 return ErrnoError() << "Error writing key blob file " << path;
63 } else {
64 return {};
65 }
Martijn Coenen95194842020-09-24 16:56:46 +020066}
67
68Result<void> KeymasterSigningKey::createSigningKey() {
69 KeymasterSigningKey signingKey;
Martijn Coenen3883ec62021-02-25 09:14:01 +010070 auto keymaster = Keymaster::getInstance();
71 if (!keymaster.has_value()) {
72 return Error() << "Failed to initialize keymaster.";
73 }
74 mKeymaster = keymaster;
Martijn Coenen95194842020-09-24 16:56:46 +020075
76 auto keyBlob = mKeymaster->createKey();
77
78 if (!keyBlob.ok()) {
79 return keyBlob.error();
80 }
81
82 mVerifiedKeyBlob.assign(keyBlob->begin(), keyBlob->end());
83
84 return {};
85}
86
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010087Result<std::unique_ptr<KeymasterSigningKey>> KeymasterSigningKey::createAndPersistNewKey() {
88 auto signingKey = std::make_unique<KeymasterSigningKey>();
Martijn Coenen95194842020-09-24 16:56:46 +020089
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010090 auto status = signingKey->createSigningKey();
91
92 if (!status.ok()) {
93 return status.error();
Martijn Coenen95194842020-09-24 16:56:46 +020094 }
95
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010096 status = signingKey->saveKeyblob(kSigningKeyBlob);
97 if (!status.ok()) {
98 return status.error();
Martijn Coenen95194842020-09-24 16:56:46 +020099 }
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100100
101 return signingKey;
102}
103
104Result<SigningKey*> KeymasterSigningKey::getInstance() {
105 auto key = loadFromBlobAndVerify(kSigningKeyBlob);
106
107 if (!key.ok()) {
108 key = createAndPersistNewKey();
109 if (!key.ok()) {
110 return key.error();
111 }
112 }
113
114 return key->release();
Martijn Coenen95194842020-09-24 16:56:46 +0200115}
116
117Result<std::vector<uint8_t>> KeymasterSigningKey::getPublicKey() const {
Martijn Coenen95194842020-09-24 16:56:46 +0200118 auto publicKey = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
Martijn Coenen95194842020-09-24 16:56:46 +0200119 if (!publicKey.ok()) {
120 return publicKey.error();
121 }
122
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100123 // Keymaster returns the public key not in a full X509 cert, but just the
124 // "SubjectPublicKeyInfo"
125 return extractPublicKeyFromSubjectPublicKeyInfo(publicKey.value());
Martijn Coenen95194842020-09-24 16:56:46 +0200126}
127
128Result<void> KeymasterSigningKey::initializeFromKeyblob(const std::string& path) {
Martijn Coenen95194842020-09-24 16:56:46 +0200129 std::string keyBlobData;
Martijn Coenen3883ec62021-02-25 09:14:01 +0100130 auto keymaster = Keymaster::getInstance();
131 if (!keymaster.has_value()) {
132 return Error() << "Failed to initialize keymaster.";
133 }
134 mKeymaster = keymaster;
Martijn Coenen95194842020-09-24 16:56:46 +0200135
136 bool result = ReadFileToString(path, &keyBlobData);
137 if (!result) {
138 return ErrnoError() << "Failed to read " << path;
139 }
140
141 std::vector<uint8_t> keyBlob = {keyBlobData.begin(), keyBlobData.end()};
142
143 auto verifyResult = mKeymaster->verifyKey(keyBlob);
144 if (!verifyResult.ok()) {
145 return Error() << "Failed to verify key: " << verifyResult.error().message();
146 }
147
148 if (*verifyResult == KeymasterVerifyResult::UPGRADE) {
149 auto upgradeResult = mKeymaster->upgradeKey(keyBlob);
150 if (!upgradeResult.ok()) {
151 return Error() << "Failed to upgrade key: " << upgradeResult.error().message();
152 }
153 mVerifiedKeyBlob = *upgradeResult;
154 // Make sure we persist the new blob
155 auto saveResult = saveKeyblob(path);
156 if (!saveResult.ok()) {
157 return Error() << "Failed to store upgraded key";
158 }
159 } else {
160 mVerifiedKeyBlob = keyBlob;
161 }
162
163 return {};
164}
165
166Result<std::string> KeymasterSigningKey::sign(const std::string& message) const {
167 return mKeymaster->sign(mVerifiedKeyBlob, message);
168}