Files
whitebox/api/license_whitebox_process_license_response_test.cc
Aaron Vaage 41e86ecab9 Code Drop Three (Update Two)
In this update we have:

  - Added the verified platform tests. These tests show how some
    platforms, when verified are allowed to by pass the normal policy
    restrictions. This is done with ChromeOS, thus the name of the
    tests use "chrome_os".

  - Removed WB_RESULT_INVALID_PADDING. This error was when we the
    non-license APIs exposed a AES function with padding. However,
    those functions have been removed from the API and this error is
    no longer used by the API.

  - Tests have been updated to avoid signed-vs-unsigned comparison
    and to use the Chromium path to gTest (which is mocked in this
    library).

  - Tests have been updated to use a new test base and golden data
    system to make them easier to read.
2020-05-30 11:34:32 -07:00

285 lines
12 KiB
C++

// Copyright 2020 Google LLC. All Rights Reserved.
#include "api/license_whitebox.h"
#include <string>
#include <vector>
#include "api/golden_data.h"
#include "api/license_whitebox_test_base.h"
#include "api/test_data.h"
#include "api/test_license_builder.h"
#include "crypto_utils/crypto_util.h"
#include "crypto_utils/rsa_key.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace widevine {
class LicenseWhiteboxProcessLicenseResponseTest
: public LicenseWhiteboxTestBase {
protected:
void UseLicenseWithoutSigningKey() {
TestLicenseBuilder builder;
builder.AddStubbedContentKey();
builder.Build(*public_key_, &license_);
}
void UseLicenseWithSigningKey(const std::vector<uint8_t>& padding) {
TestLicenseBuilder builder;
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey(), padding);
builder.AddStubbedContentKey();
builder.Build(*public_key_, &license_);
}
License license_;
};
TEST_F(LicenseWhiteboxProcessLicenseResponseTest, SuccessWithoutSigningKey) {
UseLicenseWithoutSigningKey();
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_OK);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseTest,
SuccessWithSigningKeyNoPadding) {
UseLicenseWithSigningKey(TestLicenseBuilder::NoPadding());
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_OK);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseTest,
SuccessWithSigningKeyPKSC8Padding) {
UseLicenseWithSigningKey(TestLicenseBuilder::PKSC8Padding());
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_OK);
}
class LicenseWhiteboxProcessLicenseResponseErrorTest
: public LicenseWhiteboxProcessLicenseResponseTest {
protected:
void SetUp() override {
LicenseWhiteboxProcessLicenseResponseTest::SetUp();
// For these tests, we don't care what license we use, it just needs to be
// a valid license.
UseLicenseWithoutSigningKey();
}
};
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidSignatureForModifedMessage) {
Modify(&license_.message);
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_SIGNATURE);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidSignatureForModifedSignature) {
Modify(&license_.signature);
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_SIGNATURE);
}
// The license request is used to derive the signing key. If the request was
// modified, then the wrong signing key should be generated.
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidSignatureForModifedLicenseRequest) {
Modify(&license_.request);
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_SIGNATURE);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForNullWhitebox) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
nullptr, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForNullMessage) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, nullptr, license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForZeroMessageSize) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), 0,
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForNullSignature) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
nullptr, license_.signature.size(), license_.session_key.data(),
license_.session_key.size(), license_.request.data(),
license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForInvalidSignatureSize) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), 5, license_.session_key.data(),
license_.session_key.size(), license_.request.data(),
license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForNullSessionKey) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(), nullptr,
license_.session_key.size(), license_.request.data(),
license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForInvalidSessionKeySize) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), 5, license_.request.data(),
license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
// If the session key is modified, unwrapping it will fail. Therefore, we will
// know that the parameter is invalid (compared to a modified license request).
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForModifedSessionKey) {
Modify(&license_.session_key);
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForNullLicenseRequest) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
nullptr, license_.request.size()),
WB_RESULT_INVALID_PARAMETER);
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidParameterForZeroLienseRequestSize) {
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), 0),
WB_RESULT_INVALID_PARAMETER);
}
class LicenseWhiteboxMultiLicenseTest
: public LicenseWhiteboxProcessLicenseResponseTest {
protected:
void SetUp() override {
LicenseWhiteboxProcessLicenseResponseTest::SetUp();
// For these tests, we don't care what license we use, it just needs to be
// a valid license.
UseLicenseWithoutSigningKey();
}
};
// A whitebox can only process a license once. If it has loaded a license
// (successfully) it should reject later calls with WB_RESULT_INVALID_STATE.
TEST_F(LicenseWhiteboxMultiLicenseTest, InvalidState) {
// Load the first license. This one is expected to succeed as the whitebox has
// not loaded a license yet.
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_OK);
// Attempt to load the same license again. This should fail as it already has
// a license (even though it is the same license).
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_STATE);
}
// Even though a whitebox can only load a license once, if it fails to load a
// license, it should still be able to try again.
TEST_F(LicenseWhiteboxMultiLicenseTest, SuccessAfterFailure) {
// Force this one to fail my changing the request, this will cause an error
// in key derivation which is a later step of license parsing.
std::vector<uint8_t> bad_request = license_.request;
Modify(&bad_request);
ASSERT_NE(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
bad_request.data(), bad_request.size()),
WB_RESULT_OK);
// Attempt to load the license again, but use the correct (unmodified)
// request.
ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_OK);
}
} // namespace widevine