1 // Copyright 2020 The Chromium Authors. All rights reserved.
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 "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h"
6
7 #include "base/optional.h"
8 #include "chrome/browser/nearby_sharing/certificates/constants.h"
9 #include "chrome/browser/nearby_sharing/certificates/test_util.h"
10 #include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
11 #include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace {
15
16 // The for_selected_contacts field of a public certificate proto is irrelevant
17 // for remote device certificates. Even if set, it is meaningless. It only has
18 // meaning for private certificates converted to public certificates and
19 // uploaded to the Nearby server.
20 const nearby_share::mojom::Visibility kTestPublicCertificateVisibility =
21 nearby_share::mojom::Visibility::kNoOne;
22
23 } // namespace
24
TEST(NearbyShareDecryptedPublicCertificateTest,Decrypt)25 TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt) {
26 nearbyshare::proto::PublicCertificate proto_cert =
27 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
28
29 base::Optional<NearbyShareDecryptedPublicCertificate> cert =
30 NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
31 proto_cert, GetNearbyShareTestEncryptedMetadataKey());
32 EXPECT_TRUE(cert);
33 EXPECT_EQ(base::Time::FromJavaTime(proto_cert.start_time().seconds() * 1000),
34 cert->not_before());
35 EXPECT_EQ(base::Time::FromJavaTime(proto_cert.end_time().seconds() * 1000),
36 cert->not_after());
37 EXPECT_EQ(std::vector<uint8_t>(proto_cert.secret_id().begin(),
38 proto_cert.secret_id().end()),
39 cert->id());
40 EXPECT_EQ(GetNearbyShareTestMetadata().SerializeAsString(),
41 cert->unencrypted_metadata().SerializeAsString());
42 }
43
TEST(NearbyShareDecryptedPublicCertificateTest,Decrypt_IncorrectKeyFailure)44 TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt_IncorrectKeyFailure) {
45 // Input incorrect metadata encryption key.
46 EXPECT_FALSE(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
47 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
48 NearbyShareEncryptedMetadataKey(
49 std::vector<uint8_t>(kNearbyShareNumBytesMetadataEncryptionKeySalt,
50 0x00),
51 std::vector<uint8_t>(kNearbyShareNumBytesMetadataEncryptionKey,
52 0x00))));
53 }
54
TEST(NearbyShareDecryptedPublicCertificateTest,Decrypt_MetadataDecryptionFailure)55 TEST(NearbyShareDecryptedPublicCertificateTest,
56 Decrypt_MetadataDecryptionFailure) {
57 // Use metadata that cannot be decrypted with the given key.
58 nearbyshare::proto::PublicCertificate proto_cert =
59 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
60 proto_cert.set_encrypted_metadata_bytes("invalid metadata");
61 EXPECT_FALSE(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
62 proto_cert, GetNearbyShareTestEncryptedMetadataKey()));
63 }
64
TEST(NearbyShareDecryptedPublicCertificateTest,Decrypt_InvalidDataFailure)65 TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt_InvalidDataFailure) {
66 // Do not accept the input PublicCertificate because the validity period does
67 // not make sense.
68 nearbyshare::proto::PublicCertificate proto_cert =
69 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
70 proto_cert.mutable_end_time()->set_seconds(proto_cert.start_time().seconds() -
71 1);
72 EXPECT_FALSE(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
73 proto_cert, GetNearbyShareTestEncryptedMetadataKey()));
74 }
75
TEST(NearbyShareDecryptedPublicCertificateTest,Verify)76 TEST(NearbyShareDecryptedPublicCertificateTest, Verify) {
77 base::Optional<NearbyShareDecryptedPublicCertificate> cert =
78 NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
79 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
80 GetNearbyShareTestEncryptedMetadataKey());
81 EXPECT_TRUE(cert->VerifySignature(GetNearbyShareTestPayloadToSign(),
82 GetNearbyShareTestSampleSignature()));
83 }
84
TEST(NearbyShareDecryptedPublicCertificateTest,Verify_InitFailure)85 TEST(NearbyShareDecryptedPublicCertificateTest, Verify_InitFailure) {
86 // Public key has invalid SubjectPublicKeyInfo format.
87 nearbyshare::proto::PublicCertificate proto_cert =
88 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
89 proto_cert.set_public_key("invalid public key");
90
91 base::Optional<NearbyShareDecryptedPublicCertificate> cert =
92 NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
93 proto_cert, GetNearbyShareTestEncryptedMetadataKey());
94 ASSERT_TRUE(cert);
95 EXPECT_FALSE(cert->VerifySignature(GetNearbyShareTestPayloadToSign(),
96 GetNearbyShareTestSampleSignature()));
97 }
98
TEST(NearbyShareDecryptedPublicCertificateTest,Verify_WrongSignature)99 TEST(NearbyShareDecryptedPublicCertificateTest, Verify_WrongSignature) {
100 base::Optional<NearbyShareDecryptedPublicCertificate> cert =
101 NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
102 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
103 GetNearbyShareTestEncryptedMetadataKey());
104 EXPECT_FALSE(
105 cert->VerifySignature(GetNearbyShareTestPayloadToSign(),
106 /*signature=*/base::span<const uint8_t>()));
107 }
108
TEST(NearbyShareDecryptedPublicCertificateTest,HashAuthenticationToken)109 TEST(NearbyShareDecryptedPublicCertificateTest, HashAuthenticationToken) {
110 base::Optional<NearbyShareDecryptedPublicCertificate> cert =
111 NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
112 GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
113 GetNearbyShareTestEncryptedMetadataKey());
114 EXPECT_EQ(GetNearbyShareTestPayloadHashUsingSecretKey(),
115 cert->HashAuthenticationToken(GetNearbyShareTestPayloadToSign()));
116 }
117