// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "sharing/certificates/common.h" #include #include #include #include #include #include #include #include "absl/time/time.h" #include "absl/types/span.h" #include "internal/crypto_cros/encryptor.h" #include "internal/crypto_cros/hkdf.h" #include "internal/crypto_cros/symmetric_key.h" #include "internal/platform/crypto.h" #include "sharing/certificates/constants.h" #include "sharing/internal/public/logging.h" namespace nearby { namespace sharing { bool IsNearbyShareCertificateExpired(absl::Time current_time, absl::Time not_after, bool use_public_certificate_tolerance) { absl::Duration tolerance = use_public_certificate_tolerance ? kNearbySharePublicCertificateValidityBoundOffsetTolerance : absl::ZeroDuration(); return current_time >= not_after + tolerance; } bool IsNearbyShareCertificateWithinValidityPeriod( absl::Time current_time, absl::Time not_before, absl::Time not_after, bool use_public_certificate_tolerance) { absl::Duration tolerance = use_public_certificate_tolerance ? kNearbySharePublicCertificateValidityBoundOffsetTolerance : absl::ZeroDuration(); return current_time >= not_before - tolerance && !IsNearbyShareCertificateExpired(current_time, not_after, use_public_certificate_tolerance); } std::vector DeriveNearbyShareKey(absl::Span key, size_t new_num_bytes) { return crypto::HkdfSha256(key, /*salt=*/absl::Span(), /*info=*/absl::Span(), new_num_bytes); } std::vector ComputeAuthenticationTokenHash( absl::Span authentication_token, absl::Span secret_key) { return crypto::HkdfSha256(authentication_token, secret_key, /*info=*/absl::Span(), kNearbyShareNumBytesAuthenticationTokenHash); } std::vector GenerateRandomBytes(size_t num_bytes) { std::vector bytes(num_bytes); RandBytes(absl::Span(bytes)); return bytes; } std::unique_ptr CreateNearbyShareCtrEncryptor( const crypto::SymmetricKey* secret_key, absl::Span salt) { DCHECK(secret_key); DCHECK_EQ(kNearbyShareNumBytesSecretKey, secret_key->key().size()); DCHECK_EQ(kNearbyShareNumBytesMetadataEncryptionKeySalt, salt.size()); auto encryptor = std::make_unique(); // For CTR mode, the iv input to Init() must be empty. Instead, the iv is // set via SetCounter(). if (!encryptor->Init(secret_key, crypto::Encryptor::Mode::CTR, /*iv=*/absl::Span())) { LOG(ERROR) << "Encryptor could not be initialized."; return nullptr; } std::vector iv = DeriveNearbyShareKey(salt, kNearbyShareNumBytesAesCtrIv); if (!encryptor->SetCounter(iv)) { LOG(ERROR) << "Could not set encryptor counter."; return nullptr; } return encryptor; } absl::Time FromJavaTime(int64_t ms_since_epoch) { return absl::UnixEpoch() + absl::Milliseconds(ms_since_epoch); } int64_t ToJavaTime(absl::Time time) { // Preserve 0 so the invalid result doesn't depend on the platform. if (time == absl::InfiniteFuture()) { return std::numeric_limits::max(); } else if (time == absl::InfinitePast()) { return std::numeric_limits::min(); } else { return (time - absl::UnixEpoch()) / absl::Milliseconds(1); } } } // namespace sharing } // namespace nearby