1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/pki/verify_signed_data.h"
6
7 #include <memory>
8 #include <set>
9
10 #include "net/cert/pki/cert_errors.h"
11 #include "net/cert/pki/mock_signature_verify_cache.h"
12 #include "net/cert/pki/signature_algorithm.h"
13 #include "net/cert/pki/test_helpers.h"
14 #include "net/der/input.h"
15 #include "net/der/parse_values.h"
16 #include "net/der/parser.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/abseil-cpp/absl/types/optional.h"
19
20 namespace net {
21
22 namespace {
23
24 enum VerifyResult {
25 SUCCESS,
26 FAILURE,
27 };
28
29 // Reads test data from |file_name| and runs VerifySignedData() over its
30 // inputs.
31 //
32 // If expected_result was SUCCESS then the test will only succeed if
33 // VerifySignedData() returns true.
34 //
35 // If expected_result was FAILURE then the test will only succeed if
36 // VerifySignedData() returns false.
RunTestCase(VerifyResult expected_result,const char * file_name,SignatureVerifyCache * cache)37 void RunTestCase(VerifyResult expected_result,
38 const char* file_name,
39 SignatureVerifyCache* cache) {
40 std::string path =
41 std::string("net/data/verify_signed_data_unittest/") + file_name;
42
43 std::string public_key;
44 std::string algorithm;
45 std::string signed_data;
46 std::string signature_value;
47
48 const PemBlockMapping mappings[] = {
49 {"PUBLIC KEY", &public_key},
50 {"ALGORITHM", &algorithm},
51 {"DATA", &signed_data},
52 {"SIGNATURE", &signature_value},
53 };
54
55 ASSERT_TRUE(ReadTestDataFromPemFile(path, mappings));
56
57 absl::optional<SignatureAlgorithm> signature_algorithm =
58 ParseSignatureAlgorithm(der::Input(&algorithm));
59 ASSERT_TRUE(signature_algorithm);
60
61 der::Parser signature_value_parser((der::Input(&signature_value)));
62 absl::optional<der::BitString> signature_value_bit_string =
63 signature_value_parser.ReadBitString();
64 ASSERT_TRUE(signature_value_bit_string.has_value())
65 << "The signature value is not a valid BIT STRING";
66
67 bool expected_result_bool = expected_result == SUCCESS;
68
69 bool result = VerifySignedData(*signature_algorithm, der::Input(&signed_data),
70 signature_value_bit_string.value(),
71 der::Input(&public_key), cache);
72
73 EXPECT_EQ(expected_result_bool, result);
74 }
75
RunTestCase(VerifyResult expected_result,const char * file_name)76 void RunTestCase(VerifyResult expected_result, const char* file_name) {
77 RunTestCase(expected_result, file_name, /*cache=*/nullptr);
78 }
79
80 // Read the descriptions in the test files themselves for details on what is
81 // being tested.
82
TEST(VerifySignedDataTest,RsaPkcs1Sha1)83 TEST(VerifySignedDataTest, RsaPkcs1Sha1) {
84 RunTestCase(SUCCESS, "rsa-pkcs1-sha1.pem");
85 }
86
TEST(VerifySignedDataTest,RsaPkcs1Sha256)87 TEST(VerifySignedDataTest, RsaPkcs1Sha256) {
88 RunTestCase(SUCCESS, "rsa-pkcs1-sha256.pem");
89 }
90
TEST(VerifySignedDataTest,Rsa2048Pkcs1Sha512)91 TEST(VerifySignedDataTest, Rsa2048Pkcs1Sha512) {
92 RunTestCase(SUCCESS, "rsa2048-pkcs1-sha512.pem");
93 }
94
TEST(VerifySignedDataTest,RsaPkcs1Sha256KeyEncodedBer)95 TEST(VerifySignedDataTest, RsaPkcs1Sha256KeyEncodedBer) {
96 RunTestCase(FAILURE, "rsa-pkcs1-sha256-key-encoded-ber.pem");
97 }
98
TEST(VerifySignedDataTest,EcdsaSecp384r1Sha256)99 TEST(VerifySignedDataTest, EcdsaSecp384r1Sha256) {
100 RunTestCase(SUCCESS, "ecdsa-secp384r1-sha256.pem");
101 }
102
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512)103 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512) {
104 RunTestCase(SUCCESS, "ecdsa-prime256v1-sha512.pem");
105 }
106
TEST(VerifySignedDataTest,RsaPssSha256)107 TEST(VerifySignedDataTest, RsaPssSha256) {
108 RunTestCase(SUCCESS, "rsa-pss-sha256.pem");
109 }
110
TEST(VerifySignedDataTest,RsaPssSha256WrongSalt)111 TEST(VerifySignedDataTest, RsaPssSha256WrongSalt) {
112 RunTestCase(FAILURE, "rsa-pss-sha256-wrong-salt.pem");
113 }
114
TEST(VerifySignedDataTest,EcdsaSecp384r1Sha256CorruptedData)115 TEST(VerifySignedDataTest, EcdsaSecp384r1Sha256CorruptedData) {
116 RunTestCase(FAILURE, "ecdsa-secp384r1-sha256-corrupted-data.pem");
117 }
118
TEST(VerifySignedDataTest,RsaPkcs1Sha1WrongAlgorithm)119 TEST(VerifySignedDataTest, RsaPkcs1Sha1WrongAlgorithm) {
120 RunTestCase(FAILURE, "rsa-pkcs1-sha1-wrong-algorithm.pem");
121 }
122
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512WrongSignatureFormat)123 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512WrongSignatureFormat) {
124 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-wrong-signature-format.pem");
125 }
126
TEST(VerifySignedDataTest,EcdsaUsingRsaKey)127 TEST(VerifySignedDataTest, EcdsaUsingRsaKey) {
128 RunTestCase(FAILURE, "ecdsa-using-rsa-key.pem");
129 }
130
TEST(VerifySignedDataTest,RsaUsingEcKey)131 TEST(VerifySignedDataTest, RsaUsingEcKey) {
132 RunTestCase(FAILURE, "rsa-using-ec-key.pem");
133 }
134
TEST(VerifySignedDataTest,RsaPkcs1Sha1BadKeyDerNull)135 TEST(VerifySignedDataTest, RsaPkcs1Sha1BadKeyDerNull) {
136 RunTestCase(FAILURE, "rsa-pkcs1-sha1-bad-key-der-null.pem");
137 }
138
TEST(VerifySignedDataTest,RsaPkcs1Sha1BadKeyDerLength)139 TEST(VerifySignedDataTest, RsaPkcs1Sha1BadKeyDerLength) {
140 RunTestCase(FAILURE, "rsa-pkcs1-sha1-bad-key-der-length.pem");
141 }
142
TEST(VerifySignedDataTest,RsaPkcs1Sha256UsingEcdsaAlgorithm)143 TEST(VerifySignedDataTest, RsaPkcs1Sha256UsingEcdsaAlgorithm) {
144 RunTestCase(FAILURE, "rsa-pkcs1-sha256-using-ecdsa-algorithm.pem");
145 }
146
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512UsingRsaAlgorithm)147 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512UsingRsaAlgorithm) {
148 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-using-rsa-algorithm.pem");
149 }
150
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512UsingEcdhKey)151 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512UsingEcdhKey) {
152 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-using-ecdh-key.pem");
153 }
154
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512UsingEcmqvKey)155 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512UsingEcmqvKey) {
156 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-using-ecmqv-key.pem");
157 }
158
TEST(VerifySignedDataTest,RsaPkcs1Sha1KeyParamsAbsent)159 TEST(VerifySignedDataTest, RsaPkcs1Sha1KeyParamsAbsent) {
160 RunTestCase(FAILURE, "rsa-pkcs1-sha1-key-params-absent.pem");
161 }
162
TEST(VerifySignedDataTest,RsaPkcs1Sha1UsingPssKeyNoParams)163 TEST(VerifySignedDataTest, RsaPkcs1Sha1UsingPssKeyNoParams) {
164 RunTestCase(FAILURE, "rsa-pkcs1-sha1-using-pss-key-no-params.pem");
165 }
166
TEST(VerifySignedDataTest,RsaPssSha256UsingPssKeyWithParams)167 TEST(VerifySignedDataTest, RsaPssSha256UsingPssKeyWithParams) {
168 // We do not support RSA-PSS SPKIs.
169 RunTestCase(FAILURE, "rsa-pss-sha256-using-pss-key-with-params.pem");
170 }
171
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512SpkiParamsNull)172 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512SpkiParamsNull) {
173 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-spki-params-null.pem");
174 }
175
TEST(VerifySignedDataTest,RsaPkcs1Sha256UsingIdEaRsa)176 TEST(VerifySignedDataTest, RsaPkcs1Sha256UsingIdEaRsa) {
177 RunTestCase(FAILURE, "rsa-pkcs1-sha256-using-id-ea-rsa.pem");
178 }
179
TEST(VerifySignedDataTest,RsaPkcs1Sha256SpkiNonNullParams)180 TEST(VerifySignedDataTest, RsaPkcs1Sha256SpkiNonNullParams) {
181 RunTestCase(FAILURE, "rsa-pkcs1-sha256-spki-non-null-params.pem");
182 }
183
TEST(VerifySignedDataTest,EcdsaPrime256v1Sha512UnusedBitsSignature)184 TEST(VerifySignedDataTest, EcdsaPrime256v1Sha512UnusedBitsSignature) {
185 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-unused-bits-signature.pem");
186 }
187
TEST(VerifySignedDataTest,Ecdsa384)188 TEST(VerifySignedDataTest, Ecdsa384) {
189 // Using the regular policy both secp384r1 and secp256r1 should be accepted.
190 RunTestCase(SUCCESS, "ecdsa-secp384r1-sha256.pem");
191 RunTestCase(SUCCESS, "ecdsa-prime256v1-sha512.pem");
192 }
193
TEST(VerifySignedDataTestWithCache,TestVerifyCache)194 TEST(VerifySignedDataTestWithCache, TestVerifyCache) {
195 MockSignatureVerifyCache verify_cache;
196 // Trivially, with no cache, all stats should be 0.
197 RunTestCase(SUCCESS, "rsa-pss-sha256.pem", /*cache=*/nullptr);
198 EXPECT_EQ(verify_cache.CacheHits(), 0U);
199 EXPECT_EQ(verify_cache.CacheMisses(), 0U);
200 EXPECT_EQ(verify_cache.CacheStores(), 0U);
201 // Use the cache, with a successful verification should see a miss and a
202 // store.
203 RunTestCase(SUCCESS, "rsa-pss-sha256.pem", &verify_cache);
204 EXPECT_EQ(verify_cache.CacheHits(), 0U);
205 EXPECT_EQ(verify_cache.CacheMisses(), 1U);
206 EXPECT_EQ(verify_cache.CacheStores(), 1U);
207 // Repeating the previous successful verification should show cache hits.
208 RunTestCase(SUCCESS, "rsa-pss-sha256.pem", &verify_cache);
209 RunTestCase(SUCCESS, "rsa-pss-sha256.pem", &verify_cache);
210 RunTestCase(SUCCESS, "rsa-pss-sha256.pem", &verify_cache);
211 EXPECT_EQ(verify_cache.CacheHits(), 3U);
212 EXPECT_EQ(verify_cache.CacheMisses(), 1U);
213 EXPECT_EQ(verify_cache.CacheStores(), 1U);
214 // Failures which are not due to a failed signature check should have no
215 // effect as they must not be cached.
216 RunTestCase(FAILURE, "ecdsa-prime256v1-sha512-using-ecdh-key.pem",
217 &verify_cache);
218 EXPECT_EQ(verify_cache.CacheHits(), 3U);
219 EXPECT_EQ(verify_cache.CacheMisses(), 1U);
220 EXPECT_EQ(verify_cache.CacheStores(), 1U);
221 // Failures which are due to a failed signature check should see a miss and a
222 // store.
223 RunTestCase(FAILURE, "ecdsa-secp384r1-sha256-corrupted-data.pem",
224 &verify_cache);
225 EXPECT_EQ(verify_cache.CacheHits(), 3U);
226 EXPECT_EQ(verify_cache.CacheMisses(), 2U);
227 EXPECT_EQ(verify_cache.CacheStores(), 2U);
228 // Repeating the previous failed verification should show cache hits.
229 RunTestCase(FAILURE, "ecdsa-secp384r1-sha256-corrupted-data.pem",
230 &verify_cache);
231 RunTestCase(FAILURE, "ecdsa-secp384r1-sha256-corrupted-data.pem",
232 &verify_cache);
233 RunTestCase(FAILURE, "ecdsa-secp384r1-sha256-corrupted-data.pem",
234 &verify_cache);
235 EXPECT_EQ(verify_cache.CacheHits(), 6U);
236 EXPECT_EQ(verify_cache.CacheMisses(), 2U);
237 EXPECT_EQ(verify_cache.CacheStores(), 2U);
238 }
239
240 } // namespace
241
242 } // namespace net
243