blob: 2519096eeeba3a9b63b602f2ce419f1fc58c1e31 [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 "missive/encryption/verification.h"
#include <memory>
#include "missive/encryption/primitives.h"
#include "missive/encryption/testing_primitives.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Ne;
namespace reporting {
namespace {
class VerificationTest : public ::testing::Test {
protected:
VerificationTest() = default;
void SetUp() override {
// Generate new pair of private key and public value.
test::GenerateSigningKeyPair(private_key_, public_value_);
}
uint8_t public_value_[kKeySize];
uint8_t private_key_[kSignKeySize];
};
TEST_F(VerificationTest, SignAndVerify) {
static constexpr char message[] = "ABCDEF 012345";
// Sign the message.
uint8_t signature[kSignatureSize];
test::SignMessage(private_key_, message, signature);
// Verify the signature.
SignatureVerifier verifier(
std::string(reinterpret_cast<const char*>(public_value_), kKeySize));
EXPECT_OK(verifier.Verify(
std::string(message, strlen(message)),
std::string(reinterpret_cast<const char*>(signature), kSignatureSize)));
}
TEST_F(VerificationTest, SignAndFailBadSignature) {
static constexpr char message[] = "ABCDEF 012345";
// Sign the message.
uint8_t signature[kSignatureSize];
test::SignMessage(private_key_, message, signature);
// Verify the signature - wrong length.
SignatureVerifier verifier(
std::string(reinterpret_cast<const char*>(public_value_), kKeySize));
Status status =
verifier.Verify(std::string(message, strlen(message)),
std::string(reinterpret_cast<const char*>(signature),
kSignatureSize - 1));
EXPECT_THAT(status.code(), Eq(error::FAILED_PRECONDITION));
EXPECT_THAT(status.message(), HasSubstr("Wrong signature size"));
// Verify the signature - mismatch.
signature[0] = ~signature[0];
status = verifier.Verify(
std::string(message, strlen(message)),
std::string(reinterpret_cast<const char*>(signature), kSignatureSize));
EXPECT_THAT(status.code(), Eq(error::INVALID_ARGUMENT));
EXPECT_THAT(status.message(), HasSubstr("Verification failed"));
}
TEST_F(VerificationTest, SignAndFailBadPublicKey) {
static constexpr char message[] = "ABCDEF 012345";
// Sign the message.
uint8_t signature[kSignatureSize];
test::SignMessage(private_key_, message, signature);
// Verify the public key - wrong length.
SignatureVerifier verifier(
std::string(reinterpret_cast<const char*>(public_value_), kKeySize - 1));
Status status = verifier.Verify(
std::string(message, strlen(message)),
std::string(reinterpret_cast<const char*>(signature), kSignatureSize));
EXPECT_THAT(status.code(), Eq(error::FAILED_PRECONDITION));
EXPECT_THAT(status.message(), HasSubstr("Wrong public key size"));
// Verify the public key - mismatch.
public_value_[0] = ~public_value_[0];
SignatureVerifier verifier2(
std::string(reinterpret_cast<const char*>(public_value_), kKeySize));
status = verifier2.Verify(
std::string(message, strlen(message)),
std::string(reinterpret_cast<const char*>(signature), kSignatureSize));
EXPECT_THAT(status.code(), Eq(error::INVALID_ARGUMENT));
EXPECT_THAT(status.message(), HasSubstr("Verification failed"));
}
TEST_F(VerificationTest, ValidateFixedKey) {
// |dev_data_to_sign| is signed on DEV server, producing
// |dev_server_signature|.
static constexpr uint8_t dev_data_to_sign[] = {
0x4D, 0x22, 0x5C, 0x4C, 0x74, 0x23, 0x82, 0x80, 0x58, 0xA2, 0x31, 0xA2,
0xC6, 0xE2, 0x6D, 0xDA, 0x48, 0x82, 0x7A, 0x9C, 0xF7, 0xD0, 0x4A, 0xF2,
0xFD, 0x19, 0x03, 0x7F, 0xC5, 0x6F, 0xBB, 0x49, 0xAF, 0x91, 0x7B, 0x74};
static constexpr uint8_t dev_server_signature[kSignatureSize] = {
0x0C, 0xA4, 0xAF, 0xE3, 0x27, 0x06, 0xD1, 0x4F, 0x0E, 0x05, 0x44,
0x74, 0x0D, 0x4F, 0xA0, 0x4C, 0x26, 0xB1, 0x0C, 0x44, 0x92, 0x0F,
0x96, 0xAF, 0x5A, 0x7E, 0x45, 0xED, 0x61, 0xB7, 0x87, 0xA8, 0xA3,
0x98, 0x52, 0x97, 0x8D, 0x56, 0xA3, 0xED, 0xF7, 0x9B, 0x54, 0x17,
0x61, 0x32, 0x6C, 0x06, 0x29, 0xBF, 0x30, 0x4E, 0x88, 0x72, 0xAB,
0xE3, 0x60, 0xDA, 0xF0, 0x37, 0xEB, 0x56, 0x28, 0x0B};
// Validate the signature using known DEV public key.
SignatureVerifier dev_verifier(SignatureVerifier::VerificationKeyDev());
const auto dev_result = dev_verifier.Verify(
std::string(reinterpret_cast<const char*>(dev_data_to_sign),
sizeof(dev_data_to_sign)),
std::string(reinterpret_cast<const char*>(dev_server_signature),
kSignatureSize));
EXPECT_OK(dev_result) << dev_result;
// |prod_data_to_sign| is signed on PROD server, producing
// |prod_server_signature|.
static constexpr uint8_t prod_data_to_sign[] = {
0xB3, 0xF9, 0xA3, 0xCC, 0xEB, 0x42, 0x88, 0x6b, 0x3f, 0x7b, 0x93, 0xC3,
0xD3, 0x61, 0x9C, 0x45, 0xB4, 0xD7, 0x4B, 0x7B, 0x4F, 0xA7, 0x1A, 0x29,
0xE1, 0x95, 0x14, 0xA4, 0x8C, 0x21, 0x36, 0x9F, 0x34, 0xA7, 0x4A, 0x57};
static constexpr uint8_t prod_server_signature[kSignatureSize] = {
0x17, 0xA4, 0x18, 0xA3, 0x78, 0x7A, 0x75, 0x24, 0xD9, 0x81, 0x3D,
0x9F, 0x17, 0x28, 0x40, 0xD8, 0xE7, 0x67, 0x88, 0x17, 0x44, 0x7C,
0xC2, 0x1A, 0xE2, 0x73, 0xAC, 0xB1, 0x0B, 0xCE, 0x60, 0xBB, 0x30,
0x58, 0xCE, 0xF6, 0x8E, 0x33, 0xB6, 0xC6, 0x18, 0x3C, 0xA7, 0xD4,
0x38, 0x91, 0x90, 0x2C, 0xBC, 0xB9, 0x76, 0x3C, 0xFF, 0x6F, 0x84,
0xEC, 0x2D, 0x1E, 0x73, 0x43, 0x1B, 0x75, 0x5E, 0x0E};
// Validate the signature using known PROD public key.
SignatureVerifier prod_verifier(SignatureVerifier::VerificationKey());
const auto prod_result = prod_verifier.Verify(
std::string(reinterpret_cast<const char*>(prod_data_to_sign),
sizeof(prod_data_to_sign)),
std::string(reinterpret_cast<const char*>(prod_server_signature),
kSignatureSize));
EXPECT_OK(prod_result) << prod_result;
}
} // namespace
} // namespace reporting