//////////////////////////////////////////////////////////////////////////////// // Copyright 2016 Google LLC. // // This software is licensed under the terms defined in the Widevine Master // License Agreement. For a copy of this agreement, please contact // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// #ifndef PROVISIONING_SDK_PUBLIC_PROVISIONING_ENGINE_H_ #define PROVISIONING_SDK_PUBLIC_PROVISIONING_ENGINE_H_ #include #include #include #include #include #include "common/certificate_type.h" #include "provisioning_sdk/public/provisioning_status.h" namespace widevine { class ProvisioningEngineImpl; class ProvisioningSession; class ProvisioningSessionImpl; // Session factory function used to implement third-party provisioning // protocols. // * |engine| is the ProvisioningEngineImpl which invokes the function. // * |new_session| will point, on successful return, to the newly created // ProvisioningSessionImpl. // * Returns OK if successful, or an appropriate error status code otherwise. typedef std::function* new_session)> SessionFactory; // Class which is used to implement a Widevine DRM device provisioning engine. // There should be only one instance of ProvisioningEngine. The engine should // be "Initialized" before being used. ProvisioningEngine::Initialize is the // only method that is not thread-safe. After initializing the engine, it can // be safely used in different threads. class ProvisioningEngine { public: ProvisioningEngine(); virtual ~ProvisioningEngine(); // Initializes the provisioning engine with required credentials. // * |certificate_type| indicates which type of certificate chains will be // used for device provisioning via this engine. // * |service_drm_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& service_drm_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); // Third-party protocol registration method. // * |protocol| is the provisioning protocol, as defined in the // SignedProvisioningMessage message. // * |session_factory| is the function which instantiates the appropriate // ProvisioningSessionImpl object for the specified protocol. void RegisterProtocol(int protocol, SessionFactory session_factory); // 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. virtual 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. virtual ProvisioningStatus AddDrmIntermediateCertificate( const std::string& intermediate_cert, const std::string& cert_private_key, const std::string& cert_private_key_passphrase); // Create a session to handle a certificate provisioning exchange between // a client device and the provisioning server. // * |protocol| is the protocol version for the session. If not sure, it // probably ought to be |PROVISIONING_30|. // * |device_public_key| is a DER-encoded PKCS#1.5 RSAPublicKey message which // will used to create the DRM certificate to be provisioned onto the // device. // * |device_private_key| is a DER-encoded PKCS#8 PrivateKeyInfo message // which contains the private key matching |device_public_key|. // * |new_session| will point, on successful return, to the newly created // ProvisioningSession. // * Returns OK if successful, or an appropriate error status code otherwise. // The key pairs can be re-used if the created session failed to process the // message. // NOTE: All ProvisioningSession objects must be deleted before the // ProvisioningEngine which created them. virtual ProvisioningStatus NewProvisioningSession( const std::string& device_public_key, const std::string& device_private_key, std::unique_ptr* new_session) const; // This is the same as NewProvisioningSession above, but with outputs reversed // To get around CLIF bug https://github.com/google/clif/issues/30. std::unique_ptr NewProvisioningSession( const std::string& device_public_key, const std::string& device_private_key, ProvisioningStatus* status) const; // Generate a new device DRM certificate to be provisioned by means other than // the Widevine provisioning protocol. // NOTE: This API should only be used to provision devices which were // manufactured without Widevine DRM support. It is meant to be used as // an exception, and not the norm. Most devices should be provisioned // by means of a ProvisioningSession. // * |system_id| is the Widevine system ID for the type of device being // provisioned. // * |public_key| is a DER-encoded PKCS#1.5 RSAPublicKey message which will // be embedded in the generated 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. ProvisioningStatus GenerateDeviceDrmCertificate( uint32_t system_id, const std::string& public_key, const std::string& serial_number, std::string* certificate) const; private: std::map protocol_registry_; #ifndef SWIGPYTHON ProvisioningEngine(const ProvisioningEngine&) = delete; ProvisioningEngine& operator=(const ProvisioningEngine&) = delete; #endif std::unique_ptr impl_; }; } // namespace widevine #endif // PROVISIONING_SDK_PUBLIC_PROVISIONING_ENGINE_H_