Files
oemcrypto/oemcrypto/odk/src/core_message_features.cpp
Googler c56808c463 Automated update of OPK code
Included changes:

  - 92a0538dc60ad0c48866b5736fcec125f6493d8d Remove unused function by John "Juce" Bruce <juce@google.com>
  - 7235e2c89a94d6b6ed086aa83cd4b22b56bd8d65 Various static function fixes by John "Juce" Bruce <juce@google.com>
  - 908055030aa283ce74915fb68571b0ce3854e12e Fix duplicate & missing headers identified by clang-tidy by John "Juce" Bruce <juce@google.com>
  - 502b8b8caeb4654f294398039fff98ec641bda24 Updated `core_message_features.cpp` to use `odk_versions.h` by Alex Dale <sigquit@google.com>
  - 3163312183f5e0b8a08b97cfe171221861743cc5 Bump ODK max supported minor versions by Matt Feddersen <mattfedd@google.com>
  - c461df67a9003e738042716ae644dd96a66d2446 Updated ODK minor versions for 2025Q2 release. by Alex Dale <sigquit@google.com>
  - 56a43e881c31e4e2d3a2a7732bef00705a252a65 Added ODK_InitializeSessionValuesEx by Alex Dale <sigquit@google.com>

GitOrigin-RevId: 92a0538dc60ad0c48866b5736fcec125f6493d8d
2025-06-06 16:09:23 -07:00

135 lines
5.0 KiB
C++

// Copyright 2021 Google LLC. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
#include "core_message_features.h"
#include <stdint.h>
#include <algorithm>
#include <ostream>
#include <tuple>
#include <utility>
#include "odk_structs.h"
#include "odk_versions.h"
namespace oemcrypto_core_message {
namespace features {
namespace {
// The first major version where we decided to prerelease a test version the ODK
// library.
constexpr uint32_t kFirstPrereleaseVersion = 20;
} // namespace
const CoreMessageFeatures CoreMessageFeatures::kDefaultFeatures;
bool CoreMessageFeatures::operator==(const CoreMessageFeatures& other) const {
return maximum_major_version == other.maximum_major_version &&
maximum_minor_version == other.maximum_minor_version;
}
CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
uint32_t maximum_major_version, bool serve_prerelease_odk_messages) {
CoreMessageFeatures features(serve_prerelease_odk_messages);
features.maximum_major_version = maximum_major_version;
// The default minor version is the highest for each major version. This also
// needs to be updated with new version releases in
// ODK_InitializeSessionValues() when the minor version is being set.
switch (maximum_major_version) {
case 16:
features.maximum_minor_version = ODK_V16_MINOR_VERSION;
break;
case 17:
features.maximum_minor_version = ODK_V17_MINOR_VERSION;
break;
case 18:
features.maximum_minor_version = ODK_V18_MINOR_VERSION;
break;
case 19:
features.maximum_minor_version = ODK_V19_MINOR_VERSION;
break;
case 20:
features.maximum_minor_version = ODK_V20_MINOR_VERSION;
break;
default:
features.maximum_minor_version = 0;
}
return features;
}
CoreMessageFeatures::CoreMessageFeatures(bool prerelease_odk_messages)
: serve_prerelease_odk_messages(prerelease_odk_messages) {
if (prerelease_odk_messages) {
// If we are allowed to serve prerelease messages, then the maximum version
// is the same as the defined constants.
maximum_major_version = ODK_MAJOR_VERSION;
maximum_minor_version = ODK_MINOR_VERSION;
}
}
// Validate request version.
bool CoreMessageFeatures::ValidateRequestVersion(uint16_t major_version,
uint16_t minor_version) const {
// First, make sure that this object has valid values. I.e. the maximum is not
// a version from the future.
if ((maximum_major_version > ODK_MAJOR_VERSION) ||
(maximum_major_version == ODK_MAJOR_VERSION &&
maximum_minor_version > ODK_MINOR_VERSION)) {
// TODO(b/147513335): this should be logged.
return false;
}
if (major_version < ODK_FIRST_VERSION) return false;
// If we are not allowed to serve messages to a prerelease device, then check
// to see if the request has a prerelease version number.
// Minor version of 0 indicates prerelease.
if (minor_version == 0 && !serve_prerelease_odk_messages) {
// if (major_version < kFirstPrereleaseVersion) Older devices are OK. There
// were no prerelease devices before kFirstPrereleaseVersion.
if (major_version < kFirstPrereleaseVersion) {
return true;
}
// If (major_version > ODK_MAJOR_VERSION), then the device is newer than the
// server. That happens when we are testing a prerelease device against a
// special test server that is explicitly for backwards compatibility
// testing. Since we want to allow prerelease devices to be tested for
// bacwards compatibility, we allow devices that are newer than the server.
//
// The UAT server, used for release validation testing, will be
// running recent software. The main reason to reject a prerelease device is
// to prevent a device from passing GTS tests with prerelease software. This
// statement assumes that UAT is updated quarterly, and that a prerelease
// ODK library will not be created in less than a few quarters after a major
// release.
if (major_version > ODK_MAJOR_VERSION) {
return true;
}
// All other prerelease devices are rejected.
return false;
}
return true;
}
bool CoreMessageFeatures::GetResponseVersion(
uint16_t request_major_version, uint16_t request_minor_version,
uint16_t& response_major_version, uint16_t& response_minor_version) const {
if (!ValidateRequestVersion(request_major_version, request_minor_version)) {
return false;
}
std::tie(response_major_version, response_minor_version) =
std::min(std::pair(request_major_version, request_minor_version),
std::pair(static_cast<uint16_t>(maximum_major_version),
static_cast<uint16_t>(maximum_minor_version)));
return true;
}
std::ostream& operator<<(std::ostream& os,
const CoreMessageFeatures& features) {
return os << "v" << features.maximum_major_version << "."
<< features.maximum_minor_version;
}
} // namespace features
} // namespace oemcrypto_core_message