xref: /aosp_15_r20/external/tink/cc/subtle/pem_parser_boringssl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2018 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 #include "tink/subtle/pem_parser_boringssl.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/status/status.h"
27 #include "absl/strings/ascii.h"
28 #include "absl/strings/escaping.h"
29 #include "absl/strings/str_cat.h"
30 #include "absl/strings/string_view.h"
31 #include "openssl/bio.h"
32 #include "openssl/bn.h"
33 #include "openssl/evp.h"
34 #include "openssl/pem.h"
35 #include "openssl/rsa.h"
36 #include "tink/internal/bn_util.h"
37 #include "tink/internal/err_util.h"
38 #include "tink/internal/rsa_util.h"
39 #include "tink/internal/ssl_unique_ptr.h"
40 #include "tink/internal/ssl_util.h"
41 #include "tink/subtle/subtle_util_boringssl.h"
42 #include "tink/util/secret_data.h"
43 #include "tink/util/status.h"
44 #include "tink/util/statusor.h"
45 #include "tink/util/test_matchers.h"
46 
47 namespace crypto {
48 namespace tink {
49 namespace subtle {
50 namespace {
51 
52 using ::crypto::tink::test::IsOk;
53 using ::crypto::tink::test::StatusIs;
54 using ::testing::Eq;
55 using ::testing::Not;
56 using ::testing::NotNull;
57 using ::testing::Test;
58 using ::testing::TestWithParam;
59 using ::testing::ValuesIn;
60 
61 // Test vectors for ECDSA were generated using the `openssl` command.
62 //
63 // 1. Generate private PEM file. In the command below, the following values were
64 // used for the -name flag: {prime256v1, secp384r1, secp521r1}.
65 //
66 // $ openssl ecparam -genkey -name prime256v1 -noout -out ec-key-pair.pem
67 //
68 // 2. Generate public PEM file from private PEM file.
69 //
70 // $ openssl ec -in ec-key-pair.pem -pubout -out pub.pem
71 //
72 // 3. Print public X, Y and private key components. The public component is
73 // obtained by removing the leading "04" character (which indicates that the key
74 // is not compressed) and splitting the remaning bytes in two. The first half is
75 // X and the 2nd half is Y.
76 //
77 // $ openssl ec -in ec-key-pair.pem -text -param_enc explicit -noout
78 struct EcKeyTestVector {
79   // EC format
80   subtle::EllipticCurveType curve;
81   std::string pub_x_hex_str;
82   std::string pub_y_hex_str;
83   std::string priv_hex_str;
84 
85   // PEM format
86   std::string pub_pem;
87   std::string priv_pem;
88 };
89 
GetEcKeyTestVectors()90 std::vector<EcKeyTestVector> GetEcKeyTestVectors() {
91   return {
92       {
93           /*.curve=*/subtle::NIST_P256,
94           /*.pub_x_hex_str=*/
95           "1455cfd594d44df125f1ff643636740c6cc59972091fee6fa9b8d3897d59b0e0",
96           /*.pub_y_hex_str=*/
97           "d0b655238d8c0cebbfde77b1fda62ad19ccc6bf25a4ebf5637d3597983094363",
98           /*.priv_hex_str=*/
99           "8485FB768E109D14BE1E219D4D806523308E0E401DB1DE95DC938E8903C49B2C",
100           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
101 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFFXP1ZTUTfEl8f9kNjZ0DGzFmXIJ
102 H+5vqbjTiX1ZsODQtlUjjYwM67/ed7H9pirRnMxr8lpOv1Y301l5gwlDYw==
103 -----END PUBLIC KEY-----)",
104           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
105 MHcCAQEEIISF+3aOEJ0Uvh4hnU2AZSMwjg5AHbHeldyTjokDxJssoAoGCCqGSM49
106 AwEHoUQDQgAEFFXP1ZTUTfEl8f9kNjZ0DGzFmXIJH+5vqbjTiX1ZsODQtlUjjYwM
107 67/ed7H9pirRnMxr8lpOv1Y301l5gwlDYw==
108 -----END EC PRIVATE KEY-----)",
109       },
110       {
111           /*.curve=*/subtle::NIST_P256,
112           /*.pub_x_hex_str=*/
113           "ee21893b340260360f1ae3d26bf0a066eadc8c63690b2f1de308220800d9d1ab",
114           /*.pub_y_hex_str=*/
115           "d334a5917d2be49475af2454feea41d4418ea99eec791d1a0cc1c2890f8b33ee",
116           /*.priv_hex_str=*/
117           "cac853f79a95c7d8697d0469ccda4faf940d80d1e0c81ffa0e6082ed9a85654b",
118           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
119 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7iGJOzQCYDYPGuPSa/CgZurcjGNp
120 Cy8d4wgiCADZ0avTNKWRfSvklHWvJFT+6kHUQY6pnux5HRoMwcKJD4sz7g==
121 -----END PUBLIC KEY-----)",
122           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
123 MHcCAQEEIMrIU/ealcfYaX0EaczaT6+UDYDR4Mgf+g5ggu2ahWVLoAoGCCqGSM49
124 AwEHoUQDQgAE7iGJOzQCYDYPGuPSa/CgZurcjGNpCy8d4wgiCADZ0avTNKWRfSvk
125 lHWvJFT+6kHUQY6pnux5HRoMwcKJD4sz7g==
126 -----END EC PRIVATE KEY-----)",
127       },
128       {
129           // example EcKey with a pub_x with a leading zero.
130           /*.curve=*/subtle::NIST_P256,
131           /*.pub_x_hex_str=*/
132           "00b02778da7b7bfd7094c36f847eb32b3077547da49c8ecf667f7acc3145693c",
133           /*.pub_y_hex_str=*/
134           "710f3044af1cfe55f10d75de077297f7f2745cf2cd6cd4306f2aa72e367f7331",
135           /*.priv_hex_str=*/
136           "f4b9b38fd2817527e5b6ef7910bce594f06d87990f31a2e9005594951e2a2f2f",
137           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
138 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEALAneNp7e/1wlMNvhH6zKzB3VH2k
139 nI7PZn96zDFFaTxxDzBErxz+VfENdd4Hcpf38nRc8s1s1DBvKqcuNn9zMQ==
140 -----END PUBLIC KEY-----)",
141           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
142 MHcCAQEEIPS5s4/SgXUn5bbveRC85ZTwbYeZDzGi6QBVlJUeKi8voAoGCCqGSM49
143 AwEHoUQDQgAEALAneNp7e/1wlMNvhH6zKzB3VH2knI7PZn96zDFFaTxxDzBErxz+
144 VfENdd4Hcpf38nRc8s1s1DBvKqcuNn9zMQ==
145 -----END EC PRIVATE KEY-----)",
146       },
147       {
148           // example EcKey with a priv with a leading zero.
149           /*.curve=*/subtle::NIST_P256,
150           /*.pub_x_hex_str=*/
151           "8b348ef165b90ea991c28f254a5caed293e42d6c64fa2db1f3991c007442bf68",
152           /*.pub_y_hex_str=*/
153           "2d45951a61ac6f99d9c6745fe129e86c74001d3c13f506f9bb2d10fd492069b4",
154           /*.priv_hex_str=*/
155           "006484950d48016cc524078de3e3216258d2bc563f2318cc49f0301059f5fd61",
156           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
157 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEizSO8WW5DqmRwo8lSlyu0pPkLWxk
158 +i2x85kcAHRCv2gtRZUaYaxvmdnGdF/hKehsdAAdPBP1Bvm7LRD9SSBptA==
159 -----END PUBLIC KEY-----)",
160           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
161 MHcCAQEEIABkhJUNSAFsxSQHjePjIWJY0rxWPyMYzEnwMBBZ9f1hoAoGCCqGSM49
162 AwEHoUQDQgAEizSO8WW5DqmRwo8lSlyu0pPkLWxk+i2x85kcAHRCv2gtRZUaYaxv
163 mdnGdF/hKehsdAAdPBP1Bvm7LRD9SSBptA==
164 -----END EC PRIVATE KEY-----)",
165       },
166       {
167           /*.curve=*/subtle::NIST_P384,
168           /*.pub_x_hex_str=*/
169           "49b1a78537281c81984e00092f04c22c610cac2aba7a3de992bf6ad22305d2d54501"
170           "87"
171           "57ed823c643334e18d95b2e642",
172           /*.pub_y_hex_str=*/
173           "d2a851445c5da0bf0d543eaad5ff98634483c549d96045243121ed6d5c9ba64dab65"
174           "6a"
175           "6d25e018b01c4d3ab3f1738989",
176           /*.priv_hex_str=*/
177           "0254cd5840eec13b0d68ba08fdbc147c22906046ecb2fca2625294be74dea29aa370"
178           "fd"
179           "830985d278099644ecf89167cd",
180           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
181 MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAESbGnhTcoHIGYTgAJLwTCLGEMrCq6ej3p
182 kr9q0iMF0tVFAYdX7YI8ZDM04Y2VsuZC0qhRRFxdoL8NVD6q1f+YY0SDxUnZYEUk
183 MSHtbVybpk2rZWptJeAYsBxNOrPxc4mJ
184 -----END PUBLIC KEY-----)",
185           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
186 MIGkAgEBBDACVM1YQO7BOw1ougj9vBR8IpBgRuyy/KJiUpS+dN6imqNw/YMJhdJ4
187 CZZE7PiRZ82gBwYFK4EEACKhZANiAARJsaeFNygcgZhOAAkvBMIsYQysKrp6PemS
188 v2rSIwXS1UUBh1ftgjxkMzThjZWy5kLSqFFEXF2gvw1UPqrV/5hjRIPFSdlgRSQx
189 Ie1tXJumTatlam0l4BiwHE06s/FziYk=
190 -----END EC PRIVATE KEY-----)",
191       },
192       {
193           /*.curve=*/subtle::NIST_P384,
194           /*.pub_x_hex_str=*/
195           "82de2530a8d589149c8a60fdd529ed7a465db62d7412771a7ec40a69be139226b609"
196           "06"
197           "cc784007d8e28a79dca528e66c",
198           /*.pub_y_hex_str=*/
199           "c41f7532b8325aad3f1dddebddb702ebe70259bb5730e6bc4a75baec0d85c52d0d00"
200           "c8"
201           "e372d1da0d1ca10136e4cfd262",
202           /*.priv_hex_str=*/
203           "a6a8415b526418966758cfda45c19b4fe0ac4cf06d301b195ffea231d0eda67a54fb"
204           "7c"
205           "bc12470296e29e86359de53aee",
206           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
207 MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEgt4lMKjViRScimD91SntekZdti10Enca
208 fsQKab4Tkia2CQbMeEAH2OKKedylKOZsxB91MrgyWq0/Hd3r3bcC6+cCWbtXMOa8
209 SnW67A2FxS0NAMjjctHaDRyhATbkz9Ji
210 -----END PUBLIC KEY-----)",
211           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
212 MIGkAgEBBDCmqEFbUmQYlmdYz9pFwZtP4KxM8G0wGxlf/qIx0O2melT7fLwSRwKW
213 4p6GNZ3lOu6gBwYFK4EEACKhZANiAASC3iUwqNWJFJyKYP3VKe16Rl22LXQSdxp+
214 xAppvhOSJrYJBsx4QAfY4op53KUo5mzEH3UyuDJarT8d3evdtwLr5wJZu1cw5rxK
215 dbrsDYXFLQ0AyONy0doNHKEBNuTP0mI=
216 -----END EC PRIVATE KEY-----)",
217       },
218       {
219           /*.curve=*/subtle::NIST_P521,
220           /*.pub_x_hex_str=*/
221           "01d09ee2f33ce601d8594b09e668e128a7708ce752ef589d1a2c405523db0b68a0cb"
222           "58"
223           "60359b12c5371fc462f4142339ca7ff2550833f0a64887951ddb64e7d139d5",
224           /*.pub_y_hex_str=*/
225           "01b45ce12804afcf17fbd60728d362d4787b750d561e52144fd517807ddaa2b396be"
226           "d9"
227           "98227a5696d9c997a1cf0b6f1a3724ce25c7396dc2ea62c4bdf467061916e3",
228           /*.priv_hex_str=*/
229           "01f1913a921271c06686482a51dbf2c853aefbcc62b2b23d473a4c818d570e555667"
230           "42"
231           "edd9f05d0532f73d40c11d3d31c3734e4470cc0491ad911a209f1e88dcd712",
232           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
233 MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB0J7i8zzmAdhZSwnmaOEop3CM51Lv
234 WJ0aLEBVI9sLaKDLWGA1mxLFNx/EYvQUIznKf/JVCDPwpkiHlR3bZOfROdUBtFzh
235 KASvzxf71gco02LUeHt1DVYeUhRP1ReAfdqis5a+2ZgielaW2cmXoc8Lbxo3JM4l
236 xzltwupixL30ZwYZFuM=
237 -----END PUBLIC KEY-----)",
238           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
239 MIHcAgEBBEIB8ZE6khJxwGaGSCpR2/LIU677zGKysj1HOkyBjVcOVVZnQu3Z8F0F
240 Mvc9QMEdPTHDc05EcMwEka2RGiCfHojc1xKgBwYFK4EEACOhgYkDgYYABAHQnuLz
241 POYB2FlLCeZo4SincIznUu9YnRosQFUj2wtooMtYYDWbEsU3H8Ri9BQjOcp/8lUI
242 M/CmSIeVHdtk59E51QG0XOEoBK/PF/vWByjTYtR4e3UNVh5SFE/VF4B92qKzlr7Z
243 mCJ6VpbZyZehzwtvGjckziXHOW3C6mLEvfRnBhkW4w==
244 -----END EC PRIVATE KEY-----)",
245       },
246       {
247           /*.curve=*/subtle::NIST_P521,
248           /*.pub_x_hex_str=*/
249           "0108803f92f8449fdfca02c8c2b49643f407f63dda728ad38e3598b887b5831ab063"
250           "d9"
251           "60c5fd321ee597f4273fc0596015ce406515a2ab24a7c96a44802d74c3ac7b",
252           /*.pub_y_hex_str=*/
253           "01f216dc0f590b920d9c026e0aedc2b1cfe85d4f2d607db632395c7f64c053285936"
254           "33"
255           "635b6ad8bf51d2ee70c88000e96fd340601211c1d1eb0b32773806506b47b0",
256           /*.priv_hex_str=*/
257           "0010a207e650cf531c98c0c6d1cfdb88a5ee57f02734cbab93b8ae30d9dac0845d17"
258           "61"
259           "9be33f9aeaeab35401e63a149a87ae45b45bf2fea125d96c5d418d96bcda85",
260           /*.pub_pem=*/R"(-----BEGIN PUBLIC KEY-----
261 MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBCIA/kvhEn9/KAsjCtJZD9Af2Pdpy
262 itOONZi4h7WDGrBj2WDF/TIe5Zf0Jz/AWWAVzkBlFaKrJKfJakSALXTDrHsB8hbc
263 D1kLkg2cAm4K7cKxz+hdTy1gfbYyOVx/ZMBTKFk2M2Nbati/UdLucMiAAOlv00Bg
264 EhHB0esLMnc4BlBrR7A=
265 -----END PUBLIC KEY-----)",
266           /*.priv_pem=*/R"(-----BEGIN EC PRIVATE KEY-----
267 MIHcAgEBBEIAEKIH5lDPUxyYwMbRz9uIpe5X8Cc0y6uTuK4w2drAhF0XYZvjP5rq
268 6rNUAeY6FJqHrkW0W/L+oSXZbF1BjZa82oWgBwYFK4EEACOhgYkDgYYABAEIgD+S
269 +ESf38oCyMK0lkP0B/Y92nKK0441mLiHtYMasGPZYMX9Mh7ll/QnP8BZYBXOQGUV
270 oqskp8lqRIAtdMOsewHyFtwPWQuSDZwCbgrtwrHP6F1PLWB9tjI5XH9kwFMoWTYz
271 Y1tq2L9R0u5wyIAA6W/TQGASEcHR6wsydzgGUGtHsA==
272 -----END EC PRIVATE KEY-----)",
273       },
274   };
275 }
276 
277 // Holds test vectors for the PemParser. The original private-key pem text was
278 // taken from
279 // google3/third_party/tink/java_src/src/test/java/com/google/crypto/tink/subtle/PemKeyTypeTest.java.
280 // The components and public-key PEM version were extracted using
281 //
282 // $ openssl rsa -in <pem file> -pubout -text
283 struct RsaKeyTestVector {
284   // RSA parameters.
285   absl::string_view modulus_hex_str;
286   absl::string_view public_exponent_hex_str;
287 
288   absl::string_view private_exponent_hex_str;
289   absl::string_view p_hex_str;
290   absl::string_view q_hex_str;
291   absl::string_view dp_hex_str;
292   absl::string_view dq_hex_str;
293   absl::string_view coefficient_hex_str;
294 
295   // PEM forms.
296   absl::string_view public_pem;
297   absl::string_view private_pem;
298 };
299 
GetRsaKeyTestVectors()300 std::vector<RsaKeyTestVector> GetRsaKeyTestVectors() {
301   return {
302       {/*.modulus_hex_str=*/
303        "00bc067ea9038c24b063cac6146b26793499cc8a93985208596b9700acd4e51a580413"
304        "316cc5acc5b499d4781421ba9b0d8af75ae56b6179d5a7fc2098f2fc4d366a6a4166b1"
305        "5f2254db1cb3ce5dd4ab80bd8bd5adb5df34b602c319d4d004299c06e5e2437fd626e2"
306        "84c29eeb79d1820b830b706072efa2fd1c8898d1eaaf39fb9f54ce7671ea2b5512a429"
307        "0d3ec58bb41639a19be6630b1c27059b9a32505bebc6f42b301f9fb2cf2b624c1b6598"
308        "702bbeaed38b5fd9941d661ff6adca65ffb251d1f314bced0861fa30ec676e2129e5ac"
309        "ba03a6cb7594f93c60cef9b2aeee45edc6aadd31f841ee1f37fd63ccff3cebbb018a3d"
310        "631b3d498a79348704bb419f",
311        /*.public_exponent_hex_str=*/"010001",
312        /*.private_exponent_hex_str=*/
313        "718b1a81c5faa34d4175fa17ea7cd944c27b9a5376f052ca6d064b0a13a6263a707b86"
314        "a540da0ca9fb1b2b483cf60b1c2a872504d5cb8f5f4e8a1ac54236ca09ca4950254b87"
315        "3f9c2e952e9fb859ed17595f50320e5a33e295d86b88eff5138b7d3ee55c0d9eacecad"
316        "6f39b8c95f9340906a1ffa9e6dc7e7418bdb7d28539897297c7da5358867e60dfe8c76"
317        "fbf5a6a4c064e0f6af1bf3c9640cbee007aea3be81017b726d088b69957b844f951fac"
318        "323ff3e79fd67daf32a3dce862320ab0f4a78255f740f7381396ab8d55f80c1b38a149"
319        "f2418a2747795b44b14092fa17d215ae0e33c78997471ab971628b897776a80bbdee7e"
320        "ddf60eca6cecba50f32281",
321        /*.p_hex_str=*/
322        "00e3f152467849f4c2d87f5a6506453878b7547996b14067966e336399e2be6a8c2ea8"
323        "f065251f05e8bdcde4733d7084523432f3aad6b75990efadbedbce91cb097ce2b85dfa"
324        "22fd3ca12a86198d76d31009531351f07246937cd7b1d81d3675f8afd759d1279edb13"
325        "06e12f757baf368e265fb429775b1b4d16d88a7b009f00c7",
326        /*.q_hex_str=*/
327        "00d32b57f3d29f741c33ccf95d98b93b4efd56af0f9bc98f9089d8761ecccf65e0ba7f"
328        "eebfbef8fce3bb38a4a5f9614d47a28f137238518ab47f0a12912dc951b1d540632bc5"
329        "70338b17ee4f866767b7ba98ac6a057f1a2b27101ee584e9e82d4a83f31ef14d11f1d9"
330        "105dc38e3052a506982ff3679e760c7ad186f361284c9069",
331        /*.dp_hex_str=*/
332        "00c536bf9694f077c2350a4aad69756e5c9351953959f67d295c033e43a0385b7b19cb"
333        "b4e1edf21f6cb4fb7492782fe76c30197d54ec1d0a7329cbcb7be607a2017d79b3462b"
334        "eb25ead50e33a3dc0f58a1614fed4151a5ad8661d744d9d4bc8fe9304a443d7fe82367"
335        "1ce6abe71bb206a38a73f72e8143e4251885159b42784f75",
336        /*.dq_hex_str=*/
337        "367023116147e807e936bb466cbbbbd5662bf59f617af9beba3a8a60f04dbb26cf0d72"
338        "000e7c63bd55a389969c0e807caa24964fc8c304adf95e20613adb7e6b08ddbb732a47"
339        "fd91ab0ead83a99eac57b74a235edd6062a5845b62b1fc16f5ae130c16fafff25355b1"
340        "096b0379e3a45569e05ab068c267ff358ac3ad55553f99",
341        /*.coefficient_hex_str=*/
342        "3a47030f3e868a1457f0290ae5e8e1a95fef23f9b8d90b20d8e75d138c94bc01e9922d"
343        "60126a8af6c7142ebb32ced086b52cf1fa5dd389bce61bf6c66ec4c9d47cd08a8b5aad"
344        "7d9f48202003cc19bdce05d1e41b568e60c43aec44a23031282bd46ac47ea77ddf2b8a"
345        "303a784e27c73f9e0dd5b5f93e7be71361c2db675130d4",
346        /*.public_pem=*/
347        R"(-----BEGIN PUBLIC KEY-----
348 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvAZ+qQOMJLBjysYUayZ5
349 NJnMipOYUghZa5cArNTlGlgEEzFsxazFtJnUeBQhupsNivda5WthedWn/CCY8vxN
350 NmpqQWaxXyJU2xyzzl3Uq4C9i9Wttd80tgLDGdTQBCmcBuXiQ3/WJuKEwp7redGC
351 C4MLcGBy76L9HIiY0eqvOfufVM52ceorVRKkKQ0+xYu0Fjmhm+ZjCxwnBZuaMlBb
352 68b0KzAfn7LPK2JMG2WYcCu+rtOLX9mUHWYf9q3KZf+yUdHzFLztCGH6MOxnbiEp
353 5ay6A6bLdZT5PGDO+bKu7kXtxqrdMfhB7h83/WPM/zzruwGKPWMbPUmKeTSHBLtB
354 nwIDAQAB
355 -----END PUBLIC KEY-----)",
356        /*.private_pem=*/
357        R"(-----BEGIN PRIVATE KEY-----
358 MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8Bn6pA4wksGPK
359 xhRrJnk0mcyKk5hSCFlrlwCs1OUaWAQTMWzFrMW0mdR4FCG6mw2K91rla2F51af8
360 IJjy/E02ampBZrFfIlTbHLPOXdSrgL2L1a213zS2AsMZ1NAEKZwG5eJDf9Ym4oTC
361 nut50YILgwtwYHLvov0ciJjR6q85+59UznZx6itVEqQpDT7Fi7QWOaGb5mMLHCcF
362 m5oyUFvrxvQrMB+fss8rYkwbZZhwK76u04tf2ZQdZh/2rcpl/7JR0fMUvO0IYfow
363 7GduISnlrLoDpst1lPk8YM75sq7uRe3Gqt0x+EHuHzf9Y8z/POu7AYo9Yxs9SYp5
364 NIcEu0GfAgMBAAECggEAcYsagcX6o01BdfoX6nzZRMJ7mlN28FLKbQZLChOmJjpw
365 e4alQNoMqfsbK0g89gscKoclBNXLj19OihrFQjbKCcpJUCVLhz+cLpUun7hZ7RdZ
366 X1AyDloz4pXYa4jv9ROLfT7lXA2erOytbzm4yV+TQJBqH/qebcfnQYvbfShTmJcp
367 fH2lNYhn5g3+jHb79aakwGTg9q8b88lkDL7gB66jvoEBe3JtCItplXuET5UfrDI/
368 8+ef1n2vMqPc6GIyCrD0p4JV90D3OBOWq41V+AwbOKFJ8kGKJ0d5W0SxQJL6F9IV
369 rg4zx4mXRxq5cWKLiXd2qAu97n7d9g7KbOy6UPMigQKBgQDj8VJGeEn0wth/WmUG
370 RTh4t1R5lrFAZ5ZuM2OZ4r5qjC6o8GUlHwXovc3kcz1whFI0MvOq1rdZkO+tvtvO
371 kcsJfOK4Xfoi/TyhKoYZjXbTEAlTE1HwckaTfNex2B02dfiv11nRJ57bEwbhL3V7
372 rzaOJl+0KXdbG00W2Ip7AJ8AxwKBgQDTK1fz0p90HDPM+V2YuTtO/VavD5vJj5CJ
373 2HYezM9l4Lp/7r+++PzjuzikpflhTUeijxNyOFGKtH8KEpEtyVGx1UBjK8VwM4sX
374 7k+GZ2e3upisagV/GisnEB7lhOnoLUqD8x7xTRHx2RBdw44wUqUGmC/zZ552DHrR
375 hvNhKEyQaQKBgQDFNr+WlPB3wjUKSq1pdW5ck1GVOVn2fSlcAz5DoDhbexnLtOHt
376 8h9stPt0kngv52wwGX1U7B0KcynLy3vmB6IBfXmzRivrJerVDjOj3A9YoWFP7UFR
377 pa2GYddE2dS8j+kwSkQ9f+gjZxzmq+cbsgajinP3LoFD5CUYhRWbQnhPdQKBgDZw
378 IxFhR+gH6Ta7Rmy7u9VmK/WfYXr5vro6imDwTbsmzw1yAA58Y71Vo4mWnA6AfKok
379 lk/IwwSt+V4gYTrbfmsI3btzKkf9kasOrYOpnqxXt0ojXt1gYqWEW2Kx/Bb1rhMM
380 Fvr/8lNVsQlrA3njpFVp4FqwaMJn/zWKw61VVT+ZAoGAOkcDDz6GihRX8CkK5ejh
381 qV/vI/m42Qsg2OddE4yUvAHpki1gEmqK9scULrsyztCGtSzx+l3TibzmG/bGbsTJ
382 1HzQiotarX2fSCAgA8wZvc4F0eQbVo5gxDrsRKIwMSgr1GrEfqd93yuKMDp4TifH
383 P54N1bX5PnvnE2HC22dRMNQ=
384 -----END PRIVATE KEY-----)"}};
385 }
386 
387 class PemParserRsaTest : public Test {
388  public:
PemParserRsaTest()389   PemParserRsaTest() : rsa_(RSA_new()) {}
390 
SetUp()391   void SetUp() override {
392     // Create a new RSA key and output to PEM.
393     ASSERT_THAT(rsa_, NotNull());
394 
395     internal::SslUniquePtr<BIGNUM> e(BN_new());
396     ASSERT_THAT(e, NotNull());
397     ASSERT_EQ(BN_set_word(e.get(), RSA_F4), 1);
398 
399     // Generate a 2048 bits RSA key pair.
400     ASSERT_EQ(RSA_generate_key_ex(rsa_.get(), 2048, e.get(), /*cb=*/nullptr), 1)
401         << internal::GetSslErrors();
402 
403     // Write keys to PEM.
404     internal::SslUniquePtr<BIO> pub_key_pem_bio(BIO_new(BIO_s_mem()));
405     internal::SslUniquePtr<BIO> prv_key_pem_bio(BIO_new(BIO_s_mem()));
406 
407     // Write in PEM format.
408     ASSERT_EQ(PEM_write_bio_RSA_PUBKEY(pub_key_pem_bio.get(), rsa_.get()), 1)
409         << internal::GetSslErrors();
410     ASSERT_EQ(PEM_write_bio_RSAPrivateKey(prv_key_pem_bio.get(), rsa_.get(),
411                                           /*enc=*/nullptr, /*kstr=*/nullptr,
412                                           /*klen=*/0, /*cb=*/nullptr,
413                                           /*u=*/nullptr),
414               1)
415         << internal::GetSslErrors();
416 
417     pem_rsa_pub_key_.resize(BIO_number_written(pub_key_pem_bio.get()));
418     pem_rsa_prv_key_.resize(BIO_number_written(prv_key_pem_bio.get()));
419     ASSERT_EQ(BIO_read(pub_key_pem_bio.get(), &pem_rsa_pub_key_[0],
420                        BIO_number_written(pub_key_pem_bio.get())),
421               BIO_number_written(pub_key_pem_bio.get()));
422     ASSERT_EQ(BIO_read(prv_key_pem_bio.get(), &pem_rsa_prv_key_[0],
423                        BIO_number_written(prv_key_pem_bio.get())),
424               BIO_number_written(prv_key_pem_bio.get()));
425   }
426 
427   // Utility function that sets expectations to test that `bn_str` equals `bn`.
ExpectBnEqual(absl::string_view bn_str,const BIGNUM * bn)428   void ExpectBnEqual(absl::string_view bn_str, const BIGNUM *bn) {
429     util::StatusOr<std::string> expected_bn_str =
430         internal::BignumToString(bn, BN_num_bytes(bn));
431     ASSERT_THAT(expected_bn_str, IsOk());
432     EXPECT_EQ(bn_str, *expected_bn_str);
433   }
434 
435  protected:
436   // PEM encoded 2048 bit RSA key pair.
437   std::string pem_rsa_pub_key_;
438   std::string pem_rsa_prv_key_;
439   // Holds the RSA object.
440   const internal::SslUniquePtr<RSA> rsa_;
441 };
442 
443 // Corrupts `container` by modifying one the elements in the middle.
444 template <class ContainerType>
Corrupt(ContainerType * container)445 void Corrupt(ContainerType *container) {
446   if (container->empty()) {
447     return;
448   }
449   std::vector<char> corrupted(container->begin(), container->end());
450   size_t pos = corrupted.size() / 2;
451   corrupted[pos] ^= 1;
452   container->assign(corrupted.begin(), corrupted.end());
453 }
454 
455 // Test we can correctly parse an RSA public key.
TEST_F(PemParserRsaTest,ReadRsaPublicKey)456 TEST_F(PemParserRsaTest, ReadRsaPublicKey) {
457   auto key = PemParser::ParseRsaPublicKey(
458       absl::string_view(pem_rsa_pub_key_.data(), pem_rsa_pub_key_.size()));
459   ASSERT_THAT(key, IsOk()) << internal::GetSslErrors();
460 
461   // Verify exponent and modulus are correctly set.
462   const BIGNUM *e_bn, *n_bn;
463   RSA_get0_key(rsa_.get(), &n_bn, &e_bn, nullptr);
464   ExpectBnEqual((*key)->e, e_bn);
465   ExpectBnEqual((*key)->n, n_bn);
466 }
467 
468 // Test we can correctly parse an RSA private key.
TEST_F(PemParserRsaTest,ReadRsaPrivatekey)469 TEST_F(PemParserRsaTest, ReadRsaPrivatekey) {
470   auto key_statusor = PemParser::ParseRsaPrivateKey(
471       absl::string_view(pem_rsa_prv_key_.data(), pem_rsa_prv_key_.size()));
472   ASSERT_THAT(key_statusor, IsOk()) << internal::GetSslErrors();
473 
474   // Verify exponents and modulus.
475   auto key = *std::move(key_statusor);
476   const BIGNUM *e_bn, *n_bn, *d_bn;
477   RSA_get0_key(rsa_.get(), &n_bn, &e_bn, &d_bn);
478   ExpectBnEqual(key->e, e_bn);
479   ExpectBnEqual(key->n, n_bn);
480 
481   ExpectBnEqual(util::SecretDataAsStringView(key->d), d_bn);
482   // Verify private key factors.
483   const BIGNUM *p_bn, *q_bn;
484   RSA_get0_factors(rsa_.get(), &p_bn, &q_bn);
485 
486   ExpectBnEqual(util::SecretDataAsStringView(key->p), p_bn);
487   ExpectBnEqual(util::SecretDataAsStringView(key->q), q_bn);
488   // Verify CRT parameters.
489   const BIGNUM *dp_bn, *dq_bn, *crt_bn;
490   RSA_get0_crt_params(rsa_.get(), &dp_bn, &dq_bn, &crt_bn);
491 
492   ExpectBnEqual(util::SecretDataAsStringView(key->dp), dp_bn);
493   ExpectBnEqual(util::SecretDataAsStringView(key->dq), dq_bn);
494   ExpectBnEqual(util::SecretDataAsStringView(key->crt), crt_bn);
495 }
496 
497 using ParametrizedPemParserRsaTest = TestWithParam<RsaKeyTestVector>;
498 
TEST_P(ParametrizedPemParserRsaTest,WriteRsaPrivateKey)499 TEST_P(ParametrizedPemParserRsaTest, WriteRsaPrivateKey) {
500   RsaKeyTestVector test_vector = GetParam();
501   internal::RsaPrivateKey key;
502   key.n = absl::HexStringToBytes(test_vector.modulus_hex_str);
503   key.e = absl::HexStringToBytes(test_vector.public_exponent_hex_str);
504 
505   key.d = util::SecretDataFromStringView(
506       absl::HexStringToBytes(test_vector.private_exponent_hex_str));
507   key.p = util::SecretDataFromStringView(
508       absl::HexStringToBytes(test_vector.p_hex_str));
509   key.q = util::SecretDataFromStringView(
510       absl::HexStringToBytes(test_vector.q_hex_str));
511   key.dp = util::SecretDataFromStringView(
512       absl::HexStringToBytes(test_vector.dp_hex_str));
513   key.dq = util::SecretDataFromStringView(
514       absl::HexStringToBytes(test_vector.dq_hex_str));
515   key.crt = util::SecretDataFromStringView(
516       absl::HexStringToBytes(test_vector.coefficient_hex_str));
517 
518   util::StatusOr<std::string> pem_result = PemParser::WriteRsaPrivateKey(key);
519   EXPECT_THAT(pem_result, IsOk()) << internal::GetSslErrors();
520   EXPECT_EQ(absl::StripAsciiWhitespace(*pem_result), test_vector.private_pem);
521 }
522 
TEST_P(ParametrizedPemParserRsaTest,WriteRsaPublicKey)523 TEST_P(ParametrizedPemParserRsaTest, WriteRsaPublicKey) {
524   RsaKeyTestVector test_vector = GetParam();
525   internal::RsaPublicKey key;
526   key.n = absl::HexStringToBytes(test_vector.modulus_hex_str);
527   key.e = absl::HexStringToBytes(test_vector.public_exponent_hex_str);
528 
529   auto pem_result = PemParser::WriteRsaPublicKey(key);
530   EXPECT_THAT(pem_result, IsOk());
531   EXPECT_EQ(absl::StripAsciiWhitespace(*pem_result), test_vector.public_pem);
532 }
533 
534 INSTANTIATE_TEST_SUITE_P(ParametrizedPemParserRsaTests,
535                          ParametrizedPemParserRsaTest,
536                          ValuesIn(GetRsaKeyTestVectors()));
537 
TEST_F(PemParserRsaTest,ReadRsaPublicKeyInvalid)538 TEST_F(PemParserRsaTest, ReadRsaPublicKeyInvalid) {
539   Corrupt(&pem_rsa_pub_key_);
540   EXPECT_THAT(
541       PemParser::ParseRsaPrivateKey(
542           absl::string_view(pem_rsa_pub_key_.data(), pem_rsa_pub_key_.size()))
543           .status(),
544       Not(IsOk()));
545 }
546 
TEST_F(PemParserRsaTest,ReadRsaPrivateKeyInvalid)547 TEST_F(PemParserRsaTest, ReadRsaPrivateKeyInvalid) {
548   Corrupt(&pem_rsa_prv_key_);
549   EXPECT_THAT(
550       PemParser::ParseRsaPrivateKey(
551           absl::string_view(pem_rsa_prv_key_.data(), pem_rsa_prv_key_.size()))
552           .status(),
553       Not(IsOk()));
554 }
555 
556 using ParametrizedPemParserEcTest = TestWithParam<EcKeyTestVector>;
557 
TEST_P(ParametrizedPemParserEcTest,ReadEcPublicKeySuccess)558 TEST_P(ParametrizedPemParserEcTest, ReadEcPublicKeySuccess) {
559   EcKeyTestVector test_vector = GetParam();
560   auto ecdsa_key = PemParser::ParseEcPublicKey(
561       absl::StripAsciiWhitespace(test_vector.pub_pem));
562 
563   EXPECT_THAT(ecdsa_key, IsOk()) << internal::GetSslErrors();
564 
565   auto x_hex_result = absl::BytesToHexString(ecdsa_key->get()->pub_x);
566   auto y_hex_result = absl::BytesToHexString(ecdsa_key->get()->pub_y);
567   EXPECT_EQ(test_vector.pub_x_hex_str, x_hex_result);
568   EXPECT_EQ(test_vector.pub_y_hex_str, y_hex_result);
569   EXPECT_EQ(test_vector.curve, ecdsa_key->get()->curve);
570 }
571 
TEST_P(ParametrizedPemParserEcTest,ReadEcPrivateKeySuccess)572 TEST_P(ParametrizedPemParserEcTest, ReadEcPrivateKeySuccess) {
573   EcKeyTestVector test_vector = GetParam();
574   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
575       PemParser::ParseEcPrivateKey(
576           absl::StripAsciiWhitespace(test_vector.priv_pem));
577 
578   EXPECT_THAT(ecdsa_key, IsOk()) << internal::GetSslErrors();
579 
580   std::string x_hex = absl::BytesToHexString((*ecdsa_key)->pub_x);
581   std::string y_hex = absl::BytesToHexString((*ecdsa_key)->pub_y);
582   std::string priv_hex =
583       absl::BytesToHexString(util::SecretDataAsStringView((*ecdsa_key)->priv));
584   EXPECT_THAT(x_hex, Eq(test_vector.pub_x_hex_str));
585   EXPECT_THAT(y_hex, Eq(test_vector.pub_y_hex_str));
586   EXPECT_THAT(priv_hex, Eq(absl::AsciiStrToLower(test_vector.priv_hex_str)));
587   EXPECT_THAT((*ecdsa_key)->curve, test_vector.curve);
588 }
589 
TEST_P(ParametrizedPemParserEcTest,ReadEcPublicKeyInvalid)590 TEST_P(ParametrizedPemParserEcTest, ReadEcPublicKeyInvalid) {
591   EcKeyTestVector test_vector = GetParam();
592   std::string corrupt_pem = test_vector.pub_pem;
593   Corrupt(&corrupt_pem);
594 
595   auto ecdsa_key =
596       PemParser::ParseEcPublicKey(absl::StripAsciiWhitespace(corrupt_pem));
597 
598   EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kInvalidArgument));
599 }
600 
TEST_P(ParametrizedPemParserEcTest,ReadEcPrivateKeyInvalid)601 TEST_P(ParametrizedPemParserEcTest, ReadEcPrivateKeyInvalid) {
602   EcKeyTestVector test_vector = GetParam();
603   std::string corrupt_pem = test_vector.pub_pem;
604   Corrupt(&corrupt_pem);
605 
606   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
607       PemParser::ParseEcPrivateKey(absl::StripAsciiWhitespace(corrupt_pem));
608 
609   EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kInvalidArgument));
610 }
TEST_P(ParametrizedPemParserEcTest,WriteEcPublicKeySucceeds)611 TEST_P(ParametrizedPemParserEcTest, WriteEcPublicKeySucceeds) {
612   EcKeyTestVector test_vector = GetParam();
613   // Load an EcKey with the test vector.
614   SubtleUtilBoringSSL::EcKey ec_key;
615   ec_key.curve = test_vector.curve;
616   ec_key.pub_x = absl::HexStringToBytes(test_vector.pub_x_hex_str);
617   ec_key.pub_y = absl::HexStringToBytes(test_vector.pub_y_hex_str);
618   ec_key.priv = util::SecretDataFromStringView(
619       absl::HexStringToBytes(test_vector.priv_hex_str));
620 
621   // Check that converting the public key with WriteEcPublicKey() succeeds.
622   util::StatusOr<std::string> pem_material =
623       PemParser::WriteEcPublicKey(ec_key);
624   ASSERT_THAT(pem_material, IsOk()) << internal::GetSslErrors();
625   EXPECT_EQ(absl::StripAsciiWhitespace(*pem_material),
626             absl::StripAsciiWhitespace(test_vector.pub_pem));
627 }
628 
TEST_P(ParametrizedPemParserEcTest,WriteEcPrivateKeySucceeds)629 TEST_P(ParametrizedPemParserEcTest, WriteEcPrivateKeySucceeds) {
630   EcKeyTestVector test_vector = GetParam();
631   // Load an EcKey with the test vector.
632   SubtleUtilBoringSSL::EcKey ec_key;
633   ec_key.curve = test_vector.curve;
634   ec_key.pub_x = absl::HexStringToBytes(test_vector.pub_x_hex_str);
635   ec_key.pub_y = absl::HexStringToBytes(test_vector.pub_y_hex_str);
636   ec_key.priv = util::SecretDataFromStringView(
637       absl::HexStringToBytes(test_vector.priv_hex_str));
638 
639   // Check that converting the private key with WriteEcPrivateKey() succeeds.
640   util::StatusOr<std::string> pem_material =
641       PemParser::WriteEcPrivateKey(ec_key);
642   ASSERT_THAT(pem_material, IsOk());
643   EXPECT_EQ(absl::StripAsciiWhitespace(*pem_material),
644             absl::StripAsciiWhitespace(test_vector.priv_pem));
645 }
646 
647 INSTANTIATE_TEST_SUITE_P(ParametrizedPemParserEcTest,
648                          ParametrizedPemParserEcTest,
649                          ValuesIn(GetEcKeyTestVectors()));
650 
TEST(PemParserEcTest,NewKeyWriteAndReadPublicKeySuccess)651 TEST(PemParserEcTest, NewKeyWriteAndReadPublicKeySuccess) {
652   util::StatusOr<SubtleUtilBoringSSL::EcKey> ec_key =
653       SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P256);
654   ASSERT_THAT(ec_key, IsOk());
655 
656   util::StatusOr<std::string> public_pem = PemParser::WriteEcPublicKey(*ec_key);
657   ASSERT_THAT(public_pem, IsOk());
658   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> public_key =
659       PemParser::ParseEcPublicKey(*public_pem);
660   EXPECT_THAT(public_key, IsOk()) << internal::GetSslErrors();
661   EXPECT_EQ((*public_key)->pub_x, ec_key->pub_x);
662   EXPECT_EQ((*public_key)->pub_y, ec_key->pub_y);
663   EXPECT_EQ((*public_key)->curve, ec_key->curve);
664 }
665 
TEST(PemParserEcTest,NewKeyWriteAndReadPrivateKeySuccess)666 TEST(PemParserEcTest, NewKeyWriteAndReadPrivateKeySuccess) {
667   util::StatusOr<SubtleUtilBoringSSL::EcKey> ec_key =
668       SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P256);
669   ASSERT_THAT(ec_key, IsOk());
670 
671   util::StatusOr<std::string> private_pem =
672       PemParser::WriteEcPrivateKey(*ec_key);
673   ASSERT_THAT(private_pem, IsOk());
674   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> parsed_ec_key =
675       PemParser::ParseEcPrivateKey(*private_pem);
676   EXPECT_THAT(parsed_ec_key, IsOk()) << internal::GetSslErrors();
677 
678   EXPECT_EQ((*parsed_ec_key)->pub_x, ec_key->pub_x);
679   EXPECT_EQ((*parsed_ec_key)->pub_y, ec_key->pub_y);
680   EXPECT_EQ((*parsed_ec_key)->priv, ec_key->priv);
681   EXPECT_EQ((*parsed_ec_key)->curve, ec_key->curve);
682 }
683 
TEST(PemParserEcTest,ReadEcPublicKeyP224_Unimplemented)684 TEST(PemParserEcTest, ReadEcPublicKeyP224_Unimplemented) {
685   constexpr absl::string_view kP224PublicKey =
686       R"(-----BEGIN PUBLIC KEY-----
687 ME4wEAYHKoZIzj0CAQYFK4EEACEDOgAE9PcDd+z3cVYhKnNbDVAXwDmShKBCPc88
688 sEUoYDu3Oi24YuZAFbwVIdX69RME4FB5PbxISleynMI=
689 -----END PUBLIC KEY-----)";
690 
691   auto ecdsa_key =
692       PemParser::ParseEcPublicKey(absl::StripAsciiWhitespace(kP224PublicKey));
693 
694   EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kUnimplemented));
695 }
696 
TEST(PemParserEcTest,ReadInvalidEcPublicKey)697 TEST(PemParserEcTest, ReadInvalidEcPublicKey) {
698   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
699       PemParser::ParseEcPublicKey("invalid");
700 
701   EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kInvalidArgument));
702 }
703 
TEST(PemParserEcTest,ReadInvalidEcPrivateKey)704 TEST(PemParserEcTest, ReadInvalidEcPrivateKey) {
705   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
706       PemParser::ParseEcPrivateKey("invalid");
707 
708   EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kInvalidArgument));
709 }
710 
711 // Makes sure parsing of a valid EC public key on secp256k1 fails because the
712 // curve is unsupported.
TEST(PemParserEcTest,ReadEcPublicKeyFailsBecauseSecp256k1Unsupported)713 TEST(PemParserEcTest, ReadEcPublicKeyFailsBecauseSecp256k1Unsupported) {
714   // Generate private key with:
715   // > openssl ecparam -genkey -name secp256k1 -noout -out ec-key-pair.pem
716   // Extract the public key:
717   // > openssl ec -in ec-key-pair.pem -pubout
718   constexpr absl::string_view kSecp256k1PublicKey =
719       R"(-----BEGIN PUBLIC KEY-----
720 MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEC9naJNDkHKVBjfDK90szJegpzatlUcFO
721 BLrJS8EVf4tMw52zdhXpKBF2FGpD54dNo+Ut2s6JIE+LoaX/FSvifw==
722 -----END PUBLIC KEY-----)";
723 
724   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
725       PemParser::ParseEcPublicKey(
726           absl::StripAsciiWhitespace(kSecp256k1PublicKey));
727   // With BoringSSL parsing of the PEM key fails when an unsupported curve is
728   // used [1]; Supported curves are defined here [2]. Tink doesn't distinguish
729   // between an error caused by a malformed PEM and an unsupported group by
730   // BoringSSL. On the other hand, with OpenSSL parsing succeeds, but this
731   // curve is unsupported by Tink. As a consequence, this fails with two
732   // different errors.
733   //
734   // [1]https://github.com/google/boringssl/blob/master/crypto/ec_extra/ec_asn1.c#L324
735   // [2]https://github.com/google/boringssl/blob/master/crypto/fipsmodule/ec/ec.c#L218
736   if (internal::IsBoringSsl()) {
737     EXPECT_THAT(ecdsa_key.status(),
738                 StatusIs(absl::StatusCode::kInvalidArgument));
739   } else {
740     EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kUnimplemented));
741   }
742 }
743 
744 // Makes sure parsing of a valid EC private key on secp256k1 fails because the
745 // curve is unsupported.
TEST(PemParserEcTest,ReadEcPrivateKeyFailsBecauseSecp256k1Unsupported)746 TEST(PemParserEcTest, ReadEcPrivateKeyFailsBecauseSecp256k1Unsupported) {
747   // Generate private key with:
748   // > openssl ecparam -genkey -name secp256k1 -noout
749   constexpr absl::string_view kSecp256k1PrivateKey =
750       R"(-----BEGIN EC PRIVATE KEY-----
751 MHQCAQEEIKSqexQyySWB705oPctFx2roLMHdfJ/W/WBISaRNu1UHoAcGBSuBBAAK
752 oUQDQgAEC9naJNDkHKVBjfDK90szJegpzatlUcFOBLrJS8EVf4tMw52zdhXpKBF2
753 FGpD54dNo+Ut2s6JIE+LoaX/FSvifw==
754 -----END EC PRIVATE KEY-----)";
755 
756   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
757       PemParser::ParseEcPrivateKey(
758           absl::StripAsciiWhitespace(kSecp256k1PrivateKey));
759 
760   // PEM parsing fails in BoringSSL when the curve is unsupported, and Tink
761   // doesn't distinguish between an error caused by a malformed PEM and an
762   // unsupported group by BoringSSL. With OpenSSL parsing succeeds, but this
763   // curve is unsupported by Tink. As a consequence, this fails with two
764   // different errors.
765   if (internal::IsBoringSsl()) {
766     EXPECT_THAT(ecdsa_key.status(),
767                 StatusIs(absl::StatusCode::kInvalidArgument));
768   } else {
769     EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kUnimplemented));
770   }
771 }
772 
TEST(PemParserEcTest,ParseEncryptedEcPrivateKey_Invalid)773 TEST(PemParserEcTest, ParseEncryptedEcPrivateKey_Invalid) {
774   // This key was generated with the command:
775   // openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:prime256v1
776   // -aes128 using pass phrase "mypassword"
777   constexpr absl::string_view kPrivateKey =
778       R"(-----BEGIN ENCRYPTED PRIVATE KEY-----
779 MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjurwMnDwdrOwICCAAw
780 DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEJHshE1SbT5XZN1bToPLsuAEgZAA
781 xmCJjv1kTjWzwbE1SEM6lwMippywDf0JH+de4JwlrPiQAb5NExq96m6Per70tX4W
782 iJ76WplZagsJzsAg/5gIJ/YcTry266rP2SBVTsuCY/GOh2vU/x6XFbPi9JCM0nvH
783 GTi1cWyqIwzGqfw8ZGejtvg4SAGulZ7/MWVCZV51C6JakfY1v3z24BQG1m50jMs=
784 -----END ENCRYPTED PRIVATE KEY-----)";
785 
786   util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>> ecdsa_key =
787       PemParser::ParseEcPrivateKey(absl::StripAsciiWhitespace(kPrivateKey));
788 
789   EXPECT_THAT(ecdsa_key.status(), StatusIs(absl::StatusCode::kInvalidArgument));
790 }
791 
TEST(PemParserEcTest,WriteEcPublicKeyWithBadXFails)792 TEST(PemParserEcTest, WriteEcPublicKeyWithBadXFails) {
793   util::StatusOr<SubtleUtilBoringSSL::EcKey> ec_key_statusor =
794       SubtleUtilBoringSSL::GetNewEcKey(subtle::NIST_P256);
795   ASSERT_THAT(ec_key_statusor, IsOk());
796   SubtleUtilBoringSSL::EcKey ec_key = *ec_key_statusor;
797   Corrupt(&ec_key.pub_x);
798   // Bad coordinates should generate a BoringSSL/OpenSSL's internal error.
799   EXPECT_THAT(PemParser::WriteEcPublicKey(ec_key).status(),
800               StatusIs(absl::StatusCode::kInternal));
801 }
802 
TEST(PemParserEcTest,WriteEcPublicKeyWithBadYFails)803 TEST(PemParserEcTest, WriteEcPublicKeyWithBadYFails) {
804   util::StatusOr<SubtleUtilBoringSSL::EcKey> ec_key_statusor =
805       SubtleUtilBoringSSL::GetNewEcKey(subtle::NIST_P256);
806   ASSERT_THAT(ec_key_statusor, IsOk());
807   SubtleUtilBoringSSL::EcKey ec_key = *ec_key_statusor;
808   Corrupt(&ec_key.pub_y);
809   EXPECT_THAT(PemParser::WriteEcPublicKey(ec_key).status(),
810               StatusIs(absl::StatusCode::kInternal));
811 }
812 
TEST(PemParserEcTest,WriteEcPrivateKeyWithBadPrivFails)813 TEST(PemParserEcTest, WriteEcPrivateKeyWithBadPrivFails) {
814   util::StatusOr<SubtleUtilBoringSSL::EcKey> ec_key_statusor =
815       SubtleUtilBoringSSL::GetNewEcKey(subtle::NIST_P256);
816   ASSERT_THAT(ec_key_statusor, IsOk());
817   SubtleUtilBoringSSL::EcKey ec_key = *ec_key_statusor;
818   std::string priv = std::string(util::SecretDataAsStringView(ec_key.priv));
819   Corrupt(&priv);
820   ec_key.priv = util::SecretDataFromStringView(priv);
821   EXPECT_THAT(PemParser::WriteEcPrivateKey(ec_key).status(),
822               StatusIs(absl::StatusCode::kInvalidArgument));
823 }
824 
825 }  // namespace
826 }  // namespace subtle
827 }  // namespace tink
828 }  // namespace crypto
829