| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/devtools/device/usb/android_rsa.h" | 5 #include "chrome/browser/devtools/device/usb/android_rsa.h" |
| 6 | 6 |
| 7 #include <stdint.h> |
| 8 |
| 9 #include <limits> |
| 10 |
| 7 #include "base/base64.h" | 11 #include "base/base64.h" |
| 8 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 9 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 10 #include "chrome/common/pref_names.h" | 14 #include "chrome/common/pref_names.h" |
| 11 #include "components/syncable_prefs/pref_service_syncable.h" | 15 #include "components/syncable_prefs/pref_service_syncable.h" |
| 12 #include "crypto/rsa_private_key.h" | 16 #include "crypto/rsa_private_key.h" |
| 13 #include "crypto/signature_creator.h" | 17 #include "crypto/signature_creator.h" |
| 14 #include "net/cert/asn1_util.h" | 18 #include "net/cert/asn1_util.h" |
| 15 | 19 |
| 16 namespace { | 20 namespace { |
| 17 | 21 |
| 18 const size_t kRSANumWords = 64; | 22 const size_t kRSANumWords = 64; |
| 19 const size_t kBigIntSize = 1024; | 23 const size_t kBigIntSize = 1024; |
| 20 | 24 |
| 21 static const char kDummyRSAPublicKey[] = | 25 static const char kDummyRSAPublicKey[] = |
| 22 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6OSJ64q+ZLg7VV2ojEPh5TRbYjwbT" | 26 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6OSJ64q+ZLg7VV2ojEPh5TRbYjwbT" |
| 23 "TifSPeFIV45CHnbTWYiiIn41wrozpYizNsMWZUBjdah1N78WVhbyDrnr0bDgFp+gXjfVppa3I" | 27 "TifSPeFIV45CHnbTWYiiIn41wrozpYizNsMWZUBjdah1N78WVhbyDrnr0bDgFp+gXjfVppa3I" |
| 24 "gjiohEcemK3omXi3GDMK8ERhriLUKfQS842SXtQ8I+KoZtpCkGM//0h7+P+Rhm0WwdipIRMhR" | 28 "gjiohEcemK3omXi3GDMK8ERhriLUKfQS842SXtQ8I+KoZtpCkGM//0h7+P+Rhm0WwdipIRMhR" |
| 25 "8haNAeyDiiCvqJcvevv2T52vqKtS3aWz+GjaTJJLVWydEpz9WdvWeLfFVhe2ZnqwwZNa30Qoj" | 29 "8haNAeyDiiCvqJcvevv2T52vqKtS3aWz+GjaTJJLVWydEpz9WdvWeLfFVhe2ZnqwwZNa30Qoj" |
| 26 "fsnvjaMwK2MU7uYfRBPuvLyK5QESWBpArNDd6ULl8Y+NU6kwNOVDc87OASCVEM1gw2IMi2mo2" | 30 "fsnvjaMwK2MU7uYfRBPuvLyK5QESWBpArNDd6ULl8Y+NU6kwNOVDc87OASCVEM1gw2IMi2mo2" |
| 27 "WO5ywp0UWRiGZCkK+wOFQIDAQAB"; | 31 "WO5ywp0UWRiGZCkK+wOFQIDAQAB"; |
| 28 | 32 |
| 29 typedef struct RSAPublicKey { | 33 typedef struct RSAPublicKey { |
| 30 int len; // Length of n[] in number of uint32 | 34 int len; // Length of n[] in number of uint32_t |
| 31 uint32 n0inv; // -1 / n[0] mod 2^32 | 35 uint32_t n0inv; // -1 / n[0] mod 2^32 |
| 32 uint32 n[kRSANumWords]; // modulus as little endian array | 36 uint32_t n[kRSANumWords]; // modulus as little endian array |
| 33 uint32 rr[kRSANumWords]; // R^2 as little endian array | 37 uint32_t rr[kRSANumWords]; // R^2 as little endian array |
| 34 int exponent; // 3 or 65537 | 38 int exponent; // 3 or 65537 |
| 35 } RSAPublicKey; | 39 } RSAPublicKey; |
| 36 | 40 |
| 37 // http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm | 41 // http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm |
| 38 // a * x + b * y = gcd(a, b) = d | 42 // a * x + b * y = gcd(a, b) = d |
| 39 void ExtendedEuclid(uint64 a, uint64 b, uint64 *x, uint64 *y, uint64 *d) { | 43 void ExtendedEuclid(uint64_t a, |
| 40 uint64 x1 = 0, x2 = 1, y1 = 1, y2 = 0; | 44 uint64_t b, |
| 45 uint64_t* x, |
| 46 uint64_t* y, |
| 47 uint64_t* d) { |
| 48 uint64_t x1 = 0, x2 = 1, y1 = 1, y2 = 0; |
| 41 | 49 |
| 42 while (b > 0) { | 50 while (b > 0) { |
| 43 uint64 q = a / b; | 51 uint64_t q = a / b; |
| 44 uint64 r = a % b; | 52 uint64_t r = a % b; |
| 45 *x = x2 - q * x1; | 53 *x = x2 - q * x1; |
| 46 *y = y2 - q * y1; | 54 *y = y2 - q * y1; |
| 47 a = b; | 55 a = b; |
| 48 b = r; | 56 b = r; |
| 49 x2 = x1; | 57 x2 = x1; |
| 50 x1 = *x; | 58 x1 = *x; |
| 51 y2 = y1; | 59 y2 = y1; |
| 52 y1 = *y; | 60 y1 = *y; |
| 53 } | 61 } |
| 54 | 62 |
| 55 *d = a; | 63 *d = a; |
| 56 *x = x2; | 64 *x = x2; |
| 57 *y = y2; | 65 *y = y2; |
| 58 } | 66 } |
| 59 | 67 |
| 60 uint32 ModInverse(uint64 a, uint64 m) | 68 uint32_t ModInverse(uint64_t a, uint64_t m) { |
| 61 { | 69 uint64_t d, x, y; |
| 62 uint64 d, x, y; | |
| 63 ExtendedEuclid(a, m, &x, &y, &d); | 70 ExtendedEuclid(a, m, &x, &y, &d); |
| 64 if (d == 1) | 71 if (d == 1) |
| 65 return static_cast<uint32>(x); | 72 return static_cast<uint32_t>(x); |
| 66 return 0; | 73 return 0; |
| 67 } | 74 } |
| 68 | 75 |
| 69 uint32* BnNew() { | 76 uint32_t* BnNew() { |
| 70 uint32* result = new uint32[kBigIntSize]; | 77 uint32_t* result = new uint32_t[kBigIntSize]; |
| 71 memset(result, 0, kBigIntSize * sizeof(uint32)); | 78 memset(result, 0, kBigIntSize * sizeof(uint32_t)); |
| 72 return result; | 79 return result; |
| 73 } | 80 } |
| 74 | 81 |
| 75 void BnFree(uint32* a) { | 82 void BnFree(uint32_t* a) { |
| 76 delete[] a; | 83 delete[] a; |
| 77 } | 84 } |
| 78 | 85 |
| 79 uint32* BnCopy(uint32* a) { | 86 uint32_t* BnCopy(uint32_t* a) { |
| 80 uint32* result = new uint32[kBigIntSize]; | 87 uint32_t* result = new uint32_t[kBigIntSize]; |
| 81 memcpy(result, a, kBigIntSize * sizeof(uint32)); | 88 memcpy(result, a, kBigIntSize * sizeof(uint32_t)); |
| 82 return result; | 89 return result; |
| 83 } | 90 } |
| 84 | 91 |
| 85 uint32* BnMul(uint32* a, uint32 b) { | 92 uint32_t* BnMul(uint32_t* a, uint32_t b) { |
| 86 uint32* result = BnNew(); | 93 uint32_t* result = BnNew(); |
| 87 uint64 carry_over = 0; | 94 uint64_t carry_over = 0; |
| 88 for (size_t i = 0; i < kBigIntSize; ++i) { | 95 for (size_t i = 0; i < kBigIntSize; ++i) { |
| 89 carry_over += static_cast<uint64>(a[i]) * b; | 96 carry_over += static_cast<uint64_t>(a[i]) * b; |
| 90 result[i] = carry_over & kuint32max; | 97 result[i] = carry_over & std::numeric_limits<uint32_t>::max(); |
| 91 carry_over >>= 32; | 98 carry_over >>= 32; |
| 92 } | 99 } |
| 93 return result; | 100 return result; |
| 94 } | 101 } |
| 95 | 102 |
| 96 void BnSub(uint32* a, uint32* b) { | 103 void BnSub(uint32_t* a, uint32_t* b) { |
| 97 int carry_over = 0; | 104 int carry_over = 0; |
| 98 for (size_t i = 0; i < kBigIntSize; ++i) { | 105 for (size_t i = 0; i < kBigIntSize; ++i) { |
| 99 int64 sub = static_cast<int64>(a[i]) - b[i] - carry_over; | 106 int64_t sub = static_cast<int64_t>(a[i]) - b[i] - carry_over; |
| 100 carry_over = 0; | 107 carry_over = 0; |
| 101 if (sub < 0) { | 108 if (sub < 0) { |
| 102 carry_over = 1; | 109 carry_over = 1; |
| 103 sub += 0x100000000LL; | 110 sub += 0x100000000LL; |
| 104 } | 111 } |
| 105 a[i] = static_cast<uint32>(sub); | 112 a[i] = static_cast<uint32_t>(sub); |
| 106 } | 113 } |
| 107 } | 114 } |
| 108 | 115 |
| 109 void BnLeftShift(uint32* a, int offset) { | 116 void BnLeftShift(uint32_t* a, int offset) { |
| 110 for (int i = kBigIntSize - offset - 1; i >= 0; --i) | 117 for (int i = kBigIntSize - offset - 1; i >= 0; --i) |
| 111 a[i + offset] = a[i]; | 118 a[i + offset] = a[i]; |
| 112 for (int i = 0; i < offset; ++i) | 119 for (int i = 0; i < offset; ++i) |
| 113 a[i] = 0; | 120 a[i] = 0; |
| 114 } | 121 } |
| 115 | 122 |
| 116 int BnCompare(uint32* a, uint32* b) { | 123 int BnCompare(uint32_t* a, uint32_t* b) { |
| 117 for (int i = kBigIntSize - 1; i >= 0; --i) { | 124 for (int i = kBigIntSize - 1; i >= 0; --i) { |
| 118 if (a[i] > b[i]) | 125 if (a[i] > b[i]) |
| 119 return 1; | 126 return 1; |
| 120 if (a[i] < b[i]) | 127 if (a[i] < b[i]) |
| 121 return -1; | 128 return -1; |
| 122 } | 129 } |
| 123 return 0; | 130 return 0; |
| 124 } | 131 } |
| 125 | 132 |
| 126 uint64 BnGuess(uint32* a, uint32* b, uint64 from, uint64 to) { | 133 uint64_t BnGuess(uint32_t* a, uint32_t* b, uint64_t from, uint64_t to) { |
| 127 if (from + 1 >= to) | 134 if (from + 1 >= to) |
| 128 return from; | 135 return from; |
| 129 | 136 |
| 130 uint64 guess = (from + to) / 2; | 137 uint64_t guess = (from + to) / 2; |
| 131 uint32* t = BnMul(b, static_cast<uint32>(guess)); | 138 uint32_t* t = BnMul(b, static_cast<uint32_t>(guess)); |
| 132 int result = BnCompare(a, t); | 139 int result = BnCompare(a, t); |
| 133 BnFree(t); | 140 BnFree(t); |
| 134 if (result > 0) | 141 if (result > 0) |
| 135 return BnGuess(a, b, guess, to); | 142 return BnGuess(a, b, guess, to); |
| 136 if (result < 0) | 143 if (result < 0) |
| 137 return BnGuess(a, b, from, guess); | 144 return BnGuess(a, b, from, guess); |
| 138 return guess; | 145 return guess; |
| 139 } | 146 } |
| 140 | 147 |
| 141 void BnDiv(uint32* a, uint32* b, uint32** pq, uint32** pr) { | 148 void BnDiv(uint32_t* a, uint32_t* b, uint32_t** pq, uint32_t** pr) { |
| 142 if (BnCompare(a, b) < 0) { | 149 if (BnCompare(a, b) < 0) { |
| 143 if (pq) | 150 if (pq) |
| 144 *pq = BnNew(); | 151 *pq = BnNew(); |
| 145 if (pr) | 152 if (pr) |
| 146 *pr = BnCopy(a); | 153 *pr = BnCopy(a); |
| 147 return; | 154 return; |
| 148 } | 155 } |
| 149 | 156 |
| 150 int oa = kBigIntSize - 1; | 157 int oa = kBigIntSize - 1; |
| 151 int ob = kBigIntSize - 1; | 158 int ob = kBigIntSize - 1; |
| 152 for (; oa > 0 && !a[oa]; --oa) {} | 159 for (; oa > 0 && !a[oa]; --oa) {} |
| 153 for (; ob > 0 && !b[ob]; --ob) {} | 160 for (; ob > 0 && !b[ob]; --ob) {} |
| 154 uint32* q = BnNew(); | 161 uint32_t* q = BnNew(); |
| 155 uint32* ca = BnCopy(a); | 162 uint32_t* ca = BnCopy(a); |
| 156 | 163 |
| 157 int digit = a[oa] < b[ob] ? oa - ob - 1 : oa - ob; | 164 int digit = a[oa] < b[ob] ? oa - ob - 1 : oa - ob; |
| 158 | 165 |
| 159 for (; digit >= 0; --digit) { | 166 for (; digit >= 0; --digit) { |
| 160 uint32* shifted_b = BnCopy(b); | 167 uint32_t* shifted_b = BnCopy(b); |
| 161 BnLeftShift(shifted_b, digit); | 168 BnLeftShift(shifted_b, digit); |
| 162 uint32 value = static_cast<uint32>( | 169 uint32_t value = static_cast<uint32_t>(BnGuess( |
| 163 BnGuess(ca, shifted_b, 0, static_cast<uint64>(kuint32max) + 1)); | 170 ca, shifted_b, 0, |
| 171 static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1)); |
| 164 q[digit] = value; | 172 q[digit] = value; |
| 165 uint32* t = BnMul(shifted_b, value); | 173 uint32_t* t = BnMul(shifted_b, value); |
| 166 BnSub(ca, t); | 174 BnSub(ca, t); |
| 167 BnFree(t); | 175 BnFree(t); |
| 168 BnFree(shifted_b); | 176 BnFree(shifted_b); |
| 169 } | 177 } |
| 170 | 178 |
| 171 if (pq) | 179 if (pq) |
| 172 *pq = q; | 180 *pq = q; |
| 173 else | 181 else |
| 174 BnFree(q); | 182 BnFree(q); |
| 175 if (pr) | 183 if (pr) |
| 176 *pr = ca; | 184 *pr = ca; |
| 177 else | 185 else |
| 178 BnFree(ca); | 186 BnFree(ca); |
| 179 } | 187 } |
| 180 | 188 |
| 181 } // namespace | 189 } // namespace |
| 182 | 190 |
| 183 crypto::RSAPrivateKey* AndroidRSAPrivateKey(Profile* profile) { | 191 crypto::RSAPrivateKey* AndroidRSAPrivateKey(Profile* profile) { |
| 184 std::string encoded_key = | 192 std::string encoded_key = |
| 185 profile->GetPrefs()->GetString(prefs::kDevToolsAdbKey); | 193 profile->GetPrefs()->GetString(prefs::kDevToolsAdbKey); |
| 186 std::string decoded_key; | 194 std::string decoded_key; |
| 187 scoped_ptr<crypto::RSAPrivateKey> key; | 195 scoped_ptr<crypto::RSAPrivateKey> key; |
| 188 if (!encoded_key.empty() && base::Base64Decode(encoded_key, &decoded_key)) { | 196 if (!encoded_key.empty() && base::Base64Decode(encoded_key, &decoded_key)) { |
| 189 std::vector<uint8> key_info(decoded_key.begin(), decoded_key.end()); | 197 std::vector<uint8_t> key_info(decoded_key.begin(), decoded_key.end()); |
| 190 key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info)); | 198 key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info)); |
| 191 } | 199 } |
| 192 if (!key) { | 200 if (!key) { |
| 193 key.reset(crypto::RSAPrivateKey::Create(2048)); | 201 key.reset(crypto::RSAPrivateKey::Create(2048)); |
| 194 std::vector<uint8> key_info; | 202 std::vector<uint8_t> key_info; |
| 195 if (!key || !key->ExportPrivateKey(&key_info)) | 203 if (!key || !key->ExportPrivateKey(&key_info)) |
| 196 return NULL; | 204 return NULL; |
| 197 | 205 |
| 198 std::string key_string(key_info.begin(), key_info.end()); | 206 std::string key_string(key_info.begin(), key_info.end()); |
| 199 base::Base64Encode(key_string, &encoded_key); | 207 base::Base64Encode(key_string, &encoded_key); |
| 200 profile->GetPrefs()->SetString(prefs::kDevToolsAdbKey, | 208 profile->GetPrefs()->SetString(prefs::kDevToolsAdbKey, |
| 201 encoded_key); | 209 encoded_key); |
| 202 } | 210 } |
| 203 return key.release(); | 211 return key.release(); |
| 204 } | 212 } |
| 205 | 213 |
| 206 std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) { | 214 std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) { |
| 207 std::vector<uint8> public_key; | 215 std::vector<uint8_t> public_key; |
| 208 if (!key) | 216 if (!key) |
| 209 return kDummyRSAPublicKey; | 217 return kDummyRSAPublicKey; |
| 210 | 218 |
| 211 key->ExportPublicKey(&public_key); | 219 key->ExportPublicKey(&public_key); |
| 212 std::string asn1(public_key.begin(), public_key.end()); | 220 std::string asn1(public_key.begin(), public_key.end()); |
| 213 | 221 |
| 214 base::StringPiece pk; | 222 base::StringPiece pk; |
| 215 if (!net::asn1::ExtractSubjectPublicKeyFromSPKI(asn1, &pk)) | 223 if (!net::asn1::ExtractSubjectPublicKeyFromSPKI(asn1, &pk)) |
| 216 return kDummyRSAPublicKey; | 224 return kDummyRSAPublicKey; |
| 217 | 225 |
| 218 // Skip 10 byte asn1 prefix to the modulus. | 226 // Skip 10 byte asn1 prefix to the modulus. |
| 219 std::vector<uint8> pk_data(pk.data() + 10, pk.data() + pk.length()); | 227 std::vector<uint8_t> pk_data(pk.data() + 10, pk.data() + pk.length()); |
| 220 uint32* n = BnNew(); | 228 uint32_t* n = BnNew(); |
| 221 for (size_t i = 0; i < kRSANumWords; ++i) { | 229 for (size_t i = 0; i < kRSANumWords; ++i) { |
| 222 uint32 t = pk_data[4 * i]; | 230 uint32_t t = pk_data[4 * i]; |
| 223 t = t << 8; | 231 t = t << 8; |
| 224 t += pk_data[4 * i + 1]; | 232 t += pk_data[4 * i + 1]; |
| 225 t = t << 8; | 233 t = t << 8; |
| 226 t += pk_data[4 * i + 2]; | 234 t += pk_data[4 * i + 2]; |
| 227 t = t << 8; | 235 t = t << 8; |
| 228 t += pk_data[4 * i + 3]; | 236 t += pk_data[4 * i + 3]; |
| 229 n[kRSANumWords - i - 1] = t; | 237 n[kRSANumWords - i - 1] = t; |
| 230 } | 238 } |
| 231 uint64 n0 = n[0]; | 239 uint64_t n0 = n[0]; |
| 232 | 240 |
| 233 RSAPublicKey pkey; | 241 RSAPublicKey pkey; |
| 234 pkey.len = kRSANumWords; | 242 pkey.len = kRSANumWords; |
| 235 pkey.exponent = 65537; // Fixed public exponent | 243 pkey.exponent = 65537; // Fixed public exponent |
| 236 pkey.n0inv = 0 - ModInverse(n0, 0x100000000LL); | 244 pkey.n0inv = 0 - ModInverse(n0, 0x100000000LL); |
| 237 if (pkey.n0inv == 0) | 245 if (pkey.n0inv == 0) |
| 238 return kDummyRSAPublicKey; | 246 return kDummyRSAPublicKey; |
| 239 | 247 |
| 240 uint32* r = BnNew(); | 248 uint32_t* r = BnNew(); |
| 241 r[kRSANumWords * 2] = 1; | 249 r[kRSANumWords * 2] = 1; |
| 242 | 250 |
| 243 uint32* rr; | 251 uint32_t* rr; |
| 244 BnDiv(r, n, NULL, &rr); | 252 BnDiv(r, n, NULL, &rr); |
| 245 | 253 |
| 246 for (size_t i = 0; i < kRSANumWords; ++i) { | 254 for (size_t i = 0; i < kRSANumWords; ++i) { |
| 247 pkey.n[i] = n[i]; | 255 pkey.n[i] = n[i]; |
| 248 pkey.rr[i] = rr[i]; | 256 pkey.rr[i] = rr[i]; |
| 249 } | 257 } |
| 250 | 258 |
| 251 BnFree(n); | 259 BnFree(n); |
| 252 BnFree(r); | 260 BnFree(r); |
| 253 BnFree(rr); | 261 BnFree(rr); |
| 254 | 262 |
| 255 std::string output; | 263 std::string output; |
| 256 std::string input(reinterpret_cast<char*>(&pkey), sizeof(pkey)); | 264 std::string input(reinterpret_cast<char*>(&pkey), sizeof(pkey)); |
| 257 base::Base64Encode(input, &output); | 265 base::Base64Encode(input, &output); |
| 258 return output; | 266 return output; |
| 259 } | 267 } |
| 260 | 268 |
| 261 std::string AndroidRSASign(crypto::RSAPrivateKey* key, | 269 std::string AndroidRSASign(crypto::RSAPrivateKey* key, |
| 262 const std::string& body) { | 270 const std::string& body) { |
| 263 std::vector<uint8> digest(body.begin(), body.end()); | 271 std::vector<uint8_t> digest(body.begin(), body.end()); |
| 264 std::vector<uint8> result; | 272 std::vector<uint8_t> result; |
| 265 if (!crypto::SignatureCreator::Sign(key, crypto::SignatureCreator::SHA1, | 273 if (!crypto::SignatureCreator::Sign(key, crypto::SignatureCreator::SHA1, |
| 266 digest.data(), digest.size(), &result)) { | 274 digest.data(), digest.size(), &result)) { |
| 267 return std::string(); | 275 return std::string(); |
| 268 } | 276 } |
| 269 return std::string(result.begin(), result.end()); | 277 return std::string(result.begin(), result.end()); |
| 270 } | 278 } |
| OLD | NEW |