1d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby/*
2d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * Copyright (C) 2012 The Android Open Source Project
3d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby *
4d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * Licensed under the Apache License, Version 2.0 (the "License");
5d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * you may not use this file except in compliance with the License.
6d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * You may obtain a copy of the License at
7d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby *
8d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby *      http://www.apache.org/licenses/LICENSE-2.0
9d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby *
10d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * Unless required by applicable law or agreed to in writing, software
11d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * distributed under the License is distributed on an "AS IS" BASIS,
12d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * See the License for the specific language governing permissions and
14d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * limitations under the License.
15d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby */
16d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
17d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <stdio.h>
18d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
19d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#ifdef _WIN32
20d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#  define WIN32_LEAN_AND_MEAN
21d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#  include "windows.h"
22d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#  include "shlobj.h"
23d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#else
24d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#  include <sys/types.h>
25d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#  include <sys/stat.h>
26d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#  include <unistd.h>
27d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#endif
28d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <string.h>
29d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
30d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "sysdeps.h"
31d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "adb.h"
32d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "adb_auth.h"
33d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
34d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby/* HACK: we need the RSAPublicKey struct
35d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * but RSA_verify conflits with openssl */
36d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#define RSA_verify RSA_verify_mincrypt
37d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "mincrypt/rsa.h"
38d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#undef RSA_verify
39d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
40d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <cutils/list.h>
41d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
42d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <openssl/evp.h>
43d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <openssl/objects.h>
44d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <openssl/pem.h>
45d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <openssl/rsa.h>
46d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include <openssl/sha.h>
47d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
48d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#define TRACE_TAG TRACE_AUTH
49d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
50d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#define ANDROID_PATH   ".android"
5164b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby#define ADB_KEY_FILE   "adbkey"
52d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
53d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
54d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystruct adb_private_key {
55d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct listnode node;
56d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    RSA *rsa;
57d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby};
58d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
59d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic struct listnode key_list;
60d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
61d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
62d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby/* Convert OpenSSL RSA private key to android pre-computed RSAPublicKey format */
63d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic int RSA_to_RSAPublicKey(RSA *rsa, RSAPublicKey *pkey)
64d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
65d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret = 1;
66d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    unsigned int i;
67d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
68d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_CTX* ctx = BN_CTX_new();
69d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* r32 = BN_new();
70d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* rr = BN_new();
71d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* r = BN_new();
72d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* rem = BN_new();
73d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* n = BN_new();
74d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* n0inv = BN_new();
75d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
76d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (RSA_size(rsa) != RSANUMBYTES) {
77d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        ret = 0;
78d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        goto out;
79d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
80d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
81d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_set_bit(r32, 32);
82d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_copy(n, rsa->n);
83d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_set_bit(r, RSANUMWORDS * 32);
84d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_mod_sqr(rr, r, n, ctx);
85d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_div(NULL, rem, n, r32, ctx);
86d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_mod_inverse(n0inv, rem, r32, ctx);
87d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
88d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    pkey->len = RSANUMWORDS;
89d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    pkey->n0inv = 0 - BN_get_word(n0inv);
90d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    for (i = 0; i < RSANUMWORDS; i++) {
91d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        BN_div(rr, rem, rr, r32, ctx);
92d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        pkey->rr[i] = BN_get_word(rem);
93d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        BN_div(n, rem, n, r32, ctx);
94d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        pkey->n[i] = BN_get_word(rem);
95d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
96d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    pkey->exponent = BN_get_word(rsa->e);
97d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
98d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyout:
99d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(n0inv);
100d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(n);
101d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(rem);
102d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(r);
103d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(rr);
104d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(r32);
105d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_CTX_free(ctx);
106d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
107d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return ret;
108d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
109d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
110d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic void get_user_info(char *buf, size_t len)
111d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
112d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char hostname[1024], username[1024];
113d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret;
114d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
115d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#ifndef _WIN32
116d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = gethostname(hostname, sizeof(hostname));
117d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (ret < 0)
118d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#endif
119d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        strcpy(hostname, "unknown");
120d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
121d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#if !defined _WIN32 && !defined ADB_HOST_ON_TARGET
122d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = getlogin_r(username, sizeof(username));
123d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (ret < 0)
124d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#endif
125d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        strcpy(username, "unknown");
126d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
127d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = snprintf(buf, len, " %s@%s", username, hostname);
128d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (ret >= (signed)len)
129d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        buf[len - 1] = '\0';
130d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
131d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
132d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic int write_public_keyfile(RSA *private_key, const char *private_key_path)
133d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
134d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    RSAPublicKey pkey;
135d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO *bio, *b64, *bfile;
136d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char path[PATH_MAX], info[MAX_PAYLOAD];
137d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret;
138d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
139d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = snprintf(path, sizeof(path), "%s.pub", private_key_path);
140d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (ret >= (signed)sizeof(path))
141d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
142d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
143d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = RSA_to_RSAPublicKey(private_key, &pkey);
144d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!ret) {
145d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to convert to publickey\n");
146d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
147d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
148d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
149d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    bfile = BIO_new_file(path, "w");
150d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!bfile) {
151d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to open '%s'\n", path);
152d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
153d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
154d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
155d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("Writing public key to '%s'\n", path);
156d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
157d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    b64 = BIO_new(BIO_f_base64());
158d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
159d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
160d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    bio = BIO_push(b64, bfile);
161d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_write(bio, &pkey, sizeof(pkey));
162d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_flush(bio);
163d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_pop(b64);
164d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_free(b64);
165d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
166d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    get_user_info(info, sizeof(info));
167d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_write(bfile, info, strlen(info));
168d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_flush(bfile);
169d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIO_free_all(bfile);
170d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
171d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return 1;
172d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
173d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
174d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic int generate_key(const char *file)
175d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
176d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    EVP_PKEY* pkey = EVP_PKEY_new();
177d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BIGNUM* exponent = BN_new();
178d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    RSA* rsa = RSA_new();
17964b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby    mode_t old_mask;
180d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    FILE *f = NULL;
181d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret = 0;
182d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
183d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("generate_key '%s'\n", file);
184d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
185d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!pkey || !exponent || !rsa) {
186d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to allocate key\n");
187d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        goto out;
188d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
189d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
190d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_set_word(exponent, RSA_F4);
191d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    RSA_generate_key_ex(rsa, 2048, exponent, NULL);
192d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    EVP_PKEY_set1_RSA(pkey, rsa);
193d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
19464b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby    old_mask = umask(077);
19564b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby
196d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    f = fopen(file, "w");
197d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!f) {
198d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to open '%s'\n", file);
19964b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby        umask(old_mask);
200d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        goto out;
201d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
202d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
20364b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby    umask(old_mask);
20464b3103017cb9038c5fb7e3601f51c6a458bed06Benoit Goby
205d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL)) {
206d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to write key\n");
207d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        goto out;
208d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
209d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
210d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!write_public_keyfile(rsa, file)) {
211d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to write public key\n");
212d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        goto out;
213d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
214d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
215d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = 1;
216d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
217d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyout:
218d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (f)
219d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        fclose(f);
220d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    EVP_PKEY_free(pkey);
221d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    RSA_free(rsa);
222d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    BN_free(exponent);
223d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return ret;
224d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
225d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
226d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic int read_key(const char *file, struct listnode *list)
227d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
228d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct adb_private_key *key;
229d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    FILE *f;
230d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
231d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("read_key '%s'\n", file);
232d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
233d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    f = fopen(file, "r");
234d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!f) {
235d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to open '%s'\n", file);
236d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
237d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
238d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
239d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    key = malloc(sizeof(*key));
240d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!key) {
241d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to alloc key\n");
242d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        fclose(f);
243d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
244d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
245d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    key->rsa = RSA_new();
246d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
247d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!PEM_read_RSAPrivateKey(f, &key->rsa, NULL, NULL)) {
248d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to read key\n");
249d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        fclose(f);
250d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        RSA_free(key->rsa);
251d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        free(key);
252d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
253d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
254d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
255d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    fclose(f);
256d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    list_add_tail(list, &key->node);
257d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return 1;
258d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
259d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
260d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic int get_user_keyfilepath(char *filename, size_t len)
261d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
262d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    const char *format, *home;
263d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char android_dir[PATH_MAX];
264d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct stat buf;
265d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#ifdef _WIN32
266d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char path[PATH_MAX];
267d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    home = getenv("ANDROID_SDK_HOME");
268d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!home) {
269d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, path);
270d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        home = path;
271d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
272d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    format = "%s\\%s";
273d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#else
274d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    home = getenv("HOME");
275d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!home)
276d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return -1;
277d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    format = "%s/%s";
278d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#endif
279d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
280d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("home '%s'\n", home);
281d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
282d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (snprintf(android_dir, sizeof(android_dir), format, home,
283d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                        ANDROID_PATH) >= (int)sizeof(android_dir))
284d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return -1;
285d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
286d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (stat(android_dir, &buf)) {
287d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        if (adb_mkdir(android_dir, 0750) < 0) {
288d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            D("Cannot mkdir '%s'", android_dir);
289d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            return -1;
290d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        }
291d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
292d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
293d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return snprintf(filename, len, format, android_dir, ADB_KEY_FILE);
294d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
295d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
296d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic int get_user_key(struct listnode *list)
297d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
298d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct stat buf;
299d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char path[PATH_MAX];
300d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret;
301d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
302d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = get_user_keyfilepath(path, sizeof(path));
303d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (ret < 0 || ret >= (signed)sizeof(path)) {
304d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Error getting user key filename");
305d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
306d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
307d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
308d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("user key '%s'\n", path);
309d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
310d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (stat(path, &buf) == -1) {
311d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        if (!generate_key(path)) {
312d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            D("Failed to generate new key\n");
313d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            return 0;
314d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        }
315d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
316d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
317d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return read_key(path, list);
318d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
319d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
320d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic void get_vendor_keys(struct listnode *list)
321d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
322d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    const char *adb_keys_path;
323d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char keys_path[MAX_PAYLOAD];
324d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char *path;
325d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char *save;
326d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct stat buf;
327d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
328d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    adb_keys_path = getenv("ADB_VENDOR_KEYS");
329d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!adb_keys_path)
330d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return;
331d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    strncpy(keys_path, adb_keys_path, sizeof(keys_path));
332d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
333d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    path = adb_strtok_r(keys_path, ENV_PATH_SEPARATOR_STR, &save);
334d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    while (path) {
335d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Reading: '%s'\n", path);
336d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
337d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        if (stat(path, &buf))
338d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            D("Can't read '%s'\n", path);
339d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        else if (!read_key(path, list))
340d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            D("Failed to read '%s'\n", path);
341d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
342d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        path = adb_strtok_r(NULL, ENV_PATH_SEPARATOR_STR, &save);
343d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
344d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
345d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
346d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyint adb_auth_sign(void *node, void *token, size_t token_size, void *sig)
347d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
348d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    unsigned int len;
349d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct adb_private_key *key = node_to_item(node, struct adb_private_key, node);
350d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
351d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!RSA_sign(NID_sha1, token, token_size, sig, &len, key->rsa)) {
352d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
353d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
354d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
355d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("adb_auth_sign len=%d\n", len);
356d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return (int)len;
357d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
358d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
359d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyvoid *adb_auth_nextkey(void *current)
360d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
361d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    struct listnode *item;
362d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
363d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (list_empty(&key_list))
364d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return NULL;
365d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
366d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!current)
367d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return list_head(&key_list);
368d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
369d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    list_for_each(item, &key_list) {
370d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        if (item == current) {
371d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            /* current is the last item, we tried all the keys */
372d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            if (item->next == &key_list)
373d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                return NULL;
374d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            return item->next;
375d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        }
376d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
377d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
378d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return NULL;
379d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
380d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
381d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyint adb_auth_get_userkey(unsigned char *data, size_t len)
382d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
383d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char path[PATH_MAX];
384d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    char *file;
385d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret;
386d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
387d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = get_user_keyfilepath(path, sizeof(path) - 4);
388d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (ret < 0 || ret >= (signed)(sizeof(path) - 4)) {
389d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Error getting user key filename");
390d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
391d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
392d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    strcat(path, ".pub");
393d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
394d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    file = load_file(path, (unsigned*)&ret);
395d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!file) {
396d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Can't load '%s'\n", path);
397d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
398d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
399d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
400d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (len < (size_t)(ret + 1)) {
401d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("%s: Content too large ret=%d\n", path, ret);
402d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return 0;
403d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
404d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
405d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    memcpy(data, file, ret);
406d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    data[ret] = '\0';
407d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
408d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    return ret + 1;
409d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
410d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
411d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyvoid adb_auth_init(void)
412d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{
413d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    int ret;
414d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
415d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    D("adb_auth_init\n");
416d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
417d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    list_init(&key_list);
418d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
419d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    ret = get_user_key(&key_list);
420d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    if (!ret) {
421d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        D("Failed to get user key\n");
422d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        return;
423d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    }
424d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
425d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    get_vendor_keys(&key_list);
426d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
427