ARC SDK
nssprivkeyinfocodec.h
1 //The following code is for for serializing and deserializing
2 // PKCS #8 PrivateKeyInfo and PublicKeyInfo
3 
4 //This part of code is introduced from chromium, therefore the BSD license applies
6 #include <list>
7 #include <vector>
8 
9 namespace AuthN {
10 
11  typedef unsigned int uint32;
12  typedef int int32;
13  typedef unsigned short uint16;
14  typedef short int16;
15  typedef unsigned char uint8;
16  typedef signed char int8;
17 
18 /*
19  struct SECKEYPrivateKeyStr;
20  struct SECKEYPublicKeyStr;
21 */
22 
23  class PrivateKeyInfoCodec {
24  public:
25 
26  // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8.
27  static const uint8 kRsaAlgorithmIdentifier[];
28 
29  // ASN.1 tags for some types we use.
30  static const uint8 kBitStringTag = 0x03;
31  static const uint8 kIntegerTag = 0x02;
32  static const uint8 kNullTag = 0x05;
33  static const uint8 kOctetStringTag = 0x04;
34  static const uint8 kSequenceTag = 0x30;
35 
36  // |big_endian| here specifies the byte-significance of the integer components
37  // that will be parsed & serialized (modulus(), etc...) during Import(),
38  // Export() and ExportPublicKeyInfo() -- not the ASN.1 DER encoding of the
39  // PrivateKeyInfo/PublicKeyInfo (which is always big-endian).
40  explicit PrivateKeyInfoCodec(bool big_endian);
41 
42  ~PrivateKeyInfoCodec();
43 
44  // Exports the contents of the integer components to the ASN.1 DER encoding
45  // of the PrivateKeyInfo structure to |output|.
46  bool Export(std::vector<uint8>* output);
47 
48  // Exports the contents of the integer components to the ASN.1 DER encoding
49  // of the PublicKeyInfo structure to |output|.
50  bool ExportPublicKeyInfo(std::vector<uint8>* output);
51 
52  // Exports the contents of the integer components to the ASN.1 DER encoding
53  // of the RSAPublicKey structure to |output|.
54  bool ExportPublicKey(std::vector<uint8>* output);
55 
56  // Parses the ASN.1 DER encoding of the PrivateKeyInfo structure in |input|
57  // and populates the integer components with |big_endian_| byte-significance.
58  // IMPORTANT NOTE: This is currently *not* security-approved for importing
59  // keys from unstrusted sources.
60  bool Import(const std::vector<uint8>& input);
61 
62  // Accessors to the contents of the integer components of the PrivateKeyInfo structure.
63  std::vector<uint8>* modulus() { return &modulus_; };
64  std::vector<uint8>* public_exponent() { return &public_exponent_; };
65  std::vector<uint8>* private_exponent() { return &private_exponent_; };
66  std::vector<uint8>* prime1() { return &prime1_; };
67  std::vector<uint8>* prime2() { return &prime2_; };
68  std::vector<uint8>* exponent1() { return &exponent1_; };
69  std::vector<uint8>* exponent2() { return &exponent2_; };
70  std::vector<uint8>* coefficient() { return &coefficient_; };
71 
72  private:
73  // Utility wrappers for PrependIntegerImpl that use the class's |big_endian_|
74  // value.
75  void PrependInteger(const std::vector<uint8>& in, std::list<uint8>* out);
76  void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data);
77 
78  // Prepends the integer stored in |val| - |val + num_bytes| with |big_endian|
79  // byte-significance into |data| as an ASN.1 integer.
80  void PrependIntegerImpl(uint8* val,
81  int num_bytes,
82  std::list<uint8>* data,
83  bool big_endian);
84 
85  // Utility wrappers for ReadIntegerImpl that use the class's |big_endian_|
86  // value.
87  bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out);
88  bool ReadIntegerWithExpectedSize(uint8** pos,
89  uint8* end,
90  size_t expected_size,
91  std::vector<uint8>* out);
92 
93  // Reads an ASN.1 integer from |pos|, and stores the result into |out| with
94  // |big_endian| byte-significance.
95  bool ReadIntegerImpl(uint8** pos,
96  uint8* end,
97  std::vector<uint8>* out,
98  bool big_endian);
99 
100  // Prepends the integer stored in |val|, starting a index |start|, for
101  // |num_bytes| bytes onto |data|.
102  void PrependBytes(uint8* val,
103  int start,
104  int num_bytes,
105  std::list<uint8>* data);
106 
107  // Helper to prepend an ASN.1 length field.
108  void PrependLength(size_t size, std::list<uint8>* data);
109 
110  // Helper to prepend an ASN.1 type header.
111  void PrependTypeHeaderAndLength(uint8 type,
112  uint32 length,
113  std::list<uint8>* output);
114 
115  // Helper to prepend an ASN.1 bit string
116  void PrependBitString(uint8* val, int num_bytes, std::list<uint8>* output);
117 
118  // Read an ASN.1 length field. This also checks that the length does not
119  // extend beyond |end|.
120  bool ReadLength(uint8** pos, uint8* end, uint32* result);
121 
122  // Read an ASN.1 type header and its length.
123  bool ReadTypeHeaderAndLength(uint8** pos,
124  uint8* end,
125  uint8 expected_tag,
126  uint32* length);
127 
128  // Read an ASN.1 sequence declaration. This consumes the type header and
129  // length field, but not the contents of the sequence.
130  bool ReadSequence(uint8** pos, uint8* end);
131 
132  // Read the RSA AlgorithmIdentifier.
133  bool ReadAlgorithmIdentifier(uint8** pos, uint8* end);
134 
135  // Read one of the two version fields in PrivateKeyInfo.
136  bool ReadVersion(uint8** pos, uint8* end);
137 
138  // The byte-significance of the stored components (modulus, etc..).
139  bool big_endian_;
140 
141  // Component integers of the PrivateKeyInfo
142  std::vector<uint8> modulus_;
143  std::vector<uint8> public_exponent_;
144  std::vector<uint8> private_exponent_;
145  std::vector<uint8> prime1_;
146  std::vector<uint8> prime2_;
147  std::vector<uint8> exponent1_;
148  std::vector<uint8> exponent2_;
149  std::vector<uint8> coefficient_;
150  };
151 
152 }