Home | History | Annotate | Download | only in crypto
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_CRYPTO_RSA_PRIVATE_KEY_H_
      6 #define BASE_CRYPTO_RSA_PRIVATE_KEY_H_
      7 
      8 #include "build/build_config.h"
      9 
     10 #if defined(USE_NSS)
     11 // Forward declaration.
     12 struct SECKEYPrivateKeyStr;
     13 struct SECKEYPublicKeyStr;
     14 #elif defined(OS_MACOSX)
     15 #include <Security/cssm.h>
     16 #elif defined(OS_WIN)
     17 #include <windows.h>
     18 #include <wincrypt.h>
     19 #endif
     20 
     21 #include <list>
     22 #include <vector>
     23 
     24 #include "base/basictypes.h"
     25 
     26 namespace base {
     27 
     28 // Used internally by RSAPrivateKey for serializing and deserializing
     29 // PKCS #8 PrivateKeyInfo and PublicKeyInfo.
     30 class PrivateKeyInfoCodec {
     31  public:
     32 
     33   // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8.
     34   static const uint8 kRsaAlgorithmIdentifier[];
     35 
     36   // ASN.1 tags for some types we use.
     37   static const uint8 kBitStringTag = 0x03;
     38   static const uint8 kIntegerTag = 0x02;
     39   static const uint8 kNullTag = 0x05;
     40   static const uint8 kOctetStringTag = 0x04;
     41   static const uint8 kSequenceTag = 0x30;
     42 
     43   // |big_endian| here specifies the byte-significance of the integer components
     44   // that will be parsed & serialized (modulus(), etc...) during Import(),
     45   // Export() and ExportPublicKeyInfo() -- not the ASN.1 DER encoding of the
     46   // PrivateKeyInfo/PublicKeyInfo (which is always big-endian).
     47   explicit PrivateKeyInfoCodec(bool big_endian) : big_endian_(big_endian) {}
     48 
     49   // Exports the contents of the integer components to the ASN.1 DER encoding
     50   // of the PrivateKeyInfo structure to |output|.
     51   bool Export(std::vector<uint8>* output);
     52 
     53   // Exports the contents of the integer components to the ASN.1 DER encoding
     54   // of the PublicKeyInfo structure to |output|.
     55   bool ExportPublicKeyInfo(std::vector<uint8>* output);
     56 
     57   // Parses the ASN.1 DER encoding of the PrivateKeyInfo structure in |input|
     58   // and populates the integer components with |big_endian_| byte-significance.
     59   // IMPORTANT NOTE: This is currently *not* security-approved for importing
     60   // keys from unstrusted sources.
     61   bool Import(const std::vector<uint8>& input);
     62 
     63   // Accessors to the contents of the integer components of the PrivateKeyInfo
     64   // structure.
     65   std::vector<uint8>* modulus() { return &modulus_; };
     66   std::vector<uint8>* public_exponent() { return &public_exponent_; };
     67   std::vector<uint8>* private_exponent() { return &private_exponent_; };
     68   std::vector<uint8>* prime1() { return &prime1_; };
     69   std::vector<uint8>* prime2() { return &prime2_; };
     70   std::vector<uint8>* exponent1() { return &exponent1_; };
     71   std::vector<uint8>* exponent2() { return &exponent2_; };
     72   std::vector<uint8>* coefficient() { return &coefficient_; };
     73 
     74  private:
     75   // Utility wrappers for PrependIntegerImpl that use the class's |big_endian_|
     76   // value.
     77   void PrependInteger(const std::vector<uint8>& in, std::list<uint8>* out);
     78   void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data);
     79 
     80   // Prepends the integer stored in |val| - |val + num_bytes| with |big_endian|
     81   // byte-significance into |data| as an ASN.1 integer.
     82   void PrependIntegerImpl(uint8* val,
     83                           int num_bytes,
     84                           std::list<uint8>* data,
     85                           bool big_endian);
     86 
     87   // Utility wrappers for ReadIntegerImpl that use the class's |big_endian_|
     88   // value.
     89   bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out);
     90   bool ReadIntegerWithExpectedSize(uint8** pos,
     91                                    uint8* end,
     92                                    size_t expected_size,
     93                                    std::vector<uint8>* out);
     94 
     95   // Reads an ASN.1 integer from |pos|, and stores the result into |out| with
     96   // |big_endian| byte-significance.
     97   bool ReadIntegerImpl(uint8** pos,
     98                        uint8* end,
     99                        std::vector<uint8>* out,
    100                        bool big_endian);
    101 
    102   // Prepends the integer stored in |val|, starting a index |start|, for
    103   // |num_bytes| bytes onto |data|.
    104   void PrependBytes(uint8* val,
    105                     int start,
    106                     int num_bytes,
    107                     std::list<uint8>* data);
    108 
    109   // Helper to prepend an ASN.1 length field.
    110   void PrependLength(size_t size, std::list<uint8>* data);
    111 
    112   // Helper to prepend an ASN.1 type header.
    113   void PrependTypeHeaderAndLength(uint8 type,
    114                                   uint32 length,
    115                                   std::list<uint8>* output);
    116 
    117   // Helper to prepend an ASN.1 bit string
    118   void PrependBitString(uint8* val, int num_bytes, std::list<uint8>* output);
    119 
    120   // Read an ASN.1 length field. This also checks that the length does not
    121   // extend beyond |end|.
    122   bool ReadLength(uint8** pos, uint8* end, uint32* result);
    123 
    124   // Read an ASN.1 type header and its length.
    125   bool ReadTypeHeaderAndLength(uint8** pos,
    126                                uint8* end,
    127                                uint8 expected_tag,
    128                                uint32* length);
    129 
    130   // Read an ASN.1 sequence declaration. This consumes the type header and
    131   // length field, but not the contents of the sequence.
    132   bool ReadSequence(uint8** pos, uint8* end);
    133 
    134   // Read the RSA AlgorithmIdentifier.
    135   bool ReadAlgorithmIdentifier(uint8** pos, uint8* end);
    136 
    137   // Read one of the two version fields in PrivateKeyInfo.
    138   bool ReadVersion(uint8** pos, uint8* end);
    139 
    140   // The byte-significance of the stored components (modulus, etc..).
    141   bool big_endian_;
    142 
    143   // Component integers of the PrivateKeyInfo
    144   std::vector<uint8> modulus_;
    145   std::vector<uint8> public_exponent_;
    146   std::vector<uint8> private_exponent_;
    147   std::vector<uint8> prime1_;
    148   std::vector<uint8> prime2_;
    149   std::vector<uint8> exponent1_;
    150   std::vector<uint8> exponent2_;
    151   std::vector<uint8> coefficient_;
    152 
    153   DISALLOW_COPY_AND_ASSIGN(PrivateKeyInfoCodec);
    154 };
    155 
    156 // Encapsulates an RSA private key. Can be used to generate new keys, export
    157 // keys to other formats, or to extract a public key.
    158 class RSAPrivateKey {
    159  public:
    160   // Create a new random instance. Can return NULL if initialization fails.
    161   static RSAPrivateKey* Create(uint16 num_bits);
    162 
    163   // Create a new instance by importing an existing private key. The format is
    164   // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if
    165   // initialization fails.
    166   static RSAPrivateKey* CreateFromPrivateKeyInfo(
    167       const std::vector<uint8>& input);
    168 
    169   ~RSAPrivateKey();
    170 
    171 #if defined(USE_NSS)
    172   SECKEYPrivateKeyStr* key() { return key_; }
    173 #elif defined(OS_WIN)
    174   HCRYPTPROV provider() { return provider_; }
    175   HCRYPTKEY key() { return key_; }
    176 #elif defined(OS_MACOSX)
    177   CSSM_CSP_HANDLE csp_handle() { return csp_handle_; }
    178   CSSM_KEY_PTR key() { return &key_; }
    179 #endif
    180 
    181   // Exports the private key to a PKCS #1 PrivateKey block.
    182   bool ExportPrivateKey(std::vector<uint8>* output);
    183 
    184   // Exports the public key to an X509 SubjectPublicKeyInfo block.
    185   bool ExportPublicKey(std::vector<uint8>* output);
    186 
    187 private:
    188   // Constructor is private. Use Create() or CreateFromPrivateKeyInfo()
    189   // instead.
    190   RSAPrivateKey();
    191 
    192 #if defined(USE_NSS)
    193   SECKEYPrivateKeyStr* key_;
    194   SECKEYPublicKeyStr* public_key_;
    195 #elif defined(OS_WIN)
    196   bool InitProvider();
    197 
    198   HCRYPTPROV provider_;
    199   HCRYPTKEY key_;
    200 #elif defined(OS_MACOSX)
    201   CSSM_KEY key_;
    202   CSSM_CSP_HANDLE csp_handle_;
    203 #endif
    204 
    205   DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey);
    206 };
    207 
    208 }  // namespace base
    209 
    210 #endif  // BASE_CRYPTO_RSA_PRIVATE_KEY_H_
    211