| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/crypto/rsa_private_key.h" | 5 #include "base/crypto/rsa_private_key.h" |
| 6 | 6 |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 #include <list> | 8 #include <list> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 | 13 |
| 14 | |
| 15 // This file manually encodes and decodes RSA private keys using PrivateKeyInfo | |
| 16 // from PKCS #8 and RSAPrivateKey from PKCS #1. These structures are: | |
| 17 // | |
| 18 // PrivateKeyInfo ::= SEQUENCE { | |
| 19 // version Version, | |
| 20 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, | |
| 21 // privateKey PrivateKey, | |
| 22 // attributes [0] IMPLICIT Attributes OPTIONAL | |
| 23 // } | |
| 24 // | |
| 25 // RSAPrivateKey ::= SEQUENCE { | |
| 26 // version Version, | |
| 27 // modulus INTEGER, | |
| 28 // publicExponent INTEGER, | |
| 29 // privateExponent INTEGER, | |
| 30 // prime1 INTEGER, | |
| 31 // prime2 INTEGER, | |
| 32 // exponent1 INTEGER, | |
| 33 // exponent2 INTEGER, | |
| 34 // coefficient INTEGER | |
| 35 // } | |
| 36 | |
| 37 | |
| 38 namespace { | 14 namespace { |
| 39 | 15 // Helper for error handling during key import. |
| 40 // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8. | |
| 41 const uint8 kRsaAlgorithmIdentifier[] = { | |
| 42 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, | |
| 43 0x05, 0x00 | |
| 44 }; | |
| 45 | |
| 46 // ASN.1 tags for some types we use. | |
| 47 const uint8 kSequenceTag = 0x30; | |
| 48 const uint8 kIntegerTag = 0x02; | |
| 49 const uint8 kNullTag = 0x05; | |
| 50 const uint8 kOctetStringTag = 0x04; | |
| 51 | |
| 52 // Helper function to prepend an array of bytes into a list, reversing their | |
| 53 // order. This is needed because ASN.1 integers are big-endian, while CryptoAPI | |
| 54 // uses little-endian. | |
| 55 static void PrependBytesInReverseOrder(uint8* val, int num_bytes, | |
| 56 std::list<uint8>* data) { | |
| 57 for (int i = 0; i < num_bytes; ++i) | |
| 58 data->push_front(val[i]); | |
| 59 } | |
| 60 | |
| 61 // Helper to prepend an ASN.1 length field. | |
| 62 static void PrependLength(size_t size, std::list<uint8>* data) { | |
| 63 // The high bit is used to indicate whether additional octets are needed to | |
| 64 // represent the length. | |
| 65 if (size < 0x80) { | |
| 66 data->push_front(static_cast<uint8>(size)); | |
| 67 } else { | |
| 68 uint8 num_bytes = 0; | |
| 69 while (size > 0) { | |
| 70 data->push_front(static_cast<uint8>(size & 0xFF)); | |
| 71 size >>= 8; | |
| 72 num_bytes++; | |
| 73 } | |
| 74 CHECK(num_bytes <= 4); | |
| 75 data->push_front(0x80 | num_bytes); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 // Helper to prepend an ASN.1 type header. | |
| 80 static void PrependTypeHeaderAndLength(uint8 type, uint32 length, | |
| 81 std::list<uint8>* output) { | |
| 82 PrependLength(length, output); | |
| 83 output->push_front(type); | |
| 84 } | |
| 85 | |
| 86 // Helper to prepend an ASN.1 integer. | |
| 87 static void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data) { | |
| 88 // Skip trailing null bytes off the MSB end, which is the tail since the input | |
| 89 // is little endian. | |
| 90 while (num_bytes > 1 && val[num_bytes - 1] == 0x00) | |
| 91 num_bytes--; | |
| 92 | |
| 93 PrependBytesInReverseOrder(val, num_bytes, data); | |
| 94 | |
| 95 // If the MSB is set, we need to add an extra null byte, otherwise the integer | |
| 96 // could be interpreted as negative. | |
| 97 if ((val[num_bytes - 1] & 0x80) != 0) { | |
| 98 data->push_front(0x00); | |
| 99 num_bytes++; | |
| 100 } | |
| 101 | |
| 102 PrependTypeHeaderAndLength(kIntegerTag, num_bytes, data); | |
| 103 } | |
| 104 | |
| 105 // Helper for error handling during key import. | |
| 106 #define READ_ASSERT(truth) \ | 16 #define READ_ASSERT(truth) \ |
| 107 if (!(truth)) { \ | 17 if (!(truth)) { \ |
| 108 NOTREACHED(); \ | 18 NOTREACHED(); \ |
| 109 return false; \ | 19 return false; \ |
| 110 } | 20 } |
| 111 | |
| 112 // Read an ASN.1 length field. This also checks that the length does not extend | |
| 113 // beyond |end|. | |
| 114 static bool ReadLength(uint8** pos, uint8* end, uint32* result) { | |
| 115 READ_ASSERT(*pos < end); | |
| 116 int length = 0; | |
| 117 | |
| 118 // If the MSB is not set, the length is just the byte itself. | |
| 119 if (!(**pos & 0x80)) { | |
| 120 length = **pos; | |
| 121 (*pos)++; | |
| 122 } else { | |
| 123 // Otherwise, the lower 7 indicate the length of the length. | |
| 124 int length_of_length = **pos & 0x7F; | |
| 125 READ_ASSERT(length_of_length <= 4); | |
| 126 (*pos)++; | |
| 127 READ_ASSERT(*pos + length_of_length < end); | |
| 128 | |
| 129 length = 0; | |
| 130 for (int i = 0; i < length_of_length; ++i) { | |
| 131 length <<= 8; | |
| 132 length |= **pos; | |
| 133 (*pos)++; | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 READ_ASSERT(*pos + length <= end); | |
| 138 if (result) *result = length; | |
| 139 return true; | |
| 140 } | |
| 141 | |
| 142 // Read an ASN.1 type header and its length. | |
| 143 static bool ReadTypeHeaderAndLength(uint8** pos, uint8* end, | |
| 144 uint8 expected_tag, uint32* length) { | |
| 145 READ_ASSERT(*pos < end); | |
| 146 READ_ASSERT(**pos == expected_tag); | |
| 147 (*pos)++; | |
| 148 | |
| 149 return ReadLength(pos, end, length); | |
| 150 } | |
| 151 | |
| 152 // Read an ASN.1 sequence declaration. This consumes the type header and length | |
| 153 // field, but not the contents of the sequence. | |
| 154 static bool ReadSequence(uint8** pos, uint8* end) { | |
| 155 return ReadTypeHeaderAndLength(pos, end, kSequenceTag, NULL); | |
| 156 } | |
| 157 | |
| 158 // Read the RSA AlgorithmIdentifier. | |
| 159 static bool ReadAlgorithmIdentifier(uint8** pos, uint8* end) { | |
| 160 READ_ASSERT(*pos + sizeof(kRsaAlgorithmIdentifier) < end); | |
| 161 READ_ASSERT(memcmp(*pos, kRsaAlgorithmIdentifier, | |
| 162 sizeof(kRsaAlgorithmIdentifier)) == 0); | |
| 163 (*pos) += sizeof(kRsaAlgorithmIdentifier); | |
| 164 return true; | |
| 165 } | |
| 166 | |
| 167 // Read one of the two version fields in PrivateKeyInfo. | |
| 168 static bool ReadVersion(uint8** pos, uint8* end) { | |
| 169 uint32 length = 0; | |
| 170 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length)) | |
| 171 return false; | |
| 172 | |
| 173 // The version should be zero. | |
| 174 for (uint32 i = 0; i < length; ++i) { | |
| 175 READ_ASSERT(**pos == 0x00); | |
| 176 (*pos)++; | |
| 177 } | |
| 178 | |
| 179 return true; | |
| 180 } | |
| 181 | |
| 182 // Read an ASN.1 integer. | |
| 183 static bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out) { | |
| 184 uint32 length = 0; | |
| 185 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length)) | |
| 186 return false; | |
| 187 | |
| 188 // Read the bytes out in reverse order because of endianness. | |
| 189 for (uint32 i = length - 1; i > 0; --i) | |
| 190 out->push_back(*(*pos + i)); | |
| 191 | |
| 192 // The last byte can be zero to force positiveness. We can ignore this. | |
| 193 if (**pos != 0x00) | |
| 194 out->push_back(**pos); | |
| 195 | |
| 196 (*pos) += length; | |
| 197 return true; | |
| 198 } | |
| 199 | |
| 200 static bool ReadIntegerWithExpectedSize(uint8** pos, uint8* end, | |
| 201 int expected_size, | |
| 202 std::vector<uint8>* out) { | |
| 203 if (!ReadInteger(pos, end, out)) | |
| 204 return false; | |
| 205 | |
| 206 if (out->size() == expected_size + 1) { | |
| 207 READ_ASSERT(out->back() == 0x00); | |
| 208 out->pop_back(); | |
| 209 } else { | |
| 210 READ_ASSERT(out->size() <= expected_size); | |
| 211 } | |
| 212 | |
| 213 // Pad out any missing bytes with null. | |
| 214 for (size_t i = out->size(); i < expected_size; ++i) | |
| 215 out->push_back(0x00); | |
| 216 | |
| 217 return true; | |
| 218 } | |
| 219 | |
| 220 } // namespace | 21 } // namespace |
| 221 | 22 |
| 222 | |
| 223 namespace base { | 23 namespace base { |
| 224 | 24 |
| 225 // static | 25 // static |
| 226 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | 26 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { |
| 227 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | 27 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
| 228 if (!result->InitProvider()) | 28 if (!result->InitProvider()) |
| 229 return NULL; | 29 return NULL; |
| 230 | 30 |
| 231 DWORD flags = CRYPT_EXPORTABLE; | 31 DWORD flags = CRYPT_EXPORTABLE; |
| 232 | 32 |
| 233 // The size is encoded as the upper 16 bits of the flags. :: sigh ::. | 33 // The size is encoded as the upper 16 bits of the flags. :: sigh ::. |
| 234 flags |= (num_bits << 16); | 34 flags |= (num_bits << 16); |
| 235 if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags, &result->key_)) | 35 if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags, &result->key_)) |
| 236 return NULL; | 36 return NULL; |
| 237 | 37 |
| 238 return result.release(); | 38 return result.release(); |
| 239 } | 39 } |
| 240 | 40 |
| 241 // static | 41 // static |
| 242 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( | 42 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( |
| 243 const std::vector<uint8>& input) { | 43 const std::vector<uint8>& input) { |
| 244 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | 44 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
| 245 if (!result->InitProvider()) | 45 if (!result->InitProvider()) |
| 246 return NULL; | 46 return NULL; |
| 247 | 47 |
| 248 uint8* src = const_cast<uint8*>(&input.front()); | 48 PrivateKeyInfoCodec pki(false); // Little-Endian |
| 249 uint8* end = src + input.size(); | 49 pki.Import(input); |
| 250 int version = -1; | |
| 251 std::vector<uint8> modulus; | |
| 252 std::vector<uint8> public_exponent; | |
| 253 std::vector<uint8> private_exponent; | |
| 254 std::vector<uint8> prime1; | |
| 255 std::vector<uint8> prime2; | |
| 256 std::vector<uint8> exponent1; | |
| 257 std::vector<uint8> exponent2; | |
| 258 std::vector<uint8> coefficient; | |
| 259 | 50 |
| 260 if (!ReadSequence(&src, end) || | 51 int blob_size = sizeof(PUBLICKEYSTRUC) + |
| 261 !ReadVersion(&src, end) || | 52 sizeof(RSAPUBKEY) + |
| 262 !ReadAlgorithmIdentifier(&src, end) || | 53 pki.modulus()->size() + |
| 263 !ReadTypeHeaderAndLength(&src, end, kOctetStringTag, NULL) || | 54 pki.prime1()->size() + |
| 264 !ReadSequence(&src, end) || | 55 pki.prime2()->size() + |
| 265 !ReadVersion(&src, end) || | 56 pki.exponent1()->size() + |
| 266 !ReadInteger(&src, end, &modulus)) | 57 pki.exponent2()->size() + |
| 267 return false; | 58 pki.coefficient()->size() + |
| 268 | 59 pki.private_exponent()->size(); |
| 269 int mod_size = modulus.size(); | |
| 270 READ_ASSERT(mod_size % 2 == 0); | |
| 271 int primes_size = mod_size / 2; | |
| 272 | |
| 273 if (!ReadIntegerWithExpectedSize(&src, end, 4, &public_exponent) || | |
| 274 !ReadIntegerWithExpectedSize(&src, end, mod_size, &private_exponent) || | |
| 275 !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime1) || | |
| 276 !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime2) || | |
| 277 !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent1) || | |
| 278 !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent2) || | |
| 279 !ReadIntegerWithExpectedSize(&src, end, primes_size, &coefficient)) | |
| 280 return false; | |
| 281 | |
| 282 READ_ASSERT(src == end); | |
| 283 | |
| 284 int blob_size = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + modulus.size() + | |
| 285 prime1.size() + prime2.size() + | |
| 286 exponent1.size() + exponent2.size() + | |
| 287 coefficient.size() + private_exponent.size(); | |
| 288 scoped_array<BYTE> blob(new BYTE[blob_size]); | 60 scoped_array<BYTE> blob(new BYTE[blob_size]); |
| 289 | 61 |
| 290 uint8* dest = blob.get(); | 62 uint8* dest = blob.get(); |
| 291 PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest); | 63 PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest); |
| 292 public_key_struc->bType = PRIVATEKEYBLOB; | 64 public_key_struc->bType = PRIVATEKEYBLOB; |
| 293 public_key_struc->bVersion = 0x02; | 65 public_key_struc->bVersion = 0x02; |
| 294 public_key_struc->reserved = 0; | 66 public_key_struc->reserved = 0; |
| 295 public_key_struc->aiKeyAlg = CALG_RSA_SIGN; | 67 public_key_struc->aiKeyAlg = CALG_RSA_SIGN; |
| 296 dest += sizeof(PUBLICKEYSTRUC); | 68 dest += sizeof(PUBLICKEYSTRUC); |
| 297 | 69 |
| 298 RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest); | 70 RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest); |
| 299 rsa_pub_key->magic = 0x32415352; | 71 rsa_pub_key->magic = 0x32415352; |
| 300 rsa_pub_key->bitlen = modulus.size() * 8; | 72 rsa_pub_key->bitlen = pki.modulus()->size() * 8; |
| 301 int public_exponent_int = 0; | 73 int public_exponent_int = 0; |
| 302 for (size_t i = public_exponent.size(); i > 0; --i) { | 74 for (size_t i = pki.public_exponent()->size(); i > 0; --i) { |
| 303 public_exponent_int <<= 8; | 75 public_exponent_int <<= 8; |
| 304 public_exponent_int |= public_exponent[i - 1]; | 76 public_exponent_int |= (*pki.public_exponent())[i - 1]; |
| 305 } | 77 } |
| 306 rsa_pub_key->pubexp = public_exponent_int; | 78 rsa_pub_key->pubexp = public_exponent_int; |
| 307 dest += sizeof(RSAPUBKEY); | 79 dest += sizeof(RSAPUBKEY); |
| 308 | 80 |
| 309 memcpy(dest, &modulus.front(), modulus.size()); | 81 memcpy(dest, &pki.modulus()->front(), pki.modulus()->size()); |
| 310 dest += modulus.size(); | 82 dest += pki.modulus()->size(); |
| 311 memcpy(dest, &prime1.front(), prime1.size()); | 83 memcpy(dest, &pki.prime1()->front(), pki.prime1()->size()); |
| 312 dest += prime1.size(); | 84 dest += pki.prime1()->size(); |
| 313 memcpy(dest, &prime2.front(), prime2.size()); | 85 memcpy(dest, &pki.prime2()->front(), pki.prime2()->size()); |
| 314 dest += prime2.size(); | 86 dest += pki.prime2()->size(); |
| 315 memcpy(dest, &exponent1.front(), exponent1.size()); | 87 memcpy(dest, &pki.exponent1()->front(), pki.exponent1()->size()); |
| 316 dest += exponent1.size(); | 88 dest += pki.exponent1()->size(); |
| 317 memcpy(dest, &exponent2.front(), exponent2.size()); | 89 memcpy(dest, &pki.exponent2()->front(), pki.exponent2()->size()); |
| 318 dest += exponent2.size(); | 90 dest += pki.exponent2()->size(); |
| 319 memcpy(dest, &coefficient.front(), coefficient.size()); | 91 memcpy(dest, &pki.coefficient()->front(), pki.coefficient()->size()); |
| 320 dest += coefficient.size(); | 92 dest += pki.coefficient()->size(); |
| 321 memcpy(dest, &private_exponent.front(), private_exponent.size()); | 93 memcpy(dest, &pki.private_exponent()->front(), pki.private_exponent()->size())
; |
| 322 dest += private_exponent.size(); | 94 dest += pki.private_exponent()->size(); |
| 323 | 95 |
| 324 READ_ASSERT(dest == blob.get() + blob_size); | 96 READ_ASSERT(dest == blob.get() + blob_size); |
| 325 if (!CryptImportKey( | 97 if (!CryptImportKey( |
| 326 result->provider_, reinterpret_cast<uint8*>(public_key_struc), blob_size, | 98 result->provider_, reinterpret_cast<uint8*>(public_key_struc), blob_size, |
| 327 NULL, CRYPT_EXPORTABLE, &result->key_)) { | 99 NULL, CRYPT_EXPORTABLE, &result->key_)) { |
| 328 return NULL; | 100 return NULL; |
| 329 } | 101 } |
| 330 | 102 |
| 331 return result.release(); | 103 return result.release(); |
| 332 } | 104 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 uint8* pos = blob.get(); | 140 uint8* pos = blob.get(); |
| 369 PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos); | 141 PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos); |
| 370 pos += sizeof(PUBLICKEYSTRUC); | 142 pos += sizeof(PUBLICKEYSTRUC); |
| 371 | 143 |
| 372 RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos); | 144 RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos); |
| 373 pos += sizeof(RSAPUBKEY); | 145 pos += sizeof(RSAPUBKEY); |
| 374 | 146 |
| 375 int mod_size = rsa_pub_key->bitlen / 8; | 147 int mod_size = rsa_pub_key->bitlen / 8; |
| 376 int primes_size = rsa_pub_key->bitlen / 16; | 148 int primes_size = rsa_pub_key->bitlen / 16; |
| 377 | 149 |
| 378 uint8* modulus = pos; | 150 PrivateKeyInfoCodec pki(false); // Little-Endian |
| 151 |
| 152 pki.modulus()->assign(pos, pos + mod_size); |
| 379 pos += mod_size; | 153 pos += mod_size; |
| 380 | 154 |
| 381 uint8* prime1 = pos; | 155 pki.prime1()->assign(pos, pos + primes_size); |
| 382 pos += primes_size; | 156 pos += primes_size; |
| 383 uint8* prime2 = pos; | 157 pki.prime2()->assign(pos, pos + primes_size); |
| 384 pos += primes_size; | 158 pos += primes_size; |
| 385 | 159 |
| 386 uint8* exponent1 = pos; | 160 pki.exponent1()->assign(pos, pos + primes_size); |
| 387 pos += primes_size; | 161 pos += primes_size; |
| 388 uint8* exponent2 = pos; | 162 pki.exponent2()->assign(pos, pos + primes_size); |
| 389 pos += primes_size; | 163 pos += primes_size; |
| 390 | 164 |
| 391 uint8* coefficient = pos; | 165 pki.coefficient()->assign(pos, pos + primes_size); |
| 392 pos += primes_size; | 166 pos += primes_size; |
| 393 | 167 |
| 394 uint8* private_exponent = pos; | 168 pki.private_exponent()->assign(pos, pos + mod_size); |
| 395 pos += mod_size; | 169 pos += mod_size; |
| 396 | 170 |
| 171 pki.public_exponent()->assign(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp), |
| 172 reinterpret_cast<uint8*>(&rsa_pub_key->pubexp) + 4); |
| 173 |
| 397 CHECK((pos - blob_length) == reinterpret_cast<BYTE*>(publickey_struct)); | 174 CHECK((pos - blob_length) == reinterpret_cast<BYTE*>(publickey_struct)); |
| 398 | 175 |
| 399 std::list<uint8> content; | 176 return pki.Export(output); |
| 400 | |
| 401 // Version (always zero) | |
| 402 uint8 version = 0; | |
| 403 | |
| 404 // We build up the output in reverse order to prevent having to do copies to | |
| 405 // figure out the length. | |
| 406 PrependInteger(coefficient, primes_size, &content); | |
| 407 PrependInteger(exponent2, primes_size, &content); | |
| 408 PrependInteger(exponent1, primes_size, &content); | |
| 409 PrependInteger(prime2, primes_size, &content); | |
| 410 PrependInteger(prime1, primes_size, &content); | |
| 411 PrependInteger(private_exponent, mod_size, &content); | |
| 412 PrependInteger(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp), 4, &content); | |
| 413 PrependInteger(modulus, mod_size, &content); | |
| 414 PrependInteger(&version, 1, &content); | |
| 415 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); | |
| 416 PrependTypeHeaderAndLength(kOctetStringTag, content.size(), &content); | |
| 417 | |
| 418 // RSA algorithm OID | |
| 419 for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) | |
| 420 content.push_front(kRsaAlgorithmIdentifier[i - 1]); | |
| 421 | |
| 422 PrependInteger(&version, 1, &content); | |
| 423 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); | |
| 424 | |
| 425 // Copy everying into the output. | |
| 426 output->reserve(content.size()); | |
| 427 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) | |
| 428 output->push_back(*i); | |
| 429 | |
| 430 return true; | |
| 431 } | 177 } |
| 432 | 178 |
| 433 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | 179 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { |
| 434 DWORD key_info_len; | 180 DWORD key_info_len; |
| 435 if (!CryptExportPublicKeyInfo( | 181 if (!CryptExportPublicKeyInfo( |
| 436 provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, | 182 provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, |
| 437 NULL, &key_info_len)) { | 183 NULL, &key_info_len)) { |
| 438 NOTREACHED(); | 184 NOTREACHED(); |
| 439 return false; | 185 return false; |
| 440 } | 186 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 465 return false; | 211 return false; |
| 466 } | 212 } |
| 467 | 213 |
| 468 for (size_t i = 0; i < encoded_length; ++i) | 214 for (size_t i = 0; i < encoded_length; ++i) |
| 469 output->push_back(encoded[i]); | 215 output->push_back(encoded[i]); |
| 470 | 216 |
| 471 return true; | 217 return true; |
| 472 } | 218 } |
| 473 | 219 |
| 474 } // namespace base | 220 } // namespace base |
| OLD | NEW |