// Copyright 2020 Google LLC. All rights reserved. #ifndef VIDEO_WIDEVINE_EXPORT_SDK_EXTERNAL_CPP_WVDRM_LICENSE_SERVER_SDK_ENVIRONMENT_H_ #define VIDEO_WIDEVINE_EXPORT_SDK_EXTERNAL_CPP_WVDRM_LICENSE_SERVER_SDK_ENVIRONMENT_H_ #include #include #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "common/drm_root_certificate.h" #include "common/security_profile_list.h" #include "common/status.h" #include "sdk/external/cpp/wvdrm/license_server_sdk/session.h" #include "sdk/internal/environment_impl.h" namespace video_widevine { constexpr char kWrappingKeyLabel[] = "ENCRYPTION"; constexpr uint32_t kWrappingKeySizeBits = 128; constexpr char kSigningKeyLabel[] = "AUTHENTICATION"; constexpr uint32_t kSigningKeySizeBits = 256; class Environment { public: Environment(absl::string_view provider, const DrmRootCertificate* root_cert); virtual ~Environment(); // Add a service certificate system-wide. // |service_certificate| is a Google-generated certificate used to // authenticate the service provider for purposes of device privacy; // |service_private_key| is the encrypted PKCS#8 private RSA key corresponding // to the service certificate; and |service_private_key_passphrase| is the // password required to decrypt |service_private_key|. Status AddDrmServiceCertificate( const std::string& service_certificate, const std::string& service_private_key, const std::string& service_private_key_passphrase); // Returns true if service certificate is loaded. bool is_service_certificate_loaded(); // Specify a comma separated list of system Ids that can support having // OEMCrypto version, as specified in the license request, reflected back in // the Key Control Block which is used by partner. Otherwise, only 'kctl' or // 'kc09' is returned in KCB. void SetDevicesToHandleOEMCryptoVersionInKCB( const std::string& system_id_list); // Set pre-provisioning keys system-wide. Map key is system_id, value. // Value should be human-readable hex digits encoded bytes, e.g. // 'preProvKeys.put(100, "f7008b38acc00ec68c732ac665c55c65")'. Must be called // before any other calls to this class. Calls are thread-safe, so the keys // can be updated at any time. void SetPreProvisioningKeys(const std::map& keys); void SetPreProvisioningKeys(const std::multimap& keys); // Set the certificate status list system-wide. // |expiration_period| is the number of seconds until the // certificate_status_list expires after its creation time // (creation_time_seconds). If |allow_unknown_devices| is false, an error is // returned if the device does not appear in the certificate_status_list. Status SetCertificateStatusList(const std::string& certificate_status_list, uint32_t expiration_period_seconds, bool allow_unknown_devices); // Enable delivery of licenses to client devices. This includes devices with // TEST_ONLY status, and development platform verification certificates. // Defaults to false. void AllowDevelopmentClients(bool enable); // Enable delivery of licenses to TEST_ONLY client devices. // |device_list_make| is a comma separated list of devices to allow even // if the device is in a TEST_ONLY state. This list wil be used only if // AllowDevelopmentClient(false) is in use. void AllowTestOnlyDevicesByMake(const std::string& device_list_make); // Enable delivery of licenses to TEST_ONLY client devices. // |device_list_provider| is a comma separated list of provider to allow // even if the device is in a TEST_ONLY state. This list wil be used only if // AllowDevelopmentClient(false) is in use. void AllowTestOnlyDevicesByProvider(const std::string& device_list_provider); // Enable delivery of licenses to revoked client devices. |system_id_list| is // a comma separated list of systems Ids to allow even if revoked. void AllowRevokedDevices(const std::string& system_id_list); // A comma separated list of DRM Certificate Serial Numbers that are revoked. void RevokedDrmCertificateSerialNumbers( const std::string& drm_certificate_serial_numbers); // Restriction on core message features. If this is an empty string, the // default feature set is used. If it is an integer, that is the ODK version // supported. This restricts the features that the server will support in an // oemcrypto core message. For example, we may restrict the server to never // send a v17 message by setting the std::string to "16". For details, please see // common/oemcrypto_core_message/odk/include/core_message_features.h void SetCoreMessageFeatures(const std::string& core_message_features); // Creates a Session object. // |root_cert| is the root certificate to be used to validate client // credentials. // |signed_license_request| is the serialized SignedMessage received from the // client. |session| points to a Session*, which must be initialized to NULL // on entry, but |session| itself may not be NULL. The new Session object will // be owned by the caller. This method returns Status::OK if successful, // or an appropriate error status, in which case // Environment::GenerateErrorResponse should be invoked. // Example usage: // Environment env = absl::make_unique(kProvider, // drm_root_cert); // Session* session = NULL; // Status status = env->CreateSession(request_from_client,&session); // if (!status.ok()) { // std::string error_license; // if (env->GenerateErrorResponse(status, &error_license)) { // // Send error_license to the client. // } else { // // Handle error // } // return ... // } // // Create license, invoke GenerateSignedLicense, etc. Status CreateSession(const std::string& signed_license_request, Session** session); // Create a session for generating a license. This variation of Create takes // options to allow for the creation of the session to succeed even if the // device is revoked. Status CreateSessionWithOptions(const std::string& signed_license_request, const SessionCreateOptions& options, Session** session); // Variation of Environment::CreateSession which also fills in the parsed // LicenseRequest, for use in logging or debugging. Status CreateSession(const std::string& signed_license_request, const SessionCreateOptions& options, Session** session, LicenseRequest* parsed_request_out); // Same as CreateSession(), but caller can specify the ClientIdentification // message and/or PlatformVerificationStatus. If ClientIdentification is // specified, this variation of Create() will use the specified |client_id| // instead of what is specified in |signed_license_request|. If // PlatformVerificationStatus is specified, this method will use the specified // |platform_verification_status| instead of attempting to determine it. // Background for this function is to support cases where the client // identification is encrypted with the provider's service certificate in // which case we won't be able to decrypt OR when the provider determines // platform verification. The provider will specify the // clear client identification in |client_id| and the platform verification // in |platform_verification_status|. Status CreateSessionForProxy( const std::string& signed_license_request, const PlatformVerificationStatus platform_verification_status, const ClientIdentification* client_id, const SessionCreateOptions& options, Session** session, LicenseRequest* parsed_request_out); // Generates a SignedMessage containing a message generated in response to // an error condition. |status| is a previous error status returned by the // Session or Status(error::UNAVAILABLE, ...) to indicate that the // backend is unavailable, |signed_message| points to a std::string to contain the // serialized SignedMessage, and may not be NULL. This method returns true if // there is an error license to be sent to the client, or false otherwise. // Example usage in the Environment::Create comments above. bool GenerateErrorResponse(const Status& status, std::string* signed_message_bytes); // DeriveKey uses the NIST 800-108 KDF recommendation, using AES-CMAC PRF. // NIST 800-108: // http://csrc.nist.gov/publications/nistpubs/800-108/sp800-108.pdf // AES-CMAC: // http://tools.ietf.org/html/rfc4493 std::string DeriveKey(const std::string& key, const std::string& label, const std::string& context, const uint32_t size_bits); // Returns a std::string containing the Widevine License Server SDK version in the // form .. . std::string GetSdkVersionString(); // If set to true, adds SDK and server version information to the license // response. void SetIncludeVersionInfoInLicense(bool include_version_info); // Sets the service version information which can be included with the license // response. If SetIncludeVersionInfoInLicense() is set to true and the server // version is not empty, then the server version will be included in the // license response. The host_version must be <= 32 characters and limited to // alphanumeric and '_', '-', ':', ';', ' ', '/' and '.'. void SetHostServerVersion(const std::string& host_version); // Generate a signed request to be sent to Widevine Certificate Provisioning // Server to retrieve 'DeviceCertificateStatusList'. Status GenerateDeviceStatusListRequest( std::string* signed_device_certificate_status_list_request); // Set the custom device security profile list which is returned, from a call // to Widevine PublishedDevicesService. Status SetCustomDeviceSecurityProfiles( absl::string_view serialized_signed_device_security_profiles); // Return a list of the default profile names. Status GetDefaultDeviceSecurityProfileNames( std::vector* profile_names) const; // Return the default profile associated with |profile_name|. Status GetDefaultDeviceSecurityProfile( absl::string_view profile_name, SecurityProfile* device_security_profile) const; // Obtain the owner list for custom profiles. Status GetCustomDeviceSecurityProfileOwners( std::vector* custom_profile_owners) const; // Return a list of custom profile names associated with |owner_name|. Status GetCustomDeviceSecurityProfileNames( absl::string_view owner_name, std::vector* profile_names) const; // Return the custom profiles associated with |owner_name|. Status GetCustomDeviceSecurityProfiles( absl::string_view owner_name, std::vector* custom_device_security_profiles) const; // If |auto_set_provider_session_token| is 'true', the provider session token // may be automatically set, // // The default setting for |auto_set_provider_session_token| is 'true'. virtual void SetAutoSetProviderSessionToken( bool auto_set_provider_session_token); // Returns the setting as to whether the provider session token will be // automatically set. virtual bool GetAutoSetProviderSessionToken() const; // Set the provider key used for L3 CDM. // |provider_key_config_bytes| is a serialized ProviderKeyConfig proto // message. Return OK if parsing is successful, otherwise an error is // returned. virtual Status SetProviderKeyConfig( const std::string& provider_key_config_bytes); private: friend class EnvironmentTest; // Environment::CreateSession which also fills in the parsed // ExternalLicenseRequest. Used to create a Session object. Status CreateSession(SignedMessage* signed_message, Session** session, ExternalLicenseRequest* parsed_request_out); std::string provider_; std::unique_ptr device_security_profile_list_; std::shared_ptr env_impl_; // Provider key configuration assigned to a provider for use with L3 CDM. ProviderKeyConfig provider_key_config_; }; } // namespace video_widevine #endif // VIDEO_WIDEVINE_EXPORT_SDK_EXTERNAL_CPP_WVDRM_LICENSE_SERVER_SDK_ENVIRONMENT_H_