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