blob: 926d674d8a6ac70bf547ae1420cd2befe0ba5b15 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/lib/util/encrypted_message_util.h"
#include <utility>
#include <vector>
#include "google/protobuf/message_lite.h"
#include "src/lib/util/not_null.h"
#include "src/logging.h"
#include "src/pb/encrypted_message.pb.h"
#include "src/pb/key.pb.h"
#include "src/public/lib/status.h"
#include "src/public/lib/status_codes.h"
#include "src/tracing.h"
#if TQ_COBALT_USE_TINK
#include "src/lib/util/hybrid_tink_encrypted_message_maker.h"
#endif
namespace cobalt::util {
namespace {
#if TQ_COBALT_USE_TINK
constexpr char kShufflerContextInfo[] = "cobalt-1.0-shuffler";
constexpr char kAnalyzerContextInfo[] = "cobalt-1.0-analyzer";
#endif
// Parse and validate a serialized CobaltEncryptionKey.
lib::statusor::StatusOr<cobalt::CobaltEncryptionKey> ParseCobaltEncryptionKey(
const std::string& cobalt_encryption_key_bytes) {
cobalt::CobaltEncryptionKey cobalt_encryption_key;
if (!cobalt_encryption_key.ParseFromString(cobalt_encryption_key_bytes)) {
return Status(StatusCode::INVALID_ARGUMENT,
"EncryptedMessageMaker: Invalid Cobalt encryption key.");
}
if (cobalt_encryption_key.key_index() == 0) {
return Status(StatusCode::INVALID_ARGUMENT,
"EncryptedMessageMaker: Invalid Cobalt key_index: 0.");
}
if (cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::SHUFFLER &&
cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::ANALYZER) {
return Status(StatusCode::INVALID_ARGUMENT,
"EncryptedMessageMaker: Invalid Cobalt key purpose.");
}
return cobalt_encryption_key;
}
} // namespace
util::NotNullUniquePtr<EncryptedMessageMaker> EncryptedMessageMaker::MakeUnencrypted() {
VLOG(5) << "WARNING: Cobalt data will not be encrypted!";
return util::MakeNotNullUniquePtr<UnencryptedMessageMaker>();
}
lib::statusor::StatusOr<util::NotNullUniquePtr<EncryptedMessageMaker>>
EncryptedMessageMaker::MakeForEnvelopes(const std::string& cobalt_encryption_key_bytes) {
auto cobalt_encryption_key_or_result = ParseCobaltEncryptionKey(cobalt_encryption_key_bytes);
if (!cobalt_encryption_key_or_result.ok()) {
return cobalt_encryption_key_or_result.status();
}
auto cobalt_encryption_key = cobalt_encryption_key_or_result.value();
if (cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::SHUFFLER) {
return Status(StatusCode::INVALID_ARGUMENT, "EncryptedMessageMaker: Expected a shuffler key.");
}
#if TQ_COBALT_USE_TINK
return MakeHybridTinkEncryptedMessageMaker(cobalt_encryption_key.serialized_key(),
kShufflerContextInfo,
cobalt_encryption_key.key_index());
#else
return Status(StatusCode::UNIMPLEMENTED, "EncryptedMessageMaker: Cobalt was built without Tink.");
#endif
}
lib::statusor::StatusOr<util::NotNullUniquePtr<EncryptedMessageMaker>>
EncryptedMessageMaker::MakeForObservations(const std::string& cobalt_encryption_key_bytes) {
auto cobalt_encryption_key_or_result = ParseCobaltEncryptionKey(cobalt_encryption_key_bytes);
if (!cobalt_encryption_key_or_result.ok()) {
return cobalt_encryption_key_or_result.status();
}
auto cobalt_encryption_key = cobalt_encryption_key_or_result.value();
if (cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::ANALYZER) {
return Status(StatusCode::INVALID_ARGUMENT, "EncryptedMessageMaker: Expected an analyzer key.");
}
#if TQ_COBALT_USE_TINK
return MakeHybridTinkEncryptedMessageMaker(cobalt_encryption_key.serialized_key(),
kAnalyzerContextInfo,
cobalt_encryption_key.key_index());
#else
return Status(StatusCode::UNIMPLEMENTED, "EncryptedMessageMaker: Cobalt was built without Tink.");
#endif
}
bool UnencryptedMessageMaker::Encrypt(const google::protobuf::MessageLite& message,
EncryptedMessage* encrypted_message) const {
TRACE_DURATION("cobalt_core", "UnencryptedMessageMaker::Encrypt");
if (!encrypted_message) {
return false;
}
std::string serialized_message;
message.SerializeToString(&serialized_message);
encrypted_message->set_ciphertext(serialized_message);
VLOG(5) << "EncryptedMessage: encryption_scheme=NONE.";
return true;
}
} // namespace cobalt::util