1 /* Copyright (c) 2015, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <gtest/gtest.h>
16
17 #include <openssl/crypto.h>
18 #include <openssl/err.h>
19 #include <openssl/pkcs8.h>
20 #include <openssl/x509.h>
21
22 #include "../internal.h"
23
24
25 // kEncryptedPBES2WithDESAndSHA1 is a PKCS#8 encrypted private key using PBES2
26 // with DES-EDE3-CBC and HMAC-SHA-1 and a password of "testing". It was
27 // generated with:
28 //
29 // clang-format off
30 //
31 // openssl ecparam -genkey -name prime256v1 > test.key
32 // openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 des3 -v2prf hmacWithSHA1 -outform der
33 // xxd -i test.key.encrypted
34 //
35 // clang-format on
36 static const uint8_t kEncryptedPBES2WithDESAndSHA1[] = {
37 0x30, 0x81, 0xd5, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
38 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86,
39 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x0e, 0x04, 0x08, 0x65,
40 0x0b, 0xb8, 0x2a, 0x45, 0x13, 0x65, 0x4c, 0x02, 0x02, 0x08, 0x00, 0x30,
41 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04,
42 0x08, 0x16, 0x42, 0xa5, 0x98, 0xc2, 0x38, 0xdd, 0x80, 0x04, 0x81, 0x90,
43 0x8a, 0xfd, 0xc1, 0xb1, 0x6c, 0x8a, 0x26, 0x80, 0xff, 0x15, 0x9a, 0x15,
44 0x72, 0x04, 0x25, 0xe2, 0x2d, 0xfd, 0xfe, 0xfd, 0xbb, 0x1d, 0xcb, 0xbc,
45 0x3c, 0x07, 0xf2, 0x3e, 0x97, 0xe6, 0x24, 0x2d, 0x06, 0x1f, 0xa2, 0xc8,
46 0x72, 0xa0, 0x1b, 0x1f, 0xe2, 0x41, 0x1a, 0x53, 0xe5, 0xba, 0x17, 0x62,
47 0x49, 0xe8, 0xae, 0x1a, 0x5a, 0xf0, 0x4c, 0x5f, 0x74, 0x05, 0x3f, 0xc3,
48 0xb3, 0xa2, 0x8b, 0xb8, 0xc5, 0x17, 0x20, 0xec, 0xca, 0x3a, 0xf9, 0x00,
49 0xd8, 0xb1, 0x97, 0x61, 0x98, 0x28, 0xfe, 0x79, 0x1e, 0xe0, 0x7e, 0xb4,
50 0x7c, 0x40, 0x89, 0x1e, 0x56, 0xa6, 0x63, 0x4f, 0x32, 0x6e, 0x00, 0x77,
51 0x7d, 0xf1, 0xb9, 0x77, 0x92, 0xbf, 0x02, 0xbb, 0x9d, 0x45, 0x15, 0xd4,
52 0x4a, 0xb5, 0xe7, 0xb5, 0xb4, 0x9d, 0x06, 0x3c, 0x57, 0xf3, 0x8a, 0x9b,
53 0x58, 0x85, 0xad, 0x99, 0x16, 0x2d, 0xe9, 0x14, 0xa4, 0xa8, 0xad, 0x51,
54 0xce, 0x29, 0x55, 0x52, 0xb7, 0x42, 0xb3, 0x25, 0x6d, 0x2f, 0x00, 0x91,
55 };
56
57 // kEncryptedPBES2WithAESAndSHA256 is a PKCS#8 encrypted private key using PBES2
58 // with AES-128-CBC and HMAC-SHA-256 and a password of "testing". It was generated with:
59 //
60 // clang-format off
61 //
62 // openssl ecparam -genkey -name prime256v1 > test.key
63 // openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 aes-128-cbc -v2prf hmacWithSHA256 -outform der
64 // xxd -i test.key.encrypted
65 //
66 // clang-format on
67 static const uint8_t kEncryptedPBES2WithAESAndSHA256[] = {
68 0x30, 0x81, 0xec, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
69 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86,
70 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0xfc,
71 0x66, 0x7f, 0x51, 0xe7, 0xb8, 0x2a, 0x22, 0x02, 0x02, 0x08, 0x00, 0x30,
72 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05,
73 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
74 0x01, 0x02, 0x04, 0x10, 0xde, 0x59, 0xa1, 0x6c, 0xbc, 0xca, 0xd2, 0x04,
75 0x64, 0x93, 0xcb, 0xae, 0x0d, 0x57, 0xcd, 0x71, 0x04, 0x81, 0x90, 0x66,
76 0x84, 0x20, 0x5b, 0x8d, 0xfc, 0xa8, 0x08, 0x2c, 0xf1, 0x05, 0xea, 0xef,
77 0x74, 0x6b, 0xa7, 0xf5, 0xce, 0xf5, 0xef, 0x71, 0x55, 0xcd, 0x6c, 0x4a,
78 0xdd, 0xda, 0x6b, 0xc8, 0x51, 0xf5, 0x59, 0x87, 0x18, 0x48, 0x4e, 0xac,
79 0x8d, 0x3f, 0xa4, 0xd7, 0x51, 0x81, 0xf1, 0x4b, 0x18, 0x66, 0x3c, 0x4e,
80 0xf3, 0x08, 0x3e, 0x76, 0xf0, 0x12, 0x30, 0x93, 0x4e, 0x49, 0x86, 0xe0,
81 0xb3, 0xd1, 0x82, 0x92, 0xaa, 0x1f, 0x2b, 0x62, 0xe2, 0x6d, 0x0d, 0x0d,
82 0xad, 0xb8, 0xcf, 0xe8, 0x9a, 0x4e, 0xab, 0x31, 0x21, 0x5d, 0x6e, 0xec,
83 0xbc, 0xa1, 0x10, 0xef, 0x5f, 0xc5, 0xd3, 0x93, 0x57, 0x19, 0x95, 0xee,
84 0x0e, 0xce, 0x6c, 0x07, 0x08, 0xf1, 0xab, 0xe6, 0x0b, 0x06, 0x3f, 0xbd,
85 0x6d, 0x19, 0x48, 0x3c, 0xa0, 0xd7, 0x81, 0x5f, 0xa6, 0x06, 0x05, 0xac,
86 0x47, 0xb0, 0x51, 0x5b, 0xc5, 0x8b, 0xbe, 0x46, 0x43, 0x10, 0x9a, 0xd4,
87 0xc3, 0x49, 0xc2, 0x0a, 0xe7, 0xd0, 0x34, 0x8b, 0xad, 0xfb, 0x4d,
88 };
89
90 // kNullPassword is a PKCS#8 encrypted private key using the null password.
91 static const uint8_t kNullPassword[] = {
92 0x30, 0x81, 0xb0, 0x30, 0x1b, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
93 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0d, 0x04, 0x08, 0xb2, 0xfe, 0x68,
94 0xc2, 0xea, 0x0f, 0x10, 0x9c, 0x02, 0x01, 0x01, 0x04, 0x81, 0x90, 0xe2,
95 0xf6, 0x1c, 0xca, 0xad, 0x64, 0x30, 0xbf, 0x88, 0x04, 0x35, 0xe5, 0x0f,
96 0x11, 0x49, 0x06, 0x01, 0x14, 0x33, 0x80, 0xa2, 0x78, 0x44, 0x5b, 0xaa,
97 0x0d, 0xd7, 0x00, 0x36, 0x9d, 0x91, 0x97, 0x37, 0x20, 0x7b, 0x27, 0xc1,
98 0xa0, 0xa2, 0x73, 0x06, 0x15, 0xdf, 0xc8, 0x13, 0x9b, 0xc9, 0x8c, 0x9c,
99 0xce, 0x00, 0xd0, 0xc8, 0x42, 0xc1, 0xda, 0x2b, 0x07, 0x2b, 0x12, 0xa3,
100 0xce, 0x10, 0x39, 0x7a, 0xf1, 0x55, 0x69, 0x8d, 0xa5, 0xc4, 0x2a, 0x00,
101 0x0d, 0x94, 0xc6, 0xde, 0x6a, 0x3d, 0xb7, 0xe5, 0x6d, 0x59, 0x3e, 0x09,
102 0xb5, 0xe3, 0x3e, 0xfc, 0x50, 0x56, 0xe9, 0x50, 0x42, 0x7c, 0xe7, 0xf0,
103 0x19, 0xbd, 0x31, 0xa7, 0x85, 0x47, 0xb3, 0xe9, 0xb3, 0x50, 0x3c, 0xc9,
104 0x32, 0x37, 0x1a, 0x93, 0x78, 0x48, 0x78, 0x82, 0xde, 0xad, 0x5c, 0xf2,
105 0xcf, 0xf2, 0xbb, 0x2c, 0x44, 0x05, 0x7f, 0x4a, 0xf9, 0xb1, 0x2b, 0xdd,
106 0x49, 0xf6, 0x7e, 0xd0, 0x42, 0xaa, 0x14, 0x3c, 0x24, 0x77, 0xb4,
107 };
108
109 // kNullPasswordNSS is a PKCS#8 encrypted private key using the null password
110 // and generated by NSS.
111 static const uint8_t kNullPasswordNSS[] = {
112 0x30, 0x81, 0xb8, 0x30, 0x23, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
113 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x15, 0x04, 0x10, 0x3f, 0xac, 0xe9,
114 0x38, 0xdb, 0x40, 0x6b, 0x26, 0x89, 0x09, 0x73, 0x18, 0x8d, 0x7f, 0x1c,
115 0x82, 0x02, 0x01, 0x01, 0x04, 0x81, 0x90, 0x5e, 0x5e, 0x11, 0xef, 0xbb,
116 0x7c, 0x4d, 0xec, 0xc0, 0xdc, 0xc7, 0x23, 0xd2, 0xc4, 0x77, 0xbc, 0xf4,
117 0x5d, 0x59, 0x4c, 0x07, 0xc2, 0x8a, 0x26, 0xfa, 0x25, 0x1c, 0xaa, 0x42,
118 0xed, 0xd0, 0xed, 0xbb, 0x5c, 0xe9, 0x13, 0x07, 0xaa, 0xdd, 0x52, 0x3c,
119 0x65, 0x25, 0xbf, 0x94, 0x02, 0xaf, 0xd6, 0x97, 0xe9, 0x33, 0x00, 0x76,
120 0x64, 0x4a, 0x73, 0xab, 0xfb, 0x99, 0x6e, 0x83, 0x12, 0x05, 0x86, 0x72,
121 0x6c, 0xd5, 0xa4, 0xcf, 0xb1, 0xd5, 0x4d, 0x54, 0x87, 0x8b, 0x4b, 0x95,
122 0x1d, 0xcd, 0xf3, 0xfe, 0xa8, 0xda, 0xe0, 0xb6, 0x72, 0x13, 0x3f, 0x2e,
123 0x66, 0xe0, 0xb9, 0x2e, 0xfa, 0x69, 0x40, 0xbe, 0xd7, 0x67, 0x6e, 0x53,
124 0x2b, 0x3f, 0x53, 0xe5, 0x39, 0x54, 0x77, 0xe1, 0x1d, 0xe6, 0x81, 0x92,
125 0x58, 0x82, 0x14, 0xfb, 0x47, 0x85, 0x3c, 0xc3, 0xdf, 0xdd, 0xcc, 0x79,
126 0x9f, 0x41, 0x83, 0x72, 0xf2, 0x0a, 0xe9, 0xe1, 0x2c, 0x12, 0xb0, 0xb0,
127 0x0a, 0xb2, 0x1d, 0xca, 0x15, 0xb2, 0xca,
128 };
129
130 // kEmptyPasswordOpenSSL is a PKCS#8 encrypted private key using the empty
131 // password and generated by OpenSSL.
132 static const uint8_t kEmptyPasswordOpenSSL[] = {
133 0x30, 0x82, 0x01, 0xa1, 0x30, 0x1b, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86,
134 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0d, 0x04, 0x08, 0x86, 0xaa,
135 0xd7, 0xdf, 0x3b, 0x91, 0x97, 0x60, 0x02, 0x01, 0x01, 0x04, 0x82, 0x01,
136 0x80, 0xcb, 0x2a, 0x14, 0xaa, 0x4f, 0x38, 0x4c, 0xe1, 0x49, 0x00, 0xe2,
137 0x1a, 0x3a, 0x75, 0x87, 0x7e, 0x3d, 0xea, 0x4d, 0x53, 0xd4, 0x46, 0x47,
138 0x23, 0x8f, 0xa1, 0x72, 0x51, 0x92, 0x86, 0x8b, 0xeb, 0x53, 0xe6, 0x6a,
139 0x0a, 0x6b, 0xb6, 0xa0, 0xdc, 0x0f, 0xdc, 0x20, 0xc3, 0x45, 0x85, 0xf1,
140 0x95, 0x90, 0x5c, 0xf4, 0xfa, 0xee, 0x47, 0xaf, 0x35, 0xd0, 0xd0, 0xd3,
141 0x14, 0xde, 0x0d, 0xca, 0x1b, 0xd3, 0xbb, 0x20, 0xec, 0x9d, 0x6a, 0xd4,
142 0xc1, 0xce, 0x60, 0x81, 0xab, 0x0c, 0x72, 0x10, 0xfa, 0x28, 0x3c, 0xac,
143 0x87, 0x7b, 0x82, 0x85, 0x00, 0xb8, 0x58, 0x9c, 0x07, 0xc4, 0x7d, 0xa9,
144 0xc5, 0x94, 0x95, 0xf7, 0x23, 0x93, 0x3f, 0xed, 0xef, 0x92, 0x55, 0x25,
145 0x74, 0xbb, 0xd3, 0xd1, 0x67, 0x3b, 0x3d, 0x5a, 0xfe, 0x84, 0xf8, 0x97,
146 0x7d, 0x7c, 0x01, 0xc7, 0xd7, 0x0d, 0xf8, 0xc3, 0x6d, 0xd6, 0xf1, 0xaa,
147 0x9d, 0x1f, 0x69, 0x97, 0x45, 0x06, 0xc4, 0x1c, 0x95, 0x3c, 0xe0, 0xef,
148 0x11, 0xb2, 0xb3, 0x72, 0x91, 0x9e, 0x7d, 0x0f, 0x7f, 0xc8, 0xf6, 0x64,
149 0x49, 0x5e, 0x3c, 0x53, 0x37, 0x79, 0x03, 0x1c, 0x3f, 0x29, 0x6c, 0x6b,
150 0xea, 0x4c, 0x35, 0x9b, 0x6d, 0x1b, 0x59, 0x43, 0x4c, 0x14, 0x47, 0x2a,
151 0x36, 0x39, 0x2a, 0xd8, 0x96, 0x90, 0xdc, 0xfc, 0xd2, 0xdd, 0x23, 0x0e,
152 0x2c, 0xb3, 0x83, 0xf9, 0xf2, 0xe3, 0xe6, 0x99, 0x53, 0x57, 0x33, 0xc5,
153 0x5f, 0xf9, 0xfd, 0x56, 0x0b, 0x32, 0xd4, 0xf3, 0x9d, 0x5b, 0x34, 0xe5,
154 0x94, 0xbf, 0xb6, 0xc0, 0xce, 0xe1, 0x73, 0x5c, 0x02, 0x7a, 0x4c, 0xed,
155 0xde, 0x23, 0x38, 0x89, 0x9f, 0xcd, 0x51, 0xf3, 0x90, 0x80, 0xd3, 0x4b,
156 0x83, 0xd3, 0xee, 0xf2, 0x9e, 0x35, 0x91, 0xa5, 0xa3, 0xc0, 0x5c, 0xce,
157 0xdb, 0xaa, 0x70, 0x1e, 0x1d, 0xc1, 0x44, 0xea, 0x3b, 0xa7, 0x5a, 0x11,
158 0xd1, 0xf3, 0xf3, 0xd0, 0xf4, 0x5a, 0xc4, 0x99, 0xaf, 0x8d, 0xe2, 0xbc,
159 0xa2, 0xb9, 0x3d, 0x86, 0x5e, 0xba, 0xa0, 0xdf, 0x78, 0x81, 0x7c, 0x54,
160 0x31, 0xe3, 0x98, 0xb5, 0x46, 0xcb, 0x4d, 0x26, 0x4b, 0xf8, 0xac, 0x3a,
161 0x54, 0x1b, 0x77, 0x5a, 0x18, 0xa5, 0x43, 0x0e, 0x14, 0xde, 0x7b, 0xb7,
162 0x4e, 0x45, 0x99, 0x03, 0xd1, 0x3d, 0x18, 0xb2, 0x36, 0x00, 0x48, 0x07,
163 0x72, 0xbb, 0x4f, 0x21, 0x25, 0x3e, 0xda, 0x25, 0x24, 0x5b, 0xc8, 0xa0,
164 0x28, 0xd5, 0x9b, 0x96, 0x87, 0x07, 0x77, 0x84, 0xff, 0xd7, 0xac, 0x71,
165 0xf6, 0x61, 0x63, 0x0b, 0xfb, 0x42, 0xfd, 0x52, 0xf4, 0xc4, 0x35, 0x0c,
166 0xc2, 0xc1, 0x55, 0x22, 0x42, 0x2f, 0x13, 0x7d, 0x93, 0x27, 0xc8, 0x11,
167 0x35, 0xc5, 0xe3, 0xc5, 0xaa, 0x15, 0x3c, 0xac, 0x30, 0xbc, 0x45, 0x16,
168 0xed,
169 };
170
171 // kExplicitHMACWithSHA1 is a PBES2-encrypted private key with an explicit
172 // hmacWithSHA1 AlgorithmIdentifier in the PBKDF2 parameters.
173 static const uint8_t kExplicitHMACWithSHA1[] = {
174 0x30, 0x81, 0xec, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
175 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86,
176 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0x90,
177 0xcd, 0x1e, 0x47, 0x1d, 0xff, 0x4c, 0xa8, 0x02, 0x02, 0x08, 0x00, 0x30,
178 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x07, 0x05,
179 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
180 0x01, 0x02, 0x04, 0x10, 0x34, 0xe7, 0x5b, 0x9b, 0xf9, 0x17, 0xcf, 0x15,
181 0x59, 0x7c, 0xfd, 0xc1, 0xac, 0xed, 0x6f, 0xdd, 0x04, 0x81, 0x90, 0xe3,
182 0xd7, 0xfc, 0xbe, 0xe6, 0xe8, 0x92, 0xc1, 0xa2, 0x57, 0x42, 0x4b, 0xf1,
183 0x35, 0x6c, 0x4f, 0x58, 0x61, 0x14, 0x30, 0x4e, 0xa3, 0x8d, 0x4f, 0xde,
184 0x2d, 0x0b, 0xa2, 0x62, 0x4b, 0xee, 0x9f, 0xc4, 0xeb, 0x89, 0x33, 0x76,
185 0x3f, 0x0c, 0x20, 0xad, 0x75, 0x29, 0x42, 0xbc, 0xbd, 0x83, 0x46, 0x1d,
186 0x5c, 0xae, 0xec, 0x10, 0x05, 0xbb, 0xd3, 0x98, 0xc9, 0x5a, 0x5e, 0x0a,
187 0x95, 0x12, 0x1e, 0x65, 0x93, 0xdd, 0xdd, 0x51, 0xd5, 0x56, 0xc2, 0xa9,
188 0xf9, 0x43, 0x0f, 0x68, 0x8a, 0x14, 0x40, 0xe5, 0x62, 0x9e, 0x0d, 0xd7,
189 0x67, 0x62, 0xf4, 0x49, 0xb1, 0x62, 0x22, 0x42, 0xb1, 0xe1, 0xb2, 0x1d,
190 0x37, 0x3e, 0x95, 0x52, 0xe9, 0x61, 0x89, 0xc7, 0x62, 0xcc, 0xb1, 0x44,
191 0x40, 0xef, 0x89, 0xc8, 0xc4, 0x0e, 0xae, 0xa8, 0xf9, 0x17, 0x42, 0x2b,
192 0x8c, 0x0b, 0x26, 0xf6, 0x07, 0x00, 0xab, 0x25, 0x2b, 0x64, 0xcf, 0xc3,
193 0x68, 0xf9, 0x5e, 0x01, 0x66, 0x59, 0x5f, 0x3f, 0x05, 0x57, 0xcd,
194 };
195
TestDecrypt(const uint8_t * der,size_t der_len,const char * password)196 static void TestDecrypt(const uint8_t *der, size_t der_len,
197 const char *password) {
198 const uint8_t *data = der;
199 bssl::UniquePtr<X509_SIG> sig(d2i_X509_SIG(NULL, &data, der_len));
200 ASSERT_TRUE(sig.get());
201 ASSERT_EQ(der + der_len, data);
202
203 bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> keypair(
204 PKCS8_decrypt(sig.get(), password, -1));
205 ASSERT_TRUE(keypair);
206 }
207
TestRoundTrip(int pbe_nid,const EVP_CIPHER * cipher,const char * password,const uint8_t * salt,size_t salt_len,int iterations)208 static void TestRoundTrip(int pbe_nid, const EVP_CIPHER *cipher,
209 const char *password, const uint8_t *salt,
210 size_t salt_len, int iterations) {
211 static const uint8_t kSampleKey[] = {
212 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
213 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
214 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
215 0x8a, 0x87, 0x2f, 0xb6, 0x28, 0x93, 0xc4, 0xd1, 0xff, 0xc5, 0xb9, 0xf0,
216 0xf9, 0x17, 0x58, 0x06, 0x9f, 0x83, 0x52, 0xe0, 0x8f, 0xa0, 0x5a, 0x49,
217 0xf8, 0xdb, 0x92, 0x6c, 0xb5, 0x72, 0x87, 0x25, 0xa1, 0x44, 0x03, 0x42,
218 0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25,
219 0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, 0xc7,
220 0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, 0x92,
221 0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, 0x0d,
222 0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, 0x31,
223 0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9,
224 };
225
226 const uint8_t *ptr = kSampleKey;
227 bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> key(
228 d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, sizeof(kSampleKey)));
229 ASSERT_TRUE(key);
230 ASSERT_EQ(kSampleKey + sizeof(kSampleKey), ptr);
231
232 bssl::UniquePtr<X509_SIG> encrypted(PKCS8_encrypt(
233 pbe_nid, cipher, password, -1, salt, salt_len, iterations, key.get()));
234 ASSERT_TRUE(encrypted);
235
236 bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> key2(
237 PKCS8_decrypt(encrypted.get(), password, -1));
238 ASSERT_TRUE(key2);
239
240 uint8_t *encoded = nullptr;
241 int len = i2d_PKCS8_PRIV_KEY_INFO(key2.get(), &encoded);
242 bssl::UniquePtr<uint8_t> free_encoded(encoded);
243 ASSERT_GE(len, 0);
244 ASSERT_EQ(static_cast<size_t>(len), sizeof(kSampleKey));
245 ASSERT_EQ(0, OPENSSL_memcmp(encoded, kSampleKey, sizeof(kSampleKey)));
246 }
247
TEST(PKCS8Test,DecryptString)248 TEST(PKCS8Test, DecryptString) {
249 TestDecrypt(kEncryptedPBES2WithDESAndSHA1,
250 sizeof(kEncryptedPBES2WithDESAndSHA1), "testing");
251 TestDecrypt(kEncryptedPBES2WithAESAndSHA256,
252 sizeof(kEncryptedPBES2WithAESAndSHA256), "testing");
253 }
254
TEST(PKCS8Test,DecryptNull)255 TEST(PKCS8Test, DecryptNull) {
256 TestDecrypt(kNullPassword, sizeof(kNullPassword), NULL);
257 }
258
TEST(PKCS8Test,DecryptNullNSS)259 TEST(PKCS8Test, DecryptNullNSS) {
260 TestDecrypt(kNullPasswordNSS, sizeof(kNullPasswordNSS), NULL);
261 }
262
TEST(PKCS8Test,DecryptEmptyStringOpenSSL)263 TEST(PKCS8Test, DecryptEmptyStringOpenSSL) {
264 TestDecrypt(kEmptyPasswordOpenSSL, sizeof(kEmptyPasswordOpenSSL), "");
265 }
266
TEST(PKCS8Test,DecryptExplicitHMACWithSHA1)267 TEST(PKCS8Test, DecryptExplicitHMACWithSHA1) {
268 TestDecrypt(kExplicitHMACWithSHA1, sizeof(kExplicitHMACWithSHA1), "foo");
269 }
270
TEST(PKCS8Test,RoundTripPBEWithrSHA1And3KeyTripleDES)271 TEST(PKCS8Test, RoundTripPBEWithrSHA1And3KeyTripleDES) {
272 // Test with different salts.
273 TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
274 "password", nullptr, 0, 10);
275 TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
276 "password", nullptr, 4, 10);
277 TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
278 "password", (const uint8_t *)"salt", 4, 10);
279 // Test with a different iteration count.
280 TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
281 "password", nullptr, 0, 1);
282 }
283
284 // Test that both "" (empty password, encoded as "\0\0") and nullptr (no
285 // password, encoded as "") work.
TEST(PKCS8Test,RoundTripPBEWithSHA1And3KeyTripleDESEmptyPassword)286 TEST(PKCS8Test, RoundTripPBEWithSHA1And3KeyTripleDESEmptyPassword) {
287 TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr, "",
288 nullptr, 0, 1);
289 TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr, nullptr,
290 nullptr, 0, 1);
291 }
292
TEST(PKCS8Test,RoundTripPBEWithSHA1And40BitRC2CBC)293 TEST(PKCS8Test, RoundTripPBEWithSHA1And40BitRC2CBC) {
294 TestRoundTrip(NID_pbe_WithSHA1And40BitRC2_CBC, nullptr, "password",
295 nullptr, 0, 10);
296 }
297
TEST(PKCS8Test,RoundTripPBEWithSHA1And128BitRC4)298 TEST(PKCS8Test, RoundTripPBEWithSHA1And128BitRC4) {
299 TestRoundTrip(NID_pbe_WithSHA1And128BitRC4, nullptr, "password",
300 nullptr, 0, 10);
301 }
302
TEST(PKCS8Test,RoundTripPBES2)303 TEST(PKCS8Test, RoundTripPBES2) {
304 TestRoundTrip(-1, EVP_aes_128_cbc(), "password", nullptr, 0, 10);
305 TestRoundTrip(-1, EVP_aes_128_cbc(), "password", nullptr, 4, 10);
306 TestRoundTrip(-1, EVP_aes_128_cbc(), "password", (const uint8_t *)"salt",
307 4, 10);
308 TestRoundTrip(-1, EVP_aes_128_cbc(), "password", nullptr, 0, 1);
309 TestRoundTrip(-1, EVP_rc2_cbc(), "password", nullptr, 0, 10);
310 }
311
TEST(PKCS8Test,InvalidPBES1NIDs)312 TEST(PKCS8Test, InvalidPBES1NIDs) {
313 static const uint8_t kSampleKey[] = {
314 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
315 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
316 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
317 0x8a, 0x87, 0x2f, 0xb6, 0x28, 0x93, 0xc4, 0xd1, 0xff, 0xc5, 0xb9, 0xf0,
318 0xf9, 0x17, 0x58, 0x06, 0x9f, 0x83, 0x52, 0xe0, 0x8f, 0xa0, 0x5a, 0x49,
319 0xf8, 0xdb, 0x92, 0x6c, 0xb5, 0x72, 0x87, 0x25, 0xa1, 0x44, 0x03, 0x42,
320 0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25,
321 0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, 0xc7,
322 0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, 0x92,
323 0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, 0x0d,
324 0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, 0x31,
325 0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9,
326 };
327
328 const uint8_t *ptr = kSampleKey;
329 bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> key(
330 d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, sizeof(kSampleKey)));
331 ASSERT_TRUE(key);
332 ASSERT_EQ(kSampleKey + sizeof(kSampleKey), ptr);
333
334 bssl::UniquePtr<X509_SIG> encrypted(PKCS8_encrypt(
335 NID_pbes2, nullptr, "password", -1, nullptr, 0, 0, key.get()));
336 EXPECT_FALSE(encrypted);
337
338 encrypted.reset(PKCS8_encrypt(NID_undef, nullptr, "password", -1, nullptr, 0,
339 0, key.get()));
340 EXPECT_FALSE(encrypted);
341
342 encrypted.reset(PKCS8_encrypt(NID_rsaEncryption, nullptr, "password", -1,
343 nullptr, 0, 0, key.get()));
344 EXPECT_FALSE(encrypted);
345 }
346