diff --git a/example/wv_cas_ecm_example b/example/wv_cas_ecm_example index d341ba0..7cce9e4 100644 Binary files a/example/wv_cas_ecm_example and b/example/wv_cas_ecm_example differ diff --git a/libmedia_cas_packager_sdk.so b/libmedia_cas_packager_sdk.so index cd3e69e..57b2812 100755 Binary files a/libmedia_cas_packager_sdk.so and b/libmedia_cas_packager_sdk.so differ diff --git a/media_cas_packager_sdk/public/wv_cas_ecm.h b/media_cas_packager_sdk/public/wv_cas_ecm.h index 47d5b20..b59f785 100644 --- a/media_cas_packager_sdk/public/wv_cas_ecm.h +++ b/media_cas_packager_sdk/public/wv_cas_ecm.h @@ -51,8 +51,8 @@ class WvCasEcm { // // Note: // - 'even'/'odd' key in the ECM will be be encrypted using AEC_CBC - util::Status Initialize(int content_iv_size, bool key_rotation_enabled, - int crypto_mode); + virtual util::Status Initialize(int content_iv_size, + bool key_rotation_enabled, int crypto_mode); // Generate an ECM containing two keys (even and odd). Can be called when // |key_rotation_enabled| is initialized to 'true'. @@ -74,11 +74,13 @@ class WvCasEcm { // and |odd_key| in the ECM // - Size of |even_content_iv| and |odd_content_iv| must match // |content_iv_size| set during initialization - util::Status GenerateEcm(const std::string& even_key, - const std::string& even_content_iv, const std::string& odd_key, - const std::string& odd_content_iv, - const std::string& entitlement_key_id, - const std::string& entitlement_key, std::string* ecm); + virtual util::Status GenerateEcm(const std::string& even_key, + const std::string& even_content_iv, + const std::string& odd_key, + const std::string& odd_content_iv, + const std::string& entitlement_key_id, + const std::string& entitlement_key, + std::string* ecm) const; // Generate an ECM containing only a singe even key. Can be called when // |key_rotation_enabled| is initialized to 'false'. @@ -96,10 +98,11 @@ class WvCasEcm { // Note: // - Size of |even_content_iv| and |odd_content_iv| must match // |content_iv_size| set during initialization - util::Status GenerateSingleKeyEcm(const std::string& even_key, - const std::string& even_content_iv, - const std::string& entitlement_key_id, - const std::string& entitlement_key, std::string* ecm); + virtual util::Status GenerateSingleKeyEcm(const std::string& even_key, + const std::string& even_content_iv, + const std::string& entitlement_key_id, + const std::string& entitlement_key, + std::string* ecm) const; private: bool initialized_ = false; diff --git a/util/error_space.h b/util/error_space.h new file mode 100644 index 0000000..68c093a --- /dev/null +++ b/util/error_space.h @@ -0,0 +1,83 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 Google LLC. +// +// This software is licensed under the terms defined in the Widevine Master +// License Agreement. For a copy of this agreement, please contact +// widevine-licensing@google.com. +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_ERROR_SPACE_H_ +#define UTIL_ERROR_SPACE_H_ + +#include + +namespace widevine { +namespace util { + +class ErrorSpace { + public: + std::string SpaceName() const { return space_name_func_(this); } + std::string String(int code) const { return code_to_string_func_(this, code); } + + protected: + // typedef instead of using statements for SWIG compatibility. + typedef std::string (*SpaceNameFunc)(const ErrorSpace* space); + typedef std::string (*CodeToStringFunc)(const ErrorSpace* space, int code); + constexpr ErrorSpace(SpaceNameFunc space_name_func, + CodeToStringFunc code_to_string_func) + : space_name_func_(space_name_func), + code_to_string_func_(code_to_string_func) {} + + private: + const SpaceNameFunc space_name_func_; + const CodeToStringFunc code_to_string_func_; +}; + +// Manages creation of error space subclasses. +template +class ErrorSpaceImpl : public ErrorSpace { + public: + constexpr ErrorSpaceImpl() + : ErrorSpace(&ErrorSpaceImpl::SpaceNameImpl, + &ErrorSpaceImpl::CodeToStringImpl) {} + + // Returns the canonical instance of the `T` error space. + static constexpr const T* Get(); + + private: + // These functions adapt the stateful implementation that takes a space + // pointer to stateless static methods, so that clients of ErrorSpaceImpl are + // safe to have constexpr global instances. + static std::string SpaceNameImpl(const ErrorSpace* /*space*/) { + return T::SpaceName(); + } + + static std::string CodeToStringImpl(const ErrorSpace* /*space*/, int code) { + return T::CodeToString(code); + } +}; + +namespace internal { + +// Provides a global constexpr instance of the error space `T`. +// We need the indirection because ErrorSpaceImpl can't declare constexpr +// instances of T since it is not yet fully declared. +template +struct ErrorSpaceInstance { + static constexpr T value = {}; +}; + +template +constexpr T ErrorSpaceInstance::value; + +} // namespace internal + +template +constexpr const T* ErrorSpaceImpl::Get() { + return &internal::ErrorSpaceInstance::value; +} + +} // namespace util +} // namespace widevine + +#endif // UTIL_ERROR_SPACE_H_ diff --git a/util/status.h b/util/status.h new file mode 100644 index 0000000..5e3b15b --- /dev/null +++ b/util/status.h @@ -0,0 +1,119 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 Google LLC. +// +// This software is licensed under the terms defined in the Widevine Master +// License Agreement. For a copy of this agreement, please contact +// widevine-licensing@google.com. +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_STATUS_H_ +#define UTIL_STATUS_H_ + +#include + +#include "util/error_space.h" + +namespace widevine { +namespace util { +namespace error { + +enum StatusCode { + // Success. + OK = 0, + + // Client specified an invalid argument. + INVALID_ARGUMENT = 3, + + // Some requested entity (e.g., file or directory) was not found. + NOT_FOUND = 5, + + // Some entity that we attempted to create (e.g., file or directory) + // already exists. + ALREADY_EXISTS = 6, + + // The caller does not have permission to execute the specified + // operation. PERMISSION_DENIED must not be used for rejections + // caused by exhausting some resource (use RESOURCE_EXHAUSTED + // instead for those errors). + PERMISSION_DENIED = 7, + + // Operation is not implemented or not supported/enabled in this service. + UNIMPLEMENTED = 12, + + // Internal errors. Means some invariants expected by underlying + // system has been broken. If you see one of these errors, + // something is very broken. + INTERNAL = 13, + + // Operation is not implemented or not supported/enabled in this service. + UNAVAILABLE = 14, + + // Number of generic (non license related) errors. + NUM_ERRORS, +}; + +} // namespace error + +class GenericErrorSpace : public ErrorSpaceImpl { + public: + static std::string SpaceName(); + static std::string CodeToString(int code); +}; + +class Status { + public: + Status() : status_code_(error::OK) {} + ~Status() {} + explicit Status(error::StatusCode c) : status_code_(c) {} + Status(error::StatusCode c, const std::string& error_message) + : status_code_(c), error_message_(error_message) {} + Status(const ErrorSpace* e, error::StatusCode c, + const std::string& error_message) { + SetError(e, c, error_message); + } + Status(const ErrorSpace* e, int error, const std::string& error_message) { + SetError(e, error, error_message); + } + void SetError(const ErrorSpace* e, int c, const std::string& error_message) { + error_space_ = e; + status_code_ = c; + error_message_ = error_message; + } + + bool ok() const { return status_code_ == error::OK; } + const ErrorSpace* error_space() const { return error_space_; } + static const ErrorSpace* canonical_space() { + return GenericErrorSpace::Get(); + } + std::string ToString() const; + std::string error_message() const { return error_message_; } + int error_code() const { return status_code_; } + + private: + const ErrorSpace* error_space_ = GenericErrorSpace::Get(); + int status_code_; + std::string error_message_; +}; // class Status + +inline Status OkStatus() { return Status(); } + +// Here error_message_ is ignored during comparison. +inline bool operator==(const Status& s1, const Status& s2) { + return s1.error_space() == s2.error_space() && + s1.error_code() == s2.error_code(); +} +inline bool operator!=(const Status& s1, const Status& s2) { + return s1.error_space() != s2.error_space() || + s1.error_code() != s2.error_code(); +} + +// Prints a human-readable representation of 'x' to 'os'. +std::ostream& operator<<(std::ostream& os, const Status& x); + +#define CHECK_OK(expression) CHECK_EQ(util::error::OK, expression.error_code()) + + +} // namespace util +} // namespace widevine + +#endif // UTIL_STATUS_H_