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