1 // Copyright (c) 2011 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 "crypto/rsa_private_key.h" 6 7 #include <algorithm> 8 #include <list> 9 10 #include "base/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/string_util.h" 13 14 // This file manually encodes and decodes RSA private keys using PrivateKeyInfo 15 // from PKCS #8 and RSAPrivateKey from PKCS #1. These structures are: 16 // 17 // PrivateKeyInfo ::= SEQUENCE { 18 // version Version, 19 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, 20 // privateKey PrivateKey, 21 // attributes [0] IMPLICIT Attributes OPTIONAL 22 // } 23 // 24 // RSAPrivateKey ::= SEQUENCE { 25 // version Version, 26 // modulus INTEGER, 27 // publicExponent INTEGER, 28 // privateExponent INTEGER, 29 // prime1 INTEGER, 30 // prime2 INTEGER, 31 // exponent1 INTEGER, 32 // exponent2 INTEGER, 33 // coefficient INTEGER 34 // } 35 36 namespace { 37 // Helper for error handling during key import. 38 #define READ_ASSERT(truth) \ 39 if (!(truth)) { \ 40 NOTREACHED(); \ 41 return false; \ 42 } 43 } // namespace 44 45 namespace crypto { 46 47 const uint8 PrivateKeyInfoCodec::kRsaAlgorithmIdentifier[] = { 48 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 49 0x05, 0x00 50 }; 51 52 PrivateKeyInfoCodec::PrivateKeyInfoCodec(bool big_endian) 53 : big_endian_(big_endian) {} 54 55 PrivateKeyInfoCodec::~PrivateKeyInfoCodec() {} 56 57 bool PrivateKeyInfoCodec::Export(std::vector<uint8>* output) { 58 std::list<uint8> content; 59 60 // Version (always zero) 61 uint8 version = 0; 62 63 PrependInteger(coefficient_, &content); 64 PrependInteger(exponent2_, &content); 65 PrependInteger(exponent1_, &content); 66 PrependInteger(prime2_, &content); 67 PrependInteger(prime1_, &content); 68 PrependInteger(private_exponent_, &content); 69 PrependInteger(public_exponent_, &content); 70 PrependInteger(modulus_, &content); 71 PrependInteger(&version, 1, &content); 72 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); 73 PrependTypeHeaderAndLength(kOctetStringTag, content.size(), &content); 74 75 // RSA algorithm OID 76 for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) 77 content.push_front(kRsaAlgorithmIdentifier[i - 1]); 78 79 PrependInteger(&version, 1, &content); 80 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); 81 82 // Copy everying into the output. 83 output->reserve(content.size()); 84 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) 85 output->push_back(*i); 86 87 return true; 88 } 89 90 bool PrivateKeyInfoCodec::ExportPublicKeyInfo(std::vector<uint8>* output) { 91 // Create a sequence with the modulus (n) and public exponent (e). 92 std::vector<uint8> bit_string; 93 if (!ExportPublicKey(&bit_string)) 94 return false; 95 96 // Add the sequence as the contents of a bit string. 97 std::list<uint8> content; 98 PrependBitString(&bit_string[0], static_cast<int>(bit_string.size()), 99 &content); 100 101 // Add the RSA algorithm OID. 102 for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) 103 content.push_front(kRsaAlgorithmIdentifier[i - 1]); 104 105 // Finally, wrap everything in a sequence. 106 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); 107 108 // Copy everything into the output. 109 output->reserve(content.size()); 110 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) 111 output->push_back(*i); 112 113 return true; 114 } 115 116 bool PrivateKeyInfoCodec::ExportPublicKey(std::vector<uint8>* output) { 117 // Create a sequence with the modulus (n) and public exponent (e). 118 std::list<uint8> content; 119 PrependInteger(&public_exponent_[0], 120 static_cast<int>(public_exponent_.size()), 121 &content); 122 PrependInteger(&modulus_[0], static_cast<int>(modulus_.size()), &content); 123 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); 124 125 // Copy everything into the output. 126 output->reserve(content.size()); 127 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) 128 output->push_back(*i); 129 130 return true; 131 } 132 133 bool PrivateKeyInfoCodec::Import(const std::vector<uint8>& input) { 134 if (input.empty()) { 135 return false; 136 } 137 138 // Parse the private key info up to the public key values, ignoring 139 // the subsequent private key values. 140 uint8* src = const_cast<uint8*>(&input.front()); 141 uint8* end = src + input.size(); 142 if (!ReadSequence(&src, end) || 143 !ReadVersion(&src, end) || 144 !ReadAlgorithmIdentifier(&src, end) || 145 !ReadTypeHeaderAndLength(&src, end, kOctetStringTag, NULL) || 146 !ReadSequence(&src, end) || 147 !ReadVersion(&src, end) || 148 !ReadInteger(&src, end, &modulus_)) 149 return false; 150 151 int mod_size = modulus_.size(); 152 READ_ASSERT(mod_size % 2 == 0); 153 int primes_size = mod_size / 2; 154 155 if (!ReadIntegerWithExpectedSize(&src, end, 4, &public_exponent_) || 156 !ReadIntegerWithExpectedSize(&src, end, mod_size, &private_exponent_) || 157 !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime1_) || 158 !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime2_) || 159 !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent1_) || 160 !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent2_) || 161 !ReadIntegerWithExpectedSize(&src, end, primes_size, &coefficient_)) 162 return false; 163 164 READ_ASSERT(src == end); 165 166 167 return true; 168 } 169 170 void PrivateKeyInfoCodec::PrependInteger(const std::vector<uint8>& in, 171 std::list<uint8>* out) { 172 uint8* ptr = const_cast<uint8*>(&in.front()); 173 PrependIntegerImpl(ptr, in.size(), out, big_endian_); 174 } 175 176 // Helper to prepend an ASN.1 integer. 177 void PrivateKeyInfoCodec::PrependInteger(uint8* val, 178 int num_bytes, 179 std::list<uint8>* data) { 180 PrependIntegerImpl(val, num_bytes, data, big_endian_); 181 } 182 183 void PrivateKeyInfoCodec::PrependIntegerImpl(uint8* val, 184 int num_bytes, 185 std::list<uint8>* data, 186 bool big_endian) { 187 // Reverse input if little-endian. 188 std::vector<uint8> tmp; 189 if (!big_endian) { 190 tmp.assign(val, val + num_bytes); 191 reverse(tmp.begin(), tmp.end()); 192 val = &tmp.front(); 193 } 194 195 // ASN.1 integers are unpadded byte arrays, so skip any null padding bytes 196 // from the most-significant end of the integer. 197 int start = 0; 198 while (start < (num_bytes - 1) && val[start] == 0x00) { 199 start++; 200 num_bytes--; 201 } 202 PrependBytes(val, start, num_bytes, data); 203 204 // ASN.1 integers are signed. To encode a positive integer whose sign bit 205 // (the most significant bit) would otherwise be set and make the number 206 // negative, ASN.1 requires a leading null byte to force the integer to be 207 // positive. 208 uint8 front = data->front(); 209 if ((front & 0x80) != 0) { 210 data->push_front(0x00); 211 num_bytes++; 212 } 213 214 PrependTypeHeaderAndLength(kIntegerTag, num_bytes, data); 215 } 216 217 bool PrivateKeyInfoCodec::ReadInteger(uint8** pos, 218 uint8* end, 219 std::vector<uint8>* out) { 220 return ReadIntegerImpl(pos, end, out, big_endian_); 221 } 222 223 bool PrivateKeyInfoCodec::ReadIntegerWithExpectedSize(uint8** pos, 224 uint8* end, 225 size_t expected_size, 226 std::vector<uint8>* out) { 227 std::vector<uint8> temp; 228 if (!ReadIntegerImpl(pos, end, &temp, true)) // Big-Endian 229 return false; 230 231 int pad = expected_size - temp.size(); 232 int index = 0; 233 if (out->size() == expected_size + 1) { 234 READ_ASSERT(out->front() == 0x00); 235 pad++; 236 index++; 237 } else { 238 READ_ASSERT(out->size() <= expected_size); 239 } 240 241 while (pad) { 242 out->push_back(0x00); 243 pad--; 244 } 245 out->insert(out->end(), temp.begin(), temp.end()); 246 247 // Reverse output if little-endian. 248 if (!big_endian_) 249 reverse(out->begin(), out->end()); 250 return true; 251 } 252 253 bool PrivateKeyInfoCodec::ReadIntegerImpl(uint8** pos, 254 uint8* end, 255 std::vector<uint8>* out, 256 bool big_endian) { 257 uint32 length = 0; 258 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length) || !length) 259 return false; 260 261 // The first byte can be zero to force positiveness. We can ignore this. 262 if (**pos == 0x00) { 263 ++(*pos); 264 --length; 265 } 266 267 if (length) 268 out->insert(out->end(), *pos, (*pos) + length); 269 270 (*pos) += length; 271 272 // Reverse output if little-endian. 273 if (!big_endian) 274 reverse(out->begin(), out->end()); 275 return true; 276 } 277 278 void PrivateKeyInfoCodec::PrependBytes(uint8* val, 279 int start, 280 int num_bytes, 281 std::list<uint8>* data) { 282 while (num_bytes > 0) { 283 --num_bytes; 284 data->push_front(val[start + num_bytes]); 285 } 286 } 287 288 void PrivateKeyInfoCodec::PrependLength(size_t size, std::list<uint8>* data) { 289 // The high bit is used to indicate whether additional octets are needed to 290 // represent the length. 291 if (size < 0x80) { 292 data->push_front(static_cast<uint8>(size)); 293 } else { 294 uint8 num_bytes = 0; 295 while (size > 0) { 296 data->push_front(static_cast<uint8>(size & 0xFF)); 297 size >>= 8; 298 num_bytes++; 299 } 300 CHECK_LE(num_bytes, 4); 301 data->push_front(0x80 | num_bytes); 302 } 303 } 304 305 void PrivateKeyInfoCodec::PrependTypeHeaderAndLength(uint8 type, 306 uint32 length, 307 std::list<uint8>* output) { 308 PrependLength(length, output); 309 output->push_front(type); 310 } 311 312 void PrivateKeyInfoCodec::PrependBitString(uint8* val, 313 int num_bytes, 314 std::list<uint8>* output) { 315 // Start with the data. 316 PrependBytes(val, 0, num_bytes, output); 317 // Zero unused bits. 318 output->push_front(0); 319 // Add the length. 320 PrependLength(num_bytes + 1, output); 321 // Finally, add the bit string tag. 322 output->push_front((uint8) kBitStringTag); 323 } 324 325 bool PrivateKeyInfoCodec::ReadLength(uint8** pos, uint8* end, uint32* result) { 326 READ_ASSERT(*pos < end); 327 int length = 0; 328 329 // If the MSB is not set, the length is just the byte itself. 330 if (!(**pos & 0x80)) { 331 length = **pos; 332 (*pos)++; 333 } else { 334 // Otherwise, the lower 7 indicate the length of the length. 335 int length_of_length = **pos & 0x7F; 336 READ_ASSERT(length_of_length <= 4); 337 (*pos)++; 338 READ_ASSERT(*pos + length_of_length < end); 339 340 length = 0; 341 for (int i = 0; i < length_of_length; ++i) { 342 length <<= 8; 343 length |= **pos; 344 (*pos)++; 345 } 346 } 347 348 READ_ASSERT(*pos + length <= end); 349 if (result) *result = length; 350 return true; 351 } 352 353 bool PrivateKeyInfoCodec::ReadTypeHeaderAndLength(uint8** pos, 354 uint8* end, 355 uint8 expected_tag, 356 uint32* length) { 357 READ_ASSERT(*pos < end); 358 READ_ASSERT(**pos == expected_tag); 359 (*pos)++; 360 361 return ReadLength(pos, end, length); 362 } 363 364 bool PrivateKeyInfoCodec::ReadSequence(uint8** pos, uint8* end) { 365 return ReadTypeHeaderAndLength(pos, end, kSequenceTag, NULL); 366 } 367 368 bool PrivateKeyInfoCodec::ReadAlgorithmIdentifier(uint8** pos, uint8* end) { 369 READ_ASSERT(*pos + sizeof(kRsaAlgorithmIdentifier) < end); 370 READ_ASSERT(memcmp(*pos, kRsaAlgorithmIdentifier, 371 sizeof(kRsaAlgorithmIdentifier)) == 0); 372 (*pos) += sizeof(kRsaAlgorithmIdentifier); 373 return true; 374 } 375 376 bool PrivateKeyInfoCodec::ReadVersion(uint8** pos, uint8* end) { 377 uint32 length = 0; 378 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length)) 379 return false; 380 381 // The version should be zero. 382 for (uint32 i = 0; i < length; ++i) { 383 READ_ASSERT(**pos == 0x00); 384 (*pos)++; 385 } 386 387 return true; 388 } 389 390 } // namespace crypto 391