/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "WidevineRemotelyProvisionedComponent.h" #include #include #include #include #include #include #include #include #include #include namespace aidl::android::hardware::security::keymint { using ::std::string; using ::std::unique_ptr; using ::std::vector; using bytevec = ::std::vector; using ScopedAStatus = ::ndk::ScopedAStatus; namespace { constexpr auto STATUS_FAILED = IRemotelyProvisionedComponent::STATUS_FAILED; struct AStatusDeleter { void operator()(AStatus* p) { AStatus_delete(p); } }; class Status { public: Status() : status_(AStatus_newOk()) {} Status(int32_t errCode, const std::string& errMsg) : status_(AStatus_fromServiceSpecificErrorWithMessage(errCode, errMsg.c_str())) {} explicit Status(const std::string& errMsg) : status_(AStatus_fromServiceSpecificErrorWithMessage(STATUS_FAILED, errMsg.c_str())) {} explicit Status(AStatus* status) : status_(status ? status : AStatus_newOk()) {} Status(Status&&) = default; Status(const Status&) = delete; operator ::ndk::ScopedAStatus() && { // NOLINT(google-explicit-constructor) return ndk::ScopedAStatus(status_.release()); } bool isOk() const { return AStatus_isOk(status_.get()); } const char* getMessage() const { return AStatus_getMessage(status_.get()); } private: std::unique_ptr status_; }; } // namespace ScopedAStatus WidevineRemotelyProvisionedComponent::getHardwareInfo( RpcHardwareInfo* info) { info->versionNumber = 3; info->rpcAuthorName = "Google"; info->supportedEekCurve = RpcHardwareInfo::CURVE_25519; info->uniqueId = "Widevine Implementation"; return ScopedAStatus::ok(); } ScopedAStatus WidevineRemotelyProvisionedComponent::generateEcdsaP256KeyPair( bool testMode, MacedPublicKey* macedPublicKey, bytevec* privateKeyHandle) { return Status("Invalid operation."); } ScopedAStatus WidevineRemotelyProvisionedComponent::generateCertificateRequest( bool testMode, const vector& keysToSign, const bytevec& endpointEncCertChain, const bytevec& challenge, DeviceInfo* deviceInfo, ProtectedData* protectedData, bytevec* keysToSignMac) { if (!keysToSign.empty()) { return Status("Invalid operation: Keys to sign must be empty."); } if (deviceInfo == nullptr) { return Status("Parameter deviceInfo must not be null."); } if (protectedData == nullptr) { return Status("Parameter protectedData must not be null."); } if (provisioner_ == nullptr) { provisioner_ = std::make_unique(); } if (!provisioner_->GenerateCertificateRequest(testMode, endpointEncCertChain, deviceInfo->deviceInfo, protectedData->protectedData)) { return Status("Failed to generate certificate request."); } return ScopedAStatus::ok(); } ScopedAStatus WidevineRemotelyProvisionedComponent::generateCertificateRequestV2( const std::vector& keysToSign, const std::vector& challenge, std::vector* csr) { if (!keysToSign.empty()) { return Status("Invalid operation: Keys to sign must be empty."); } if (csr == nullptr) { return Status("Parameter csr must not be null."); } if (provisioner_ == nullptr) { provisioner_ = std::make_unique(); } if (!provisioner_->GenerateCertificateRequestV2(challenge, csr)) { return Status("Failed to generate certificate request V2."); } return ScopedAStatus::ok(); } } // namespace aidl::android::hardware::security::keymint