1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/devtools/adb/android_rsa.h"
7 #include "base/base64.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/browser/prefs/pref_service_syncable.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/common/pref_names.h"
12 #include "crypto/rsa_private_key.h"
13 #include "crypto/signature_creator.h"
14 #include "net/cert/asn1_util.h"
18 const size_t kRSANumWords = 64;
19 const size_t kBigIntSize = 1024;
21 static const char kDummyRSAPublicKey[] =
22 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6OSJ64q+ZLg7VV2ojEPh5TRbYjwbT"
23 "TifSPeFIV45CHnbTWYiiIn41wrozpYizNsMWZUBjdah1N78WVhbyDrnr0bDgFp+gXjfVppa3I"
24 "gjiohEcemK3omXi3GDMK8ERhriLUKfQS842SXtQ8I+KoZtpCkGM//0h7+P+Rhm0WwdipIRMhR"
25 "8haNAeyDiiCvqJcvevv2T52vqKtS3aWz+GjaTJJLVWydEpz9WdvWeLfFVhe2ZnqwwZNa30Qoj"
26 "fsnvjaMwK2MU7uYfRBPuvLyK5QESWBpArNDd6ULl8Y+NU6kwNOVDc87OASCVEM1gw2IMi2mo2"
27 "WO5ywp0UWRiGZCkK+wOFQIDAQAB";
29 typedef struct RSAPublicKey {
30 int len; // Length of n[] in number of uint32
31 uint32 n0inv; // -1 / n[0] mod 2^32
32 uint32 n[kRSANumWords]; // modulus as little endian array
33 uint32 rr[kRSANumWords]; // R^2 as little endian array
34 int exponent; // 3 or 65537
37 // http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
38 // a * x + b * y = gcd(a, b) = d
39 void ExtendedEuclid(uint64 a, uint64 b, uint64 *x, uint64 *y, uint64 *d) {
40 uint64 x1 = 0, x2 = 1, y1 = 1, y2 = 0;
60 uint32 ModInverse(uint64 a, uint64 m)
63 ExtendedEuclid(a, m, &x, &y, &d);
65 return static_cast<uint32>(x);
70 uint32* result = new uint32[kBigIntSize];
71 memset(result, 0, kBigIntSize * sizeof(uint32));
75 void BnFree(uint32* a) {
79 void BnPrint(const std::string& title, uint32_t* a) {
80 int i = kBigIntSize - 1;
81 fprintf(stderr, "%s: ", title.c_str());
84 fprintf(stderr, "%08x", a[i]);
85 fprintf(stderr, "\n");
88 uint32* BnCopy(uint32* a) {
89 uint32* result = new uint32[kBigIntSize];
90 memcpy(result, a, kBigIntSize * sizeof(uint32));
94 void BnAdd(uint32* a, uint32* b) {
95 uint64 carry_over = 0;
96 for (size_t i = 0; i < kBigIntSize; ++i) {
97 carry_over += static_cast<uint64>(a[i]) + b[i];
98 a[i] = carry_over & kuint32max;
103 uint32* BnMul(uint32* a, uint32 b) {
104 uint32* result = BnNew();
105 uint64 carry_over = 0;
106 for (size_t i = 0; i < kBigIntSize; ++i) {
107 carry_over += static_cast<uint64>(a[i]) * b;
108 result[i] = carry_over & kuint32max;
114 void BnSub(uint32* a, uint32* b) {
116 for (size_t i = 0; i < kBigIntSize; ++i) {
117 int64 sub = static_cast<int64>(a[i]) - b[i] - carry_over;
121 sub += GG_LONGLONG(0x100000000);
123 a[i] = static_cast<uint32>(sub);
127 void BnLeftShift(uint32* a, int offset) {
128 for (int i = kBigIntSize - offset - 1; i >= 0; --i)
129 a[i + offset] = a[i];
130 for (int i = 0; i < offset; ++i)
134 int BnCompare(uint32* a, uint32* b) {
135 for (int i = kBigIntSize - 1; i >= 0; --i) {
144 uint64 BnGuess(uint32* a, uint32* b, uint64 from, uint64 to) {
148 uint64 guess = (from + to) / 2;
149 uint32* t = BnMul(b, static_cast<uint32>(guess));
150 int result = BnCompare(a, t);
153 return BnGuess(a, b, guess, to);
155 return BnGuess(a, b, from, guess);
159 void BnDiv(uint32* a, uint32* b, uint32** pq, uint32** pr) {
160 if (BnCompare(a, b) < 0) {
168 int oa = kBigIntSize - 1;
169 int ob = kBigIntSize - 1;
170 for (; oa > 0 && !a[oa]; --oa) {}
171 for (; ob > 0 && !b[ob]; --ob) {}
173 uint32* ca = BnCopy(a);
175 int digit = a[oa] < b[ob] ? oa - ob - 1 : oa - ob;
177 for (; digit >= 0; --digit) {
178 uint32* shifted_b = BnCopy(b);
179 BnLeftShift(shifted_b, digit);
180 uint32 value = static_cast<uint32>(
181 BnGuess(ca, shifted_b, 0, static_cast<uint64>(kuint32max) + 1));
183 uint32* t = BnMul(shifted_b, value);
201 crypto::RSAPrivateKey* AndroidRSAPrivateKey(Profile* profile) {
202 std::string encoded_key =
203 profile->GetPrefs()->GetString(prefs::kDevToolsAdbKey);
204 std::string decoded_key;
205 scoped_ptr<crypto::RSAPrivateKey> key;
206 if (!encoded_key.empty() && base::Base64Decode(encoded_key, &decoded_key)) {
207 std::vector<uint8> key_info(decoded_key.begin(), decoded_key.end());
208 key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
211 key.reset(crypto::RSAPrivateKey::Create(2048));
212 std::vector<uint8> key_info;
213 if (!key || !key->ExportPrivateKey(&key_info))
216 std::string key_string(key_info.begin(), key_info.end());
217 if (base::Base64Encode(key_string, &encoded_key)) {
218 profile->GetPrefs()->SetString(prefs::kDevToolsAdbKey,
222 return key.release();
225 std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) {
226 std::vector<uint8> public_key;
228 return kDummyRSAPublicKey;
230 key->ExportPublicKey(&public_key);
231 std::string asn1(public_key.begin(), public_key.end());
233 base::StringPiece pk;
234 if (!net::asn1::ExtractSubjectPublicKeyFromSPKI(asn1, &pk))
235 return kDummyRSAPublicKey;
237 // Skip 10 byte asn1 prefix to the modulus.
238 std::vector<uint8> pk_data(pk.data() + 10, pk.data() + pk.length());
240 for (size_t i = 0; i < kRSANumWords; ++i) {
241 uint32 t = pk_data[4 * i];
243 t += pk_data[4 * i + 1];
245 t += pk_data[4 * i + 2];
247 t += pk_data[4 * i + 3];
248 n[kRSANumWords - i - 1] = t;
253 pkey.len = kRSANumWords;
254 pkey.exponent = 65537; // Fixed public exponent
255 pkey.n0inv = 0 - ModInverse(n0, GG_LONGLONG(0x100000000));
257 return kDummyRSAPublicKey;
260 r[kRSANumWords * 2] = 1;
263 BnDiv(r, n, NULL, &rr);
265 for (size_t i = 0; i < kRSANumWords; ++i) {
275 std::string input(reinterpret_cast<char*>(&pkey), sizeof(pkey));
276 base::Base64Encode(input, &output);
280 std::string AndroidRSASign(crypto::RSAPrivateKey* key,
281 const std::string& body) {
282 std::vector<uint8> digest(body.begin(), body.end());
283 std::vector<uint8> result;
284 if (!crypto::SignatureCreator::Sign(key, vector_as_array(&digest),
285 digest.size(), &result)) {
286 return std::string();
288 return std::string(result.begin(), result.end());