blob: ed6a9a8aa8fa2f08147ba257f2650691b5d9a603 [file] [log] [blame]
Benoit Gobyd5fcafa2012-04-12 12:23:49 -07001/*
2 * Copyright (C) 2012 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
Yabin Cuiaed3c612015-09-22 15:52:57 -070017#define TRACE_TAG AUTH
Dan Albert33134262015-03-19 15:21:08 -070018
Josh Gao2e671202016-08-18 22:00:12 -070019#include <dirent.h>
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070020#include <stdio.h>
Christopher Ferris67a7a4a2014-11-06 14:34:24 -080021#include <stdlib.h>
Dan Albert33134262015-03-19 15:21:08 -070022#include <string.h>
Josh Gao2e671202016-08-18 22:00:12 -070023#if defined(__linux__)
24#include <sys/inotify.h>
25#endif
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070026
Josh Gao2e671202016-08-18 22:00:12 -070027#include <map>
Elliott Hughes0aeb5052016-06-29 17:42:01 -070028#include <mutex>
Josh Gao2e671202016-08-18 22:00:12 -070029#include <set>
30#include <string>
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070031
David Pursell5f787ed2016-01-27 08:52:53 -080032#include <android-base/errors.h>
Elliott Hughese8b663f2016-05-26 22:43:19 -070033#include <android-base/file.h>
Yurii Zubrytskyidace0152016-05-26 09:46:10 -070034#include <android-base/stringprintf.h>
Elliott Hughes4f713192015-12-04 22:00:26 -080035#include <android-base/strings.h>
Mattias Nissler097b6bb2016-03-31 16:32:09 +020036#include <crypto_utils/android_pubkey.h>
Elliott Hughes625faf02016-06-21 16:50:48 -070037#include <openssl/base64.h>
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070038#include <openssl/evp.h>
39#include <openssl/objects.h>
40#include <openssl/pem.h>
41#include <openssl/rsa.h>
42#include <openssl/sha.h>
43
Josh Gao2e671202016-08-18 22:00:12 -070044#include "adb.h"
45#include "adb_auth.h"
Josh Gao2dc4cab2018-11-15 17:45:46 -080046#include "adb_io.h"
Josh Gao2e671202016-08-18 22:00:12 -070047#include "adb_utils.h"
48#include "sysdeps.h"
Josh Gao3bd28792016-10-05 19:02:29 -070049#include "transport.h"
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070050
Josh Gao2e671202016-08-18 22:00:12 -070051static std::mutex& g_keys_mutex = *new std::mutex;
52static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
53 *new std::map<std::string, std::shared_ptr<RSA>>;
54static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070055
Josh Gao032989a2019-04-29 12:36:32 -070056static std::string get_user_info() {
57 std::string hostname;
58 if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
59#if !defined(_WIN32)
60 char buf[64];
61 if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
62#endif
63 if (hostname.empty()) hostname = "unknown";
64
65 std::string username;
66 if (getenv("LOGNAME")) username = getenv("LOGNAME");
67#if !defined(_WIN32)
68 if (username.empty() && getlogin()) username = getlogin();
69#endif
70 if (username.empty()) hostname = "unknown";
71
72 return " " + username + "@" + hostname;
73}
74
Josh Gao2dc4cab2018-11-15 17:45:46 -080075static bool calculate_public_key(std::string* out, RSA* private_key) {
Mattias Nissler097b6bb2016-03-31 16:32:09 +020076 uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
Elliott Hughes625faf02016-06-21 16:50:48 -070077 if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
78 LOG(ERROR) << "Failed to convert to public key";
79 return false;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070080 }
81
Elliott Hughes0b771b32017-05-01 13:45:30 -070082 size_t expected_length;
83 if (!EVP_EncodedLength(&expected_length, sizeof(binary_key_data))) {
Elliott Hughes625faf02016-06-21 16:50:48 -070084 LOG(ERROR) << "Public key too large to base64 encode";
85 return false;
Adam Langley179d9d62014-09-03 14:34:47 -070086 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070087
Josh Gao2dc4cab2018-11-15 17:45:46 -080088 out->resize(expected_length);
89 size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
Elliott Hughes0b771b32017-05-01 13:45:30 -070090 sizeof(binary_key_data));
Josh Gao2dc4cab2018-11-15 17:45:46 -080091 out->resize(actual_length);
Josh Gao032989a2019-04-29 12:36:32 -070092 out->append(get_user_info());
Elliott Hughes625faf02016-06-21 16:50:48 -070093 return true;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070094}
95
Elliott Hughes0aeb5052016-06-29 17:42:01 -070096static int generate_key(const std::string& file) {
97 LOG(INFO) << "generate_key(" << file << ")...";
98
Benoit Goby64b31032012-08-31 12:14:21 -070099 mode_t old_mask;
Yi Kongaed415c2018-07-13 18:15:16 -0700100 FILE *f = nullptr;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700101 int ret = 0;
Josh Gao032989a2019-04-29 12:36:32 -0700102 std::string pubkey;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700103
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700104 EVP_PKEY* pkey = EVP_PKEY_new();
105 BIGNUM* exponent = BN_new();
106 RSA* rsa = RSA_new();
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700107 if (!pkey || !exponent || !rsa) {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700108 LOG(ERROR) << "Failed to allocate key";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700109 goto out;
110 }
111
112 BN_set_word(exponent, RSA_F4);
Yi Kongaed415c2018-07-13 18:15:16 -0700113 RSA_generate_key_ex(rsa, 2048, exponent, nullptr);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700114 EVP_PKEY_set1_RSA(pkey, rsa);
115
Josh Gao032989a2019-04-29 12:36:32 -0700116 if (!calculate_public_key(&pubkey, rsa)) {
117 LOG(ERROR) << "failed to calculate public key";
118 goto out;
119 }
120
Benoit Goby64b31032012-08-31 12:14:21 -0700121 old_mask = umask(077);
122
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700123 f = fopen(file.c_str(), "w");
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700124 if (!f) {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700125 PLOG(ERROR) << "Failed to open " << file;
Benoit Goby64b31032012-08-31 12:14:21 -0700126 umask(old_mask);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700127 goto out;
128 }
129
Benoit Goby64b31032012-08-31 12:14:21 -0700130 umask(old_mask);
131
Yi Kongaed415c2018-07-13 18:15:16 -0700132 if (!PEM_write_PrivateKey(f, pkey, nullptr, nullptr, 0, nullptr, nullptr)) {
Josh Gao032989a2019-04-29 12:36:32 -0700133 LOG(ERROR) << "Failed to write key";
134 goto out;
135 }
136
137 if (!android::base::WriteStringToFile(pubkey, file + ".pub")) {
138 PLOG(ERROR) << "failed to write public key";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700139 goto out;
140 }
141
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700142 ret = 1;
143
144out:
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700145 if (f) fclose(f);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700146 EVP_PKEY_free(pkey);
147 RSA_free(rsa);
148 BN_free(exponent);
149 return ret;
150}
151
Josh Gao2e671202016-08-18 22:00:12 -0700152static std::string hash_key(RSA* key) {
153 unsigned char* pubkey = nullptr;
154 int len = i2d_RSA_PUBKEY(key, &pubkey);
155 if (len < 0) {
156 LOG(ERROR) << "failed to encode RSA public key";
157 return std::string();
158 }
159
160 std::string result;
161 result.resize(SHA256_DIGEST_LENGTH);
162 SHA256(pubkey, len, reinterpret_cast<unsigned char*>(&result[0]));
163 OPENSSL_free(pubkey);
164 return result;
165}
166
Josh Gao2dc4cab2018-11-15 17:45:46 -0800167static std::shared_ptr<RSA> read_key_file(const std::string& file) {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700168 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(file.c_str(), "r"), fclose);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700169 if (!fp) {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700170 PLOG(ERROR) << "Failed to open '" << file << "'";
Josh Gao2dc4cab2018-11-15 17:45:46 -0800171 return nullptr;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700172 }
173
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700174 RSA* key = RSA_new();
175 if (!PEM_read_RSAPrivateKey(fp.get(), &key, nullptr, nullptr)) {
176 LOG(ERROR) << "Failed to read key";
177 RSA_free(key);
Josh Gao2dc4cab2018-11-15 17:45:46 -0800178 return nullptr;
179 }
180
181 return std::shared_ptr<RSA>(key, RSA_free);
182}
183
184static bool load_key(const std::string& file) {
185 std::shared_ptr<RSA> key = read_key_file(file);
186 if (!key) {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700187 return false;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700188 }
189
Josh Gao2e671202016-08-18 22:00:12 -0700190 std::lock_guard<std::mutex> lock(g_keys_mutex);
Josh Gao2dc4cab2018-11-15 17:45:46 -0800191 std::string fingerprint = hash_key(key.get());
Josh Gao2e671202016-08-18 22:00:12 -0700192 if (g_keys.find(fingerprint) != g_keys.end()) {
193 LOG(INFO) << "ignoring already-loaded key: " << file;
Josh Gao2e671202016-08-18 22:00:12 -0700194 } else {
Josh Gao2dc4cab2018-11-15 17:45:46 -0800195 g_keys[fingerprint] = std::move(key);
Josh Gao2e671202016-08-18 22:00:12 -0700196 }
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700197 return true;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700198}
199
Josh Gao2dc4cab2018-11-15 17:45:46 -0800200static bool load_keys(const std::string& path, bool allow_dir = true) {
201 LOG(INFO) << "load_keys '" << path << "'...";
Josh Gao2e671202016-08-18 22:00:12 -0700202
203 struct stat st;
204 if (stat(path.c_str(), &st) != 0) {
205 PLOG(ERROR) << "failed to stat '" << path << "'";
206 return false;
207 }
208
209 if (S_ISREG(st.st_mode)) {
Josh Gao2dc4cab2018-11-15 17:45:46 -0800210 return load_key(path);
Josh Gao2e671202016-08-18 22:00:12 -0700211 } else if (S_ISDIR(st.st_mode)) {
212 if (!allow_dir) {
213 // inotify isn't recursive. It would break expectations to load keys in nested
214 // directories but not monitor them for new keys.
215 LOG(WARNING) << "refusing to recurse into directory '" << path << "'";
216 return false;
217 }
218
219 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
220 if (!dir) {
221 PLOG(ERROR) << "failed to open directory '" << path << "'";
222 return false;
223 }
224
225 bool result = false;
226 while (struct dirent* dent = readdir(dir.get())) {
227 std::string name = dent->d_name;
228
229 // We can't use dent->d_type here because it's not available on Windows.
230 if (name == "." || name == "..") {
231 continue;
232 }
233
Josh Gaoa27666b2016-12-14 16:59:29 -0800234 if (!android::base::EndsWith(name, ".adb_key")) {
235 LOG(INFO) << "skipping non-adb_key '" << path << "/" << name << "'";
236 continue;
237 }
238
Josh Gao2dc4cab2018-11-15 17:45:46 -0800239 result |= load_key((path + OS_PATH_SEPARATOR + name));
Josh Gao2e671202016-08-18 22:00:12 -0700240 }
241 return result;
242 }
243
244 LOG(ERROR) << "unexpected type for '" << path << "': 0x" << std::hex << st.st_mode;
245 return false;
246}
247
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700248static std::string get_user_key_path() {
Josh Gaoe0b75022016-08-30 15:23:35 -0700249 return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adbkey";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700250}
251
Josh Gao2dc4cab2018-11-15 17:45:46 -0800252static bool generate_userkey() {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700253 std::string path = get_user_key_path();
254 if (path.empty()) {
255 PLOG(ERROR) << "Error getting user key filename";
256 return false;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700257 }
258
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700259 struct stat buf;
260 if (stat(path.c_str(), &buf) == -1) {
261 LOG(INFO) << "User key '" << path << "' does not exist...";
Dan Albert286bb6d2015-07-09 20:35:09 +0000262 if (!generate_key(path)) {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700263 LOG(ERROR) << "Failed to generate new key";
264 return false;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700265 }
266 }
267
Josh Gao2dc4cab2018-11-15 17:45:46 -0800268 return load_key(path);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700269}
270
Josh Gao2e671202016-08-18 22:00:12 -0700271static std::set<std::string> get_vendor_keys() {
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700272 const char* adb_keys_path = getenv("ADB_VENDOR_KEYS");
273 if (adb_keys_path == nullptr) {
Josh Gao2e671202016-08-18 22:00:12 -0700274 return std::set<std::string>();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700275 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700276
Josh Gao2e671202016-08-18 22:00:12 -0700277 std::set<std::string> result;
Elliott Hughes65fe2512015-10-07 15:59:35 -0700278 for (const auto& path : android::base::Split(adb_keys_path, ENV_PATH_SEPARATOR_STR)) {
Josh Gao2e671202016-08-18 22:00:12 -0700279 result.emplace(path);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700280 }
Josh Gao2e671202016-08-18 22:00:12 -0700281 return result;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700282}
283
Josh Gao2e671202016-08-18 22:00:12 -0700284std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() {
285 std::deque<std::shared_ptr<RSA>> result;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700286
Josh Gao2e671202016-08-18 22:00:12 -0700287 // Copy all the currently known keys.
288 std::lock_guard<std::mutex> lock(g_keys_mutex);
289 for (const auto& it : g_keys) {
290 result.push_back(it.second);
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700291 }
292
293 // Add a sentinel to the list. Our caller uses this to mean "out of private keys,
294 // but try using the public key" (the empty deque could otherwise mean this _or_
295 // that this function hasn't been called yet to request the keys).
296 result.push_back(nullptr);
297
298 return result;
299}
300
Josh Gaof571fcb2018-02-05 18:49:10 -0800301static std::string adb_auth_sign(RSA* key, const char* token, size_t token_size) {
Sami Tolvanen7b9c20d2015-01-27 16:48:35 +0000302 if (token_size != TOKEN_SIZE) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700303 D("Unexpected token size %zd", token_size);
Yi Kongaed415c2018-07-13 18:15:16 -0700304 return nullptr;
Sami Tolvanen7b9c20d2015-01-27 16:48:35 +0000305 }
306
Josh Gaof571fcb2018-02-05 18:49:10 -0800307 std::string result;
308 result.resize(MAX_PAYLOAD);
309
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700310 unsigned int len;
Josh Gao06d61d42016-10-06 13:31:44 -0700311 if (!RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
Josh Gaof571fcb2018-02-05 18:49:10 -0800312 reinterpret_cast<uint8_t*>(&result[0]), &len, key)) {
313 return std::string();
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700314 }
315
Josh Gaof571fcb2018-02-05 18:49:10 -0800316 result.resize(len);
317
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700318 D("adb_auth_sign len=%d", len);
Josh Gaof571fcb2018-02-05 18:49:10 -0800319 return result;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700320}
321
Josh Gao2dc4cab2018-11-15 17:45:46 -0800322static bool pubkey_from_privkey(std::string* out, const std::string& path) {
323 std::shared_ptr<RSA> privkey = read_key_file(path);
324 if (!privkey) {
325 return false;
326 }
327 return calculate_public_key(out, privkey.get());
328}
329
Elliott Hughese8b663f2016-05-26 22:43:19 -0700330std::string adb_auth_get_userkey() {
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700331 std::string path = get_user_key_path();
332 if (path.empty()) {
333 PLOG(ERROR) << "Error getting user key filename";
Elliott Hughese8b663f2016-05-26 22:43:19 -0700334 return "";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700335 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700336
Josh Gao2dc4cab2018-11-15 17:45:46 -0800337 std::string result;
338 if (!pubkey_from_privkey(&result, path)) {
Elliott Hughese8b663f2016-05-26 22:43:19 -0700339 return "";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700340 }
Josh Gao2dc4cab2018-11-15 17:45:46 -0800341 return result;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700342}
343
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800344int adb_auth_keygen(const char* filename) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800345 return (generate_key(filename) == 0);
346}
347
Josh Gao2dc4cab2018-11-15 17:45:46 -0800348int adb_auth_pubkey(const char* filename) {
349 std::string pubkey;
350 if (!pubkey_from_privkey(&pubkey, filename)) {
351 return 1;
352 }
353 pubkey.push_back('\n');
354
355 return WriteFdExactly(STDOUT_FILENO, pubkey.data(), pubkey.size()) ? 0 : 1;
356}
357
Josh Gao2e671202016-08-18 22:00:12 -0700358#if defined(__linux__)
359static void adb_auth_inotify_update(int fd, unsigned fd_event, void*) {
360 LOG(INFO) << "adb_auth_inotify_update called";
361 if (!(fd_event & FDE_READ)) {
362 return;
363 }
364
365 char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
366 while (true) {
367 ssize_t rc = TEMP_FAILURE_RETRY(unix_read(fd, buf, sizeof(buf)));
368 if (rc == -1) {
369 if (errno == EAGAIN) {
370 LOG(INFO) << "done reading inotify fd";
371 break;
372 }
373 PLOG(FATAL) << "read of inotify event failed";
374 }
375
376 // The read potentially returned multiple events.
377 char* start = buf;
378 char* end = buf + rc;
379
380 while (start < end) {
381 inotify_event* event = reinterpret_cast<inotify_event*>(start);
382 auto root_it = g_monitored_paths.find(event->wd);
383 if (root_it == g_monitored_paths.end()) {
384 LOG(FATAL) << "observed inotify event for unmonitored path, wd = " << event->wd;
385 }
386
387 std::string path = root_it->second;
388 if (event->len > 0) {
389 path += '/';
390 path += event->name;
391 }
392
393 if (event->mask & (IN_CREATE | IN_MOVED_TO)) {
394 if (event->mask & IN_ISDIR) {
395 LOG(INFO) << "ignoring new directory at '" << path << "'";
396 } else {
397 LOG(INFO) << "observed new file at '" << path << "'";
Josh Gao2dc4cab2018-11-15 17:45:46 -0800398 load_keys(path, false);
Josh Gao2e671202016-08-18 22:00:12 -0700399 }
400 } else {
401 LOG(WARNING) << "unmonitored event for " << path << ": 0x" << std::hex
402 << event->mask;
403 }
404
405 start += sizeof(struct inotify_event) + event->len;
406 }
407 }
408}
409
410static void adb_auth_inotify_init(const std::set<std::string>& paths) {
411 LOG(INFO) << "adb_auth_inotify_init...";
Josh Gaofb9a7e52017-01-18 18:14:17 -0800412
Josh Gao2e671202016-08-18 22:00:12 -0700413 int infd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
Josh Gaofb9a7e52017-01-18 18:14:17 -0800414 if (infd < 0) {
415 PLOG(ERROR) << "failed to create inotify fd";
416 return;
417 }
418
Josh Gao2e671202016-08-18 22:00:12 -0700419 for (const std::string& path : paths) {
420 int wd = inotify_add_watch(infd, path.c_str(), IN_CREATE | IN_MOVED_TO);
421 if (wd < 0) {
422 PLOG(ERROR) << "failed to inotify_add_watch on path '" << path;
423 continue;
424 }
425
426 g_monitored_paths[wd] = path;
427 LOG(INFO) << "watch descriptor " << wd << " registered for " << path;
428 }
429
430 fdevent* event = fdevent_create(infd, adb_auth_inotify_update, nullptr);
431 fdevent_add(event, FDE_READ);
432}
433#endif
434
Elliott Hughes0aeb5052016-06-29 17:42:01 -0700435void adb_auth_init() {
436 LOG(INFO) << "adb_auth_init...";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700437
Josh Gao2dc4cab2018-11-15 17:45:46 -0800438 if (!generate_userkey()) {
439 LOG(ERROR) << "Failed to generate user key";
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700440 return;
441 }
442
Josh Gao2e671202016-08-18 22:00:12 -0700443 const auto& key_paths = get_vendor_keys();
444
445#if defined(__linux__)
446 adb_auth_inotify_init(key_paths);
447#endif
448
449 for (const std::string& path : key_paths) {
Greg Kaisere2125fd2019-03-26 11:58:53 -0700450 load_keys(path);
Josh Gao2e671202016-08-18 22:00:12 -0700451 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700452}
Josh Gao3bd28792016-10-05 19:02:29 -0700453
454static void send_auth_publickey(atransport* t) {
455 LOG(INFO) << "Calling send_auth_publickey";
456
457 std::string key = adb_auth_get_userkey();
458 if (key.empty()) {
459 D("Failed to get user public key");
460 return;
461 }
462
463 if (key.size() >= MAX_PAYLOAD_V1) {
464 D("User public key too large (%zu B)", key.size());
465 return;
466 }
467
468 apacket* p = get_apacket();
Josh Gao3bd28792016-10-05 19:02:29 -0700469 p->msg.command = A_AUTH;
470 p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
471
472 // adbd expects a null-terminated string.
Josh Gao1ce99572018-03-07 16:52:28 -0800473 p->payload.assign(key.data(), key.data() + key.size() + 1);
Josh Gaof571fcb2018-02-05 18:49:10 -0800474 p->msg.data_length = p->payload.size();
Josh Gao3bd28792016-10-05 19:02:29 -0700475 send_packet(p, t);
476}
477
Josh Gao06d61d42016-10-06 13:31:44 -0700478void send_auth_response(const char* token, size_t token_size, atransport* t) {
Josh Gao3bd28792016-10-05 19:02:29 -0700479 std::shared_ptr<RSA> key = t->NextKey();
480 if (key == nullptr) {
481 // No more private keys to try, send the public key.
Josh Gao704494b2018-05-04 16:04:49 -0700482 t->SetConnectionState(kCsUnauthorized);
Josh Gao362e6962018-08-08 16:20:14 -0700483 t->SetConnectionEstablished(true);
Josh Gao3bd28792016-10-05 19:02:29 -0700484 send_auth_publickey(t);
485 return;
486 }
487
488 LOG(INFO) << "Calling send_auth_response";
489 apacket* p = get_apacket();
490
Josh Gaof571fcb2018-02-05 18:49:10 -0800491 std::string result = adb_auth_sign(key.get(), token, token_size);
492 if (result.empty()) {
Josh Gao3bd28792016-10-05 19:02:29 -0700493 D("Error signing the token");
494 put_apacket(p);
495 return;
496 }
497
498 p->msg.command = A_AUTH;
499 p->msg.arg0 = ADB_AUTH_SIGNATURE;
Josh Gao1ce99572018-03-07 16:52:28 -0800500 p->payload.assign(result.begin(), result.end());
Josh Gaof571fcb2018-02-05 18:49:10 -0800501 p->msg.data_length = p->payload.size();
Josh Gao3bd28792016-10-05 19:02:29 -0700502 send_packet(p, t);
503}