| 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 <list> | 7 #include <list> |
| 8 | 8 |
| 9 #include "base/crypto/cssm_init.h" | 9 #include "base/crypto/cssm_init.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
| 12 | 12 |
| 13 namespace { | |
| 14 | |
| 15 // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8. | |
| 16 const uint8 kRsaAlgorithmIdentifier[] = { | |
| 17 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, | |
| 18 0x05, 0x00 | |
| 19 }; | |
| 20 | |
| 21 // ASN.1 tags for some types we use. | |
| 22 const uint8 kSequenceTag = 0x30; | |
| 23 const uint8 kIntegerTag = 0x02; | |
| 24 const uint8 kNullTag = 0x05; | |
| 25 const uint8 kOctetStringTag = 0x04; | |
| 26 const uint8 kBitStringTag = 0x03; | |
| 27 | |
| 28 // Helper for error handling during key import. | |
| 29 #define READ_ASSERT(truth) \ | |
| 30 if (!(truth)) { \ | |
| 31 NOTREACHED(); \ | |
| 32 return false; \ | |
| 33 } | |
| 34 | |
| 35 static void PrependBytesInOrder(uint8* val, int start, int num_bytes, | |
| 36 std::list<uint8>* data) { | |
| 37 while(num_bytes > start) { | |
| 38 --num_bytes; | |
| 39 data->push_front(val[num_bytes]); | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 // Helper to prepend an ASN.1 length field. | |
| 44 static void PrependLength(size_t size, std::list<uint8>* data) { | |
| 45 // The high bit is used to indicate whether additional octets are needed to | |
| 46 // represent the length. | |
| 47 if (size < 0x80) { | |
| 48 data->push_front(static_cast<uint8>(size)); | |
| 49 } else { | |
| 50 uint8 num_bytes = 0; | |
| 51 while (size > 0) { | |
| 52 data->push_front(static_cast<uint8>(size & 0xFF)); | |
| 53 size >>= 8; | |
| 54 num_bytes++; | |
| 55 } | |
| 56 CHECK(num_bytes <= 4); | |
| 57 data->push_front(0x80 | num_bytes); | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 // Helper to prepend an ASN.1 type header. | |
| 62 static void PrependTypeHeaderAndLength(uint8 type, uint32 length, | |
| 63 std::list<uint8>* output) { | |
| 64 PrependLength(length, output); | |
| 65 output->push_front(type); | |
| 66 } | |
| 67 | |
| 68 // Helper to prepend an ASN.1 bit string | |
| 69 static void PrependBitString(uint8* val, int num_bytes, | |
| 70 std::list<uint8>* output) { | |
| 71 // Start with the data. | |
| 72 PrependBytesInOrder(val, 0, num_bytes, output); | |
| 73 // Zero unused bits. | |
| 74 output->push_front(0); | |
| 75 // Add the length. | |
| 76 PrependLength(num_bytes + 1, output); | |
| 77 // Finally, add the bit string tag. | |
| 78 output->push_front(kBitStringTag); | |
| 79 } | |
| 80 | |
| 81 // Helper to prepend an ASN.1 integer. | |
| 82 static void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data) { | |
| 83 // ASN.1 integers are unpadded byte arrays, so skip any null padding bytes | |
| 84 // from the most-significant end of the integer. | |
| 85 int start = 0; | |
| 86 while (start < (num_bytes - 1) && val[start] == 0x00) | |
| 87 start++; | |
| 88 | |
| 89 PrependBytesInOrder(val, start, num_bytes, data); | |
| 90 | |
| 91 // ASN.1 integers are signed. To encode a positive integer whose sign bit | |
| 92 // (the most significant bit) would otherwise be set and make the number | |
| 93 // negative, ASN.1 requires a leading null byte to force the integer to be | |
| 94 // positive. | |
| 95 if ((val[start] & 0x80) != 0) { | |
| 96 data->push_front(0x00); | |
| 97 num_bytes++; | |
| 98 } | |
| 99 | |
| 100 PrependTypeHeaderAndLength(kIntegerTag, num_bytes, data); | |
| 101 } | |
| 102 | |
| 103 // Read an ASN.1 length field. This also checks that the length does not extend | |
| 104 // beyond |end|. | |
| 105 static bool ReadLength(uint8** pos, uint8* end, uint32* result) { | |
| 106 READ_ASSERT(*pos < end); | |
| 107 int length = 0; | |
| 108 | |
| 109 // If the MSB is not set, the length is just the byte itself. | |
| 110 if (!(**pos & 0x80)) { | |
| 111 length = **pos; | |
| 112 (*pos)++; | |
| 113 } else { | |
| 114 // Otherwise, the lower 7 indicate the length of the length. | |
| 115 int length_of_length = **pos & 0x7F; | |
| 116 READ_ASSERT(length_of_length <= 4); | |
| 117 (*pos)++; | |
| 118 READ_ASSERT(*pos + length_of_length < end); | |
| 119 | |
| 120 length = 0; | |
| 121 for (int i = 0; i < length_of_length; ++i) { | |
| 122 length <<= 8; | |
| 123 length |= **pos; | |
| 124 (*pos)++; | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 READ_ASSERT(*pos + length <= end); | |
| 129 if (result) *result = length; | |
| 130 return true; | |
| 131 } | |
| 132 | |
| 133 // Read an ASN.1 type header and its length. | |
| 134 static bool ReadTypeHeaderAndLength(uint8** pos, uint8* end, | |
| 135 uint8 expected_tag, uint32* length) { | |
| 136 READ_ASSERT(*pos < end); | |
| 137 READ_ASSERT(**pos == expected_tag); | |
| 138 (*pos)++; | |
| 139 | |
| 140 return ReadLength(pos, end, length); | |
| 141 } | |
| 142 | |
| 143 // Read an ASN.1 sequence declaration. This consumes the type header and length | |
| 144 // field, but not the contents of the sequence. | |
| 145 static bool ReadSequence(uint8** pos, uint8* end) { | |
| 146 return ReadTypeHeaderAndLength(pos, end, kSequenceTag, NULL); | |
| 147 } | |
| 148 | |
| 149 // Read the RSA AlgorithmIdentifier. | |
| 150 static bool ReadAlgorithmIdentifier(uint8** pos, uint8* end) { | |
| 151 READ_ASSERT(*pos + sizeof(kRsaAlgorithmIdentifier) < end); | |
| 152 READ_ASSERT(memcmp(*pos, kRsaAlgorithmIdentifier, | |
| 153 sizeof(kRsaAlgorithmIdentifier)) == 0); | |
| 154 (*pos) += sizeof(kRsaAlgorithmIdentifier); | |
| 155 return true; | |
| 156 } | |
| 157 | |
| 158 // Read one of the two version fields in PrivateKeyInfo. | |
| 159 static bool ReadVersion(uint8** pos, uint8* end) { | |
| 160 uint32 length = 0; | |
| 161 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length)) | |
| 162 return false; | |
| 163 | |
| 164 // The version should be zero. | |
| 165 for (uint32 i = 0; i < length; ++i) { | |
| 166 READ_ASSERT(**pos == 0x00); | |
| 167 (*pos)++; | |
| 168 } | |
| 169 | |
| 170 return true; | |
| 171 } | |
| 172 | |
| 173 // Read an ASN.1 integer. | |
| 174 static bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out) { | |
| 175 uint32 length = 0; | |
| 176 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length) || !length) | |
| 177 return false; | |
| 178 | |
| 179 // The first byte can be zero to force positiveness. We can ignore this. | |
| 180 if (**pos == 0x00) { | |
| 181 ++(*pos); | |
| 182 --length; | |
| 183 } | |
| 184 | |
| 185 if (length) | |
| 186 out->insert(out->end(), *pos, (*pos) + length); | |
| 187 | |
| 188 (*pos) += length; | |
| 189 return true; | |
| 190 } | |
| 191 | |
| 192 } // namespace | |
| 193 | |
| 194 namespace base { | 13 namespace base { |
| 195 | 14 |
| 196 // static | 15 // static |
| 197 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | 16 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { |
| 198 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | 17 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
| 199 | 18 |
| 200 CSSM_CC_HANDLE cc_handle; | 19 CSSM_CC_HANDLE cc_handle; |
| 201 CSSM_RETURN crtn; | 20 CSSM_RETURN crtn; |
| 202 crtn = CSSM_CSP_CreateKeyGenContext(result->csp_handle(), CSSM_ALGID_RSA, | 21 crtn = CSSM_CSP_CreateKeyGenContext(result->csp_handle(), CSSM_ALGID_RSA, |
| 203 num_bits, NULL, NULL, NULL, NULL, NULL, | 22 num_bits, NULL, NULL, NULL, NULL, NULL, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 if (!key_.KeyData.Data || !key_.KeyData.Length) { | 130 if (!key_.KeyData.Data || !key_.KeyData.Length) { |
| 312 return false; | 131 return false; |
| 313 } | 132 } |
| 314 output->clear(); | 133 output->clear(); |
| 315 output->insert(output->end(), key_.KeyData.Data, | 134 output->insert(output->end(), key_.KeyData.Data, |
| 316 key_.KeyData.Data + key_.KeyData.Length); | 135 key_.KeyData.Data + key_.KeyData.Length); |
| 317 return true; | 136 return true; |
| 318 } | 137 } |
| 319 | 138 |
| 320 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | 139 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { |
| 321 if (!key_.KeyData.Data || !key_.KeyData.Length) { | 140 PrivateKeyInfoCodec private_key_info(true); |
| 322 return false; | 141 std::vector<uint8> private_key_data; |
| 323 } | 142 private_key_data.assign(key_.KeyData.Data, |
| 324 | 143 key_.KeyData.Data + key_.KeyData.Length); |
| 325 // Parse the private key info up to the public key values, ignoring | 144 return (private_key_info.Import(private_key_data) && |
| 326 // the subsequent private key values. | 145 private_key_info.ExportPublicKeyInfo(output)); |
| 327 uint8* src = key_.KeyData.Data; | |
| 328 uint8* end = src + key_.KeyData.Length; | |
| 329 std::vector<uint8> modulus; | |
| 330 std::vector<uint8> public_exponent; | |
| 331 if (!ReadSequence(&src, end) || | |
| 332 !ReadVersion(&src, end) || | |
| 333 !ReadAlgorithmIdentifier(&src, end) || | |
| 334 !ReadTypeHeaderAndLength(&src, end, kOctetStringTag, NULL) || | |
| 335 !ReadSequence(&src, end) || | |
| 336 !ReadVersion(&src, end) || | |
| 337 !ReadInteger(&src, end, &modulus) || | |
| 338 !ReadInteger(&src, end, &public_exponent)) | |
| 339 return false; | |
| 340 | |
| 341 // Create a sequence with the modulus (n) and public exponent (e). | |
| 342 std::list<uint8> content; | |
| 343 PrependInteger(&public_exponent[0], static_cast<int>(public_exponent.size()), | |
| 344 &content); | |
| 345 PrependInteger(&modulus[0], static_cast<int>(modulus.size()), &content); | |
| 346 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); | |
| 347 | |
| 348 // Copy the sequence with n and e into a buffer. | |
| 349 std::vector<uint8> bit_string; | |
| 350 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) | |
| 351 bit_string.push_back(*i); | |
| 352 content.clear(); | |
| 353 // Add the sequence as the contents of a bit string. | |
| 354 PrependBitString(&bit_string[0], static_cast<int>(bit_string.size()), | |
| 355 &content); | |
| 356 | |
| 357 // Add the RSA algorithm OID. | |
| 358 for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) | |
| 359 content.push_front(kRsaAlgorithmIdentifier[i - 1]); | |
| 360 | |
| 361 // Finally, wrap everything in a sequence. | |
| 362 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); | |
| 363 | |
| 364 // Copy everything into the output. | |
| 365 output->reserve(content.size()); | |
| 366 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) | |
| 367 output->push_back(*i); | |
| 368 | |
| 369 return true; | |
| 370 } | 146 } |
| 371 | 147 |
| 372 } // namespace base | 148 } // namespace base |
| OLD | NEW |