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