// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. #ifndef WVCDM_CORE_CERTIFICATE_PROVISIONING_H_ #define WVCDM_CORE_CERTIFICATE_PROVISIONING_H_ #include #include #include "crypto_session.h" #include "disallow_copy_and_assign.h" #include "license_protocol.pb.h" #include "metrics_collections.h" #include "oemcrypto_adapter.h" #include "service_certificate.h" #include "wv_cdm_types.h" namespace wvutil { class FileSystem; } namespace wvcdm { class CdmClientPropertySet; class CdmSession; class ServiceCertificate; class CertificateProvisioning { public: CertificateProvisioning(metrics::CryptoMetrics* metrics) : crypto_session_(CryptoSession::MakeCryptoSession(metrics)), cert_type_(kCertificateWidevine), service_certificate_(new ServiceCertificate()) {} ~CertificateProvisioning() {} CdmResponseType Init(const std::string& service_certificate); // Construct a valid provisioning request. // The request will be sent to the provisioning server. CdmResponseType GetProvisioningRequest( wvutil::FileSystem* file_system, SecurityLevel requested_security_level, CdmCertificateType cert_type, const std::string& cert_authority, const std::string& origin, const std::string& spoid, CdmProvisioningRequest* request, std::string* default_url); // Process the provisioning response. CdmResponseType HandleProvisioningResponse( wvutil::FileSystem* file_system, const CdmProvisioningResponse& response, std::string* cert, std::string* wrapped_key); bool supports_core_messages() const { return supports_core_messages_; } // Helper methods // Extract serial number and system ID from a DRM Device certificate. // Either |serial_number| or |system_id| may be null, but not both. // Both |creation_time_seconds| and |expiration_time_seconds| may be null. // |creation_time_seconds| and |expiration_time_seconds| will be set to -1 // if not present, 0 if unlimited and a valid time otherwise static bool ExtractDeviceInfo(const std::string& device_certificate, std::string* serial_number, uint32_t* system_id, int64_t* creation_time_seconds, int64_t* expiration_time_seconds); // Removes json wrapping if applicable to extract the // SignedProvisioningMessage static bool ExtractAndDecodeSignedMessage( const std::string& provisioning_response, std::string* result); // Retrieve the provisioning server URL used for certificate // provisioning. This will be the same value as returned in // |default_url| by GetProvisioningRequest(). static void GetProvisioningServerUrl(std::string* default_url); private: CdmResponseType GetProvisioningRequestInternal( wvutil::FileSystem* file_system, SecurityLevel requested_security_level, CdmCertificateType cert_type, const std::string& cert_authority, const std::string& origin, const std::string& spoid, CdmProvisioningRequest* request, std::string* default_url); CdmResponseType GetProvisioning40RequestInternal( wvutil::FileSystem* file_system, CdmProvisioningRequest* request); CdmResponseType FillEncryptedClientId( const std::string& client_token, video_widevine::ProvisioningRequest& provisioning_request); CdmResponseType HandleProvisioning40Response( wvutil::FileSystem* file_system, const std::string& response_message); CdmResponseType SetSpoidParameter( const std::string& origin, const std::string& spoid, video_widevine::ProvisioningRequest* request); video_widevine::SignedProvisioningMessage::ProvisioningType GetProvisioningType(); // Closes crypto session if one is open. Avoid calling this method when // processing a response. Multiple provisioning responses might be // simultaneously in flight. Only the response associated with the last // provisioning request can be processed. All the other responses will // fail. If the session is closed when these responses fail, even the one // associated with the last provisioning request may fail. CdmResponseType CloseSessionOnError(CdmResponseType status); void CloseSession(); std::unique_ptr crypto_session_; CdmCertificateType cert_type_; std::unique_ptr service_certificate_; // The wrapped private key in provisioning 4 generated by calling // GenerateCertificateKeyPair. It will be saved to file system if a valid // response is received. std::string provisioning_40_wrapped_private_key_; // Key type of the generated key pair in provisioning 4. CryptoWrappedKey::Type provisioning_40_key_type_; // Indicates whether OEMCrypto supports core messages, and whether the // CDM should expect a core message in the response. This is primarily // used to distinguish between v16+ OEMCrypto or an earlier version. // Assume core messages are supported, and check if OEMCrypto populates // the core message field when calling PrepAndSignProvisioningRequest(). bool supports_core_messages_ = true; CORE_DISALLOW_COPY_AND_ASSIGN(CertificateProvisioning); }; } // namespace wvcdm #endif // WVCDM_CORE_CERTIFICATE_PROVISIONING_H_