Files
oemcrypto/util/include/hls_key.h
Googler 5387878a5b Automated update of OPK code
Included changes:

  - 676ac7be8548d80c420591fc0b4fb9a11723ef34 Backwards compatibility script for CDM v18 and OPK v19 by Vicky Min <vickymin@google.com>
  - 3cd4f71fda91245ac0b61c4c847950952f3021c0 Change BuildInformation ree fields to optional by Matt Feddersen <mattfedd@google.com>
  - a2259e95dea40c27a4be02ad479aec8f1fc84737 Created a DICE CBOR Cert parser/serializer. by Alex Dale <sigquit@google.com>
  - b8f2c364afeb6279e5aee6488d4527e189ac42ff Don't create invalid enum value by John "Juce" Bruce <juce@google.com>
  - b0aed212a3b2dd8f752d8fc43982848c1aa6c152 Created an HLS Key type. by Alex Dale <sigquit@google.com>
  - f8cfc54b41f124ba849596dbe6438b7f271a72b7 Specify C/C++ standard when running clang-tidy on OPK by John "Juce" Bruce <juce@google.com>

GitOrigin-RevId: 676ac7be8548d80c420591fc0b4fb9a11723ef34
2025-05-30 09:58:39 -07:00

211 lines
8.1 KiB
C++

