Commit e1de5c2f authored by Josh Nohle's avatar Josh Nohle Committed by Commit Bot

[Nearby] Add method to get private certs as public certs

Add a method to the certificate manager that returns all of the local
device private certificates of a given visibility, converted to public
certificates.

This feature was requested in crrev/c/2346325.

Bug: 1114765
Change-Id: Ifec56ec08a6072018f35e5e0121ecf9562201faf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2348295
Commit-Queue: Josh Nohle <nohle@chromium.org>
Reviewed-by: default avatarHimanshu Jaju <himanshujaju@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798246}
parent 72a154e0
......@@ -68,7 +68,8 @@ TEST(NearbyShareCertificatesCommonTest, ValidityPeriod_PrivateCertificate) {
TEST(NearbyShareCertificatesCommonTest, ValidityPeriod_PublicCertificate) {
NearbyShareDecryptedPublicCertificate cert =
*NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(
NearbyShareVisibility::kAllContacts),
GetNearbyShareTestEncryptedMetadataKey());
const bool use_public_certificate_tolerance = true;
......
......@@ -50,6 +50,13 @@ FakeNearbyShareCertificateManager::GetValidPrivateCertificate(
return GetNearbyShareTestPrivateCertificate(visibility);
}
std::vector<nearbyshare::proto::PublicCertificate>
FakeNearbyShareCertificateManager::GetPrivateCertificatesAsPublicCertificates(
NearbyShareVisibility visibility) {
++num_get_private_certificates_as_public_certificates_calls_;
return GetNearbyShareTestPublicCertificateList(visibility);
}
void FakeNearbyShareCertificateManager::GetDecryptedPublicCertificate(
NearbyShareEncryptedMetadataKey encrypted_metadata_key,
CertDecryptedCallback callback) {
......
......@@ -13,6 +13,7 @@
#include "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_private_certificate.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
// A fake implementation of NearbyShareCertificateManager, along with a fake
// factory, to be used in tests.
......@@ -64,6 +65,9 @@ class FakeNearbyShareCertificateManager : public NearbyShareCertificateManager {
// NearbyShareCertificateManager:
NearbySharePrivateCertificate GetValidPrivateCertificate(
NearbyShareVisibility visibility) override;
std::vector<nearbyshare::proto::PublicCertificate>
GetPrivateCertificatesAsPublicCertificates(
NearbyShareVisibility visibility) override;
void GetDecryptedPublicCertificate(
NearbyShareEncryptedMetadataKey encrypted_metadata_key,
CertDecryptedCallback callback) override;
......@@ -77,6 +81,10 @@ class FakeNearbyShareCertificateManager : public NearbyShareCertificateManager {
return num_get_valid_private_certificate_calls_;
}
size_t num_get_private_certificates_as_public_certificates_calls() {
return num_get_private_certificates_as_public_certificates_calls_;
}
size_t num_download_public_certificates_calls() {
return num_download_public_certificates_calls_;
}
......@@ -92,6 +100,7 @@ class FakeNearbyShareCertificateManager : public NearbyShareCertificateManager {
void OnStop() override;
size_t num_get_valid_private_certificate_calls_ = 0;
size_t num_get_private_certificates_as_public_certificates_calls_ = 0;
size_t num_download_public_certificates_calls_ = 0;
std::vector<GetDecryptedPublicCertificateCall>
get_decrypted_public_certificate_calls_;
......
......@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_NEARBY_SHARING_CERTIFICATES_NEARBY_SHARE_CERTIFICATE_MANAGER_H_
#define CHROME_BROWSER_NEARBY_SHARING_CERTIFICATES_NEARBY_SHARE_CERTIFICATE_MANAGER_H_
#include <vector>
#include "base/callback.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
......@@ -13,6 +15,7 @@
#include "chrome/browser/nearby_sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_private_certificate.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_visibility.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
// The Nearby Share certificate manager maintains the local device's private
// certificates and contacts' public certificates. The manager communicates with
......@@ -50,6 +53,16 @@ class NearbyShareCertificateManager {
virtual NearbySharePrivateCertificate GetValidPrivateCertificate(
NearbyShareVisibility visibility) = 0;
// Returns all local device private certificates of |visibility| converted to
// public certificates. The public certificates' for_selected_contacts fields
// will be set to reflect the |visibility|. NOTE: Only certificates with the
// requested visibility will be returned; if selected-contacts visibility is
// passed in, the all-contacts visibility certificates will *not* be returned
// as well.
virtual std::vector<nearbyshare::proto::PublicCertificate>
GetPrivateCertificatesAsPublicCertificates(
NearbyShareVisibility visibility) = 0;
// Returns in |callback| the public certificate that is able to be decrypted
// using |encrypted_metadata_key|, and returns base::nullopt if no such public
// certificate exists.
......
......@@ -46,6 +46,13 @@ NearbyShareCertificateManagerImpl::GetValidPrivateCertificate(
nearbyshare::proto::EncryptedMetadata());
}
std::vector<nearbyshare::proto::PublicCertificate>
NearbyShareCertificateManagerImpl::GetPrivateCertificatesAsPublicCertificates(
NearbyShareVisibility visibility) {
NOTIMPLEMENTED();
return std::vector<nearbyshare::proto::PublicCertificate>();
}
void NearbyShareCertificateManagerImpl::GetDecryptedPublicCertificate(
NearbyShareEncryptedMetadataKey encrypted_metadata_key,
CertDecryptedCallback callback) {
......
......@@ -6,11 +6,13 @@
#define CHROME_BROWSER_NEARBY_SHARING_CERTIFICATES_NEARBY_SHARE_CERTIFICATE_MANAGER_IMPL_H_
#include <memory>
#include <vector>
#include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_private_certificate.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_visibility.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
// TODO(nohle): Add description after class is fully implemented.
class NearbyShareCertificateManagerImpl : public NearbyShareCertificateManager {
......@@ -36,6 +38,9 @@ class NearbyShareCertificateManagerImpl : public NearbyShareCertificateManager {
// NearbyShareCertificateManager:
NearbySharePrivateCertificate GetValidPrivateCertificate(
NearbyShareVisibility visibility) override;
std::vector<nearbyshare::proto::PublicCertificate>
GetPrivateCertificatesAsPublicCertificates(
NearbyShareVisibility visibility) override;
void GetDecryptedPublicCertificate(
NearbyShareEncryptedMetadataKey encrypted_metadata_key,
CertDecryptedCallback callback) override;
......
......@@ -10,23 +10,31 @@
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// The for_selected_contacts field of a public certificate proto is irrelevant
// for remote device certificates. Even if set, it is meaningless. It only has
// meaning for private certificates converted to public certificates and
// uploaded to the Nearby server.
const NearbyShareVisibility kTestPublicCertificateVisibility =
NearbyShareVisibility::kNoOne;
} // namespace
TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt) {
nearbyshare::proto::PublicCertificate proto_cert =
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
base::Optional<NearbyShareDecryptedPublicCertificate> cert =
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestEncryptedMetadataKey());
proto_cert, GetNearbyShareTestEncryptedMetadataKey());
EXPECT_TRUE(cert);
EXPECT_EQ(
base::Time::FromJavaTime(
GetNearbyShareTestPublicCertificate().start_time().seconds() * 1000),
cert->not_before());
EXPECT_EQ(
base::Time::FromJavaTime(
GetNearbyShareTestPublicCertificate().end_time().seconds() * 1000),
cert->not_after());
EXPECT_EQ(std::vector<uint8_t>(
GetNearbyShareTestPublicCertificate().secret_id().begin(),
GetNearbyShareTestPublicCertificate().secret_id().end()),
EXPECT_EQ(base::Time::FromJavaTime(proto_cert.start_time().seconds() * 1000),
cert->not_before());
EXPECT_EQ(base::Time::FromJavaTime(proto_cert.end_time().seconds() * 1000),
cert->not_after());
EXPECT_EQ(std::vector<uint8_t>(proto_cert.secret_id().begin(),
proto_cert.secret_id().end()),
cert->id());
EXPECT_EQ(GetNearbyShareTestMetadata().SerializeAsString(),
cert->unencrypted_metadata().SerializeAsString());
......@@ -35,7 +43,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt) {
TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt_IncorrectKeyFailure) {
// Input incorrect metadata encryption key.
EXPECT_FALSE(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
NearbyShareEncryptedMetadataKey(
std::vector<uint8_t>(kNearbyShareNumBytesMetadataEncryptionKeySalt,
0x00),
......@@ -47,7 +55,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest,
Decrypt_MetadataDecryptionFailure) {
// Use metadata that cannot be decrypted with the given key.
nearbyshare::proto::PublicCertificate proto_cert =
GetNearbyShareTestPublicCertificate();
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
proto_cert.set_encrypted_metadata_bytes("invalid metadata");
EXPECT_FALSE(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
proto_cert, GetNearbyShareTestEncryptedMetadataKey()));
......@@ -57,7 +65,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt_InvalidDataFailure) {
// Do not accept the input PublicCertificate because the validity period does
// not make sense.
nearbyshare::proto::PublicCertificate proto_cert =
GetNearbyShareTestPublicCertificate();
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
proto_cert.mutable_end_time()->set_seconds(proto_cert.start_time().seconds() -
1);
EXPECT_FALSE(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
......@@ -67,7 +75,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt_InvalidDataFailure) {
TEST(NearbyShareDecryptedPublicCertificateTest, Verify) {
base::Optional<NearbyShareDecryptedPublicCertificate> cert =
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
GetNearbyShareTestEncryptedMetadataKey());
EXPECT_TRUE(cert->VerifySignature(GetNearbyShareTestPayloadToSign(),
GetNearbyShareTestSampleSignature()));
......@@ -76,7 +84,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Verify) {
TEST(NearbyShareDecryptedPublicCertificateTest, Verify_InitFailure) {
// Public key has invalid SubjectPublicKeyInfo format.
nearbyshare::proto::PublicCertificate proto_cert =
GetNearbyShareTestPublicCertificate();
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
proto_cert.set_public_key("invalid public key");
base::Optional<NearbyShareDecryptedPublicCertificate> cert =
......@@ -90,7 +98,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Verify_InitFailure) {
TEST(NearbyShareDecryptedPublicCertificateTest, Verify_WrongSignature) {
base::Optional<NearbyShareDecryptedPublicCertificate> cert =
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
GetNearbyShareTestEncryptedMetadataKey());
EXPECT_FALSE(
cert->VerifySignature(GetNearbyShareTestPayloadToSign(),
......@@ -100,7 +108,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Verify_WrongSignature) {
TEST(NearbyShareDecryptedPublicCertificateTest, HashAuthenticationToken) {
base::Optional<NearbyShareDecryptedPublicCertificate> cert =
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility),
GetNearbyShareTestEncryptedMetadataKey());
EXPECT_EQ(GetNearbyShareTestPayloadHashUsingSecretKey(),
cert->HashAuthenticationToken(GetNearbyShareTestPayloadToSign()));
......
......@@ -104,12 +104,15 @@ TEST(NearbySharePrivateCertificateTest,
TEST(NearbySharePrivateCertificateTest, PublicCertificateConversion) {
NearbySharePrivateCertificate private_certificate =
GetNearbyShareTestPrivateCertificate(NearbyShareVisibility::kAllContacts);
GetNearbyShareTestPrivateCertificate(
NearbyShareVisibility::kSelectedContacts);
private_certificate.offset_for_testing() = GetNearbyShareTestValidityOffset();
base::Optional<nearbyshare::proto::PublicCertificate> public_certificate =
private_certificate.ToPublicCertificate();
ASSERT_TRUE(public_certificate);
EXPECT_EQ(GetNearbyShareTestPublicCertificate().SerializeAsString(),
EXPECT_EQ(GetNearbyShareTestPublicCertificate(
NearbyShareVisibility::kSelectedContacts)
.SerializeAsString(),
public_certificate->SerializeAsString());
}
......
......@@ -229,10 +229,11 @@ const std::vector<uint8_t>& GetNearbyShareTestPayloadHashUsingSecretKey() {
}
NearbySharePrivateCertificate GetNearbyShareTestPrivateCertificate(
NearbyShareVisibility visibility) {
NearbyShareVisibility visibility,
base::Time not_before) {
NearbySharePrivateCertificate cert(
visibility, GetNearbyShareTestNotBefore(),
GetNearbyShareTestNotBefore() + kNearbyShareCertificateValidityPeriod,
visibility, not_before,
not_before + kNearbyShareCertificateValidityPeriod,
GetNearbyShareTestP256KeyPair(), GetNearbyShareTestSecretKey(),
GetNearbyShareTestMetadataEncryptionKey(),
GetNearbyShareTestCertificateId(), GetNearbyShareTestMetadata(),
......@@ -241,49 +242,64 @@ NearbySharePrivateCertificate GetNearbyShareTestPrivateCertificate(
return cert;
}
const nearbyshare::proto::PublicCertificate&
GetNearbyShareTestPublicCertificate() {
static const base::NoDestructor<nearbyshare::proto::PublicCertificate> cert(
[] {
nearbyshare::proto::PublicCertificate cert;
cert.set_secret_id(
std::string(GetNearbyShareTestCertificateId().begin(),
GetNearbyShareTestCertificateId().end()));
cert.set_secret_key(GetNearbyShareTestSecretKey()->key());
cert.set_public_key(
std::string(GetNearbyShareTestP256PublicKey().begin(),
GetNearbyShareTestP256PublicKey().end()));
cert.mutable_start_time()->set_seconds(
(GetNearbyShareTestNotBefore() - GetNearbyShareTestValidityOffset())
.ToJavaTime() /
1000);
cert.mutable_end_time()->set_seconds(
(GetNearbyShareTestNotBefore() +
kNearbyShareCertificateValidityPeriod +
GetNearbyShareTestValidityOffset())
.ToJavaTime() /
1000);
cert.set_for_selected_contacts(false);
cert.set_metadata_encryption_key(
std::string(GetNearbyShareTestMetadataEncryptionKey().begin(),
GetNearbyShareTestMetadataEncryptionKey().end()));
cert.set_encrypted_metadata_bytes(
std::string(GetNearbyShareTestEncryptedMetadata().begin(),
GetNearbyShareTestEncryptedMetadata().end()));
cert.set_metadata_encryption_key_tag(
std::string(GetNearbyShareTestMetadataEncryptionKeyTag().begin(),
GetNearbyShareTestMetadataEncryptionKeyTag().end()));
return cert;
}());
return *cert;
nearbyshare::proto::PublicCertificate GetNearbyShareTestPublicCertificate(
NearbyShareVisibility visibility,
base::Time not_before) {
nearbyshare::proto::PublicCertificate cert;
cert.set_secret_id(std::string(GetNearbyShareTestCertificateId().begin(),
GetNearbyShareTestCertificateId().end()));
cert.set_secret_key(GetNearbyShareTestSecretKey()->key());
cert.set_public_key(std::string(GetNearbyShareTestP256PublicKey().begin(),
GetNearbyShareTestP256PublicKey().end()));
cert.mutable_start_time()->set_seconds(
(not_before - GetNearbyShareTestValidityOffset()).ToJavaTime() / 1000);
cert.mutable_end_time()->set_seconds((not_before +
kNearbyShareCertificateValidityPeriod +
GetNearbyShareTestValidityOffset())
.ToJavaTime() /
1000);
cert.set_for_selected_contacts(visibility ==
NearbyShareVisibility::kSelectedContacts);
cert.set_metadata_encryption_key(
std::string(GetNearbyShareTestMetadataEncryptionKey().begin(),
GetNearbyShareTestMetadataEncryptionKey().end()));
cert.set_encrypted_metadata_bytes(
std::string(GetNearbyShareTestEncryptedMetadata().begin(),
GetNearbyShareTestEncryptedMetadata().end()));
cert.set_metadata_encryption_key_tag(
std::string(GetNearbyShareTestMetadataEncryptionKeyTag().begin(),
GetNearbyShareTestMetadataEncryptionKeyTag().end()));
return cert;
}
std::vector<NearbySharePrivateCertificate>
GetNearbyShareTestPrivateCertificateList(NearbyShareVisibility visibility) {
std::vector<NearbySharePrivateCertificate> list;
for (size_t i = 0; i < kNearbyShareNumPrivateCertificates; ++i) {
list.push_back(GetNearbyShareTestPrivateCertificate(
visibility, GetNearbyShareTestNotBefore() +
i * kNearbyShareCertificateValidityPeriod));
}
return list;
}
std::vector<nearbyshare::proto::PublicCertificate>
GetNearbyShareTestPublicCertificateList(NearbyShareVisibility visibility) {
std::vector<nearbyshare::proto::PublicCertificate> list;
for (size_t i = 0; i < kNearbyShareNumPrivateCertificates; ++i) {
list.push_back(GetNearbyShareTestPublicCertificate(
visibility, GetNearbyShareTestNotBefore() +
i * kNearbyShareCertificateValidityPeriod));
}
return list;
}
const NearbyShareDecryptedPublicCertificate&
GetNearbyShareTestDecryptedPublicCertificate() {
static const base::NoDestructor<NearbyShareDecryptedPublicCertificate> cert(
*NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(
NearbyShareVisibility::kAllContacts),
GetNearbyShareTestEncryptedMetadataKey()));
return *cert;
}
......@@ -42,10 +42,18 @@ const std::vector<uint8_t>& GetNearbyShareTestSampleSignature();
const std::vector<uint8_t>& GetNearbyShareTestPayloadHashUsingSecretKey();
NearbySharePrivateCertificate GetNearbyShareTestPrivateCertificate(
NearbyShareVisibility visibility);
const nearbyshare::proto::PublicCertificate&
GetNearbyShareTestPublicCertificate();
NearbyShareVisibility visibility,
base::Time not_before = GetNearbyShareTestNotBefore());
nearbyshare::proto::PublicCertificate GetNearbyShareTestPublicCertificate(
NearbyShareVisibility visibility,
base::Time not_before = GetNearbyShareTestNotBefore());
// Returns a list of |kNearbyShareNumPrivateCertificates| private/public
// certificates, spanning contiguous validity periods.
std::vector<NearbySharePrivateCertificate>
GetNearbyShareTestPrivateCertificateList(NearbyShareVisibility visibility);
std::vector<nearbyshare::proto::PublicCertificate>
GetNearbyShareTestPublicCertificateList(NearbyShareVisibility visibility);
const NearbyShareDecryptedPublicCertificate&
GetNearbyShareTestDecryptedPublicCertificate();
......
......@@ -30,6 +30,7 @@
#include "chrome/browser/nearby_sharing/mock_nearby_process_manager.h"
#include "chrome/browser/nearby_sharing/mock_nearby_sharing_decoder.h"
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/services/sharing/public/cpp/advertisement.h"
......@@ -317,7 +318,8 @@ class NearbySharingServiceImplTest : public testing::Test {
if (success) {
std::move(calls.back().callback)
.Run(NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
GetNearbyShareTestPublicCertificate(),
GetNearbyShareTestPublicCertificate(
NearbyShareVisibility::kAllContacts),
GetNearbyShareTestEncryptedMetadataKey()));
} else {
std::move(calls.back().callback).Run(base::nullopt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment