//////////////////////////////////////////////////////////////////////////////// // Copyright 2016 Google Inc. // // This software is licensed under the terms defined in the Widevine Master // License Agreement. For a copy of this agreement, please contact // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// // ProvisioningEngine internal implementation. This class is thread-safe. #ifndef PROVISIONING_SDK_INTERNAL_PROVISIONING_ENGINE_IMPL_H_ #define PROVISIONING_SDK_INTERNAL_PROVISIONING_ENGINE_IMPL_H_ #include #include #include #include #include #include "base/mutex.h" #include "base/thread_annotations.h" #include "common/rsa_key.h" #include "provisioning_sdk/internal/oem_device_cert.h" #include "provisioning_sdk/public/certificate_type.h" #include "provisioning_sdk/public/provisioning_status.h" #include "protos/public/device_certificate.pb.h" #include "protos/public/provisioned_device_info.pb.h" #include "protos/public/signed_device_certificate.pb.h" namespace widevine { class ProvisioningSession; class ProvisioningEngineImpl { public: ProvisioningEngineImpl(); virtual ~ProvisioningEngineImpl(); // Initializes the provisioning engine with required credentials. // * |certificate_type| indicates which type of certificate chains will be // used for device provisioning via this engine. // * |drm_service_certificate| is a Google-generated certificate used to // authenticate the service provider for purposes of user privacy. // * |service_private_key| is the encrypted PKCS#8 private RSA key // corresponding to the service certificate. // * |service_private_key_passphrase| is the password required to decrypt // |service_private_key|, if any. // * |provisioning_drm_certificate| is a Google-generated certificate used to // sign intermediate DRM certificates. // * |provisioning_private_key| is the encrypted PKCS#8 private RSA key // corresponding to the provisioning certificate. // * |provisioning_private_key_passphrase| is the password required to // decrypt |provisioning_private_key|, if any. // * |secret_spoid_sauce| is a stable secret used as a factor in the // derivation of Stable Per-Origin IDentifiers. // * Returns OK on success, or an appropriate error status code otherwise. ProvisioningStatus Initialize( CertificateType certificate_type, const std::string& drm_service_certificate, const std::string& service_private_key, const std::string& service_private_key_passphrase, const std::string& provisioning_drm_certificate, const std::string& provisioning_private_key, const std::string& provisioning_private_key_passphrase, const std::string& secret_spoid_sauce); // Set the certificate status list for this engine. // * |certificate_status_list| is a certificate status list generated by the // Widevine Provisioning Service. // * |expiration_period| is the number of seconds until the // |certificate_status_list| expires after its creation time // (creation_time_seconds). Zero means it will never expire. // * Returns OK on success, or an appropriate error status code otherwise. ProvisioningStatus SetCertificateStatusList( const std::string& certificate_status_list, uint32_t expiration_period_seconds); // Generate an intermediate DRM certificate. // * |system_id| is the Widevine system ID for the type of device. // * |public_key| is a DER-encoded PKCS#1.5 RSAPublicKey message which will // be embedded in the generated certificate. // * |certificate| will contain the new intermediate certificate, upon // successful return. // * Returns OK on success, or an appropriate error status code otherwise. // NOTE: The generated certificate and associated private key should be stored // securely to be reused. They should also be propagated to all // engines, including this one, by invoking // |AddIntermediatedrmcertificate| on all active ProvisioningEngine(s). ProvisioningStatus GenerateDrmIntermediateCertificate( uint32_t system_id, const std::string& public_key, std::string* certificate) const; // Add an intermediate DRM certificate to the provisioning engine. This is // usually done once for each supported device type. // * |intermediate_cert| is the intermediate DRM certificate to be added. // * |cert_private_key| is a PKCS#8 private key corresponding to // |intermediate_cert|. // * |cert_private_key_passphrase| is the passphrase for cert_private_key, // if any. // * Returns OK on success, or an appropriate error status code otherwise. ProvisioningStatus AddDrmIntermediateCertificate( const std::string& intermediate_cert, const std::string& cert_private_key, const std::string& cert_private_key_passphrase); // Generate a new device DRM certificate to be provisioned. // * |system_id| is the Widevine system ID for the type of device being // provisioned. // * |oem_ca_serial_number| is the oem serial number for the type of device // being provisioned. ProvisioningEngine uses |system_id| and // |oem_ca_serial_number| to determine if the device is valid, e.g. whether // it has been revoked. |oem_ca_serial_number| can be empty if we do not // care about serial number matches or not. // * |public_key| is a DER-encoded PKCS#1.5 RSAPublicKey message which will // be embedded in the generated certificate. // * |certificate_serial_number| is a binary std::string to be used as the // generated DRM certificate serial number. // * |certificate| will contain, upon successful return the generated // certificate. // * Returns OK on success, or an appropriate error status code otherwise. // Virtual for mocking. virtual ProvisioningStatus GenerateDeviceDrmCertificate( uint32_t system_id, const std::string& oem_ca_serial_number, const std::string& public_key, const std::string& certificate_serial_number, std::string* certificate) const; // Internal version of the method above. Allows specifying |provider_id|. virtual ProvisioningStatus GenerateProviderDeviceDrmCertificate( uint32_t system_id, const std::string& oem_ca_serial_number, const std::string& provider_id, const std::string& public_key, const std::string& certificate_serial_number, std::string* certificate) const; // Get the device info for the given |system_id|. std::shared_ptr GetDeviceInfo( uint32_t system_id) const; // Returns the service private key. const RsaPrivateKey* service_private_key() const { return service_private_key_.get(); } const OemDeviceCert& oem_device_cert() const { return oem_device_cert_; } const std::string& secret_spoid_sauce() const { return secret_spoid_sauce_; } private: friend class ProvisioningEngineImplTest; ProvisioningEngineImpl(const ProvisioningEngineImpl&) = delete; ProvisioningEngineImpl& operator=(const ProvisioningEngineImpl&) = delete; // Load DRM root public key with type |certificate_type|. bool LoadDrmRootPublicKey(CertificateType certificate_type); // Check device status. // If |oem_ca_serial_number| is empty, we do not care whether serial number // matches or not. // * Returns OK on success, or an appropriate error status code otherwise. ProvisioningStatus CheckDeviceStatus( uint32_t system_id, const std::string& oem_ca_serial_number) const; // Inject rsa_key_factory for testing. void set_rsa_key_factory(std::unique_ptr rsa_key_factory) { rsa_key_factory_ = std::move(rsa_key_factory); } std::unique_ptr rsa_key_factory_; std::unique_ptr root_public_key_; std::unique_ptr service_public_key_; std::unique_ptr service_private_key_; SignedDrmDeviceCertificate signed_provisioning_cert_; std::unique_ptr provisioning_public_key_; std::unique_ptr provisioning_private_key_; std::string secret_spoid_sauce_; OemDeviceCert oem_device_cert_; mutable Mutex mutex_; // POSIX time, in seconds, when the list would be expired. uint32_t certificate_expiration_seconds_utc_ GUARDED_BY(mutex_) = 0; // Maps with system_id as the key. std::map certificate_status_map_ GUARDED_BY(mutex_); struct IntermediateCertificateInfo { SignedDrmDeviceCertificate signed_drm_certificate; std::shared_ptr device_info; std::shared_ptr private_key; }; std::map intermediate_certs_info_; }; } // namespace widevine #endif // PROVISIONING_SDK_INTERNAL_PROVISIONING_ENGINE_IMPL_H_