// Copyright 2025 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#ifndef WVCDM_UTIL_HLS_KEY_H_
#define WVCDM_UTIL_HLS_KEY_H_
#include <inttypes.h>
#include <ostream>
#include <set>
#include <string>
#include <vector>
#include "wv_class_utils.h"
namespace wvutil {
class HlsAttributeList;
// Data wrapper types for HLS Key fields.
//
// Ensures that the values of each attribute of an
// HLS key is valid. The class does not enforce contextual
// requirements between attributes; however, IsWellFormed()
// can optionally be called to ensure some fields are set
// appropriately based on the values of other fields.
//
// This class is based on RFC 8216 section 4.3.2.4.
class HlsKey {
public:
// HLS Tag for key data.
static constexpr char kTag[] = "EXT-X-KEY";
// Attribute names for HLS keys.
// METHOD is an enumerated string with three known values
// of NONE, AES-128, or SAMPLE-AES.
// METHOD may be a different value so long as it is a
// valid enum string.
// METHOD is required, if set to NONE, then the other
// fields SHOULD NOT be set.
static constexpr char kMethodName[] = "METHOD";
// URI is a quoted string containing be a valid URI which
// identifies where to find the key(s) used for content
// decryption.
// Must be set if METHOD is not NONE.
// Should not be set if METHOD is NONE.
static constexpr char kUriName[] = "URI";
// IV is a hex sequence for a 128-bit initialization vector
// used for decryption of media content.
// Must be set if METHOD is not NONE.
// Should not be set if METHOD is NONE.
static constexpr char kIvName[] = "IV";
// The key format is a quoted string which identifies the
// format of the key acquired by the URI.
// Optionally set if METHOD is not NONE, if not set, then
// it is assumed the URI will directly acquire the key.
// Should not be set if METHOD is NONE.
static constexpr char kKeyFormatName[] = "KEYFORMAT";
// The key format versions is a quoted string containing one
// or more positive integers (of HLS integer format) separated
// by a '/', which indicates the vendor-specific versions of the
// key acquired via the URI.
// Optionally set if METHOD is not NONE, assumed to contain
// a value of 1 if not set but a version is required.
// Should not be set if METHOD is NONE.
static constexpr char kKeyFormatVersionsName[] = "KEYFORMATVERSIONS";
// List of known METHOD values.
static constexpr char kMethodNone[] = "NONE";
static constexpr char kMethodAes128[] = "AES-128";
static constexpr char kMethodSampleAes[] = "SAMPLE-AES";
// HLS keys require an IV length of 128-bits / 16 octets.
static constexpr size_t kIvLength = 16;
// Checks if the provided |method| is one of the known
// values for the enumerated string METHOD.
static bool IsKnownMethod(const std::string& method);
// Checks if the provided |method| is a valid HLS enum
// string value.
static bool IsValidMethod(const std::string& method);
// Simply checks that the provided URI is a valid HLS quoted
// string value. Does not valid URI format.
static bool IsValidUriValue(const std::string& uri);
// Checks that the specified IV length (in octets) is a supported
// length.
static constexpr bool IsValidIvLength(size_t iv_length) {
return iv_length == kIvLength;
}
static bool IsValidIv(const std::string& iv) {
return IsValidIvLength(iv.size());
}
static bool IsValidIv(const std::vector<uint8_t>& iv) {
return IsValidIvLength(iv.size());
}
// Checks that the provided key format conforms to the quoted
// string value requirements of HLS.
static bool IsValidKeyFormat(const std::string& key_format);
// Checks if the specified |version| is a valid key format
// version (must be positive).
static constexpr bool IsValidKeyFormatVersion(uint64_t version) {
return version > 0;
}
// Checks that all the values in the set of |versions| is a valid
// versions.
// The set of versions cannot be empty, and all versions must be a
// positive value.
static bool IsValidKeyFormatVersions(const std::set<uint64_t>& versions);
// Checks that the provided formatted version list is a valid
// representation of key format versions.
// Note: There is no requirement that the versions are unique.
static bool IsValidKeyFormatVersionListRep(
const std::string& version_list_rep);
HlsKey() = default;
WVCDM_DEFAULT_COPY_AND_MOVE(HlsKey);
const std::string& method() const { return method_; }
bool HasMethod() const { return !method_.empty(); }
bool SetMethod(const std::string& method);
void ClearMethod() { method_.clear(); }
// URIs are only validated that they are valid quoted string
// values; not that they are well formed URIs.
const std::string& uri() const { return uri_; }
bool HasUri() const { return !uri_.empty(); }
bool SetUri(const std::string& uri);
void ClearUri() { uri_.clear(); }
const std::vector<uint8_t>& iv() const { return iv_; }
bool HasIv() const { return !iv_.empty(); }
bool SetIv(const std::vector<uint8_t>& iv);
bool SetIv(const std::string& iv);
bool SetIvHex(const std::string& iv_hex);
void ClearIv() { iv_.clear(); }
const std::string& key_format() const { return key_format_; }
bool HasKeyFormat() const { return !key_format_.empty(); }
bool SetKeyFormat(const std::string& key_format);
void ClearKeyFormat() { key_format_.clear(); }
const std::set<uint64_t>& key_format_versions() const {
return key_format_versions_;
}
bool HasKeyFormatVersions() const { return !key_format_versions_.empty(); }
bool HasKeyFormatVersion(uint64_t version) const;
bool SetKeyFormatVersions(const std::set<uint64_t>& versions);
bool SetKeyFormatVersions(const std::vector<uint64_t>& versions);
bool AddKeyFormatVersion(uint64_t version);
void ClearKeyFormatVersions() { key_format_versions_.clear(); }
void Clear() {
ClearMethod();
ClearUri();
ClearIv();
ClearKeyFormat();
ClearKeyFormatVersions();
}
// Checks that the HLS key is well-formed based on the requirements
// of an HLS key. Relies mainly on the requirements of METHOD.
bool IsWellFormed() const;
// == Parsing / Serialization ==
// Initializes the HLS key from a populated instance of
// HlsAttributeList.
//
// Requirements:
// - METHOD must be set, must be one of the well-known methods.
// - URI is optional, must be quoted string if set.
// - IV is optional, must be a 16-byte / 128-bit hex sequence if set.
// - KEYFORMAT is optional, must be a quoted string if set, defaults
// to "identify" is not set.
// - KEYFORMATVERSIONS is optional, must be a quoted string containing
// a valid sequence of '/' separated version if set, defaults to
// "1" if not set.
bool FromAttributeList(const HlsAttributeList& attr_list);
// Initializes the HLS key from the HLS serialized HLS Attribute List.
// Internally uses FromAttributeList(), and follows the same requirements.
bool ParseAttributeList(const std::string& attr_list_rep);
// Packages the HLS key into the HlsAttributeList instance.
// Clears existing data in |attr_list|.
//
// Serializing does not enforce any field requirements other than
// types.
//
// Follows the following rules:
// - METHOD packaged as enum string if set
// - URI packaged as quoted string if set
// - IV packaged as hex sequence if set
// - KEYFORMAT packaged as quoted string if set
// - KEYFORMATVERSIONS packaged as quoted string containing slash
// separated version if any version is set.
bool ToAttributeList(HlsAttributeList* attr_list) const;
// Serializes the HLS key into an HLS attribute string format.
// Internally uses ToAttributeList(), and follows the same packaging
// rules.
std::string Serialize() const;
bool SerializeToStream(std::ostream* out) const;
private:
// Values are either empty or set to valid values.
std::string method_;
std::string uri_;
std::vector<uint8_t> iv_;
std::string key_format_;
std::set<uint64_t> key_format_versions_;
}; // class HlsKey
} // namespace wvutil
#endif // WVCDM_UTIL_HLS_KEY_H_