2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define TRACE_TAG TRACE_AUTH
26 #include "cutils/list.h"
27 #include "cutils/sockets.h"
28 #include "mincrypt/rsa.h"
29 #include "mincrypt/sha.h"
33 #include "transport.h"
35 struct adb_public_key {
40 static const char *key_paths[] = {
42 "/data/misc/adb/adb_keys",
46 static fdevent listener_fde;
47 static int framework_fd = -1;
49 static void usb_disconnected(void* unused, atransport* t);
50 static struct adisconnect usb_disconnect = { usb_disconnected, 0, 0, 0 };
51 static atransport* usb_transport;
52 static bool needs_retry = false;
54 static void read_keys(const char *file, struct listnode *list)
57 char buf[MAX_PAYLOAD];
61 f = fopen(file, "re");
63 D("Can't open '%s'\n", file);
67 while (fgets(buf, sizeof(buf), f)) {
68 /* Allocate 4 extra bytes to decode the base64 data in-place */
69 auto key = reinterpret_cast<adb_public_key*>(
70 calloc(1, sizeof(adb_public_key) + 4));
72 D("Can't malloc key\n");
76 sep = strpbrk(buf, " \t");
80 ret = __b64_pton(buf, (u_char *)&key->key, sizeof(key->key) + 4);
81 if (ret != sizeof(key->key)) {
82 D("%s: Invalid base64 data ret=%d\n", file, ret);
87 if (key->key.len != RSANUMWORDS) {
88 D("%s: Invalid key len %d\n", file, key->key.len);
93 list_add_tail(list, &key->node);
99 static void free_keys(struct listnode *list)
101 struct listnode *item;
103 while (!list_empty(list)) {
104 item = list_head(list);
106 free(node_to_item(item, struct adb_public_key, node));
110 static void load_keys(struct listnode *list)
113 const char** paths = key_paths;
118 while ((path = *paths++)) {
119 if (!stat(path, &buf)) {
120 D("Loading keys from '%s'\n", path);
121 read_keys(path, list);
126 int adb_auth_generate_token(void *token, size_t token_size)
131 f = fopen("/dev/urandom", "re");
135 ret = fread(token, token_size, 1, f);
138 return ret * token_size;
141 int adb_auth_verify(uint8_t* token, uint8_t* sig, int siglen)
143 struct listnode *item;
144 struct listnode key_list;
147 if (siglen != RSANUMBYTES)
150 load_keys(&key_list);
152 list_for_each(item, &key_list) {
153 adb_public_key* key = node_to_item(item, struct adb_public_key, node);
154 ret = RSA_verify(&key->key, sig, siglen, token, SHA_DIGEST_SIZE);
159 free_keys(&key_list);
164 static void usb_disconnected(void* unused, atransport* t)
166 D("USB disconnect\n");
167 remove_transport_disconnect(usb_transport, &usb_disconnect);
168 usb_transport = NULL;
172 static void adb_auth_event(int fd, unsigned events, void *data)
177 if (events & FDE_READ) {
178 ret = unix_read(fd, response, sizeof(response));
180 D("Framework disconnect\n");
182 fdevent_remove(&usb_transport->auth_fde);
185 else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
187 adb_auth_verified(usb_transport);
192 void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t)
194 char msg[MAX_PAYLOAD];
197 if (!usb_transport) {
199 add_transport_disconnect(t, &usb_disconnect);
202 if (framework_fd < 0) {
203 D("Client not connected\n");
208 if (key[len - 1] != '\0') {
209 D("Key must be a null-terminated string\n");
213 ret = snprintf(msg, sizeof(msg), "PK%s", key);
214 if (ret >= (signed)sizeof(msg)) {
215 D("Key too long. ret=%d", ret);
218 D("Sending '%s'\n", msg);
220 ret = unix_write(framework_fd, msg, ret);
222 D("Failed to write PK, errno=%d\n", errno);
226 fdevent_install(&t->auth_fde, framework_fd, adb_auth_event, t);
227 fdevent_add(&t->auth_fde, FDE_READ);
230 static void adb_auth_listener(int fd, unsigned events, void *data)
232 struct sockaddr addr;
238 s = adb_socket_accept(fd, &addr, &alen);
240 D("Failed to accept: errno=%d\n", errno);
248 send_auth_request(usb_transport);
252 void adbd_cloexec_auth_socket() {
253 int fd = android_get_control_socket("adbd");
255 D("Failed to get adbd socket\n");
258 fcntl(fd, F_SETFD, FD_CLOEXEC);
261 void adbd_auth_init(void) {
262 int fd = android_get_control_socket("adbd");
264 D("Failed to get adbd socket\n");
268 if (listen(fd, 4) == -1) {
269 D("Failed to listen on '%d'\n", fd);
273 fdevent_install(&listener_fde, fd, adb_auth_listener, NULL);
274 fdevent_add(&listener_fde, FDE_READ);