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