diff options
author | Benoit Goby <benoit@android.com> | 2012-08-20 23:04:11 -0700 |
---|---|---|
committer | Benoit Goby <benoit@android.com> | 2012-08-20 23:04:11 -0700 |
commit | 871eb1e26166372d7d6740f8f103c6bd3c797271 (patch) | |
tree | d836f250c7bcff407248f1cf055f11caa77be8f9 | |
parent | 53698d00e1ec302d35a67c3965c50e20e7c9cb0e (diff) | |
download | adb-871eb1e26166372d7d6740f8f103c6bd3c797271.tar.gz |
Revert "adb: Add public key authentification"
This reverts commit f4ed516643ee8ed3a59ad1a8048f7ce5f47f93fb.
-rw-r--r-- | Android.mk | 15 | ||||
-rw-r--r-- | adb.c | 128 | ||||
-rw-r--r-- | adb.h | 14 | ||||
-rw-r--r-- | adb_auth.h | 54 | ||||
-rw-r--r-- | adb_auth_client.c | 245 | ||||
-rw-r--r-- | adb_auth_host.c | 418 | ||||
-rw-r--r-- | protocol.txt | 19 |
7 files changed, 18 insertions, 875 deletions
@@ -17,20 +17,18 @@ ifeq ($(HOST_OS),linux) USB_SRCS := usb_linux.c EXTRA_SRCS := get_my_path_linux.c LOCAL_LDLIBS += -lrt -lncurses -lpthread - LOCAL_SHARED_LIBRARIES := libcrypto endif ifeq ($(HOST_OS),darwin) USB_SRCS := usb_osx.c EXTRA_SRCS := get_my_path_darwin.c - LOCAL_LDLIBS += -lpthread -lcrypto -framework CoreFoundation -framework IOKit -framework Carbon + LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon endif ifeq ($(HOST_OS),freebsd) USB_SRCS := usb_libusb.c EXTRA_SRCS := get_my_path_freebsd.c LOCAL_LDLIBS += -lpthread -lusb - LOCAL_SHARED_LIBRARIES := libcrypto endif ifeq ($(HOST_OS),windows) @@ -49,7 +47,6 @@ ifeq ($(HOST_OS),windows) LOCAL_C_INCLUDES += /usr/i586-mingw32msvc/include/ddk endif LOCAL_C_INCLUDES += development/host/windows/usb/api/ - LOCAL_SHARED_LIBRARIES := libcrypto endif LOCAL_SRC_FILES := \ @@ -60,7 +57,6 @@ LOCAL_SRC_FILES := \ transport_usb.c \ commandline.c \ adb_client.c \ - adb_auth_host.c \ sockets.c \ services.c \ file_sync_client.c \ @@ -69,7 +65,6 @@ LOCAL_SRC_FILES := \ utils.c \ usb_vendors.c -LOCAL_C_INCLUDES += external/openssl/include ifneq ($(USE_SYSDEPS_WIN32),) LOCAL_SRC_FILES += sysdeps_win32.c @@ -109,7 +104,6 @@ LOCAL_SRC_FILES := \ transport.c \ transport_local.c \ transport_usb.c \ - adb_auth_client.c \ sockets.c \ services.c \ file_sync_service.c \ @@ -133,7 +127,7 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN) LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED) -LOCAL_STATIC_LIBRARIES := libcutils libc libmincrypt +LOCAL_STATIC_LIBRARIES := libcutils libc include $(BUILD_EXECUTABLE) @@ -152,7 +146,6 @@ LOCAL_SRC_FILES := \ transport_usb.c \ commandline.c \ adb_client.c \ - adb_auth_host.c \ sockets.c \ services.c \ file_sync_client.c \ @@ -172,13 +165,9 @@ LOCAL_CFLAGS := \ -D_XOPEN_SOURCE \ -D_GNU_SOURCE -LOCAL_C_INCLUDES += external/openssl/include - LOCAL_MODULE := adb LOCAL_STATIC_LIBRARIES := libzipfile libunz libcutils -LOCAL_SHARED_LIBRARIES := libcrypto - include $(BUILD_EXECUTABLE) endif @@ -28,7 +28,6 @@ #include "sysdeps.h" #include "adb.h" -#include "adb_auth.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -47,8 +46,6 @@ ADB_MUTEX_DEFINE( D_lock ); int HOST = 0; -static int auth_enabled = 0; - #if !ADB_HOST static const char *adb_device_banner = "device"; #endif @@ -103,7 +100,6 @@ void adb_trace_init(void) { "transport", TRACE_TRANSPORT }, { "jdwp", TRACE_JDWP }, { "services", TRACE_SERVICES }, - { "auth", TRACE_AUTH }, { NULL, 0 } }; @@ -207,21 +203,19 @@ void put_apacket(apacket *p) free(p); } -void handle_online(atransport *t) +void handle_online(void) { D("adb: online\n"); - t->online = 1; } void handle_offline(atransport *t) { D("adb: offline\n"); //Close the associated usb - t->online = 0; run_transport_disconnects(t); } -#if DEBUG_PACKETS +#if TRACE_PACKETS #define DUMPMAX 32 void print_packet(const char *label, apacket *p) { @@ -236,7 +230,6 @@ void print_packet(const char *label, apacket *p) case A_OKAY: tag = "OKAY"; break; case A_CLSE: tag = "CLSE"; break; case A_WRTE: tag = "WRTE"; break; - case A_AUTH: tag = "AUTH"; break; default: tag = "????"; break; } @@ -258,7 +251,7 @@ void print_packet(const char *label, apacket *p) } x++; } - fprintf(stderr, "%s", tag); + fprintf(stderr, tag); } #endif @@ -322,70 +315,11 @@ static void send_connect(atransport *t) cp->msg.data_length = fill_connect_data((char *)cp->data, sizeof(cp->data)); send_packet(cp, t); -} - -static void send_auth_request(atransport *t) -{ - D("Calling send_auth_request\n"); - apacket *p; - int ret; - - ret = adb_auth_generate_token(t->token, sizeof(t->token)); - if (ret != sizeof(t->token)) { - D("Error generating token ret=%d\n", ret); - return; - } - - p = get_apacket(); - memcpy(p->data, t->token, ret); - p->msg.command = A_AUTH; - p->msg.arg0 = ADB_AUTH_TOKEN; - p->msg.data_length = ret; - send_packet(p, t); -} - -static void send_auth_response(uint8_t *token, size_t token_size, atransport *t) -{ - D("Calling send_auth_response\n"); - apacket *p = get_apacket(); - int ret; - - ret = adb_auth_sign(t->key, token, token_size, p->data); - if (!ret) { - D("Error signing the token\n"); - put_apacket(p); - return; - } - - p->msg.command = A_AUTH; - p->msg.arg0 = ADB_AUTH_SIGNATURE; - p->msg.data_length = ret; - send_packet(p, t); -} - -static void send_auth_publickey(atransport *t) -{ - D("Calling send_auth_publickey\n"); - apacket *p = get_apacket(); - int ret; - - ret = adb_auth_get_userkey(p->data, sizeof(p->data)); - if (!ret) { - D("Failed to get user public key\n"); - put_apacket(p); - return; - } - - p->msg.command = A_AUTH; - p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY; - p->msg.data_length = ret; - send_packet(p, t); -} - -void adb_auth_verified(atransport *t) -{ - handle_online(t); - send_connect(t); +#if ADB_HOST + /* XXX why sleep here? */ + // allow the device some time to respond to the connect message + adb_sleep_ms(1000); +#endif } static char *connection_state_name(atransport *t) @@ -517,42 +451,13 @@ void handle_packet(apacket *p, atransport *t) t->connection_state = CS_OFFLINE; handle_offline(t); } - parse_banner((char*) p->data, t); - - if (HOST || !auth_enabled) { - handle_online(t); - if(!HOST) send_connect(t); - } else { - send_auth_request(t); - } - break; - - case A_AUTH: - if (p->msg.arg0 == ADB_AUTH_TOKEN) { - t->key = adb_auth_nextkey(t->key); - if (t->key) { - send_auth_response(p->data, p->msg.data_length, t); - } else { - /* No more private keys to try, send the public key */ - send_auth_publickey(t); - } - } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) { - if (adb_auth_verify(t->token, p->data, p->msg.data_length)) { - adb_auth_verified(t); - t->failed_auth_attempts = 0; - } else { - if (t->failed_auth_attempts++ > 10) - sleep(1); - send_auth_request(t); - } - } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) { - adb_auth_confirm_key(p->data, p->msg.data_length, t); - } + handle_online(); + if(!HOST) send_connect(t); break; case A_OPEN: /* OPEN(local-id, 0, "destination") */ - if (t->online) { + if(t->connection_state != CS_OFFLINE) { char *name = (char*) p->data; name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; s = create_local_service_socket(name); @@ -568,7 +473,7 @@ void handle_packet(apacket *p, atransport *t) break; case A_OKAY: /* READY(local-id, remote-id, "") */ - if (t->online) { + if(t->connection_state != CS_OFFLINE) { if((s = find_local_socket(p->msg.arg1))) { if(s->peer == 0) { s->peer = create_remote_socket(p->msg.arg0, t); @@ -580,7 +485,7 @@ void handle_packet(apacket *p, atransport *t) break; case A_CLSE: /* CLOSE(local-id, remote-id, "") */ - if (t->online) { + if(t->connection_state != CS_OFFLINE) { if((s = find_local_socket(p->msg.arg1))) { s->close(s); } @@ -588,7 +493,7 @@ void handle_packet(apacket *p, atransport *t) break; case A_WRTE: - if (t->online) { + if(t->connection_state != CS_OFFLINE) { if((s = find_local_socket(p->msg.arg1))) { unsigned rid = p->msg.arg0; p->len = p->msg.data_length; @@ -1109,7 +1014,6 @@ int adb_main(int is_daemon, int server_port) usb_vendors_init(); usb_init(); local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); - adb_auth_init(); char local_name[30]; build_local_name(local_name, sizeof(local_name), server_port); @@ -1117,10 +1021,6 @@ int adb_main(int is_daemon, int server_port) exit(1); } #else - property_get("ro.adb.secure", value, "0"); - auth_enabled = !strcmp(value, "1"); - if (auth_enabled) - adb_auth_init(); // Our external storage path may be different than apps, since // we aren't able to bind mount after dropping root. @@ -29,14 +29,13 @@ #define A_OKAY 0x59414b4f #define A_CLSE 0x45534c43 #define A_WRTE 0x45545257 -#define A_AUTH 0x48545541 #define A_VERSION 0x01000000 // ADB protocol version #define ADB_VERSION_MAJOR 1 // Used for help/version information #define ADB_VERSION_MINOR 0 // Used for help/version information -#define ADB_SERVER_VERSION 30 // Increment this when we want to force users to start a new adb server +#define ADB_SERVER_VERSION 29 // Increment this when we want to force users to start a new adb server typedef struct amessage amessage; typedef struct apacket apacket; @@ -166,8 +165,6 @@ typedef enum transport_type { kTransportHost, } transport_type; -#define TOKEN_SIZE 20 - struct atransport { atransport *next; @@ -184,7 +181,6 @@ struct atransport int ref_count; unsigned sync_token; int connection_state; - int online; transport_type type; /* usb handle or socket fd as needed */ @@ -202,11 +198,6 @@ struct atransport /* a list of adisconnect callbacks called when the transport is kicked */ int kicked; adisconnect disconnects; - - void *key; - unsigned char token[TOKEN_SIZE]; - fdevent auth_fde; - unsigned failed_auth_attempts; }; @@ -358,7 +349,6 @@ typedef enum { TRACE_SYSDEPS, TRACE_JDWP, /* 0x100 */ TRACE_SERVICES, - TRACE_AUTH, } AdbTrace; #if ADB_TRACE @@ -418,7 +408,7 @@ void adb_qemu_trace(const char* fmt, ...); #endif -#if !DEBUG_PACKETS +#if !TRACE_PACKETS #define print_packet(tag,p) do {} while (0) #endif diff --git a/adb_auth.h b/adb_auth.h deleted file mode 100644 index 1fffa49..0000000 --- a/adb_auth.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#ifndef __ADB_AUTH_H -#define __ADB_AUTH_H - -void adb_auth_init(void); -void adb_auth_verified(atransport *t); - -/* AUTH packets first argument */ -/* Request */ -#define ADB_AUTH_TOKEN 1 -/* Response */ -#define ADB_AUTH_SIGNATURE 2 -#define ADB_AUTH_RSAPUBLICKEY 3 - -#if ADB_HOST - -int adb_auth_sign(void *key, void *token, size_t token_size, void *sig); -void *adb_auth_nextkey(void *current); -int adb_auth_get_userkey(unsigned char *data, size_t len); - -static inline int adb_auth_generate_token(void *token, size_t token_size) { return 0; } -static inline int adb_auth_verify(void *token, void *sig, int siglen) { return 0; } -static inline void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t) { } -static inline void adb_auth_reload_keys(void) { } - -#else // !ADB_HOST - -static inline int adb_auth_sign(void* key, void *token, size_t token_size, void *sig) { return 0; } -static inline void *adb_auth_nextkey(void *current) { return NULL; } -static inline int adb_auth_get_userkey(unsigned char *data, size_t len) { return 0; } - -int adb_auth_generate_token(void *token, size_t token_size); -int adb_auth_verify(void *token, void *sig, int siglen); -void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t); -void adb_auth_reload_keys(void); - -#endif // ADB_HOST - -#endif // __ADB_AUTH_H diff --git a/adb_auth_client.c b/adb_auth_client.c deleted file mode 100644 index 0b4913e..0000000 --- a/adb_auth_client.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2012 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 <stdio.h> -#include <string.h> -#include <resolv.h> -#include <cutils/list.h> -#include <cutils/sockets.h> - -#include "sysdeps.h" -#include "adb.h" -#include "adb_auth.h" -#include "fdevent.h" -#include "mincrypt/rsa.h" - -#define TRACE_TAG TRACE_AUTH - - -struct adb_public_key { - struct listnode node; - RSAPublicKey key; -}; - -static struct listnode key_list; - -static char *key_paths[] = { - "/adb_keys", - "/data/misc/adb/adb_keys", - NULL -}; - -static fdevent listener_fde; -static int framework_fd = -1; - - -static void read_keys(const char *file, struct listnode *list) -{ - struct adb_public_key *key; - FILE *f; - char buf[MAX_PAYLOAD]; - char *sep; - int ret; - - f = fopen(file, "r"); - if (!f) { - D("Can't open '%s'\n", file); - return; - } - - while (fgets(buf, sizeof(buf), f)) { - /* Allocate 4 extra bytes to decode the base64 data in-place */ - key = calloc(1, sizeof(*key) + 4); - if (!key) { - D("Can't malloc key\n"); - break; - } - - sep = strpbrk(buf, " \t"); - if (sep) - *sep = '\0'; - - ret = __b64_pton(buf, (u_char *)&key->key, sizeof(key->key) + 4); - if (ret != sizeof(key->key)) { - D("%s: Invalid base64 data ret=%d\n", file, ret); - free(key); - continue; - } - - if (key->key.len != RSANUMWORDS) { - D("%s: Invalid key len %d\n", file, key->key.len); - free(key); - continue; - } - - list_add_tail(list, &key->node); - } - - fclose(f); -} - -static void free_keys(struct listnode *list) -{ - struct listnode *item; - - while (!list_empty(list)) { - item = list_head(list); - list_remove(item); - free(node_to_item(item, struct adb_public_key, node)); - } -} - -void adb_auth_reload_keys(void) -{ - char *path; - char **paths = key_paths; - struct stat buf; - - free_keys(&key_list); - - while ((path = *paths++)) { - if (!stat(path, &buf)) { - D("Loading keys from '%s'\n", path); - read_keys(path, &key_list); - } - } -} - -int adb_auth_generate_token(void *token, size_t token_size) -{ - FILE *f; - int ret; - - f = fopen("/dev/urandom", "r"); - if (!f) - return 0; - - ret = fread(token, token_size, 1, f); - - fclose(f); - return ret * token_size; -} - -int adb_auth_verify(void *token, void *sig, int siglen) -{ - struct listnode *item; - struct adb_public_key *key; - int ret; - - if (siglen != RSANUMBYTES) - return 0; - - list_for_each(item, &key_list) { - key = node_to_item(item, struct adb_public_key, node); - ret = RSA_verify(&key->key, sig, siglen, token); - if (ret) - return 1; - } - - return 0; -} - -static void adb_auth_event(int fd, unsigned events, void *data) -{ - atransport *t = data; - char response[2]; - int ret; - - if (events & FDE_READ) { - ret = unix_read(fd, response, sizeof(response)); - if (ret < 0) { - D("Disconnect"); - fdevent_remove(&t->auth_fde); - framework_fd = -1; - } - else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { - adb_auth_reload_keys(); - adb_auth_verified(t); - } - } -} - -void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t) -{ - char msg[MAX_PAYLOAD]; - int ret; - - if (framework_fd < 0) { - D("Client not connected\n"); - return; - } - - if (key[len - 1] != '\0') { - D("Key must be a null-terminated string\n"); - return; - } - - ret = snprintf(msg, sizeof(msg), "PK%s", key); - if (ret >= (signed)sizeof(msg)) { - D("Key too long. ret=%d", ret); - return; - } - D("Sending '%s'\n", msg); - - ret = unix_write(framework_fd, msg, ret); - if (ret < 0) { - D("Failed to write PK, errno=%d\n", errno); - return; - } - - fdevent_install(&t->auth_fde, framework_fd, adb_auth_event, t); - fdevent_add(&t->auth_fde, FDE_READ); -} - -static void adb_auth_listener(int fd, unsigned events, void *data) -{ - struct sockaddr addr; - socklen_t alen; - int s; - - alen = sizeof(addr); - - s = adb_socket_accept(fd, &addr, &alen); - if (s < 0) { - D("Failed to accept: errno=%d\n", errno); - return; - } - - framework_fd = s; -} - -void adb_auth_init(void) -{ - int fd, ret; - - list_init(&key_list); - adb_auth_reload_keys(); - - fd = android_get_control_socket("adbd"); - if (fd < 0) { - D("Failed to get adbd socket\n"); - return; - } - - ret = listen(fd, 4); - if (ret < 0) { - D("Failed to listen on '%d'\n", fd); - return; - } - - fdevent_install(&listener_fde, fd, adb_auth_listener, NULL); - fdevent_add(&listener_fde, FDE_READ); -} diff --git a/adb_auth_host.c b/adb_auth_host.c deleted file mode 100644 index d50782f..0000000 --- a/adb_auth_host.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright (C) 2012 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 <stdio.h> - -#ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# include "windows.h" -# include "shlobj.h" -#else -# include <sys/types.h> -# include <sys/stat.h> -# include <unistd.h> -#endif -#include <string.h> - -#include "sysdeps.h" -#include "adb.h" -#include "adb_auth.h" - -/* HACK: we need the RSAPublicKey struct - * but RSA_verify conflits with openssl */ -#define RSA_verify RSA_verify_mincrypt -#include "mincrypt/rsa.h" -#undef RSA_verify - -#include <cutils/list.h> - -#include <openssl/evp.h> -#include <openssl/objects.h> -#include <openssl/pem.h> -#include <openssl/rsa.h> -#include <openssl/sha.h> - -#define TRACE_TAG TRACE_AUTH - -#define ANDROID_PATH ".android" -#define ADB_KEY_FILE "adb_key" - - -struct adb_private_key { - struct listnode node; - RSA *rsa; -}; - -static struct listnode key_list; - - -/* Convert OpenSSL RSA private key to android pre-computed RSAPublicKey format */ -static int RSA_to_RSAPublicKey(RSA *rsa, RSAPublicKey *pkey) -{ - unsigned int i; - - BN_CTX* ctx = BN_CTX_new(); - BIGNUM* r32 = BN_new(); - BIGNUM* rr = BN_new(); - BIGNUM* r = BN_new(); - BIGNUM* rem = BN_new(); - BIGNUM* n = BN_new(); - BIGNUM* n0inv = BN_new(); - - if (RSA_size(rsa) != RSANUMBYTES) - return 0; - - BN_set_bit(r32, 32); - BN_copy(n, rsa->n); - BN_set_bit(r, RSANUMWORDS * 32); - BN_mod_sqr(rr, r, n, ctx); - BN_div(NULL, rem, n, r32, ctx); - BN_mod_inverse(n0inv, rem, r32, ctx); - - pkey->len = RSANUMWORDS; - pkey->n0inv = 0 - BN_get_word(n0inv); - for (i = 0; i < RSANUMWORDS; i++) { - BN_div(rr, rem, rr, r32, ctx); - pkey->rr[i] = BN_get_word(rem); - BN_div(n, rem, n, r32, ctx); - pkey->n[i] = BN_get_word(rem); - } - pkey->exponent = BN_get_word(rsa->e); - - BN_free(n0inv); - BN_free(n); - BN_free(rem); - BN_free(r); - BN_free(rr); - BN_free(r32); - BN_CTX_free(ctx); - - return 1; -} - -static void get_user_info(char *buf, size_t len) -{ - char hostname[1024], username[1024]; - int ret; - -#ifndef _WIN32 - ret = gethostname(hostname, sizeof(hostname)); - if (ret < 0) -#endif - strcpy(hostname, "unknown"); - -#if !defined _WIN32 && !defined ADB_HOST_ON_TARGET - ret = getlogin_r(username, sizeof(username)); - if (ret < 0) -#endif - strcpy(username, "unknown"); - - ret = snprintf(buf, len, " %s@%s", username, hostname); - if (ret >= (signed)len) - buf[len - 1] = '\0'; -} - -static int write_public_keyfile(RSA *private_key, const char *private_key_path) -{ - RSAPublicKey pkey; - BIO *bio, *b64, *bfile; - char path[PATH_MAX], info[MAX_PAYLOAD]; - int ret; - - ret = snprintf(path, sizeof(path), "%s.pub", private_key_path); - if (ret >= (signed)sizeof(path)) - return 0; - - ret = RSA_to_RSAPublicKey(private_key, &pkey); - if (!ret) { - D("Failed to convert to publickey\n"); - return 0; - } - - bfile = BIO_new_file(path, "w"); - if (!bfile) { - D("Failed to open '%s'\n", path); - return 0; - } - - D("Writing public key to '%s'\n", path); - - b64 = BIO_new(BIO_f_base64()); - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - - bio = BIO_push(b64, bfile); - BIO_write(bio, &pkey, sizeof(pkey)); - BIO_flush(bio); - BIO_pop(b64); - BIO_free(b64); - - get_user_info(info, sizeof(info)); - BIO_write(bfile, info, strlen(info)); - BIO_flush(bfile); - BIO_free_all(bfile); - - return 1; -} - -static int generate_key(const char *file) -{ - EVP_PKEY* pkey = EVP_PKEY_new(); - BIGNUM* exponent = BN_new(); - RSA* rsa = RSA_new(); - FILE *f = NULL; - int ret = 0; - - D("generate_key '%s'\n", file); - - if (!pkey || !exponent || !rsa) { - D("Failed to allocate key\n"); - goto out; - } - - BN_set_word(exponent, RSA_F4); - RSA_generate_key_ex(rsa, 2048, exponent, NULL); - EVP_PKEY_set1_RSA(pkey, rsa); - - f = fopen(file, "w"); - if (!f) { - D("Failed to open '%s'\n", file); - goto out; - } - - if (!PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL)) { - D("Failed to write key\n"); - goto out; - } - - if (!write_public_keyfile(rsa, file)) { - D("Failed to write public key\n"); - goto out; - } - - ret = 1; - -out: - if (f) - fclose(f); - EVP_PKEY_free(pkey); - RSA_free(rsa); - BN_free(exponent); - return ret; -} - -static int read_key(const char *file, struct listnode *list) -{ - struct adb_private_key *key; - FILE *f; - - D("read_key '%s'\n", file); - - f = fopen(file, "r"); - if (!f) { - D("Failed to open '%s'\n", file); - return 0; - } - - key = malloc(sizeof(*key)); - if (!key) { - D("Failed to alloc key\n"); - fclose(f); - return 0; - } - key->rsa = RSA_new(); - - if (!PEM_read_RSAPrivateKey(f, &key->rsa, NULL, NULL)) { - D("Failed to read key\n"); - fclose(f); - RSA_free(key->rsa); - free(key); - return 0; - } - - fclose(f); - list_add_tail(list, &key->node); - return 1; -} - -static int get_user_keyfilepath(char *filename, size_t len) -{ - const char *format, *home; - char android_dir[PATH_MAX]; - struct stat buf; -#ifdef _WIN32 - char path[PATH_MAX]; - home = getenv("ANDROID_SDK_HOME"); - if (!home) { - SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, path); - home = path; - } - format = "%s\\%s"; -#else - home = getenv("HOME"); - if (!home) - return -1; - format = "%s/%s"; -#endif - - D("home '%s'\n", home); - - if (snprintf(android_dir, sizeof(android_dir), format, home, - ANDROID_PATH) >= (int)sizeof(android_dir)) - return -1; - - if (stat(android_dir, &buf)) { - if (adb_mkdir(android_dir, 0750) < 0) { - D("Cannot mkdir '%s'", android_dir); - return -1; - } - } - - return snprintf(filename, len, format, android_dir, ADB_KEY_FILE); -} - -static int get_user_key(struct listnode *list) -{ - struct stat buf; - char path[PATH_MAX]; - int ret; - - ret = get_user_keyfilepath(path, sizeof(path)); - if (ret < 0 || ret >= (signed)sizeof(path)) { - D("Error getting user key filename"); - return 0; - } - - D("user key '%s'\n", path); - - if (stat(path, &buf) == -1) { - if (!generate_key(path)) { - D("Failed to generate new key\n"); - return 0; - } - } - - return read_key(path, list); -} - -static void get_vendor_keys(struct listnode *list) -{ - const char *adb_keys_path; - char keys_path[MAX_PAYLOAD]; - char *keys = keys_path; - char *path; - struct stat buf; - - adb_keys_path = getenv("ADB_VENDOR_KEYS"); - if (!adb_keys_path) - return; - strncpy(keys_path, adb_keys_path, sizeof(keys_path)); - - do { - path = strsep(&keys, ";"); - D("Reading: %s\n", path); - - if (stat(path, &buf)) { - D("Can't read '%s'\n", path); - continue; - } - - if (!read_key(path, list)) - continue; - - } while (keys); -} - -int adb_auth_sign(void *node, void *token, size_t token_size, void *sig) -{ - unsigned int len; - struct adb_private_key *key = node_to_item(node, struct adb_private_key, node); - - if (!RSA_sign(NID_sha1, token, token_size, sig, &len, key->rsa)) { - return 0; - } - - D("adb_auth_sign len=%d\n", len); - return (int)len; -} - -void *adb_auth_nextkey(void *current) -{ - struct listnode *item; - - if (list_empty(&key_list)) - return NULL; - - if (!current) - return list_head(&key_list); - - list_for_each(item, &key_list) { - if (item == current) { - /* current is the last item, we tried all the keys */ - if (item->next == &key_list) - return NULL; - return item->next; - } - } - - return NULL; -} - -int adb_auth_get_userkey(unsigned char *data, size_t len) -{ - char path[PATH_MAX]; - char *file; - int ret; - - ret = get_user_keyfilepath(path, sizeof(path) - 4); - if (ret < 0 || ret >= (signed)(sizeof(path) - 4)) { - D("Error getting user key filename"); - return 0; - } - strcat(path, ".pub"); - - file = load_file(path, (unsigned*)&ret); - if (!file) { - D("Can't load '%s'\n", path); - return 0; - } - - if (len < (size_t)(ret + 1)) { - D("%s: Content too large ret=%d\n", path, ret); - return 0; - } - - memcpy(data, file, ret); - data[ret] = '\0'; - - return ret + 1; -} - -void adb_auth_init(void) -{ - int ret; - - D("adb_auth_init\n"); - - list_init(&key_list); - - ret = get_user_key(&key_list); - if (!ret) { - D("Failed to get user key\n"); - return; - } - - get_vendor_keys(&key_list); -} diff --git a/protocol.txt b/protocol.txt index c9d3c24..abd63f9 100644 --- a/protocol.txt +++ b/protocol.txt @@ -75,24 +75,6 @@ kind of unique ID (or empty), and banner is a human-readable version or identifier string. The banner is used to transmit useful properties. ---- AUTH(type, 0, "data") ---------------------------------------------- - -The AUTH message informs the recipient that authentication is required to -connect to the sender. If type is TOKEN(1), data is a random token that -the recipient can sign with a private key. The recipient replies with an -AUTH packet where type is SIGNATURE(2) and data is the signature. If the -signature verification succeeds, the sender replies with a CONNECT packet. - -If the signature verification fails, the sender replies with a new AUTH -packet and a new random token, so that the recipient can retry signing -with a different private key. - -Once the recipient has tried all its private keys, it can reply with an -AUTH packet where type is RSAPUBLICKEY(3) and data is the public key. If -possible, an on-screen confirmation may be displayed for the user to -confirm they want to install the public key on the device. - - --- OPEN(local-id, 0, "destination") ----------------------------------- The OPEN message informs the recipient that the sender has a stream @@ -184,7 +166,6 @@ to send across the wire. #define A_SYNC 0x434e5953 #define A_CNXN 0x4e584e43 -#define A_AUTH 0x48545541 #define A_OPEN 0x4e45504f #define A_OKAY 0x59414b4f #define A_CLSE 0x45534c43 |