Home | History | Annotate | Download | only in adb
      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.
      4 
      5 #include "chrome/browser/devtools/adb/android_rsa.h"
      6 
      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"
     15 
     16 namespace {
     17 
     18 const size_t kRSANumWords = 64;
     19 const size_t kBigIntSize = 1024;
     20 
     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";
     28 
     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
     35 } RSAPublicKey;
     36 
     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;
     41 
     42   while (b > 0) {
     43     uint64 q = a / b;
     44     uint64 r = a % b;
     45     *x = x2 - q * x1;
     46     *y = y2 - q * y1;
     47     a = b;
     48     b = r;
     49     x2 = x1;
     50     x1 = *x;
     51     y2 = y1;
     52     y1 = *y;
     53   }
     54 
     55   *d = a;
     56   *x = x2;
     57   *y = y2;
     58 }
     59 
     60 uint32 ModInverse(uint64 a, uint64 m)
     61 {
     62   uint64 d, x, y;
     63   ExtendedEuclid(a, m, &x, &y, &d);
     64   if (d == 1)
     65     return static_cast<uint32>(x);
     66   return 0;
     67 }
     68 
     69 uint32* BnNew() {
     70   uint32* result = new uint32[kBigIntSize];
     71   memset(result, 0, kBigIntSize * sizeof(uint32));
     72   return result;
     73 }
     74 
     75 void BnFree(uint32* a) {
     76   delete[] a;
     77 }
     78 
     79 void BnPrint(const std::string& title, uint32_t* a) {
     80     int i = kBigIntSize - 1;
     81     fprintf(stderr, "%s: ", title.c_str());
     82     while (!a[i]) --i;
     83     for (; i >= 0; --i)
     84         fprintf(stderr, "%08x", a[i]);
     85     fprintf(stderr, "\n");
     86 }
     87 
     88 uint32* BnCopy(uint32* a) {
     89   uint32* result = new uint32[kBigIntSize];
     90   memcpy(result, a, kBigIntSize * sizeof(uint32));
     91   return result;
     92 }
     93 
     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;
     99     carry_over >>= 32;
    100   }
    101 }
    102 
    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;
    109     carry_over >>= 32;
    110   }
    111   return result;
    112 }
    113 
    114 void BnSub(uint32* a, uint32* b) {
    115   int carry_over = 0;
    116   for (size_t i = 0; i < kBigIntSize; ++i) {
    117     int64 sub = static_cast<int64>(a[i]) - b[i] - carry_over;
    118     carry_over = 0;
    119     if (sub < 0) {
    120       carry_over = 1;
    121       sub += GG_LONGLONG(0x100000000);
    122     }
    123     a[i] = static_cast<uint32>(sub);
    124   }
    125 }
    126 
    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)
    131     a[i] = 0;
    132 }
    133 
    134 int BnCompare(uint32* a, uint32* b) {
    135   for (int i = kBigIntSize - 1; i >= 0; --i) {
    136     if (a[i] > b[i])
    137       return 1;
    138     if (a[i] < b[i])
    139       return -1;
    140   }
    141   return 0;
    142 }
    143 
    144 uint64 BnGuess(uint32* a, uint32* b, uint64 from, uint64 to) {
    145   if (from + 1 >= to)
    146     return from;
    147 
    148   uint64 guess = (from + to) / 2;
    149   uint32* t = BnMul(b, static_cast<uint32>(guess));
    150   int result = BnCompare(a, t);
    151   BnFree(t);
    152   if (result > 0)
    153     return BnGuess(a, b, guess, to);
    154   if (result < 0)
    155     return BnGuess(a, b, from, guess);
    156   return guess;
    157 }
    158 
    159 void BnDiv(uint32* a, uint32* b, uint32** pq, uint32** pr) {
    160   if (BnCompare(a, b) < 0) {
    161     if (pq)
    162       *pq = BnNew();
    163     if (pr)
    164       *pr = BnCopy(a);
    165     return;
    166   }
    167 
    168   int oa = kBigIntSize - 1;
    169   int ob = kBigIntSize - 1;
    170   for (; oa > 0 && !a[oa]; --oa) {}
    171   for (; ob > 0 && !b[ob]; --ob) {}
    172   uint32* q = BnNew();
    173   uint32* ca = BnCopy(a);
    174 
    175   int digit = a[oa] < b[ob] ? oa - ob - 1 : oa - ob;
    176 
    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));
    182     q[digit] = value;
    183     uint32* t = BnMul(shifted_b, value);
    184     BnSub(ca, t);
    185     BnFree(t);
    186     BnFree(shifted_b);
    187   }
    188 
    189   if (pq)
    190     *pq = q;
    191   else
    192     BnFree(q);
    193   if (pr)
    194     *pr = ca;
    195   else
    196     BnFree(ca);
    197 }
    198 
    199 }  // namespace
    200 
    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));
    209   }
    210   if (!key) {
    211     key.reset(crypto::RSAPrivateKey::Create(2048));
    212     std::vector<uint8> key_info;
    213     if (!key || !key->ExportPrivateKey(&key_info))
    214       return NULL;
    215 
    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,
    219                                      encoded_key);
    220     }
    221   }
    222   return key.release();
    223 }
    224 
    225 std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) {
    226   std::vector<uint8> public_key;
    227   if (!key)
    228     return kDummyRSAPublicKey;
    229 
    230   key->ExportPublicKey(&public_key);
    231   std::string asn1(public_key.begin(), public_key.end());
    232 
    233   base::StringPiece pk;
    234   if (!net::asn1::ExtractSubjectPublicKeyFromSPKI(asn1, &pk))
    235     return kDummyRSAPublicKey;
    236 
    237   // Skip 10 byte asn1 prefix to the modulus.
    238   std::vector<uint8> pk_data(pk.data() + 10, pk.data() + pk.length());
    239   uint32* n = BnNew();
    240   for (size_t i = 0; i < kRSANumWords; ++i) {
    241     uint32 t = pk_data[4 * i];
    242     t = t << 8;
    243     t += pk_data[4 * i + 1];
    244     t = t << 8;
    245     t += pk_data[4 * i + 2];
    246     t = t << 8;
    247     t += pk_data[4 * i + 3];
    248     n[kRSANumWords - i - 1] = t;
    249   }
    250   uint64 n0 = n[0];
    251 
    252   RSAPublicKey pkey;
    253   pkey.len = kRSANumWords;
    254   pkey.exponent = 65537; // Fixed public exponent
    255   pkey.n0inv = 0 - ModInverse(n0, GG_LONGLONG(0x100000000));
    256   if (pkey.n0inv == 0)
    257     return kDummyRSAPublicKey;
    258 
    259   uint32* r = BnNew();
    260   r[kRSANumWords * 2] = 1;
    261 
    262   uint32* rr;
    263   BnDiv(r, n, NULL, &rr);
    264 
    265   for (size_t i = 0; i < kRSANumWords; ++i) {
    266     pkey.n[i] = n[i];
    267     pkey.rr[i] = rr[i];
    268   }
    269 
    270   BnFree(n);
    271   BnFree(r);
    272   BnFree(rr);
    273 
    274   std::string output;
    275   std::string input(reinterpret_cast<char*>(&pkey), sizeof(pkey));
    276   base::Base64Encode(input, &output);
    277   return output;
    278 }
    279 
    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();
    287   }
    288   return std::string(result.begin(), result.end());
    289 }
    290