From 5d690be108d2f8f180c36e7d42f7e70820302fa3 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Wed, 10 Jan 2018 19:17:52 -0800 Subject: [PATCH] Merges to android Pi release (part 11) These are a set of CLs merged from the wv cdm repo to the android repo. * Get System ID From OEM Cert Author: John W. Bruce [ Merge of http://go/wvgerrit/37940 ] (This is a merge of http://go/wvgerrit/30220 . However, it has been significantly modified in the merge due to needing to support both OpenSSL and BoringSSL.) Previously, extracting the system ID was only supported on Keybox-based systems. This patch adds support for extracting the system ID from the OEM Certificate chain on Provisioning 3.0 devices. This is done by getting the Widevine intermediate cert from the chain, finding the Widevine System ID extension in that cert, and extracting the value. The code that does the extraction is separate from any code that calls OEMCrypto so that it can be unit-tested in isolation. This patch adds a crypto_session_unittest test to do this unit-testing. Bug: 34776194 Test: crypto_session_unittest Test: widevine_ce_cdm_unittest * Remove unique_ptr from oemcrypto mod mock Author: Fred Gylys-Colwell [ Merge of http://go/wvgerrit/38500 ] Because we can't have C++11. Bug: 69935608 * Update CHANGELOG.md Author: Gene Morgan [ Merge of http://go/wvgerrit/38460 ] - Add items about adapter support. - Add mention of SRM support. Merged from cdm_partner_3.5 (Change-Id: I6d891e157edc3afb2797bf281ef3f06bdb8fe474) * Add Adapter for OEMCrypto v13 to v12. Author: Gene Morgan [ Merge of http://go/wvgerrit/38440 ] Also fix OEMCrypto_LoadKeys() definition broken by wvcl/38160 (srm_requirement param). * Allow certain warnings in protobuf build. Author: Gene Morgan [ Merge of http://go/wvgerrit/38424 ] maybe-uninitialized is triggered in release build. Allow it. * Enable -fPIC for jsmc.c build. Author: Gene Morgan [ Merge of http://go/wvgerrit/38423 ] -fPIC was removed for common c/c++ build rules. Add it back. * Missing OEMCrypto_LoadKeys param in static adapter. Author: Gene Morgan [ Merge of http://go/wvgerrit/38422 ] srm_requirement param was omitted in v11 static adapter. * Remove OEMCrypto v12 specification. Author: Gene Morgan [ Merge of http://go/wvgerrit/38421 ] * Update documentation for v3.5. Author: Gene Morgan [ Merge of http://go/wvgerrit/38420 ] * Added padded preprov key for 7880 Author: Srujan Gaddam [ Merge of http://go/wvgerrit/36924 ] Bug: 68765915 * Change overrides in CE L3FileSystem Author: Srujan Gaddam [ Merge of http://go/wvgerrit/38380 ] The 'override's are changed to the macro defined in override.h to be gnu++98 compliant. * Use source android level3 + add cache_flush call Author: Srujan Gaddam [ Merge of http://go/wvgerrit/37900 ] I put both changes in this CL since I have to generate Level3 libraries for both anyways. The first change involves shifting from using a prebuilt static library to using an obfuscated source library output from the Haystack tool on google3. The second change is from here: https://critique.corp.google.com/#review/176536782, and addresses b/69387416. Since the cache_flush function wasn't being used, the execution on Angler gave inconsistent segfaults, which this CL fixes. Verified on Angler, Sailfish, and Linux. 11/27/17: Added mips and mips64 libraries. * Make CDM result codes constexprs Author: Rahul Frias [ Merge of http://go/wvgerrit/38280 ] The values in the enumeration list of CdmResponseType error codes were earlier implicit. Comments were added to denote the actual values. This changes to make it fixed values, which makes it slightly more error prone, but cleaner when errors are retired. * Change watchdog timer to 2 minutes [ Merge of http://go/wvgerrit/36340 ] This relaxes the watchdog timer around the level 3 oemcrypto initialization to 120 seconds. There are also a couple of new log messages at the end of initialization and at termination. Library for arm updated: level3/arm/libwvlevel3.a Level3 Library 4445 Oct 4 2017 17:06:25 Bug: 65379279 Merged from https://widevine-internal-review.googlesource.com/35480 * Add test to get service certificate from server. Author: Gene Morgan [ Merge of http://go/wvgerrit/37780 ] This was extracted from Ic38dd27d06dc7528ae4cd995da4261fe6c34ad55 * Add watch dog timer to OEMCrypto L3 commit ec624ea483cbf8fb3d4e8f393bc25c90a0e29d4b Author: Fred Gylys-Colwell [ Merge of http://go/wvgerrit/34260 ] This code adds a watchdog timer to the level 3 initialization. If initialization does not finish within 5 seconds, the process will abort, printing a small amount of debugging information. arm/libwvlevel3.a Level3 Library 4445 Sep 11 2017 14:05:15 Test: unit tests on bullhead. Video on Play Movies. GTS tests run on loop overnight. Bug: 65379279 Merged from https://widevine-internal-review.googlesource.com/33540 * Remove libwidevinehidl_utils dependency Author: Rahul Frias [ Merge of http://go/wvgerrit/37822 ] libwvdrmcryptoplugin_hidl has a dependency on libwidevinehidl_utils which was introduced due to an out of order merge from oc-mr1-dev to master. Bug: 69573113 * Automatically generate log location information Author: Rahul Frias [ Merge of http://go/wvgerrit/36563 ] Currently class and method names are manually added to each log message in the CDM on android and some other platforms. This change prepends log messages with file name, line number and function name automatically. The code is platform specific so it can be enabled and the precise format configured on a per-platform basis. As an example, here is a log on android before the change, 11-01 02:48:48.658 D/WVCdm (32198): CryptoSession::Open: Lock: requested_security_level: Default and after, 11-01 02:48:48.658 D/WVCdm (32198): [crypto_session.cpp(1108):Open] Lock: requested_security_level: Default A follow on CL will remove the manually added class/method information. Bug: 9261010 * Fix BoringSSL Compatibility of oec_session_util.cpp Author: John W. Bruce [ Merge of http://go/wvgerrit/37121 ] A previous change inadvertantly used APIs from OpenSSL that do not exist in BoringSSL in oec_session_util.cpp. As a temporary fix until we can move all targets to BoringSSL, this patch switches that file to use conditional compilation to choose the correct API depending on the library in use. It does not otherwise change the behavior of the file. Bug: 67908123 Test: wv_ce_cdm_unittest on x86-64 Test: linux_unit_tests * Create local shared_ptr implementation Author: Gene Morgan [ Merge of http://go/wvgerrit/37600 ] Derived from protobuf version, which came from google3. Removed locking (not thread-safe) and removed weak pointers (not needed for usages in CDM). Locking can easily be added if needed. * Revert C++11 usage - back to gnu++98 Author: Gene Morgan [ Merge of http://go/wvgerrit/37440 ] These changes roll back C++11-specific constructs: std::unique_ptr -> std::auto_ptr container initializers nullptr -> NULL std::shared_ptr to local shared_ptr compiler flags (-std=c++11 -> -sdt=gnu++98) NOTE: the "local" shared_ptr implementation is temporarily a direct reference to the shared_ptr implementation in third_party/protobuf. This has been fixed (implementation extracted and moved to core/include) in CL 37600. BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: Ie09ecb970aa06fe9301ac255375ca7d8e7ead8bc --- .../build_and_run_all_unit_tests.sh | 1 + .../cdm/core/include/crypto_session.h | 4 + libwvdrmengine/cdm/core/include/log.h | 19 +- .../cdm/core/include/oemcrypto_adapter.h | 14 +- .../cdm/core/include/service_certificate.h | 2 +- .../cdm/core/include/wv_cdm_types.h | 559 +++++++++--------- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 38 +- libwvdrmengine/cdm/core/src/cdm_session.cpp | 20 +- .../cdm/core/src/cdm_session_map.cpp | 6 +- .../cdm/core/src/crypto_session.cpp | 205 ++++++- .../core/src/oemcrypto_adapter_dynamic.cpp | 10 +- .../cdm/core/src/service_certificate.cpp | 4 +- .../cdm/core/src/usage_table_header.cpp | 2 +- .../core/test/usage_table_header_unittest.cpp | 154 ++++- libwvdrmengine/cdm/src/log.cpp | 22 +- libwvdrmengine/cdm/test/Android.mk | 4 + libwvdrmengine/include/mapErrors-inl.h | 11 - libwvdrmengine/include_hidl/mapErrors-inl.h | 9 - libwvdrmengine/level3/Android.mk | 3 +- libwvdrmengine/level3/arm/Android.mk | 15 +- libwvdrmengine/level3/arm64/Android.mk | 15 +- libwvdrmengine/level3/mips/Android.mk | 24 +- libwvdrmengine/level3/x86/Android.mk | 15 +- libwvdrmengine/level3/x86_64/Android.mk | 15 +- libwvdrmengine/mediacrypto/Android.mk | 1 - .../oemcrypto_engine_device_properties.cpp | 4 +- .../oemcrypto_engine_device_properties_L1.cpp | 8 +- ...emcrypto_engine_device_properties_cert.cpp | 8 +- ...oemcrypto_engine_device_properties_mod.cpp | 8 +- ...crypto_engine_device_properties_prov30.cpp | 8 +- .../mock/src/oemcrypto_engine_mock.cpp | 4 +- .../mock/src/oemcrypto_engine_mock.h | 6 +- .../oemcrypto/mock/src/oemcrypto_mock.cpp | 4 +- .../oemcrypto/test/oec_session_util.cpp | 36 +- 34 files changed, 804 insertions(+), 454 deletions(-) diff --git a/libwvdrmengine/build_and_run_all_unit_tests.sh b/libwvdrmengine/build_and_run_all_unit_tests.sh index 3143fb2d..65b9ad81 100755 --- a/libwvdrmengine/build_and_run_all_unit_tests.sh +++ b/libwvdrmengine/build_and_run_all_unit_tests.sh @@ -82,6 +82,7 @@ try_adb_push cdm_feature_test try_adb_push cdm_extended_duration_test try_adb_push cdm_session_unittest try_adb_push counter_metric_unittest +try_adb_push crypto_session_unittest try_adb_push device_files_unittest try_adb_push distribution_unittest try_adb_push event_metric_unittest diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index ae84948f..7720b55e 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -217,11 +217,15 @@ class CryptoSession { bool* exists, uint32_t* nonce); private: + friend class CryptoSessionForTest; + bool GetProvisioningMethod(CdmClientTokenType* token_type); void Init(); void Terminate(); bool GetTokenFromKeybox(std::string* token); bool GetTokenFromOemCert(std::string* token); + static bool ExtractSystemIdFromOemCert(const std::string& oem_cert, + uint32_t* system_id); bool GenerateSignature(const std::string& message, std::string* signature); bool GenerateRsaSignature(const std::string& message, std::string* signature); diff --git a/libwvdrmengine/cdm/core/include/log.h b/libwvdrmengine/cdm/core/include/log.h index d03ef873..3ef15223 100644 --- a/libwvdrmengine/cdm/core/include/log.h +++ b/libwvdrmengine/cdm/core/include/log.h @@ -25,15 +25,20 @@ extern LogPriority g_cutoff; // unit tests. void InitLogging(); -void Log(const char* file, int line, LogPriority level, const char* fmt, ...); +void Log(const char* file, const char* function, int line, LogPriority level, + const char* fmt, ...); // Log APIs -#define LOGE(...) Log(__FILE__, __LINE__, wvcdm::LOG_ERROR, __VA_ARGS__) -#define LOGW(...) Log(__FILE__, __LINE__, wvcdm::LOG_WARN, __VA_ARGS__) -#define LOGI(...) Log(__FILE__, __LINE__, wvcdm::LOG_INFO, __VA_ARGS__) -#define LOGD(...) Log(__FILE__, __LINE__, wvcdm::LOG_DEBUG, __VA_ARGS__) -#define LOGV(...) Log(__FILE__, __LINE__, wvcdm::LOG_VERBOSE, __VA_ARGS__) - +#define LOGE(...) Log(__FILE__, __func__, __LINE__, \ + wvcdm::LOG_ERROR, __VA_ARGS__) +#define LOGW(...) Log(__FILE__, __func__, __LINE__, \ + wvcdm::LOG_WARN, __VA_ARGS__) +#define LOGI(...) Log(__FILE__, __func__, __LINE__, \ + wvcdm::LOG_INFO, __VA_ARGS__) +#define LOGD(...) Log(__FILE__, __func__, __LINE__, \ + wvcdm::LOG_DEBUG, __VA_ARGS__) +#define LOGV(...) Log(__FILE__, __func__, __LINE__, \ + wvcdm::LOG_VERBOSE, __VA_ARGS__) } // namespace wvcdm #endif // WVCDM_CORE_LOG_H_ diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index 2059241b..19d78542 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -54,13 +54,24 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(SecurityLevel level, uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst, size_t pst_length); +} // namespace wvcdm + /* The following functions are deprecated in OEMCrypto v13. They are defined * here so that core cdm code may be backwards compatible with an OEMCrypto * v12. */ extern "C" { + +OEMCryptoResult OEMCrypto_LoadKeys_V11_or_V12( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, + const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, const uint8_t* pst, + size_t pst_length); + OEMCryptoResult OEMCrypto_UpdateUsageTable(); -OEMCryptoResult OEMCrypto_DeactivateUsageEntry_12(const uint8_t* pst, + +OEMCryptoResult OEMCrypto_DeactivateUsageEntry_V12(const uint8_t* pst, size_t pst_length); OEMCryptoResult OEMCrypto_DeleteUsageEntry( OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length, @@ -70,6 +81,5 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry( OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, size_t pst_length); } // extern "C" -} // namespace wvcdm #endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_ diff --git a/libwvdrmengine/cdm/core/include/service_certificate.h b/libwvdrmengine/cdm/core/include/service_certificate.h index ce8ad817..d672c3ac 100644 --- a/libwvdrmengine/cdm/core/include/service_certificate.h +++ b/libwvdrmengine/cdm/core/include/service_certificate.h @@ -75,7 +75,7 @@ class ServiceCertificate { std::string provider_id_; // Public key. - std::unique_ptr public_key_; + std::auto_ptr public_key_; CORE_DISALLOW_COPY_AND_ASSIGN(ServiceCertificate); }; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 4ae91b94..7c0978b9 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -38,286 +38,285 @@ enum CdmKeyRequestType { }; enum CdmResponseType { - NO_ERROR, /* 0 */ - UNKNOWN_ERROR, - KEY_ADDED, - KEY_ERROR, - KEY_MESSAGE, - NEED_KEY, /* 5 */ - KEY_CANCELED, - NEED_PROVISIONING, - DEVICE_REVOKED, - INSUFFICIENT_CRYPTO_RESOURCES, - ADD_KEY_ERROR, /* 10 */ - CERT_PROVISIONING_GET_KEYBOX_ERROR_1, - CERT_PROVISIONING_GET_KEYBOX_ERROR_2, - CERT_PROVISIONING_INVALID_CERT_TYPE, - CERT_PROVISIONING_REQUEST_ERROR_1, - CERT_PROVISIONING_NONCE_GENERATION_ERROR, /* 15 */ - CERT_PROVISIONING_REQUEST_ERROR_3, - CERT_PROVISIONING_REQUEST_ERROR_4, - CERT_PROVISIONING_RESPONSE_ERROR_1, - CERT_PROVISIONING_RESPONSE_ERROR_2, - CERT_PROVISIONING_RESPONSE_ERROR_3, /* 20 */ - CERT_PROVISIONING_RESPONSE_ERROR_4, - CERT_PROVISIONING_RESPONSE_ERROR_5, - CERT_PROVISIONING_RESPONSE_ERROR_6, - CERT_PROVISIONING_RESPONSE_ERROR_7, - CERT_PROVISIONING_RESPONSE_ERROR_8, /* 25 */ - CRYPTO_SESSION_OPEN_ERROR_1, - CRYPTO_SESSION_OPEN_ERROR_2, - CRYPTO_SESSION_OPEN_ERROR_3, - CRYPTO_SESSION_OPEN_ERROR_4, - CRYPTO_SESSION_OPEN_ERROR_5, /* 30 */ - DECRYPT_NOT_READY, - DEVICE_CERTIFICATE_ERROR_1, - DEVICE_CERTIFICATE_ERROR_2, - DEVICE_CERTIFICATE_ERROR_3, - DEVICE_CERTIFICATE_ERROR_4, /* 35 */ - EMPTY_KEY_DATA_1, - EMPTY_KEY_DATA_2, - EMPTY_KEYSET_ID, - EMPTY_KEYSET_ID_ENG_1, - EMPTY_KEYSET_ID_ENG_2, /* 40 */ - EMPTY_KEYSET_ID_ENG_3, - EMPTY_KEYSET_ID_ENG_4, - EMPTY_LICENSE_RENEWAL, - EMPTY_LICENSE_RESPONSE_1, - EMPTY_LICENSE_RESPONSE_2, /* 45 */ - EMPTY_PROVISIONING_CERTIFICATE_1, - EMPTY_PROVISIONING_RESPONSE, - EMPTY_SESSION_ID, - GENERATE_DERIVED_KEYS_ERROR, - LICENSE_RENEWAL_NONCE_GENERATION_ERROR, /* 50 */ - GENERATE_USAGE_REPORT_ERROR, - GET_LICENSE_ERROR, - GET_RELEASED_LICENSE_ERROR, - GET_USAGE_INFO_ERROR_1, - GET_USAGE_INFO_ERROR_2, /* 55 */ - GET_USAGE_INFO_ERROR_3, - GET_USAGE_INFO_ERROR_4, - INIT_DATA_NOT_FOUND, - INVALID_CRYPTO_SESSION_1, - INVALID_CRYPTO_SESSION_2, /* 60 */ - INVALID_CRYPTO_SESSION_3, - INVALID_CRYPTO_SESSION_4, - INVALID_CRYPTO_SESSION_5, - INVALID_DECRYPT_PARAMETERS_ENG_1, - INVALID_DECRYPT_PARAMETERS_ENG_2, /* 65 */ - INVALID_DECRYPT_PARAMETERS_ENG_3, - INVALID_DECRYPT_PARAMETERS_ENG_4, - INVALID_DEVICE_CERTIFICATE_TYPE, - INVALID_KEY_SYSTEM, - INVALID_LICENSE_RESPONSE, /* 70 */ - INVALID_LICENSE_TYPE, - INVALID_PARAMETERS_ENG_1, - INVALID_PARAMETERS_ENG_2, - INVALID_PARAMETERS_ENG_3, - INVALID_PARAMETERS_ENG_4, /* 75 */ - INVALID_PARAMETERS_LIC_1, - INVALID_PARAMETERS_LIC_2, - INVALID_PROVISIONING_PARAMETERS_1, - INVALID_PROVISIONING_PARAMETERS_2, - INVALID_PROVISIONING_REQUEST_PARAM_1, /* 80 */ - INVALID_PROVISIONING_REQUEST_PARAM_2, - INVALID_QUERY_KEY, - INVALID_SESSION_ID, - KEY_REQUEST_ERROR_1, - UNUSED_1, /* previously KEY_REQUEST_ERROR_2 */ /* 85 */ - KEY_SIZE_ERROR, - KEYSET_ID_NOT_FOUND_1, - KEYSET_ID_NOT_FOUND_2, - KEYSET_ID_NOT_FOUND_3, - LICENSE_ID_NOT_FOUND, /* 90 */ - LICENSE_PARSER_INIT_ERROR, - LICENSE_PARSER_NOT_INITIALIZED_1, - LICENSE_PARSER_NOT_INITIALIZED_2, - LICENSE_PARSER_NOT_INITIALIZED_3, - LICENSE_RESPONSE_NOT_SIGNED, /* 95 */ - LICENSE_RESPONSE_PARSE_ERROR_1, - LICENSE_RESPONSE_PARSE_ERROR_2, - LICENSE_RESPONSE_PARSE_ERROR_3, - LOAD_KEY_ERROR, - NO_CONTENT_KEY, /* 100 */ - REFRESH_KEYS_ERROR, - RELEASE_ALL_USAGE_INFO_ERROR_1, - RELEASE_ALL_USAGE_INFO_ERROR_2, - RELEASE_KEY_ERROR, - RELEASE_KEY_REQUEST_ERROR, /* 105 */ - RELEASE_LICENSE_ERROR_1, - RELEASE_LICENSE_ERROR_2, - RELEASE_USAGE_INFO_ERROR, - RENEW_KEY_ERROR_1, - RENEW_KEY_ERROR_2, /* 110 */ - LICENSE_RENEWAL_SIGNING_ERROR, - UNUSED_4, /* previously RESTORE_OFFLINE_LICENSE_ERROR_1 */ - RESTORE_OFFLINE_LICENSE_ERROR_2, - SESSION_INIT_ERROR_1, - SESSION_INIT_ERROR_2, /* 115 */ - UNUSED_5, /* previously SESSION_INIT_GET_KEYBOX_ERROR */ - SESSION_NOT_FOUND_1, - SESSION_NOT_FOUND_2, - SESSION_NOT_FOUND_3, - SESSION_NOT_FOUND_4, /* 120 */ - SESSION_NOT_FOUND_5, - SESSION_NOT_FOUND_6, - SESSION_NOT_FOUND_7, - SESSION_NOT_FOUND_8, - SESSION_NOT_FOUND_9, /* 125 */ - SESSION_NOT_FOUND_10, - SESSION_NOT_FOUND_FOR_DECRYPT, - SESSION_KEYS_NOT_FOUND, - SIGNATURE_NOT_FOUND, - STORE_LICENSE_ERROR_1, /* 130 */ - STORE_LICENSE_ERROR_2, - UNUSED_6, /* previously STORE_LICENSE_ERROR_3 */ - STORE_USAGE_INFO_ERROR, - UNPROVISION_ERROR_1, - UNPROVISION_ERROR_2, /* 135 */ - UNPROVISION_ERROR_3, - UNPROVISION_ERROR_4, - UNSUPPORTED_INIT_DATA, - USAGE_INFO_NOT_FOUND, - UNUSED_8, /* 140 */ - /* UNUSED_8 previously LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR */ - PARSE_SERVICE_CERTIFICATE_ERROR, - UNUSED_10, /* previously SERVICE_CERTIFICATE_TYPE_ERROR */ - CLIENT_ID_GENERATE_RANDOM_ERROR, - CLIENT_ID_AES_INIT_ERROR, - CLIENT_ID_AES_ENCRYPT_ERROR, /* 145 */ - CLIENT_ID_RSA_INIT_ERROR, - CLIENT_ID_RSA_ENCRYPT_ERROR, - INVALID_QUERY_STATUS, - UNUSED_3, /* previously EMPTY_PROVISIONING_CERTIFICATE_2 on mnc-dev, */ - /* DUPLICATE_SESSION_ID_SPECIFIED on master */ - LICENSE_PARSER_NOT_INITIALIZED_4, /* 150 */ - INVALID_PARAMETERS_LIC_3, - INVALID_PARAMETERS_LIC_4, - UNUSED_2, /* previously INVALID_PARAMETERS_LIC_5 */ - INVALID_PARAMETERS_LIC_6, - INVALID_PARAMETERS_LIC_7, /* 155 */ - LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR, - CENC_INIT_DATA_UNAVAILABLE, - PREPARE_CENC_CONTENT_ID_FAILED, - WEBM_INIT_DATA_UNAVAILABLE, - PREPARE_WEBM_CONTENT_ID_FAILED, /* 160 */ - UNSUPPORTED_INIT_DATA_FORMAT, - LICENSE_REQUEST_NONCE_GENERATION_ERROR, - LICENSE_REQUEST_SIGNING_ERROR, - EMPTY_LICENSE_REQUEST, - SECURE_BUFFER_REQUIRED, /* 165 */ - DUPLICATE_SESSION_ID_SPECIFIED, - LICENSE_RENEWAL_PROHIBITED, - EMPTY_PROVISIONING_CERTIFICATE_2, - OFFLINE_LICENSE_PROHIBITED, - STORAGE_PROHIBITED, /* 170 */ - EMPTY_KEYSET_ID_ENG_5, - SESSION_NOT_FOUND_11, - LOAD_USAGE_INFO_FILE_ERROR, - LOAD_USAGE_INFO_MISSING, - SESSION_FILE_HANDLE_INIT_ERROR, /* 175 */ - INCORRECT_CRYPTO_MODE, - INVALID_PARAMETERS_ENG_5, - DECRYPT_ERROR, - INSUFFICIENT_OUTPUT_PROTECTION, - SESSION_NOT_FOUND_12, /* 180 */ - KEY_NOT_FOUND_1, - KEY_NOT_FOUND_2, - KEY_CONFLICT_1, - INVALID_PARAMETERS_ENG_6, - INVALID_PARAMETERS_ENG_7, /* 185 */ - INVALID_PARAMETERS_ENG_8, - INVALID_PARAMETERS_ENG_9, - INVALID_PARAMETERS_ENG_10, - INVALID_PARAMETERS_ENG_11, - INVALID_PARAMETERS_ENG_12, /* 190 */ - SESSION_NOT_FOUND_13, - SESSION_NOT_FOUND_14, - SESSION_NOT_FOUND_15, - SESSION_NOT_FOUND_16, - KEY_NOT_FOUND_3, /* 195 */ - KEY_NOT_FOUND_4, - KEY_NOT_FOUND_5, - KEY_NOT_FOUND_6, - INVALID_SESSION_1, - NO_DEVICE_KEY_1, /* 200 */ - NO_CONTENT_KEY_2, - INSUFFICIENT_CRYPTO_RESOURCES_2, - INVALID_PARAMETERS_ENG_13, - INVALID_PARAMETERS_ENG_14, - INVALID_PARAMETERS_ENG_15, /* 205 */ - INVALID_PARAMETERS_ENG_16, - UNUSED_7, /* previously DEVICE_CERTIFICATE_ERROR_5 */ - CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1, - CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2, - LICENSING_CLIENT_TOKEN_ERROR_1, /* 210 */ - ANALOG_OUTPUT_ERROR, - UNKNOWN_SELECT_KEY_ERROR_1, - UNKNOWN_SELECT_KEY_ERROR_2, - CREATE_USAGE_TABLE_ERROR, - LOAD_USAGE_HEADER_GENERATION_SKEW, /* 215 */ - LOAD_USAGE_HEADER_SIGNATURE_FAILURE, - LOAD_USAGE_HEADER_BAD_MAGIC, - LOAD_USAGE_HEADER_UNKNOWN_ERROR, - INVALID_PARAMETERS_ENG_17, - INVALID_PARAMETERS_ENG_18, /* 220 */ - INSUFFICIENT_CRYPTO_RESOURCES_3, - CREATE_USAGE_ENTRY_UNKNOWN_ERROR, - LOAD_USAGE_ENTRY_GENERATION_SKEW, - LOAD_USAGE_ENTRY_SIGNATURE_FAILURE, - LOAD_USAGE_ENTRY_UNKNOWN_ERROR, /* 225 */ - INVALID_PARAMETERS_ENG_19, - INVALID_PARAMETERS_ENG_20, - UPDATE_USAGE_ENTRY_UNKNOWN_ERROR, - INVALID_PARAMETERS_ENG_21, - SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR, /* 230 */ - MOVE_USAGE_ENTRY_UNKNOWN_ERROR, - COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR, - INVALID_PARAMETERS_ENG_22, - LIST_LICENSE_ERROR_1, - LIST_LICENSE_ERROR_2, /* 235 */ - INVALID_PARAMETERS_ENG_23, - USAGE_INFORMATION_SUPPORT_FAILED, - USAGE_SUPPORT_GET_API_FAILED, - UNEXPECTED_EMPTY_USAGE_ENTRY, - INVALID_USAGE_ENTRY_NUMBER_MODIFICATION, /* 240 */ - USAGE_INVALID_NEW_ENTRY, - USAGE_INVALID_PARAMETERS_1, - USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED, - USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED, - USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE, /* 245 */ - USAGE_ENTRY_NUMBER_MISMATCH, - USAGE_STORE_LICENSE_FAILED, - USAGE_STORE_USAGE_INFO_FAILED, - USAGE_INVALID_LOAD_ENTRY, - RELEASE_ALL_USAGE_INFO_ERROR_4, /* 250 */ - RELEASE_ALL_USAGE_INFO_ERROR_5, - RELEASE_USAGE_INFO_FAILED, - INCORRECT_USAGE_SUPPORT_TYPE_1, - INCORRECT_USAGE_SUPPORT_TYPE_2, - KEY_PROHIBITED_FOR_SECURITY_LEVEL, /* 255 */ - KEY_NOT_FOUND_IN_SESSION, - NO_USAGE_ENTRIES, - LIST_USAGE_ERROR_1, - LIST_USAGE_ERROR_2, - DELETE_USAGE_ERROR_1, /* 260 */ - DELETE_USAGE_ERROR_2, - DELETE_USAGE_ERROR_3, - PRIVACY_MODE_ERROR_1, - PRIVACY_MODE_ERROR_2, - PRIVACY_MODE_ERROR_3, /* 265 */ - EMPTY_RESPONSE_ERROR_1, - INVALID_PARAMETERS_ENG_24, - PARSE_RESPONSE_ERROR_1, - PARSE_RESPONSE_ERROR_2, - PARSE_RESPONSE_ERROR_3, /* 270 */ - PARSE_RESPONSE_ERROR_4, - USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED, - USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED, - USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE, - RELEASE_ALL_USAGE_INFO_ERROR_6, /* 275 */ - RELEASE_ALL_USAGE_INFO_ERROR_7, - LICENSE_REQUEST_INVALID_SUBLICENSE, + NO_ERROR = 0, + UNKNOWN_ERROR = 1, + KEY_ADDED = 2, + KEY_ERROR = 3, + KEY_MESSAGE = 4, + NEED_KEY = 5, + KEY_CANCELED = 6, + NEED_PROVISIONING = 7, + DEVICE_REVOKED = 8, + INSUFFICIENT_CRYPTO_RESOURCES = 9, + ADD_KEY_ERROR = 10, + CERT_PROVISIONING_GET_KEYBOX_ERROR_1 = 11, + CERT_PROVISIONING_GET_KEYBOX_ERROR_2 = 12, + CERT_PROVISIONING_INVALID_CERT_TYPE = 13, + CERT_PROVISIONING_REQUEST_ERROR_1 = 14, + CERT_PROVISIONING_NONCE_GENERATION_ERROR = 15, + CERT_PROVISIONING_REQUEST_ERROR_3 = 16, + CERT_PROVISIONING_REQUEST_ERROR_4 = 17, + CERT_PROVISIONING_RESPONSE_ERROR_1 = 18, + CERT_PROVISIONING_RESPONSE_ERROR_2 = 19, + CERT_PROVISIONING_RESPONSE_ERROR_3 = 20, + CERT_PROVISIONING_RESPONSE_ERROR_4 = 21, + CERT_PROVISIONING_RESPONSE_ERROR_5 = 22, + CERT_PROVISIONING_RESPONSE_ERROR_6 = 23, + CERT_PROVISIONING_RESPONSE_ERROR_7 = 24, + CERT_PROVISIONING_RESPONSE_ERROR_8 = 25, + CRYPTO_SESSION_OPEN_ERROR_1 = 26, + CRYPTO_SESSION_OPEN_ERROR_2 = 27, + CRYPTO_SESSION_OPEN_ERROR_3 = 28, + CRYPTO_SESSION_OPEN_ERROR_4 = 29, + CRYPTO_SESSION_OPEN_ERROR_5 = 30, + DECRYPT_NOT_READY = 31, + DEVICE_CERTIFICATE_ERROR_1 = 32, + DEVICE_CERTIFICATE_ERROR_2 = 33, + DEVICE_CERTIFICATE_ERROR_3 = 34, + DEVICE_CERTIFICATE_ERROR_4 = 35, + EMPTY_KEY_DATA_1 = 36, + EMPTY_KEY_DATA_2 = 37, + EMPTY_KEYSET_ID = 38, + EMPTY_KEYSET_ID_ENG_1 = 39, + EMPTY_KEYSET_ID_ENG_2 = 40, + EMPTY_KEYSET_ID_ENG_3 = 41, + EMPTY_KEYSET_ID_ENG_4 = 42, + EMPTY_LICENSE_RENEWAL = 43, + EMPTY_LICENSE_RESPONSE_1 = 44, + EMPTY_LICENSE_RESPONSE_2 = 45, + EMPTY_PROVISIONING_CERTIFICATE_1 = 46, + EMPTY_PROVISIONING_RESPONSE = 47, + EMPTY_SESSION_ID = 48, + GENERATE_DERIVED_KEYS_ERROR = 49, + LICENSE_RENEWAL_NONCE_GENERATION_ERROR = 50, + GENERATE_USAGE_REPORT_ERROR = 51, + GET_LICENSE_ERROR = 52, + GET_RELEASED_LICENSE_ERROR = 53, + GET_USAGE_INFO_ERROR_1 = 54, + GET_USAGE_INFO_ERROR_2 = 55, + GET_USAGE_INFO_ERROR_3 = 56, + GET_USAGE_INFO_ERROR_4 = 57, + INIT_DATA_NOT_FOUND = 58, + INVALID_CRYPTO_SESSION_1 = 59, + INVALID_CRYPTO_SESSION_2 = 60, + INVALID_CRYPTO_SESSION_3 = 61, + INVALID_CRYPTO_SESSION_4 = 62, + INVALID_CRYPTO_SESSION_5 = 63, + INVALID_DECRYPT_PARAMETERS_ENG_1 = 64, + INVALID_DECRYPT_PARAMETERS_ENG_2 = 65, + INVALID_DECRYPT_PARAMETERS_ENG_3 = 66, + INVALID_DECRYPT_PARAMETERS_ENG_4 = 67, + INVALID_DEVICE_CERTIFICATE_TYPE = 68, + INVALID_KEY_SYSTEM = 69, + INVALID_LICENSE_RESPONSE = 70, + INVALID_LICENSE_TYPE = 71, + INVALID_PARAMETERS_ENG_1 = 72, + INVALID_PARAMETERS_ENG_2 = 73, + INVALID_PARAMETERS_ENG_3 = 74, + INVALID_PARAMETERS_ENG_4 = 75, + INVALID_PARAMETERS_LIC_1 = 76, + INVALID_PARAMETERS_LIC_2 = 77, + INVALID_PROVISIONING_PARAMETERS_1 = 78, + INVALID_PROVISIONING_PARAMETERS_2 = 79, + INVALID_PROVISIONING_REQUEST_PARAM_1 = 80, + INVALID_PROVISIONING_REQUEST_PARAM_2 = 81, + INVALID_QUERY_KEY = 82, + INVALID_SESSION_ID = 83, + KEY_REQUEST_ERROR_1 = 84, + /* previously KEY_REQUEST_ERROR_2 = 85 */ + KEY_SIZE_ERROR = 86, + KEYSET_ID_NOT_FOUND_1 = 87, + KEYSET_ID_NOT_FOUND_2 = 88, + KEYSET_ID_NOT_FOUND_3 = 89, + LICENSE_ID_NOT_FOUND = 90, + LICENSE_PARSER_INIT_ERROR = 91, + LICENSE_PARSER_NOT_INITIALIZED_1 = 92, + LICENSE_PARSER_NOT_INITIALIZED_2 = 93, + LICENSE_PARSER_NOT_INITIALIZED_3 = 94, + LICENSE_RESPONSE_NOT_SIGNED = 95, + LICENSE_RESPONSE_PARSE_ERROR_1 = 96, + LICENSE_RESPONSE_PARSE_ERROR_2 = 97, + LICENSE_RESPONSE_PARSE_ERROR_3 = 98, + LOAD_KEY_ERROR = 99, + NO_CONTENT_KEY = 100, + REFRESH_KEYS_ERROR = 101, + RELEASE_ALL_USAGE_INFO_ERROR_1 = 102, + RELEASE_ALL_USAGE_INFO_ERROR_2 = 103, + RELEASE_KEY_ERROR = 104, + RELEASE_KEY_REQUEST_ERROR = 105, + RELEASE_LICENSE_ERROR_1 = 106, + RELEASE_LICENSE_ERROR_2 = 107, + RELEASE_USAGE_INFO_ERROR = 108, + RENEW_KEY_ERROR_1 = 109, + RENEW_KEY_ERROR_2 = 110, + LICENSE_RENEWAL_SIGNING_ERROR = 111, + /* previously RESTORE_OFFLINE_LICENSE_ERROR_1 = 112 */ + RESTORE_OFFLINE_LICENSE_ERROR_2 = 113, + SESSION_INIT_ERROR_1 = 114, + SESSION_INIT_ERROR_2 = 115, + /* previously SESSION_INIT_GET_KEYBOX_ERROR = 116 */ + SESSION_NOT_FOUND_1 = 117, + SESSION_NOT_FOUND_2 = 118, + SESSION_NOT_FOUND_3 = 119, + SESSION_NOT_FOUND_4 = 120, + SESSION_NOT_FOUND_5 = 121, + SESSION_NOT_FOUND_6 = 122, + SESSION_NOT_FOUND_7 = 123, + SESSION_NOT_FOUND_8 = 124, + SESSION_NOT_FOUND_9 = 125, + SESSION_NOT_FOUND_10 = 126, + SESSION_NOT_FOUND_FOR_DECRYPT = 127, + SESSION_KEYS_NOT_FOUND = 128, + SIGNATURE_NOT_FOUND = 129, + STORE_LICENSE_ERROR_1 = 130, + STORE_LICENSE_ERROR_2 = 131, + /* previously STORE_LICENSE_ERROR_3 = 132 */ + STORE_USAGE_INFO_ERROR = 133, + UNPROVISION_ERROR_1 = 134, + UNPROVISION_ERROR_2 = 135, + UNPROVISION_ERROR_3 = 136, + UNPROVISION_ERROR_4 = 137, + UNSUPPORTED_INIT_DATA = 138, + USAGE_INFO_NOT_FOUND = 139, + /* previously LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR = 140 */ + PARSE_SERVICE_CERTIFICATE_ERROR = 141, + /* previously SERVICE_CERTIFICATE_TYPE_ERROR = 142 */ + CLIENT_ID_GENERATE_RANDOM_ERROR = 143, + CLIENT_ID_AES_INIT_ERROR = 144, + CLIENT_ID_AES_ENCRYPT_ERROR = 145, + CLIENT_ID_RSA_INIT_ERROR = 146, + CLIENT_ID_RSA_ENCRYPT_ERROR = 147, + INVALID_QUERY_STATUS = 148, + /* previously EMPTY_PROVISIONING_CERTIFICATE_2 = 149 on mnc-dev, */ + /* and DUPLICATE_SESSION_ID_SPECIFIED = 149 on master */ + LICENSE_PARSER_NOT_INITIALIZED_4 = 150, + INVALID_PARAMETERS_LIC_3 = 151, + INVALID_PARAMETERS_LIC_4 = 152, + /* previously INVALID_PARAMETERS_LIC_5 = 153 */ + INVALID_PARAMETERS_LIC_6 = 154, + INVALID_PARAMETERS_LIC_7 = 155, + LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR = 156, + CENC_INIT_DATA_UNAVAILABLE = 157, + PREPARE_CENC_CONTENT_ID_FAILED = 158, + WEBM_INIT_DATA_UNAVAILABLE = 159, + PREPARE_WEBM_CONTENT_ID_FAILED = 160, + UNSUPPORTED_INIT_DATA_FORMAT = 161, + LICENSE_REQUEST_NONCE_GENERATION_ERROR = 162, + LICENSE_REQUEST_SIGNING_ERROR = 163, + EMPTY_LICENSE_REQUEST = 164, + SECURE_BUFFER_REQUIRED = 165, + DUPLICATE_SESSION_ID_SPECIFIED = 166, + LICENSE_RENEWAL_PROHIBITED = 167, + EMPTY_PROVISIONING_CERTIFICATE_2 = 168, + OFFLINE_LICENSE_PROHIBITED = 169, + STORAGE_PROHIBITED = 170, + EMPTY_KEYSET_ID_ENG_5 = 171, + SESSION_NOT_FOUND_11 = 172, + LOAD_USAGE_INFO_FILE_ERROR = 173, + LOAD_USAGE_INFO_MISSING = 174, + SESSION_FILE_HANDLE_INIT_ERROR = 175, + INCORRECT_CRYPTO_MODE = 176, + INVALID_PARAMETERS_ENG_5 = 177, + DECRYPT_ERROR = 178, + INSUFFICIENT_OUTPUT_PROTECTION = 179, + SESSION_NOT_FOUND_12 = 180, + KEY_NOT_FOUND_1 = 181, + KEY_NOT_FOUND_2 = 182, + KEY_CONFLICT_1 = 183, + INVALID_PARAMETERS_ENG_6 = 184, + INVALID_PARAMETERS_ENG_7 = 185, + INVALID_PARAMETERS_ENG_8 = 186, + INVALID_PARAMETERS_ENG_9 = 187, + INVALID_PARAMETERS_ENG_10 = 188, + INVALID_PARAMETERS_ENG_11 = 189, + INVALID_PARAMETERS_ENG_12 = 190, + SESSION_NOT_FOUND_13 = 191, + SESSION_NOT_FOUND_14 = 192, + SESSION_NOT_FOUND_15 = 193, + SESSION_NOT_FOUND_16 = 194, + KEY_NOT_FOUND_3 = 195, + KEY_NOT_FOUND_4 = 196, + KEY_NOT_FOUND_5 = 197, + KEY_NOT_FOUND_6 = 198, + INVALID_SESSION_1 = 199, + NO_DEVICE_KEY_1 = 200, + NO_CONTENT_KEY_2 = 201, + INSUFFICIENT_CRYPTO_RESOURCES_2 = 202, + INVALID_PARAMETERS_ENG_13 = 203, + INVALID_PARAMETERS_ENG_14 = 204, + INVALID_PARAMETERS_ENG_15 = 205, + INVALID_PARAMETERS_ENG_16 = 206, + /* previously DEVICE_CERTIFICATE_ERROR_5 = 207 */ + CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1 = 208, + CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2 = 209, + LICENSING_CLIENT_TOKEN_ERROR_1 = 210, + ANALOG_OUTPUT_ERROR = 211, + UNKNOWN_SELECT_KEY_ERROR_1 = 212, + UNKNOWN_SELECT_KEY_ERROR_2 = 213, + CREATE_USAGE_TABLE_ERROR = 214, + LOAD_USAGE_HEADER_GENERATION_SKEW = 215, + LOAD_USAGE_HEADER_SIGNATURE_FAILURE = 216, + LOAD_USAGE_HEADER_BAD_MAGIC = 217, + LOAD_USAGE_HEADER_UNKNOWN_ERROR = 218, + INVALID_PARAMETERS_ENG_17 = 219, + INVALID_PARAMETERS_ENG_18 = 220, + INSUFFICIENT_CRYPTO_RESOURCES_3 = 221, + CREATE_USAGE_ENTRY_UNKNOWN_ERROR = 222, + LOAD_USAGE_ENTRY_GENERATION_SKEW = 223, + LOAD_USAGE_ENTRY_SIGNATURE_FAILURE = 224, + LOAD_USAGE_ENTRY_UNKNOWN_ERROR = 225, + INVALID_PARAMETERS_ENG_19 = 226, + INVALID_PARAMETERS_ENG_20 = 227, + UPDATE_USAGE_ENTRY_UNKNOWN_ERROR = 228, + INVALID_PARAMETERS_ENG_21 = 229, + SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR = 230, + MOVE_USAGE_ENTRY_UNKNOWN_ERROR = 231, + COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR = 232, + INVALID_PARAMETERS_ENG_22 = 233, + LIST_LICENSE_ERROR_1 = 234, + LIST_LICENSE_ERROR_2 = 235, + INVALID_PARAMETERS_ENG_23 = 236, + USAGE_INFORMATION_SUPPORT_FAILED = 237, + USAGE_SUPPORT_GET_API_FAILED = 238, + UNEXPECTED_EMPTY_USAGE_ENTRY = 239, + INVALID_USAGE_ENTRY_NUMBER_MODIFICATION = 240, + USAGE_INVALID_NEW_ENTRY = 241, + USAGE_INVALID_PARAMETERS_1 = 242, + USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED = 243, + USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED = 244, + USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE = 245, + USAGE_ENTRY_NUMBER_MISMATCH = 246, + USAGE_STORE_LICENSE_FAILED = 247, + USAGE_STORE_USAGE_INFO_FAILED = 248, + USAGE_INVALID_LOAD_ENTRY = 249, + RELEASE_ALL_USAGE_INFO_ERROR_4 = 250, + RELEASE_ALL_USAGE_INFO_ERROR_5 = 251, + RELEASE_USAGE_INFO_FAILED = 252, + INCORRECT_USAGE_SUPPORT_TYPE_1 = 253, + INCORRECT_USAGE_SUPPORT_TYPE_2 = 254, + KEY_PROHIBITED_FOR_SECURITY_LEVEL = 255, + KEY_NOT_FOUND_IN_SESSION = 256, + NO_USAGE_ENTRIES = 257, + LIST_USAGE_ERROR_1 = 258, + LIST_USAGE_ERROR_2 = 259, + DELETE_USAGE_ERROR_1 = 260, + DELETE_USAGE_ERROR_2 = 261, + DELETE_USAGE_ERROR_3 = 262, + PRIVACY_MODE_ERROR_1 = 263, + PRIVACY_MODE_ERROR_2 = 264, + PRIVACY_MODE_ERROR_3 = 265, + EMPTY_RESPONSE_ERROR_1 = 266, + INVALID_PARAMETERS_ENG_24 = 267, + PARSE_RESPONSE_ERROR_1 = 268, + PARSE_RESPONSE_ERROR_2 = 269, + PARSE_RESPONSE_ERROR_3 = 270, + PARSE_RESPONSE_ERROR_4 = 271, + USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED = 272, + USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED = 273, + USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE = 274, + RELEASE_ALL_USAGE_INFO_ERROR_6 = 275, + RELEASE_ALL_USAGE_INFO_ERROR_7 = 276, + LICENSE_REQUEST_INVALID_SUBLICENSE = 277, }; enum CdmKeyStatus { diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 827e510a..3cc5ace6 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -262,7 +262,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest( id = iter->second.first; } - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(id, &session)) { LOGE("CdmEngine::GenerateKeyRequest: session_id not found = %s", id.c_str()); @@ -336,7 +336,7 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, id = iter->second.first; } - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(id, &session)) { LOGE("CdmEngine::AddKey: session id not found = %s", id.c_str()); return SESSION_NOT_FOUND_3; @@ -380,7 +380,7 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, return EMPTY_KEYSET_ID_ENG_4; } - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::RestoreKey: session_id not found = %s ", session_id.c_str()); @@ -403,7 +403,7 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) { LOGI("CdmEngine::RemoveKeys"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::RemoveKeys: session_id not found = %s", session_id.c_str()); @@ -419,7 +419,7 @@ CdmResponseType CdmEngine::GenerateRenewalRequest( const CdmSessionId& session_id, CdmKeyRequest* key_request) { LOGI("CdmEngine::GenerateRenewalRequest"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenerateRenewalRequest: session_id not found = %s", session_id.c_str()); @@ -448,7 +448,7 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data) { LOGI("CdmEngine::RenewKey"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::RenewKey: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_7; @@ -640,7 +640,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, CdmQueryMap* query_response) { LOGI("CdmEngine::QuerySessionStatus"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QuerySessionStatus: session_id not found = %s", session_id.c_str()); @@ -651,7 +651,7 @@ CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, bool CdmEngine::IsReleaseSession(const CdmSessionId& session_id) { LOGI("CdmEngine::IsReleaseSession"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::IsReleaseSession: session_id not found = %s", session_id.c_str()); @@ -662,7 +662,7 @@ bool CdmEngine::IsReleaseSession(const CdmSessionId& session_id) { bool CdmEngine::IsOfflineSession(const CdmSessionId& session_id) { LOGI("CdmEngine::IsOfflineSession"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::IsOfflineSession: session_id not found = %s", session_id.c_str()); @@ -674,7 +674,7 @@ bool CdmEngine::IsOfflineSession(const CdmSessionId& session_id) { CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id, CdmQueryMap* query_response) { LOGI("CdmEngine::QueryKeyStatus"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QueryKeyStatus: session_id not found = %s", session_id.c_str()); @@ -691,7 +691,7 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id, LOGE("CdmEngine::QueryKeyAllowedUsage: no response destination"); return INVALID_PARAMETERS_ENG_12; } - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QueryKeyAllowedUsage: session_id not found = %s", session_id.c_str()); @@ -742,7 +742,7 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, CdmResponseType CdmEngine::QueryOemCryptoSessionId( const CdmSessionId& session_id, CdmQueryMap* query_response) { LOGI("CdmEngine::QueryOemCryptoSessionId"); - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QueryOemCryptoSessionId: session_id not found = %s", session_id.c_str()); @@ -1298,7 +1298,7 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, return EMPTY_KEYSET_ID_ENG_5; } - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(key_set_id, &session)) { LOGE("CdmEngine::LoadUsageSession: session_id not found = %s ", key_set_id.c_str()); @@ -1383,7 +1383,7 @@ CdmResponseType CdmEngine::Decrypt(const CdmSessionId& session_id, // else we must be level 1 direct and we don't need to return a buffer. } - std::shared_ptr session; + shared_ptr session; if (session_id.empty()) { CdmSessionList sessions; session_map_.GetSessionList(sessions); @@ -1420,7 +1420,7 @@ CdmResponseType CdmEngine::GenericEncrypt( const std::string& session_id, const std::string& in_buffer, const std::string& key_id, const std::string& iv, CdmEncryptionAlgorithm algorithm, std::string* out_buffer) { - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericEncrypt: session_id not found = %s ", session_id.c_str()); @@ -1434,7 +1434,7 @@ CdmResponseType CdmEngine::GenericDecrypt( const std::string& key_id, const std::string& iv, CdmEncryptionAlgorithm algorithm, std::string* out_buffer) { - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericDecrypt: session_id not found = %s ", session_id.c_str()); @@ -1447,7 +1447,7 @@ CdmResponseType CdmEngine::GenericSign( const std::string& session_id, const std::string& message, const std::string& key_id, CdmSigningAlgorithm algorithm, std::string* signature) { - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericSign: session_id not found = %s ", session_id.c_str()); @@ -1460,7 +1460,7 @@ CdmResponseType CdmEngine::GenericVerify( const std::string& session_id, const std::string& message, const std::string& key_id, CdmSigningAlgorithm algorithm, const std::string& signature) { - std::shared_ptr session; + shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericVerify: session_id not found = %s ", session_id.c_str()); @@ -1520,7 +1520,7 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id, bool CdmEngine::NotifyResolution(const CdmSessionId& session_id, uint32_t width, uint32_t height) { - std::shared_ptr session; + shared_ptr session; if (session_map_.FindSession(session_id, &session)) { session->NotifyResolution(width, height); return true; diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 47991a31..64875f1d 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -124,7 +124,7 @@ CdmResponseType CdmSession::Init( // indicate that provisioning is needed. Get token from stored certificate std::string wrapped_key; if (!file_handle_->RetrieveCertificate(&client_token, &wrapped_key, - &serial_number, nullptr)) { + &serial_number, NULL)) { return NEED_PROVISIONING; } bool load_cert_sts; @@ -219,7 +219,7 @@ CdmResponseType CdmSession::RestoreOfflineSession( if (usage_support_type_ == kUsageEntrySupport) { if (!license_parser_->ExtractProviderSessionToken( key_response_, &provider_session_token) || - usage_table_header_ == nullptr) { + usage_table_header_ == NULL) { provider_session_token.clear(); } else { CdmResponseType sts = @@ -248,7 +248,7 @@ CdmResponseType CdmSession::RestoreOfflineSession( } if (usage_support_type_ == kUsageEntrySupport && - !provider_session_token.empty() && usage_table_header_ != nullptr) { + !provider_session_token.empty() && usage_table_header_ != NULL) { CdmResponseType sts = usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_); if (sts != NO_ERROR) { @@ -281,7 +281,7 @@ CdmResponseType CdmSession::RestoreUsageSession( usage_provider_session_token_ = usage_data.provider_session_token; if (usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { + usage_table_header_ != NULL) { CdmResponseType sts = usage_table_header_->LoadEntry( crypto_session_.get(), usage_entry_, usage_entry_number_); if (sts != NO_ERROR) { @@ -296,7 +296,7 @@ CdmResponseType CdmSession::RestoreUsageSession( } if (usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { + usage_table_header_ != NULL) { CdmResponseType sts = usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_); if (sts != NO_ERROR) { @@ -431,7 +431,7 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) { CdmResponseType sts; std::string provider_session_token; if (usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { + usage_table_header_ != NULL) { if (license_parser_->ExtractProviderSessionToken( key_response, &provider_session_token) && !provider_session_token.empty()) { @@ -448,7 +448,7 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) { // Update or delete entry if usage table header+entries are supported if (usage_support_type_ == kUsageEntrySupport && !provider_session_token.empty() && - usage_table_header_ != nullptr) { + usage_table_header_ != NULL) { if (sts != KEY_ADDED) { CdmResponseType delete_sts = usage_table_header_->DeleteEntry(usage_entry_number_, @@ -473,7 +473,7 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) { if (is_offline_ || has_provider_session_token()) { if (has_provider_session_token() && usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { + usage_table_header_ != NULL) { usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_); } @@ -888,12 +888,12 @@ CdmResponseType CdmSession::UpdateUsageTableInformation() { CdmResponseType CdmSession::UpdateUsageEntryInformation() { if (usage_support_type_ != kUsageEntrySupport || !has_provider_session_token() || - usage_table_header_ == nullptr) { + usage_table_header_ == NULL) { LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected state, " "usage support type: %d, PST present: %s, usage table header available" ": %s", usage_support_type_, has_provider_session_token() ? "yes" : "no", - usage_table_header_ == nullptr ? "no" : "yes"); + usage_table_header_ == NULL ? "no" : "yes"); return INCORRECT_USAGE_SUPPORT_TYPE_2; } diff --git a/libwvdrmengine/cdm/core/src/cdm_session_map.cpp b/libwvdrmengine/cdm/core/src/cdm_session_map.cpp index 6fb06446..c577a26a 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session_map.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session_map.cpp @@ -26,7 +26,7 @@ void CdmSessionMap::Add(const std::string& id, CdmSession* session) { bool CdmSessionMap::CloseSession(const std::string& id) { AutoLock lock(lock_); - std::shared_ptr session; + shared_ptr session; if (!FindSessionNoLock(id, &session)) { return false; } @@ -41,13 +41,13 @@ bool CdmSessionMap::Exists(const std::string& id) { } bool CdmSessionMap::FindSession(const CdmSessionId& id, - std::shared_ptr* session) { + shared_ptr* session) { AutoLock lock(lock_); return FindSessionNoLock(id, session); } bool CdmSessionMap::FindSessionNoLock(const CdmSessionId& session_id, - std::shared_ptr* session) { + shared_ptr* session) { CdmIdToSessionMap::iterator iter = sessions_.find(session_id); if (iter == sessions_.end()) { return false; diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 23d855d2..52c04c57 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -7,12 +7,15 @@ #include // needed for ntoh() #include -#include #include +#include +#include #include "crypto_key.h" #include "log.h" +#include "openssl/asn1.h" #include "openssl/sha.h" +#include "openssl/x509v3.h" #include "properties.h" #include "pst_report.h" #include "string_conversions.h" @@ -74,6 +77,32 @@ const uint32_t kRsaSignatureLength = 256; const size_t kMaximumChunkSize = 100 * 1024; // 100 KiB const size_t kEstimatedInitialUsageTableHeader = 40; const size_t kOemCryptoApiVersionSupportsBigUsageTables = 13; + +// Constants and utility objects relating to OEM Certificates +const int kExtensionOidSize = 64; +const char* const kWidevineSystemIdExtensionOid = "1.3.6.1.4.1.11129.4.1.1"; + +// Helpers for working with OpenSSL / BoringSSL +template +class openssl_ptr { + public: + explicit openssl_ptr(T* p = NULL) : ptr_(p) {} + ~openssl_ptr() { + if (ptr_) func(ptr_); + } + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + private: + T* ptr_; + CORE_DISALLOW_COPY_AND_ASSIGN(openssl_ptr); +}; +#ifdef OPENSSL_IS_BORINGSSL +void DeleteX509Stack(STACK_OF(X509)* stack) { + sk_X509_pop_free(stack, X509_free); +} +#endif } namespace wvcdm { @@ -983,39 +1012,173 @@ bool CryptoSession::GetApiVersion(uint32_t* version) { bool CryptoSession::GetSystemId(uint32_t* system_id) { if (!system_id) { - LOGE("CryptoSession::GetSystemId : No buffer passed to method."); + LOGE("CryptoSession::GetSystemId: No buffer passed to method."); return false; } - uint8_t buf[KEYBOX_KEY_DATA_SIZE]; - size_t buf_size = sizeof(buf); - LOGV("CryptoSession::GetSystemId: Lock"); AutoLock auto_lock(crypto_lock_); if (!initialized_) { return false; } - OEMCryptoResult sts; - M_TIME( - sts = OEMCrypto_GetKeyData( - buf, - &buf_size, - requested_security_level_), - metrics_, - oemcrypto_get_key_data_, - sts, - metrics::Pow2Bucket(buf_size)); - if (OEMCrypto_SUCCESS != sts) { + if (pre_provision_token_type_ == kClientTokenKeybox) { + uint8_t buf[KEYBOX_KEY_DATA_SIZE]; + size_t buf_size = sizeof(buf); + + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_GetKeyData( + buf, + &buf_size, + requested_security_level_), + metrics_, + oemcrypto_get_key_data_, + sts, + metrics::Pow2Bucket(buf_size)); + + if (OEMCrypto_SUCCESS != sts) { + LOGE("CryptoSession::GetSystemId: OEMCrypto_GetKeyData failed with %d", + sts); + return false; + } + + // Decode 32-bit int encoded as network-byte-order byte array starting at + // index 4. + uint32_t* id = reinterpret_cast(&buf[4]); + + *system_id = ntohl(*id); + return true; + } else if (pre_provision_token_type_ == kClientTokenOemCert) { + // Get the OEM Cert + std::string oem_cert; + if (GetTokenFromOemCert(&oem_cert)) { + return ExtractSystemIdFromOemCert(oem_cert, system_id); + } else { + return false; + } + } else { + LOGE("CryptoSession::GetSystemId: Unsupported pre-provision token type %d", + pre_provision_token_type_); + return false; + } +} + +bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert, + uint32_t* system_id) { + // Load the certificate chain into an OpenSSL X509 Stack +#ifdef OPENSSL_IS_BORINGSSL + const openssl_ptr x509_stack( + sk_X509_new_null()); + if (x509_stack.get() == NULL) { + LOGE("CryptoSession::GetSystemId: Unable to allocate X509 Stack."); return false; } - // Decode 32-bit int encoded as network-byte-order byte array starting at - // index 4. - uint32_t* id = reinterpret_cast(&buf[4]); + CBS pkcs7; + CBS_init(&pkcs7, reinterpret_cast(oem_cert.data()), + oem_cert.size()); + if (!PKCS7_get_certificates(x509_stack.get(), &pkcs7)) { + LOGE("CryptoSession::GetSystemId: Error getting certificate chain."); + return false; + } - *system_id = ntohl(*id); - return true; + STACK_OF(X509)* certs = x509_stack.get(); +#else + openssl_ptr bio( + // This const_cast is safe because BIO_new_mem_buf() creates a read-only + // buffer from the data given and does not mutate it. Its first parameter + // could be const, but it isn't. + BIO_new_mem_buf( + reinterpret_cast(const_cast(oem_cert.data())), + oem_cert.size())); + if (bio.get() == NULL) { + LOGE("CryptoSession::GetSystemId: Unable to allocate BIO buffer."); + return false; + } + + openssl_ptr cert(d2i_PKCS7_bio(bio.get(), NULL)); + if (cert.get() == NULL) { + LOGE("CryptoSession::GetSystemId: Unable to allocate PKCS#7 buffer."); + return false; + } + + STACK_OF(X509)* certs = cert->d.sign->cert; +#endif + + // Get the Widevine intermediate cert from the stack + if (sk_X509_num(certs) != 2) { + LOGE("CryptoSession::GetSystemId: Expected 2 certificates in chain, got %d", + sk_X509_num(certs)); + return false; + } + + X509* const intermediate_cert = sk_X509_value(certs, 1); + if (!intermediate_cert) { + LOGE("CryptoSession::GetSystemId: Unable to get intermediate cert."); + return false; + } + + // Find the Widevine System ID extension in the intermediate cert + const int extension_count = X509_get_ext_count(intermediate_cert); + for (int i = 0; i < extension_count; ++i) { + X509_EXTENSION* const extension = X509_get_ext(intermediate_cert, i); + if (!extension) { + LOGE("CryptoSession::GetSystemId: Unable to get cert extension %d", i); + continue; + } + + ASN1_OBJECT* const extension_object = X509_EXTENSION_get_object(extension); + if (!extension_object) { + LOGE("CryptoSession::GetSystemId: Unable to get object of cert " + "extension %d", i); + continue; + } + + char extension_name[kExtensionOidSize + 1]; + OBJ_obj2txt(extension_name, kExtensionOidSize, extension_object, 1); + if (strcmp(extension_name, kWidevineSystemIdExtensionOid) != 0) { + // This extension is not the Widevine System ID, so we should move on to + // the next one. + continue; + } + + ASN1_OCTET_STRING* const octet_str = X509_EXTENSION_get_data(extension); + if (!octet_str) { + LOGE("CryptoSession::GetSystemId: Unable to get data of Widevine System " + "ID extension."); + return false; + } + + const unsigned char* data = octet_str->data; + if (!data) { + LOGE("CryptoSession::GetSystemId: Null data in Widevine System ID " + "extension."); + return false; + } + + ASN1_INTEGER* const asn1_integer = + d2i_ASN1_INTEGER(NULL, &data, octet_str->length); + if (!asn1_integer) { + LOGE("CryptoSession::GetSystemId: Unable to decode data in Widevine " + "System ID extension."); + return false; + } + + const long system_id_long = ASN1_INTEGER_get(asn1_integer); + ASN1_INTEGER_free(asn1_integer); + if (system_id_long == -1) { + LOGE("CryptoSession::GetSystemId: Unable to decode ASN integer in " + "Widevine System ID extension."); + return false; + } + + *system_id = static_cast(system_id_long); + return true; + } + + LOGE("CryptoSession::GetSystemId: Widevine System ID extension not found."); + return false; } bool CryptoSession::GetProvisioningId(std::string* provisioning_id) { diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 2e57f974..b4859ca3 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -390,7 +390,7 @@ class WatchDog { file_system.Remove(filename); if (size == size_read && flag) { LOGE("Previous L3 Init failed."); - if (metrics == nullptr) return; + if (metrics == NULL) return; metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( wvcdm::metrics::OEMCrypto_INITIALIZED_L3_INITIALIZATION_FAILED); } @@ -437,7 +437,7 @@ class WatchDog { pthread_mutex_lock(&mutex_); struct timespec time_to_giveup; clock_gettime(CLOCK_REALTIME, &time_to_giveup); - time_to_giveup.tv_sec += 5; // wait 5 seconds. + time_to_giveup.tv_sec += 120; // wait 2 minutes. if (running_) { pthread_cond_timedwait(&condition_, &mutex_, &time_to_giveup); } @@ -445,6 +445,9 @@ class WatchDog { gave_up_ = true; status_ = OEMCrypto_ERROR_INIT_FAILED; LOGE("XXX WATCH DOG ERROR XXX"); + // HACK: this normally just returns an error. However, we are using it + // as a signal to dump debugging information. + Level3_GetOEMPublicCertificate(0, NULL, NULL); SaveFailureInformation(); // This tells the worker thread to clean up after itself. It is not // really needed since we are going to abort. However, if somebody @@ -549,6 +552,7 @@ class Adapter { wvcdm::metrics::OEMCrypto_INITIALIZED_FORCING_L3); return result; } + LOGI("L3 Initialized. Trying L1."); std::string library_name; if (!wvcdm::Properties::GetOEMCryptoPath(&library_name)) { LOGW("L1 library not specified. Falling back to L3"); @@ -576,7 +580,7 @@ class Adapter { } bool LoadLevel1(wvcdm::metrics::OemCryptoDynamicAdapterMetrics* metrics) { - if (metrics == nullptr) { + if (metrics == NULL) { return false; } level1_valid_ = true; diff --git a/libwvdrmengine/cdm/core/src/service_certificate.cpp b/libwvdrmengine/cdm/core/src/service_certificate.cpp index 927e7314..52983a8e 100644 --- a/libwvdrmengine/cdm/core/src/service_certificate.cpp +++ b/libwvdrmengine/cdm/core/src/service_certificate.cpp @@ -191,7 +191,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { CdmResponseType ServiceCertificate::VerifySignedMessage( const std::string& message, const std::string& signature) { - if (!public_key_) { + if (public_key_.get() == NULL) { LOGE("Service certificate not set."); return DEVICE_CERTIFICATE_ERROR_4; } @@ -204,7 +204,7 @@ CdmResponseType ServiceCertificate::VerifySignedMessage( CdmResponseType ServiceCertificate::EncryptRsaOaep(const std::string& plaintext, std::string* ciphertext) { - if (!public_key_) { + if (public_key_.get() == NULL) { LOGE("Service certificate not set."); return DEVICE_CERTIFICATE_ERROR_4; } diff --git a/libwvdrmengine/cdm/core/src/usage_table_header.cpp b/libwvdrmengine/cdm/core/src/usage_table_header.cpp index 8b5abbe2..c718929d 100644 --- a/libwvdrmengine/cdm/core/src/usage_table_header.cpp +++ b/libwvdrmengine/cdm/core/src/usage_table_header.cpp @@ -76,7 +76,7 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level, metrics::CryptoMetrics alternate_metrics; metrics::CryptoMetrics* metrics = - crypto_session->GetCryptoMetrics() != nullptr ? + crypto_session->GetCryptoMetrics() != NULL ? crypto_session->GetCryptoMetrics() : &alternate_metrics; UpgradeFromUsageTable(file_handle_.get(), metrics); diff --git a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp index 960dd500..56bae583 100644 --- a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp @@ -1,9 +1,11 @@ // Copyright 2017 Google Inc. All Rights Reserved. #include "usage_table_header.h" + #include #include #include + #include "crypto_session.h" #include "device_files.h" #include "file_store.h" @@ -50,18 +52,29 @@ const CdmUsageEntryInfo kUsageEntryInfoStorageTypeUnknown = { .storage_type = kStorageTypeUnknown, .key_set_id = "", .usage_info_file_name = ""}; + const std::vector kEmptyLicenseList; -const std::vector kLicenseList = { + +const std::string kLicenseArray[] = { kUsageEntryInfoOfflineLicense1.key_set_id, kUsageEntryInfoOfflineLicense2.key_set_id, kUsageEntryInfoOfflineLicense3.key_set_id, }; +const size_t kLicenseArraySize = sizeof(kLicenseArray)/ + sizeof(kLicenseArray[0]); +std::vector kLicenseList; + const std::vector kEmptyUsageInfoFilesList; -const std::vector kUsageInfoFileList = { + +const std::string kUsageInfoFileArray[] = { kUsageEntryInfoSecureStop1.usage_info_file_name, kUsageEntryInfoSecureStop2.usage_info_file_name, kUsageEntryInfoSecureStop3.usage_info_file_name, }; +const size_t kUsageInfoFileArraySize = sizeof(kUsageInfoFileArray)/ + sizeof(kUsageInfoFileArray[0]); +std::vector kUsageInfoFileList; + const DeviceFiles::CdmUsageData kCdmUsageData1 = { .provider_session_token = "provider_session_token_1", .license_request = "license_request_1", @@ -87,13 +100,10 @@ const DeviceFiles::CdmUsageData kCdmUsageData3 = { .usage_entry_number = 0, }; const std::vector kEmptyUsageInfoUsageDataList; -const std::vector kUsageInfoUsageDataList = { - kCdmUsageData1, kCdmUsageData2, kCdmUsageData3, -}; + const std::vector kEmptyUsageEntryInfoVector; -const std::vector kUsageEntryInfoVector = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown}; +std::vector kUsageEntryInfoVector; + const DeviceFiles::LicenseState kActiveLicenseState = DeviceFiles::kLicenseStateActive; const CdmInitData kPsshData = "pssh data"; @@ -108,6 +118,36 @@ int64_t kPlaybackStartTime = 1030005; int64_t kPlaybackDuration = 300; int64_t kGracePeriodEndTime = 60; +namespace { + +void InitVectorConstants() { + kUsageEntryInfoVector.clear(); + kUsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense1); + kUsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop1); + kUsageEntryInfoVector.push_back(kUsageEntryInfoStorageTypeUnknown); + + kUsageInfoFileList.clear(); + for (size_t i = 0; i < kUsageInfoFileArraySize; i++) { + kUsageInfoFileList.push_back(kUsageInfoFileArray[i]); + } + + kLicenseList.clear(); + for (size_t i = 0; i < kLicenseArraySize; i++) { + kLicenseList.push_back(kLicenseArray[i]); + } +} + +void ToVector(std::vector& vec, + const CdmUsageEntryInfo* arr, size_t total_size) { + size_t max = total_size / sizeof(CdmUsageEntryInfo); + vec.clear(); + for (size_t i = 0; i < max; i++) { + vec.push_back(arr[i]); + } +} + +}; // namespace + class MockDeviceFiles : public DeviceFiles { public: MockDeviceFiles() : DeviceFiles(&file_system_) { Init(kSecurityLevelL1); } @@ -167,6 +207,11 @@ using ::testing::UnorderedElementsAre; using ::testing::UnorderedElementsAreArray; class UsageTableHeaderTest : public ::testing::Test { + public: + static void SetUpTestCase() { + InitVectorConstants(); + } + protected: virtual void SetUp() { // UsageTableHeader will take ownership of the pointer @@ -214,7 +259,13 @@ TEST_F(UsageTableHeaderTest, InitError) { class UsageTableHeaderInitializationTest : public UsageTableHeaderTest, - public ::testing::WithParamInterface {}; + public ::testing::WithParamInterface { + public: + static void SetUpTestCase() { + InitVectorConstants(); + } + +}; TEST_P(UsageTableHeaderInitializationTest, CreateUsageTableHeader) { EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull())) @@ -525,9 +576,12 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_InvalidUsageEntryNumber) { // // # of usage entries 4 4 TEST_F(UsageTableHeaderTest, DeleteEntry_CryptoSessionError) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -561,9 +615,12 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_CryptoSessionError) { // // # of usage entries 4 3 TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntry) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -606,9 +663,12 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntry) { // // # of usage entries 4 3 TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntry) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop2}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -656,10 +716,13 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntry) { // # of usage entries 5 2 TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntriesHaveMissingLicenses) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -705,10 +768,13 @@ TEST_F(UsageTableHeaderTest, // // # of usage entries 5 2 TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntriesAreMissing) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -768,10 +834,13 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntriesAreMissing) { // # of usage entries 5 2 TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntriesHaveIncorrectUsageEntryNumber) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -834,10 +903,13 @@ TEST_F(UsageTableHeaderTest, // # of usage entries 5 2 TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntriesHaveIncorrectUsageEntryNumber) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -909,10 +981,13 @@ TEST_F(UsageTableHeaderTest, // // # of usage entries 7 4 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreStorageTypeUnknown) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -962,10 +1037,13 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreStorageTypeUnknown) { // # of usage entries 5 5 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsOffline_MoveOfflineEntryFailed) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1028,10 +1106,13 @@ TEST_F(UsageTableHeaderTest, // # of usage entries 5 5 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsSecureStop_MoveSecureStopEntryFailed) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1101,11 +1182,14 @@ TEST_F(UsageTableHeaderTest, // # of usage entries 7 5 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreOfflineAndUnknown_MoveOfflineEntryFailed) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1179,11 +1263,14 @@ TEST_F(UsageTableHeaderTest, // # of usage entries 7 5 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreSecureStopAndUnknown_MoveOfflineEntryFailed) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1252,10 +1339,13 @@ TEST_F(UsageTableHeaderTest, // // # of usage entries 5 4 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsOffline) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1366,10 +1456,13 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsOffline) { // // # of usage entries 5 4 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsSecureStop) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1465,11 +1558,14 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsSecureStop) { // // # of usage entries 7 4 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreOfflineAndUnknknown) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1584,11 +1680,14 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreOfflineAndUnknknown) { // // # of usage entries 7 4 TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreSecureStopAndUnknknown) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); uint32_t usage_entry_number_to_be_deleted = @@ -1665,9 +1764,12 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreSecureStopAndUnknknown) { // If the crypto session says the usage table header is stale, init should fail. TEST_F(UsageTableHeaderTest, StaleHeader) { - const std::vector usage_entry_info_vector = { + std::vector usage_entry_info_vector; + const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; + ToVector(usage_entry_info_vector, usage_entry_info_array, + sizeof(usage_entry_info_array)); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), diff --git a/libwvdrmengine/cdm/src/log.cpp b/libwvdrmengine/cdm/src/log.cpp index e1a930b5..61daf9d3 100644 --- a/libwvdrmengine/cdm/src/log.cpp +++ b/libwvdrmengine/cdm/src/log.cpp @@ -22,6 +22,8 @@ #include "log.h" #include +#include + #include #include @@ -38,13 +40,21 @@ LogPriority g_cutoff = LOG_VERBOSE; void InitLogging() {} -void Log(const char* /* file */, int /* line */, LogPriority level, - const char* fmt, ...) { - va_list ap; +void Log(const char* file, const char* function, int line, LogPriority level, + const char* format, ...) { + const char* filename = strrchr(file, '/'); + filename = filename == nullptr ? file : filename + 1; + char buf[LOG_BUF_SIZE]; - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); + int len = snprintf(buf, LOG_BUF_SIZE, "[%s(%d):%s] ", filename, line, + function); + if (len < 0) len = 0; + if (len < sizeof(buf)) { + va_list ap; + va_start(ap, format); + vsnprintf(buf+len, LOG_BUF_SIZE-len, format, ap); + va_end(ap); + } android_LogPriority prio = ANDROID_LOG_VERBOSE; diff --git a/libwvdrmengine/cdm/test/Android.mk b/libwvdrmengine/cdm/test/Android.mk index 84c85ca3..b42b99af 100644 --- a/libwvdrmengine/cdm/test/Android.mk +++ b/libwvdrmengine/cdm/test/Android.mk @@ -31,6 +31,10 @@ test_name := counter_metric_unittest test_src_dir := ../metrics/test include $(LOCAL_PATH)/unit-test.mk +test_name := crypto_session_unittest +test_src_dir := ../core/test +include $(LOCAL_PATH)/unit-test.mk + test_name := device_files_unittest test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index 8195860b..2b05a510 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -539,17 +539,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kReleaseAllUsageInfoError7; case wvcdm::LICENSE_REQUEST_INVALID_SUBLICENSE: return kLicenseRequestInvalidSublicense; - - case wvcdm::UNUSED_1: - case wvcdm::UNUSED_2: - case wvcdm::UNUSED_3: - case wvcdm::UNUSED_4: - case wvcdm::UNUSED_5: - case wvcdm::UNUSED_6: - case wvcdm::UNUSED_7: - case wvcdm::UNUSED_8: - case wvcdm::UNUSED_10: - return android::UNKNOWN_ERROR; } // Return here instead of as a default case so that the compiler will warn diff --git a/libwvdrmengine/include_hidl/mapErrors-inl.h b/libwvdrmengine/include_hidl/mapErrors-inl.h index bb8696b2..6219c310 100644 --- a/libwvdrmengine/include_hidl/mapErrors-inl.h +++ b/libwvdrmengine/include_hidl/mapErrors-inl.h @@ -310,15 +310,6 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { return Status::ERROR_DRM_UNKNOWN; case wvcdm::UNKNOWN_ERROR: - case wvcdm::UNUSED_1: - case wvcdm::UNUSED_2: - case wvcdm::UNUSED_3: - case wvcdm::UNUSED_4: - case wvcdm::UNUSED_5: - case wvcdm::UNUSED_6: - case wvcdm::UNUSED_7: - case wvcdm::UNUSED_8: - case wvcdm::UNUSED_10: return Status::ERROR_DRM_UNKNOWN; } diff --git a/libwvdrmengine/level3/Android.mk b/libwvdrmengine/level3/Android.mk index 83384322..1d4ec7f8 100644 --- a/libwvdrmengine/level3/Android.mk +++ b/libwvdrmengine/level3/Android.mk @@ -1,2 +1 @@ -include $(call all-subdir-makefiles) - +include $(call all-subdir-makefiles) \ No newline at end of file diff --git a/libwvdrmengine/level3/arm/Android.mk b/libwvdrmengine/level3/arm/Android.mk index d8176fcc..c4a2f968 100644 --- a/libwvdrmengine/level3/arm/Android.mk +++ b/libwvdrmengine/level3/arm/Android.mk @@ -1,11 +1,20 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_CFLAGS := \ + -DDYNAMIC_ADAPTER \ + -Wno-unused +LOCAL_C_INCLUDES := \ + vendor/widevine/libwvdrmengine/cdm/core/include \ + vendor/widevine/libwvdrmengine/level3/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include LOCAL_MODULE := libwvlevel3 LOCAL_MODULE_CLASS := STATIC_LIBRARIES -LOCAL_MODULE_SUFFIX := .a -LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_SRC_FILES := libl3oemcrypto.cpp \ + ../src/get_unique_id_android.cpp \ + ../src/level3_file_system_android.cpp \ + ../src/level3_file_system_android_factory.cpp LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MODULE_OWNER := widevine LOCAL_MODULE_TARGET_ARCH := arm -include $(BUILD_PREBUILT) +include $(BUILD_STATIC_LIBRARY) diff --git a/libwvdrmengine/level3/arm64/Android.mk b/libwvdrmengine/level3/arm64/Android.mk index ccc4a207..e186a5f8 100644 --- a/libwvdrmengine/level3/arm64/Android.mk +++ b/libwvdrmengine/level3/arm64/Android.mk @@ -1,11 +1,20 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_CFLAGS := \ + -DDYNAMIC_ADAPTER \ + -Wno-unused +LOCAL_C_INCLUDES := \ + vendor/widevine/libwvdrmengine/cdm/core/include \ + vendor/widevine/libwvdrmengine/level3/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include LOCAL_MODULE := libwvlevel3 LOCAL_MODULE_CLASS := STATIC_LIBRARIES -LOCAL_MODULE_SUFFIX := .a -LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_SRC_FILES := libl3oemcrypto.cpp \ + ../src/get_unique_id_android.cpp \ + ../src/level3_file_system_android.cpp \ + ../src/level3_file_system_android_factory.cpp LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MODULE_OWNER := widevine LOCAL_MODULE_TARGET_ARCH := arm64 -include $(BUILD_PREBUILT) +include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/libwvdrmengine/level3/mips/Android.mk b/libwvdrmengine/level3/mips/Android.mk index bd3d481c..113f84e3 100644 --- a/libwvdrmengine/level3/mips/Android.mk +++ b/libwvdrmengine/level3/mips/Android.mk @@ -1,18 +1,20 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE := libwvlevel3 -LOCAL_MODULE_CLASS := STATIC_LIBRARIES -LOCAL_MODULE_SUFFIX := .a -LOCAL_SRC_FILES := level3_stubs.cpp - +LOCAL_CFLAGS := \ + -DDYNAMIC_ADAPTER \ + -Wno-unused LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/cdm/core/include \ - vendor/widevine/libwvdrmengine/cdm/include \ - vendor/widevine/libwvdrmengine/oemcrypto/include \ - vendor/widevine/libwvdrmengine/third_party/stringencoders/src - + vendor/widevine/libwvdrmengine/level3/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include +LOCAL_MODULE := libwvlevel3 +LOCAL_MODULE_CLASS := STATIC_LIBRARIES +LOCAL_SRC_FILES := libl3oemcrypto.cpp \ + ../src/get_unique_id_android.cpp \ + ../src/level3_file_system_android.cpp \ + ../src/level3_file_system_android_factory.cpp LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MODULE_OWNER := widevine -LOCAL_MODULE_TARGET_ARCH := mips mips64 -include $(BUILD_STATIC_LIBRARY) +LOCAL_MODULE_TARGET_ARCH := mips +include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/libwvdrmengine/level3/x86/Android.mk b/libwvdrmengine/level3/x86/Android.mk index 37d3830c..4968ff7f 100644 --- a/libwvdrmengine/level3/x86/Android.mk +++ b/libwvdrmengine/level3/x86/Android.mk @@ -1,11 +1,20 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_CFLAGS := \ + -DDYNAMIC_ADAPTER \ + -Wno-unused +LOCAL_C_INCLUDES := \ + vendor/widevine/libwvdrmengine/cdm/core/include \ + vendor/widevine/libwvdrmengine/level3/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include LOCAL_MODULE := libwvlevel3 LOCAL_MODULE_CLASS := STATIC_LIBRARIES -LOCAL_MODULE_SUFFIX := .a -LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_SRC_FILES := libl3oemcrypto.cpp \ + ../src/get_unique_id_android.cpp \ + ../src/level3_file_system_android.cpp \ + ../src/level3_file_system_android_factory.cpp LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MODULE_OWNER := widevine LOCAL_MODULE_TARGET_ARCH := x86 -include $(BUILD_PREBUILT) +include $(BUILD_STATIC_LIBRARY) diff --git a/libwvdrmengine/level3/x86_64/Android.mk b/libwvdrmengine/level3/x86_64/Android.mk index 28b7c273..3f3d101d 100644 --- a/libwvdrmengine/level3/x86_64/Android.mk +++ b/libwvdrmengine/level3/x86_64/Android.mk @@ -1,11 +1,20 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_CFLAGS := \ + -DDYNAMIC_ADAPTER \ + -Wno-unused +LOCAL_C_INCLUDES := \ + vendor/widevine/libwvdrmengine/cdm/core/include \ + vendor/widevine/libwvdrmengine/level3/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include LOCAL_MODULE := libwvlevel3 LOCAL_MODULE_CLASS := STATIC_LIBRARIES -LOCAL_MODULE_SUFFIX := .a -LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_SRC_FILES := libl3oemcrypto.cpp \ + ../src/get_unique_id_android.cpp \ + ../src/level3_file_system_android.cpp \ + ../src/level3_file_system_android_factory.cpp LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MODULE_OWNER := widevine LOCAL_MODULE_TARGET_ARCH := x86_64 -include $(BUILD_PREBUILT) +include $(BUILD_STATIC_LIBRARY) diff --git a/libwvdrmengine/mediacrypto/Android.mk b/libwvdrmengine/mediacrypto/Android.mk index 8f83f7c1..eaf6646c 100644 --- a/libwvdrmengine/mediacrypto/Android.mk +++ b/libwvdrmengine/mediacrypto/Android.mk @@ -61,7 +61,6 @@ LOCAL_HEADER_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libcdm_protos \ libcrypto \ - libwidevinehidl_utils \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp index 44322d88..b0f90598 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp @@ -8,8 +8,8 @@ namespace wvoec_mock { CryptoEngine* CryptoEngine::MakeCryptoEngine( - std::unique_ptr file_system) { - return new CryptoEngine(std::move(file_system)); + std::auto_ptr file_system) { + return new CryptoEngine(file_system); } } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp index 5c4ee1ef..f483231d 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp @@ -10,8 +10,8 @@ namespace wvoec_mock { class L1CryptoEngine : public CryptoEngine { public: - explicit L1CryptoEngine(std::unique_ptr file_system) - : CryptoEngine(std::move(file_system)) {} + explicit L1CryptoEngine(std::auto_ptr file_system) + : CryptoEngine(file_system) {} bool config_local_display_only() { return true; } @@ -29,8 +29,8 @@ class L1CryptoEngine : public CryptoEngine { }; CryptoEngine* CryptoEngine::MakeCryptoEngine( - std::unique_ptr file_system) { - return new L1CryptoEngine(std::move(file_system)); + std::auto_ptr file_system) { + return new L1CryptoEngine(file_system); } } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp index ddb702e3..b8532311 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp @@ -13,8 +13,8 @@ namespace wvoec_mock { class CertOnlyCryptoEngine : public CryptoEngine { public: - explicit CertOnlyCryptoEngine(std::unique_ptr file_system) - : CryptoEngine(std::move(file_system)) {} + explicit CertOnlyCryptoEngine(std::auto_ptr file_system) + : CryptoEngine(file_system) {} bool config_local_display_only() { return true; } @@ -28,8 +28,8 @@ class CertOnlyCryptoEngine : public CryptoEngine { }; CryptoEngine* CryptoEngine::MakeCryptoEngine( - std::unique_ptr file_system) { - return new CertOnlyCryptoEngine(std::move(file_system)); + std::auto_ptr file_system) { + return new CertOnlyCryptoEngine(file_system); } } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp index a40083bb..4b4b693e 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp @@ -92,8 +92,8 @@ const std::string kDefaultOptionsFile = "/data/mediadrm/oemcrypto/options.txt"; class AndroidModifiableCryptoEngine : public CryptoEngine { public: - AndroidModifiableCryptoEngine(std::unique_ptr file_system) - : CryptoEngine(std::move(file_system)), + AndroidModifiableCryptoEngine(std::auto_ptr file_system) + : CryptoEngine(file_system), options_file_(kDefaultOptionsFile), srm_loaded_(false), srm_version_(0), @@ -588,8 +588,8 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { }; CryptoEngine* CryptoEngine::MakeCryptoEngine( - std::unique_ptr file_system) { - return new AndroidModifiableCryptoEngine(std::move(file_system)); + std::auto_ptr file_system) { + return new AndroidModifiableCryptoEngine(file_system); } } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp index eb2b7ff2..f9d2f304 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp @@ -17,8 +17,8 @@ namespace wvoec_mock { class Prov30CryptoEngine : public CryptoEngine { public: - explicit Prov30CryptoEngine(std::unique_ptr file_system) - : CryptoEngine(std::move(file_system)) {} + explicit Prov30CryptoEngine(std::auto_ptr file_system) + : CryptoEngine(file_system) {} bool config_local_display_only() { return true; } @@ -75,8 +75,8 @@ class Prov30CryptoEngine : public CryptoEngine { }; CryptoEngine* CryptoEngine::MakeCryptoEngine( - std::unique_ptr file_system) { - return new Prov30CryptoEngine(std::move(file_system)); + std::auto_ptr file_system) { + return new Prov30CryptoEngine(file_system); } } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp index 062a613d..51987b71 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp @@ -27,9 +27,9 @@ namespace wvoec_mock { // all configurations. See the files oemcrypto_engine_device_properties*.cpp // for methods that are configured for specific configurations. -CryptoEngine::CryptoEngine(std::unique_ptr file_system) +CryptoEngine::CryptoEngine(std::auto_ptr file_system) : root_of_trust_(config_provisioning_method()), - file_system_(std::move(file_system)), + file_system_(file_system), usage_table_(this) { ERR_load_crypto_strings(); } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h index dfe72a96..c4df07ca 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h @@ -35,7 +35,7 @@ class CryptoEngine { // NOTE: The caller must instantiate a FileSystem object - ownership // will be transferred to the new CryptoEngine object. static CryptoEngine* MakeCryptoEngine( - std::unique_ptr file_system); + std::auto_ptr file_system); virtual ~CryptoEngine(); @@ -163,14 +163,14 @@ class CryptoEngine { } protected: - explicit CryptoEngine(std::unique_ptr file_system); + explicit CryptoEngine(std::auto_ptr file_system); uint8_t* destination_; private: ActiveSessions sessions_; AuthenticationRoot root_of_trust_; wvcdm::Lock session_table_lock_; - std::unique_ptr file_system_; + std::auto_ptr file_system_; UsageTable usage_table_; CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine); diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index 66381d87..4fb98b08 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -66,8 +66,8 @@ extern "C" OEMCryptoResult OEMCrypto_Initialize(void) { } // NOTE: This requires a compatible Filesystem implementation. // NOTE: Ownership of the FileSystem object is transferred to CryptoEngine - std::unique_ptr fs(new wvcdm::FileSystem()); - crypto_engine = CryptoEngine::MakeCryptoEngine(std::move(fs)); + std::auto_ptr fs(new wvcdm::FileSystem()); + crypto_engine = CryptoEngine::MakeCryptoEngine(fs); if (!crypto_engine || !crypto_engine->Initialize()) { LOGE("[OEMCrypto_Initialize(): failed]"); diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index 3de2db0a..bb92b9e8 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -49,6 +49,16 @@ int GetRandBytes(unsigned char* buf, int num) { return RAND_bytes(buf, num); #endif } + +#ifdef OPENSSL_IS_BORINGSSL +void DeleteX509Stack(STACK_OF(X509)* stack) { + sk_X509_pop_free(stack, X509_free); +} + +typedef size_t X509Count; +#else +typedef int X509Count; +#endif } // namespace namespace wvoec { @@ -85,7 +95,7 @@ class openssl_ptr { T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } - bool NotNull() { return ptr_; } + bool NotNull() const { return ptr_; } private: T* ptr_; @@ -586,6 +596,7 @@ void Session::TestSelectExpired(unsigned int key_index) { } void Session::LoadOEMCert(bool verify_cert) { + // Get the OEM Public Cert from OEMCrypto vector public_cert; size_t public_cert_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, @@ -596,6 +607,22 @@ void Session::LoadOEMCert(bool verify_cert) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetOEMPublicCertificate(session_id(), &public_cert[0], &public_cert_length)); + + // Load the certificate chain into an OpenSSL X509 Stack +#ifdef OPENSSL_IS_BORINGSSL + const openssl_ptr x509_stack( + sk_X509_new_null()); + ASSERT_TRUE(x509_stack.NotNull()) << "Unable to allocate X509 stack."; + + CBS pkcs7; + CBS_init(&pkcs7, public_cert.data(), public_cert.size()); + if (!PKCS7_get_certificates(x509_stack.get(), &pkcs7)) { + dump_openssl_error(); + FAIL() << "Unable to deserialize certificate chain."; + } + + STACK_OF(X509)* certs = x509_stack.get(); +#else // load the cert into rsa_key_. openssl_ptr bio( BIO_new_mem_buf(&public_cert[0], public_cert_length)); @@ -606,7 +633,10 @@ void Session::LoadOEMCert(bool verify_cert) { EXPECT_EQ(OBJ_obj2nid(cert->type), NID_pkcs7_signed); STACK_OF(X509)* certs = cert->d.sign->cert; - for (int i = 0; certs && i < sk_X509_num(certs); i++) { +#endif + + // Load the public cert's key into public_rsa_ and verify, if requested + for (X509Count i = 0; certs && i < sk_X509_num(certs); i++) { X509* x509_cert = sk_X509_value(certs, i); openssl_ptr pubkey(X509_get_pubkey(x509_cert)); ASSERT_TRUE(pubkey.NotNull()); @@ -631,7 +661,9 @@ void Session::LoadOEMCert(bool verify_cert) { ASSERT_TRUE(store_ctx.NotNull()); X509_STORE_CTX_init(store_ctx.get(), store.get(), x509_cert, NULL); + // TODO(fredgc): Verify cert is signed by Google. + int result = X509_verify_cert(store_ctx.get()); #if (OPENSSL_VERSION_NUMBER < 0x10100000L) ASSERT_GE(0, result) << " OEM Cert not valid. " <<