| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/common/cast/cast_cert_validator.h" | 5 #include "components/cast_certificate/cast_cert_validator.h" |
| 6 | 6 |
| 7 #include "extensions/common/cast/cast_cert_validator_test_helpers.h" | 7 #include "components/cast_certificate/cast_cert_validator_test_helpers.h" |
| 8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
| 9 | 9 |
| 10 namespace extensions { | 10 namespace cast_certificate { |
| 11 | |
| 12 namespace api { | |
| 13 | |
| 14 namespace cast_crypto { | |
| 15 | 11 |
| 16 namespace { | 12 namespace { |
| 17 | 13 |
| 18 // Creates an std::string given a uint8_t array. | 14 // Creates an std::string given a uint8_t array. |
| 19 template <size_t N> | 15 template <size_t N> |
| 20 std::string CreateString(const uint8_t (&data)[N]) { | 16 std::string CreateString(const uint8_t (&data)[N]) { |
| 21 return std::string(reinterpret_cast<const char*>(data), N); | 17 return std::string(reinterpret_cast<const char*>(data), N); |
| 22 } | 18 } |
| 23 | 19 |
| 24 // Indicates the expected result of test verification. | 20 // Indicates the expected result of test verification. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 38 // * |time| - The timestamp to use when verifying the certificate. | 34 // * |time| - The timestamp to use when verifying the certificate. |
| 39 // * |optional_signed_data_file_name| - optional path to a PEM file containing | 35 // * |optional_signed_data_file_name| - optional path to a PEM file containing |
| 40 // a valid signature generated by the device certificate. | 36 // a valid signature generated by the device certificate. |
| 41 // | 37 // |
| 42 void RunTest(TestResult expected_result, | 38 void RunTest(TestResult expected_result, |
| 43 const std::string& expected_common_name, | 39 const std::string& expected_common_name, |
| 44 CastDeviceCertPolicy expected_policy, | 40 CastDeviceCertPolicy expected_policy, |
| 45 const std::string& certs_file_name, | 41 const std::string& certs_file_name, |
| 46 const base::Time::Exploded& time, | 42 const base::Time::Exploded& time, |
| 47 const std::string& optional_signed_data_file_name) { | 43 const std::string& optional_signed_data_file_name) { |
| 48 auto certs = cast_test_helpers::ReadCertificateChainFromFile(certs_file_name); | 44 auto certs = |
| 45 cast_certificate::testing::ReadCertificateChainFromFile(certs_file_name); |
| 49 | 46 |
| 50 std::unique_ptr<CertVerificationContext> context; | 47 std::unique_ptr<CertVerificationContext> context; |
| 51 CastDeviceCertPolicy policy; | 48 CastDeviceCertPolicy policy; |
| 52 bool result = VerifyDeviceCert(certs, time, &context, &policy); | 49 bool result = VerifyDeviceCert(certs, time, &context, &policy); |
| 53 | 50 |
| 54 if (expected_result == RESULT_FAIL) { | 51 if (expected_result == RESULT_FAIL) { |
| 55 ASSERT_FALSE(result); | 52 ASSERT_FALSE(result); |
| 56 return; | 53 return; |
| 57 } | 54 } |
| 58 | 55 |
| 59 ASSERT_TRUE(result); | 56 ASSERT_TRUE(result); |
| 60 EXPECT_EQ(expected_policy, policy); | 57 EXPECT_EQ(expected_policy, policy); |
| 61 ASSERT_TRUE(context.get()); | 58 ASSERT_TRUE(context.get()); |
| 62 | 59 |
| 63 // Test that the context is good. | 60 // Test that the context is good. |
| 64 EXPECT_EQ(expected_common_name, context->GetCommonName()); | 61 EXPECT_EQ(expected_common_name, context->GetCommonName()); |
| 65 | 62 |
| 66 ASSERT_TRUE(context); | 63 ASSERT_TRUE(context); |
| 67 | 64 |
| 68 // Test verification of some invalid signatures. | 65 // Test verification of some invalid signatures. |
| 69 EXPECT_FALSE( | 66 EXPECT_FALSE( |
| 70 context->VerifySignatureOverData("bogus signature", "bogus data")); | 67 context->VerifySignatureOverData("bogus signature", "bogus data")); |
| 71 EXPECT_FALSE(context->VerifySignatureOverData("", "bogus data")); | 68 EXPECT_FALSE(context->VerifySignatureOverData("", "bogus data")); |
| 72 EXPECT_FALSE(context->VerifySignatureOverData("", "")); | 69 EXPECT_FALSE(context->VerifySignatureOverData("", "")); |
| 73 | 70 |
| 74 // If valid signatures are known for this device certificate, test them. | 71 // If valid signatures are known for this device certificate, test them. |
| 75 if (!optional_signed_data_file_name.empty()) { | 72 if (!optional_signed_data_file_name.empty()) { |
| 76 auto signature_data = cast_test_helpers::ReadSignatureTestData( | 73 auto signature_data = cast_certificate::testing::ReadSignatureTestData( |
| 77 optional_signed_data_file_name); | 74 optional_signed_data_file_name); |
| 78 | 75 |
| 79 // Test verification of a valid SHA1 signature. | 76 // Test verification of a valid SHA1 signature. |
| 80 EXPECT_TRUE(context->VerifySignatureOverData(signature_data.signature_sha1, | 77 EXPECT_TRUE(context->VerifySignatureOverData(signature_data.signature_sha1, |
| 81 signature_data.message)); | 78 signature_data.message)); |
| 82 | 79 |
| 83 // Test verification of a valid SHA256 | 80 // Test verification of a valid SHA256 |
| 84 // | 81 // |
| 85 // TODO(eroman): This fails because there isn't currently support | 82 // TODO(eroman): This fails because there isn't currently support |
| 86 // for specifying a signature algorithm other than RSASSA PKCS#1 v1.5 with | 83 // for specifying a signature algorithm other than RSASSA PKCS#1 v1.5 with |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 120 |
| 124 // Tests verifying a valid certificate chain of length 2: | 121 // Tests verifying a valid certificate chain of length 2: |
| 125 // | 122 // |
| 126 // 0: 2ZZBG9 FA8FCA3EF91A | 123 // 0: 2ZZBG9 FA8FCA3EF91A |
| 127 // 1: Eureka Gen1 ICA | 124 // 1: Eureka Gen1 ICA |
| 128 // | 125 // |
| 129 // Chains to trust anchor: | 126 // Chains to trust anchor: |
| 130 // Eureka Root CA (not included) | 127 // Eureka Root CA (not included) |
| 131 TEST(VerifyCastDeviceCertTest, ChromecastGen1) { | 128 TEST(VerifyCastDeviceCertTest, ChromecastGen1) { |
| 132 RunTest(RESULT_SUCCESS, "2ZZBG9 FA8FCA3EF91A", CastDeviceCertPolicy::NONE, | 129 RunTest(RESULT_SUCCESS, "2ZZBG9 FA8FCA3EF91A", CastDeviceCertPolicy::NONE, |
| 133 "cast_certificates/chromecast_gen1.pem", AprilFirst2016(), | 130 "certificates/chromecast_gen1.pem", AprilFirst2016(), |
| 134 "cast_signeddata/2ZZBG9_FA8FCA3EF91A.pem"); | 131 "signeddata/2ZZBG9_FA8FCA3EF91A.pem"); |
| 135 } | 132 } |
| 136 | 133 |
| 137 // Tests verifying a valid certificate chain of length 2: | 134 // Tests verifying a valid certificate chain of length 2: |
| 138 // | 135 // |
| 139 // 0: 2ZZBG9 FA8FCA3EF91A | 136 // 0: 2ZZBG9 FA8FCA3EF91A |
| 140 // 1: Eureka Gen1 ICA | 137 // 1: Eureka Gen1 ICA |
| 141 // | 138 // |
| 142 // Chains to trust anchor: | 139 // Chains to trust anchor: |
| 143 // Cast Root CA (not included) | 140 // Cast Root CA (not included) |
| 144 TEST(VerifyCastDeviceCertTest, ChromecastGen1Reissue) { | 141 TEST(VerifyCastDeviceCertTest, ChromecastGen1Reissue) { |
| 145 RunTest(RESULT_SUCCESS, "2ZZBG9 FA8FCA3EF91A", CastDeviceCertPolicy::NONE, | 142 RunTest(RESULT_SUCCESS, "2ZZBG9 FA8FCA3EF91A", CastDeviceCertPolicy::NONE, |
| 146 "cast_certificates/chromecast_gen1_reissue.pem", AprilFirst2016(), | 143 "certificates/chromecast_gen1_reissue.pem", AprilFirst2016(), |
| 147 "cast_signeddata/2ZZBG9_FA8FCA3EF91A.pem"); | 144 "signeddata/2ZZBG9_FA8FCA3EF91A.pem"); |
| 148 } | 145 } |
| 149 | 146 |
| 150 // Tests verifying a valid certificate chain of length 2: | 147 // Tests verifying a valid certificate chain of length 2: |
| 151 // | 148 // |
| 152 // 0: 3ZZAK6 FA8FCA3F0D35 | 149 // 0: 3ZZAK6 FA8FCA3F0D35 |
| 153 // 1: Chromecast ICA 3 | 150 // 1: Chromecast ICA 3 |
| 154 // | 151 // |
| 155 // Chains to trust anchor: | 152 // Chains to trust anchor: |
| 156 // Cast Root CA (not included) | 153 // Cast Root CA (not included) |
| 157 TEST(VerifyCastDeviceCertTest, ChromecastGen2) { | 154 TEST(VerifyCastDeviceCertTest, ChromecastGen2) { |
| 158 RunTest(RESULT_SUCCESS, "3ZZAK6 FA8FCA3F0D35", CastDeviceCertPolicy::NONE, | 155 RunTest(RESULT_SUCCESS, "3ZZAK6 FA8FCA3F0D35", CastDeviceCertPolicy::NONE, |
| 159 "cast_certificates/chromecast_gen2.pem", AprilFirst2016(), ""); | 156 "certificates/chromecast_gen2.pem", AprilFirst2016(), ""); |
| 160 } | 157 } |
| 161 | 158 |
| 162 // Tests verifying a valid certificate chain of length 3: | 159 // Tests verifying a valid certificate chain of length 3: |
| 163 // | 160 // |
| 164 // 0: -6394818897508095075 | 161 // 0: -6394818897508095075 |
| 165 // 1: Asus fugu Cast ICA | 162 // 1: Asus fugu Cast ICA |
| 166 // 2: Widevine Cast Subroot | 163 // 2: Widevine Cast Subroot |
| 167 // | 164 // |
| 168 // Chains to trust anchor: | 165 // Chains to trust anchor: |
| 169 // Cast Root CA (not included) | 166 // Cast Root CA (not included) |
| 170 TEST(VerifyCastDeviceCertTest, Fugu) { | 167 TEST(VerifyCastDeviceCertTest, Fugu) { |
| 171 RunTest(RESULT_SUCCESS, "-6394818897508095075", CastDeviceCertPolicy::NONE, | 168 RunTest(RESULT_SUCCESS, "-6394818897508095075", CastDeviceCertPolicy::NONE, |
| 172 "cast_certificates/fugu.pem", AprilFirst2016(), ""); | 169 "certificates/fugu.pem", AprilFirst2016(), ""); |
| 173 } | 170 } |
| 174 | 171 |
| 175 // Tests verifying an invalid certificate chain of length 1: | 172 // Tests verifying an invalid certificate chain of length 1: |
| 176 // | 173 // |
| 177 // 0: Cast Test Untrusted Device | 174 // 0: Cast Test Untrusted Device |
| 178 // | 175 // |
| 179 // Chains to: | 176 // Chains to: |
| 180 // Cast Test Untrusted ICA (not included) | 177 // Cast Test Untrusted ICA (not included) |
| 181 // | 178 // |
| 182 // This is invalid because it does not chain to a trust anchor. | 179 // This is invalid because it does not chain to a trust anchor. |
| 183 TEST(VerifyCastDeviceCertTest, Unchained) { | 180 TEST(VerifyCastDeviceCertTest, Unchained) { |
| 184 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, | 181 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, |
| 185 "cast_certificates/unchained.pem", AprilFirst2016(), ""); | 182 "certificates/unchained.pem", AprilFirst2016(), ""); |
| 186 } | 183 } |
| 187 | 184 |
| 188 // Tests verifying one of the self-signed trust anchors (chain of length 1): | 185 // Tests verifying one of the self-signed trust anchors (chain of length 1): |
| 189 // | 186 // |
| 190 // 0: Cast Root CA | 187 // 0: Cast Root CA |
| 191 // | 188 // |
| 192 // Chains to trust anchor: | 189 // Chains to trust anchor: |
| 193 // Cast Root CA | 190 // Cast Root CA |
| 194 // | 191 // |
| 195 // Although this is a valid and trusted certificate (it is one of the | 192 // Although this is a valid and trusted certificate (it is one of the |
| 196 // trust anchors after all) it fails the test as it is not a *device | 193 // trust anchors after all) it fails the test as it is not a *device |
| 197 // certificate*. | 194 // certificate*. |
| 198 TEST(VerifyCastDeviceCertTest, CastRootCa) { | 195 TEST(VerifyCastDeviceCertTest, CastRootCa) { |
| 199 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, | 196 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, |
| 200 "cast_certificates/cast_root_ca.pem", AprilFirst2016(), ""); | 197 "certificates/cast_root_ca.pem", AprilFirst2016(), ""); |
| 201 } | 198 } |
| 202 | 199 |
| 203 // Tests verifying a valid certificate chain of length 2: | 200 // Tests verifying a valid certificate chain of length 2: |
| 204 // | 201 // |
| 205 // 0: 4ZZDZJ FA8FCA7EFE3C | 202 // 0: 4ZZDZJ FA8FCA7EFE3C |
| 206 // 1: Chromecast ICA 4 (Audio) | 203 // 1: Chromecast ICA 4 (Audio) |
| 207 // | 204 // |
| 208 // Chains to trust anchor: | 205 // Chains to trust anchor: |
| 209 // Cast Root CA (not included) | 206 // Cast Root CA (not included) |
| 210 // | 207 // |
| 211 // This device certificate has a policy that means it is valid only for audio | 208 // This device certificate has a policy that means it is valid only for audio |
| 212 // devices. | 209 // devices. |
| 213 TEST(VerifyCastDeviceCertTest, ChromecastAudio) { | 210 TEST(VerifyCastDeviceCertTest, ChromecastAudio) { |
| 214 RunTest(RESULT_SUCCESS, "4ZZDZJ FA8FCA7EFE3C", | 211 RunTest(RESULT_SUCCESS, "4ZZDZJ FA8FCA7EFE3C", |
| 215 CastDeviceCertPolicy::AUDIO_ONLY, | 212 CastDeviceCertPolicy::AUDIO_ONLY, "certificates/chromecast_audio.pem", |
| 216 "cast_certificates/chromecast_audio.pem", AprilFirst2016(), ""); | 213 AprilFirst2016(), ""); |
| 217 } | 214 } |
| 218 | 215 |
| 219 // Tests verifying a valid certificate chain of length 3: | 216 // Tests verifying a valid certificate chain of length 3: |
| 220 // | 217 // |
| 221 // 0: MediaTek Audio Dev Test | 218 // 0: MediaTek Audio Dev Test |
| 222 // 1: MediaTek Audio Dev Model | 219 // 1: MediaTek Audio Dev Model |
| 223 // 2: Cast Audio Dev Root CA | 220 // 2: Cast Audio Dev Root CA |
| 224 // | 221 // |
| 225 // Chains to trust anchor: | 222 // Chains to trust anchor: |
| 226 // Cast Root CA (not included) | 223 // Cast Root CA (not included) |
| 227 // | 224 // |
| 228 // This device certificate has a policy that means it is valid only for audio | 225 // This device certificate has a policy that means it is valid only for audio |
| 229 // devices. | 226 // devices. |
| 230 TEST(VerifyCastDeviceCertTest, MtkAudioDev) { | 227 TEST(VerifyCastDeviceCertTest, MtkAudioDev) { |
| 231 RunTest(RESULT_SUCCESS, "MediaTek Audio Dev Test", | 228 RunTest(RESULT_SUCCESS, "MediaTek Audio Dev Test", |
| 232 CastDeviceCertPolicy::AUDIO_ONLY, | 229 CastDeviceCertPolicy::AUDIO_ONLY, "certificates/mtk_audio_dev.pem", |
| 233 "cast_certificates/mtk_audio_dev.pem", JanuaryFirst2015(), ""); | 230 JanuaryFirst2015(), ""); |
| 234 } | 231 } |
| 235 | 232 |
| 236 // Tests verifying a valid certificate chain of length 2: | 233 // Tests verifying a valid certificate chain of length 2: |
| 237 // | 234 // |
| 238 // 0: 9V0000VB FA8FCA784D01 | 235 // 0: 9V0000VB FA8FCA784D01 |
| 239 // 1: Cast TV ICA (Vizio) | 236 // 1: Cast TV ICA (Vizio) |
| 240 // | 237 // |
| 241 // Chains to trust anchor: | 238 // Chains to trust anchor: |
| 242 // Cast Root CA (not included) | 239 // Cast Root CA (not included) |
| 243 TEST(VerifyCastDeviceCertTest, Vizio) { | 240 TEST(VerifyCastDeviceCertTest, Vizio) { |
| 244 RunTest(RESULT_SUCCESS, "9V0000VB FA8FCA784D01", CastDeviceCertPolicy::NONE, | 241 RunTest(RESULT_SUCCESS, "9V0000VB FA8FCA784D01", CastDeviceCertPolicy::NONE, |
| 245 "cast_certificates/vizio.pem", AprilFirst2016(), ""); | 242 "certificates/vizio.pem", AprilFirst2016(), ""); |
| 246 } | 243 } |
| 247 | 244 |
| 248 // Tests verifying a valid certificate chain of length 2 using expired | 245 // Tests verifying a valid certificate chain of length 2 using expired |
| 249 // time points. | 246 // time points. |
| 250 TEST(VerifyCastDeviceCertTest, ChromecastGen2InvalidTime) { | 247 TEST(VerifyCastDeviceCertTest, ChromecastGen2InvalidTime) { |
| 251 const char* kCertsFile = "cast_certificates/chromecast_gen2.pem"; | 248 const char* kCertsFile = "certificates/chromecast_gen2.pem"; |
| 252 | 249 |
| 253 // Control test - certificate should be valid at some time otherwise | 250 // Control test - certificate should be valid at some time otherwise |
| 254 // this test is pointless. | 251 // this test is pointless. |
| 255 RunTest(RESULT_SUCCESS, "3ZZAK6 FA8FCA3F0D35", CastDeviceCertPolicy::NONE, | 252 RunTest(RESULT_SUCCESS, "3ZZAK6 FA8FCA3F0D35", CastDeviceCertPolicy::NONE, |
| 256 kCertsFile, AprilFirst2016(), ""); | 253 kCertsFile, AprilFirst2016(), ""); |
| 257 | 254 |
| 258 // Use a time before notBefore. | 255 // Use a time before notBefore. |
| 259 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, kCertsFile, | 256 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, kCertsFile, |
| 260 JanuaryFirst2015(), ""); | 257 JanuaryFirst2015(), ""); |
| 261 | 258 |
| 262 // Use a time after notAfter. | 259 // Use a time after notAfter. |
| 263 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, kCertsFile, | 260 RunTest(RESULT_FAIL, "", CastDeviceCertPolicy::NONE, kCertsFile, |
| 264 MarchFirst2040(), ""); | 261 MarchFirst2040(), ""); |
| 265 } | 262 } |
| 266 | 263 |
| 267 // Tests verifying a valid certificate chain of length 3: | 264 // Tests verifying a valid certificate chain of length 3: |
| 268 // | 265 // |
| 269 // 0: Audio Reference Dev Test | 266 // 0: Audio Reference Dev Test |
| 270 // 1: Audio Reference Dev Model | 267 // 1: Audio Reference Dev Model |
| 271 // 2: Cast Audio Dev Root CA | 268 // 2: Cast Audio Dev Root CA |
| 272 // | 269 // |
| 273 // Chains to trust anchor: | 270 // Chains to trust anchor: |
| 274 // Cast Root CA (not included) | 271 // Cast Root CA (not included) |
| 275 // | 272 // |
| 276 // This device certificate has a policy that means it is valid only for audio | 273 // This device certificate has a policy that means it is valid only for audio |
| 277 // devices. | 274 // devices. |
| 278 TEST(VerifyCastDeviceCertTest, AudioRefDevTestChain3) { | 275 TEST(VerifyCastDeviceCertTest, AudioRefDevTestChain3) { |
| 279 RunTest(RESULT_SUCCESS, "Audio Reference Dev Test", | 276 RunTest(RESULT_SUCCESS, "Audio Reference Dev Test", |
| 280 CastDeviceCertPolicy::AUDIO_ONLY, | 277 CastDeviceCertPolicy::AUDIO_ONLY, |
| 281 "cast_certificates/audio_ref_dev_test_chain_3.pem", AprilFirst2016(), | 278 "certificates/audio_ref_dev_test_chain_3.pem", AprilFirst2016(), |
| 282 "cast_signeddata/AudioReferenceDevTest.pem"); | 279 "signeddata/AudioReferenceDevTest.pem"); |
| 283 } | 280 } |
| 284 | 281 |
| 285 // ------------------------------------------------------ | 282 // ------------------------------------------------------ |
| 286 // Valid signature using 1024-bit RSA key | 283 // Valid signature using 1024-bit RSA key |
| 287 // ------------------------------------------------------ | 284 // ------------------------------------------------------ |
| 288 | 285 |
| 289 // This test vector comes from the NIST test vectors (pkcs1v15sign-vectors.txt), | 286 // This test vector comes from the NIST test vectors (pkcs1v15sign-vectors.txt), |
| 290 // PKCS#1 v1.5 Signature Example 1.2. | 287 // PKCS#1 v1.5 Signature Example 1.2. |
| 291 // | 288 // |
| 292 // It is a valid signature using a 1024 bit key and SHA-1. | 289 // It is a valid signature using a 1024 bit key and SHA-1. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 TEST(VerifyCastDeviceCertTest, VerifySignature2048BitRsa) { | 406 TEST(VerifyCastDeviceCertTest, VerifySignature2048BitRsa) { |
| 410 auto context = | 407 auto context = |
| 411 CertVerificationContextImplForTest(CreateString(kEx2PublicKeySpki)); | 408 CertVerificationContextImplForTest(CreateString(kEx2PublicKeySpki)); |
| 412 | 409 |
| 413 EXPECT_TRUE(context->VerifySignatureOverData(CreateString(kEx2Signature), | 410 EXPECT_TRUE(context->VerifySignatureOverData(CreateString(kEx2Signature), |
| 414 CreateString(kEx2Message))); | 411 CreateString(kEx2Message))); |
| 415 } | 412 } |
| 416 | 413 |
| 417 } // namespace | 414 } // namespace |
| 418 | 415 |
| 419 } // namespace cast_crypto | 416 } // namespace cast_certificate |
| 420 | |
| 421 } // namespace api | |
| 422 | |
| 423 } // namespace extensions | |
| OLD | NEW |