Certificate provisioning proto updates

[ Merge of http://go/wvgerrit/117266 ]

These changes facilitate communication of provisioning errors from
provisioning service/SDK to the client.

Clients will indicate in the SignedProvisioningMessage whether they
support handling of error information in the ProvisioningResponse.
The provisioning service/SDK can then indicate why the provisioning
request is being rejected.

The protocol_version field from SignedProvisioningMessage has also been
broken into separate protocol version and provisioning type fields.
This will support changes planned for future releases.

Bug: 174174765
Test: WV unit/integration tests
Change-Id: Ic1a41ed8f83b69697300c586a78266fac20298fb
This commit is contained in:
Rahul Frias
2021-02-18 00:21:20 -08:00
parent a1d66834de
commit 41ecde78cc
4 changed files with 60 additions and 13 deletions

View File

@@ -68,8 +68,8 @@ class CertificateProvisioning {
const std::string& origin, const std::string& spoid,
video_widevine::ProvisioningRequest* request);
video_widevine::SignedProvisioningMessage::ProtocolVersion
GetProtocolVersion();
video_widevine::SignedProvisioningMessage::ProvisioningType
GetProvisioningType();
std::unique_ptr<CryptoSession> crypto_session_;
CdmCertificateType cert_type_;

View File

@@ -172,8 +172,8 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
* Return the provisioning protocol version - dictated by OEMCrypto
* support for OEM certificates.
*/
SignedProvisioningMessage::ProtocolVersion
CertificateProvisioning::GetProtocolVersion() {
SignedProvisioningMessage::ProvisioningType
CertificateProvisioning::GetProvisioningType() {
if (crypto_session_->GetPreProvisionTokenType() == kClientTokenOemCert)
return SignedProvisioningMessage::PROVISIONING_30;
else
@@ -291,7 +291,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
SignedProvisioningMessage signed_provisioning_msg;
signed_provisioning_msg.set_message(serialized_message);
signed_provisioning_msg.set_signature(request_signature);
signed_provisioning_msg.set_protocol_version(GetProtocolVersion());
signed_provisioning_msg.set_provisioning_type(GetProvisioningType());
if (core_message.empty()) {
// OEMCrypto does not support core messages.
supports_core_messages_ = false;

View File

@@ -471,6 +471,21 @@ message SignedMessage {
optional bytes oemcrypto_core_message = 9;
}
// ----------------------------------------------------------------------------
// hash_algorithm.proto
// ----------------------------------------------------------------------------
// Description of section:
// Public protocol buffer definitions for Widevine Hash Algorithm protocol.
enum HashAlgorithmProto {
// Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms
// and SHA_1 shall be used otherwise.
HASH_ALGORITHM_UNSPECIFIED = 0;
HASH_ALGORITHM_SHA_1 = 1;
HASH_ALGORITHM_SHA_256 = 2;
HASH_ALGORITHM_SHA_384 = 3;
}
// ----------------------------------------------------------------------------
// certificate_provisioning.proto
// ----------------------------------------------------------------------------
@@ -556,6 +571,15 @@ message ProvisioningResponse {
// Device CA token component of the keybox.
optional bytes device_ca_token = 3;
}
enum ProvisioningStatus {
// Indicates a valid provisioning response
NO_ERROR = 0;
// The device credentials have been revoked. Provisioning is not possible.
REVOKED_DEVICE_CREDENTIALS = 1;
// Devices in this series have been revoked. Provisioning is not possible.
REVOKED_DEVICE_SERIES = 2;
}
// AES-128 encrypted device private RSA key. PKCS#1 ASN.1 DER-encoded.
// Required. For X.509 certificates, the private RSA key may also include
// a prefix as specified by private_key_prefix in the X509CertificateMetadata
@@ -575,6 +599,10 @@ message ProvisioningResponse {
optional bytes wrapping_key = 5;
// Only populated in OTA keybox provisioning response.
optional OtaKeybox ota_keybox = 6;
// The provisioning service may return a ProvisioningStatus. Fields other
// than |status| may be empty and should be ignored if the |status|
// is present and not NO_ERROR
optional ProvisioningStatus status = 7;
}
// Protocol-specific context data used to hold the state of the server in
@@ -607,7 +635,21 @@ message ProvisioningContextKeyData {
// Serialized ProvisioningRequest or ProvisioningResponse signed with
// The message authentication key.
message SignedProvisioningMessage {
enum ProtocolVersion {
enum ProvisioningProtocolVersion {
VERSION_UNSPECIFIED = 0;
VERSION_1 = 1;
// Version 1.1 changed error handling. Some errors are returned as a field
// in a response message rather than being handled as errors via the API
// implementation. E.g. embedded in the ProvisioningResponse rather than
// returning a 400 error to the caller.
VERSION_1_1 = 2;
// Version 2 will implement a larger change of the protocol definition
// in protobufs. This will provide a cleaner separation between protocols.
VERSION_2 = 3;
}
enum ProvisioningType { // This enum was renamed to avoid confusion
PROVISIONING_TYPE_UNSPECIFIED = 0;
SERVICE_CERTIFICATE_REQUEST = 1; // Service certificate request.
PROVISIONING_20 = 2; // Keybox factory-provisioned devices.
PROVISIONING_30 = 3; // OEM certificate factory-provisioned devices.
@@ -624,9 +666,9 @@ message SignedProvisioningMessage {
// response.
optional bytes signature = 2;
// Version number of provisioning protocol.
optional ProtocolVersion protocol_version = 3 [default = PROVISIONING_20];
optional ProvisioningType provisioning_type = 3 [default = PROVISIONING_20];
// Protocol-specific context / state information for multiple-exchange,
// stateful provisioing protocols. Optional.
// stateful provisioning protocols. Optional.
optional SignedProvisioningContext signed_provisioning_context = 4;
// Remote attestation data to authenticate that the ChromeOS client device
// is operating in verified mode. Remote attestation challenge data is
@@ -637,6 +679,10 @@ message SignedProvisioningMessage {
// This field was introduced in OEMCrypto API v16. The core message format is
// documented in the "Widevine Core Message Serialization".
optional bytes oemcrypto_core_message = 6;
// Optional field that indicates the hash algorithm used in signature scheme.
optional HashAlgorithmProto hash_algorithm = 7;
// Indicates which version of the protocol is in use.
optional ProvisioningProtocolVersion protocol_version = 8;
}
// ----------------------------------------------------------------------------

View File

@@ -263,10 +263,11 @@ bool FakeProvisioningServer::MakeResponse(
? "WIDEVINE_DRM"
: "X509");
video_widevine::SignedProvisioningMessage::ProtocolVersion version =
signed_request.protocol_version();
LOGD("Request uses protocol version: %d", version);
if (version != video_widevine::SignedProvisioningMessage::PROVISIONING_20) {
const video_widevine::SignedProvisioningMessage::ProvisioningType
provisioning_type = signed_request.provisioning_type();
LOGD("Request uses provisioning type: %d", provisioning_type);
if (provisioning_type !=
video_widevine::SignedProvisioningMessage::PROVISIONING_20) {
LOGE("Fake provisioning server only handles Keyboxes");
return false;
}
@@ -314,7 +315,7 @@ bool FakeProvisioningServer::MakeResponse(
// Sign the response.
video_widevine::SignedProvisioningMessage signed_response;
signed_response.set_protocol_version(signed_request.protocol_version());
signed_response.set_provisioning_type(signed_request.provisioning_type());
std::string message;
provisioning_response.SerializeToString(&message);
signed_response.set_message(message);