• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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