Files
android/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h
John W. Bruce 19947dfe6f Move SPOID Enable/Disable Logic Out of WVDrmPlugin
(This is a merge of http://go/wvgerrit/25580)

While writing fixes for b/36660726, b/34716264, and b/36065223, it
became clear that having the logic that checks whether the device
supports SPOIDs embedded inside WVDrmPlugin was complicating its code
and inhibiting testing of the class. By moving this check into the code
that instantiates WVDrmPlugin, the result of the calculation can be
independently tested while the tests for WVDrmPlugin can put it in
whatever state they need for the sake of unit testing.

As a consequence of this, the check on retrieving the "deviceUniqueId"
byte array property, which was removed when SPOIDs were implemented, can
be reinstated.

Bug: 36660726
Bug: 34716264
Bug: 36065223
Test: libwvdrmdrmplugin_hidl_test & libwvdrmengine_hidl_test
Change-Id: I961d2ee42bbdc42f0c324e36d9a74ac92205a437
2017-04-18 09:56:58 -07:00

369 lines
11 KiB
C++

//
// Copyright 2017 Google Inc. All Rights Reserved.
//
#ifndef WV_DRM_PLUGIN_H_
#define WV_DRM_PLUGIN_H_
#include <map>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include "cdm_client_property_set.h"
#include "cdm_identifier.h"
#include "OEMCryptoCENC.h"
#include "wv_cdm_event_listener.h"
#include "wv_content_decryption_module.h"
#include "WVGenericCryptoInterface.h"
#include "WVTypes.h"
namespace wvdrm {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace widevine {
using ::android::hardware::drm::V1_0::EventType;
using ::android::hardware::drm::V1_0::IDrmPlugin;
using ::android::hardware::drm::V1_0::IDrmPluginListener;
using ::android::hardware::drm::V1_0::KeyRequestType;
using ::android::hardware::drm::V1_0::KeyStatus;
using ::android::hardware::drm::V1_0::KeyType;
using ::android::hardware::drm::V1_0::KeyValue;
using ::android::hardware::drm::V1_0::SecureStop;
using ::android::hardware::drm::V1_0::Status;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::sp;
using android::status_t;
using std::map;
using wvcdm::CdmIdentifier;
using wvcdm::CdmKeyStatusMap;
using wvcdm::CdmSessionId;
using wvcdm::CdmResponseType;
using wvcdm::WvContentDecryptionModule;
const OEMCrypto_Algorithm kInvalidCryptoAlgorithm =
static_cast<OEMCrypto_Algorithm>(-1);
struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
wvcdm::WvCdmEventListener {
WVDrmPlugin(const sp<WvContentDecryptionModule>& cdm,
const std::string& appPackageName,
WVGenericCryptoInterface* crypto,
bool useSpoid);
virtual ~WVDrmPlugin();
Return<void> openSession(openSession_cb _hidl_cb) override;
Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
Return<void> getKeyRequest(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) override;
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
provideKeyResponse_cb _hidl_cb) override;
Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) override;
Return<Status> restoreKeys(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keySetId) override;
Return<void> queryKeyStatus(
const hidl_vec<uint8_t>& sessionId,
queryKeyStatus_cb _hidl_cb) override;
Return<void> getProvisionRequest(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) override;
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) override;
Return<void> getSecureStops(getSecureStops_cb _hidl_cb) override;
Return<void> getSecureStop(
const hidl_vec<uint8_t>& secureStopId,
getSecureStop_cb _hidl_cb) override;
Return<Status> releaseAllSecureStops() override;
Return<Status> releaseSecureStop(
const hidl_vec<uint8_t>& secureStopId) override;
Return<void> getPropertyString(
const hidl_string& propertyName,
getPropertyString_cb _hidl_cb) override;
Return<void> getPropertyByteArray(
const hidl_string& propertyName,
getPropertyByteArray_cb _hidl_cb) override;
Return<Status> setPropertyString(
const hidl_string& propertyName,
const hidl_string& value) override;
Return<Status> setPropertyByteArray(
const hidl_string& propertyName,
const hidl_vec<uint8_t>& value) override;
Return<Status> setCipherAlgorithm(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<Status> setMacAlgorithm(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<void> encrypt(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv,
encrypt_cb _hidl_cb) override;
Return<void> decrypt(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv,
decrypt_cb _hidl_cb) override;
Return<void> sign(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
sign_cb _hidl_cb) override;
Return<void> verify(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& signature,
verify_cb _hidl_cb) override;
Return<void> signRSA(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm,
const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& wrappedkey,
signRSA_cb _hidl_cb) override;
Return<void> setListener(const sp<IDrmPluginListener>& listener) override;
Return<void> sendEvent(
EventType eventType,
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) override;
Return<void> sendExpirationUpdate(
const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) override;
Return<void> sendKeysChange(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList,
bool hasNewUsableKey) override;
// The following methods do not use hidl interface, it is used internally.
virtual status_t unprovisionDevice();
virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId);
virtual void OnSessionKeysChange(
const CdmSessionId& cdmSessionId,
const CdmKeyStatusMap& cdmKeysStatus,
bool hasNewUsableKey);
virtual void OnExpirationUpdate(
const CdmSessionId& cdmSessionId,
int64_t newExpiryTimeSeconds);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVDrmPlugin);
struct CryptoSession {
public:
CryptoSession()
: mOecSessionId(-1),
mCipherAlgorithm(kInvalidCryptoAlgorithm),
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
CryptoSession(OEMCrypto_SESSION sessionId)
: mOecSessionId(sessionId),
mCipherAlgorithm(kInvalidCryptoAlgorithm),
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
OEMCrypto_SESSION oecSessionId() const { return mOecSessionId; }
OEMCrypto_Algorithm cipherAlgorithm() const { return mCipherAlgorithm; }
void setCipherAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
mCipherAlgorithm = newAlgorithm;
}
OEMCrypto_Algorithm macAlgorithm() const { return mMacAlgorithm; }
void setMacAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
mMacAlgorithm = newAlgorithm;
}
private:
OEMCrypto_SESSION mOecSessionId;
OEMCrypto_Algorithm mCipherAlgorithm;
OEMCrypto_Algorithm mMacAlgorithm;
};
class WVClientPropertySet : public wvcdm::CdmClientPropertySet {
public:
WVClientPropertySet()
: mUsePrivacyMode(false), mShareKeys(false), mSessionSharingId(0) {}
virtual ~WVClientPropertySet() {}
virtual const std::string& security_level() const {
return mSecurityLevel;
}
void set_security_level(const std::string& securityLevel) {
mSecurityLevel = securityLevel;
}
virtual bool use_privacy_mode() const {
return mUsePrivacyMode;
}
void set_use_privacy_mode(bool usePrivacyMode) {
mUsePrivacyMode = usePrivacyMode;
}
virtual const std::string& service_certificate() const {
return mServiceCertificate;
}
virtual void set_service_certificate(
const std::string& serviceCertificate) {
mServiceCertificate = serviceCertificate;
}
virtual const std::string& device_provisioning_service_certificate() const {
// Android does not support service certificates for provisioning.
return mEmptyString;
}
virtual void set_device_provisioning_service_certificate(
const std::string& ) {
// Ignore. Android does not support service certificates for provisioning
}
virtual bool is_session_sharing_enabled() const {
return mShareKeys;
}
void set_is_session_sharing_enabled(bool shareKeys) {
mShareKeys = shareKeys;
}
virtual uint32_t session_sharing_id() const {
return mSessionSharingId;
}
virtual void set_session_sharing_id(uint32_t id) {
mSessionSharingId = id;
}
virtual const std::string& app_id() const {
return mAppId;
}
void set_app_id(const std::string& appId) {
mAppId = appId;
}
private:
DISALLOW_EVIL_CONSTRUCTORS(WVClientPropertySet);
std::string mSecurityLevel;
bool mUsePrivacyMode;
std::string mServiceCertificate;
bool mShareKeys;
uint32_t mSessionSharingId;
std::string mAppId;
const std::string mEmptyString;
} mPropertySet;
class CdmIdentifierBuilder {
public:
CdmIdentifierBuilder(bool useSpoid, const std::string& appPackageName);
const CdmIdentifier& get_identifier();
const std::string& get_device_unique_id();
bool set_device_id(const std::string& id);
const std::string& origin() const { return mCdmIdentifier.origin; }
bool set_origin(const std::string& id);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN(CdmIdentifierBuilder);
CdmIdentifier mCdmIdentifier;
bool mIsIdentifierSealed;
bool mUseSpoid;
std::string mDeviceId;
std::string mAppPackageName;
void calculateSpoid();
} mCdmIdentifierBuilder;
sp<wvcdm::WvContentDecryptionModule> const mCDM;
WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener;
status_t queryProperty(const std::string& property,
std::string& stringValue) const;
status_t queryProperty(wvcdm::SecurityLevel securityLevel,
const std::string& property,
std::string& stringValue) const;
status_t queryProperty(const std::string& property,
std::vector<uint8_t>& vector_value) const;
status_t mapAndNotifyOfCdmResponseType(const std::vector<uint8_t>& sessionId,
CdmResponseType res);
status_t mapAndNotifyOfOEMCryptoResult(const std::vector<uint8_t>& sessionId,
OEMCryptoResult res);
status_t mapOEMCryptoResult(OEMCryptoResult res);
bool initDataResemblesPSSH(const std::vector<uint8_t>& initData);
status_t unprovision(const CdmIdentifier& identifier);
};
} // namespace widevine
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace wvdrm
#endif // WV_DRM_PLUGIN_H_