/* * Copyright (C) 2023 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 #include #include #include #include "service_certificate.h" #include "vendor_widevine_fuzz_helper.h" #include "wv_cdm_event_listener.h" #include "wv_cdm_types.h" using namespace wvcdm; using namespace video_widevine; static constexpr int32_t kMaxNum = 3; static constexpr int32_t kMinNum = 0; static constexpr int32_t kMaxByte = 256; class ServiceCertificateFuzzer { public: ServiceCertificateFuzzer(const uint8_t *data, size_t size) : fdp_(data, size){}; void Process(); private: FuzzedDataProvider fdp_; }; void ServiceCertificateFuzzer::Process() { EncryptedClientIdentification encrypted_client_id; ClientIdentification clear_client_id; ServiceCertificate service_certificate; while (fdp_.remaining_bytes()) { auto invoke_service_certificate_API = fdp_.PickValueInArray>({ [&]() { FuzzCdmClientPropertySet property_set(&fdp_); property_set.enable_privacy_mode(); property_set.set_service_certificate(kTestSignedCertificate); PropertiesTestPeer::ForceReinit(); PropertiesTestPeer::AddSessionPropertySet( fdp_.ConsumeBool() ? kTestSessionId1 : fdp_.ConsumeRandomLengthString(kMaxByte), &property_set); std::string raw_service_certificate; PropertiesTestPeer::GetServiceCertificate( fdp_.ConsumeBool() ? kTestSessionId1 : fdp_.ConsumeRandomLengthString(kMaxByte), &raw_service_certificate); if (fdp_.ConsumeBool()) { service_certificate.Init(fdp_.ConsumeBool() ? raw_service_certificate : kTestSignedCertificate); } else { service_certificate.Init( fdp_.ConsumeRandomLengthString(kMaxByte)); } }, [&]() { service_certificate.VerifySignedMessage( fdp_.ConsumeRandomLengthString(kMaxByte) /*message*/, fdp_.ConsumeRandomLengthString(kMaxByte) /*signature*/); }, [&]() { CdmKeyMessage signed_certificate = fdp_.ConsumeRandomLengthString(kMaxByte); service_certificate.ParseResponse( fdp_.ConsumeRandomLengthString(kMaxByte) /*response*/, fdp_.ConsumeBool() ? nullptr : &signed_certificate /*signed_certificate*/); }, [&]() { CdmKeyMessage request; service_certificate.GetRequest(fdp_.ConsumeBool() ? nullptr : &request); }, [&]() { /** * crypto_session object is not used in EncryptClientId. * Therefore keeping crypto_session as nullptr. */ ClientIdentification_ClientCapabilities *client_capabilities = clear_client_id.mutable_client_capabilities(); /** * Default value of client_capabilities is false. * So passing true to all set methods. */ int32_t client_case = fdp_.ConsumeIntegralInRange(kMinNum, kMaxNum); switch (client_case) { case 0: client_capabilities->set_client_token(true /*Value*/); break; case 1: client_capabilities->set_session_token(true /*Value*/); break; case 2: client_capabilities->set_video_resolution_constraints( true /*Value*/); break; default: break; } service_certificate.EncryptClientId(nullptr /*crypto_session*/, &clear_client_id, &encrypted_client_id); }, }); invoke_service_certificate_API(); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ServiceCertificateFuzzer service_certificate_fuzzer(data, size); service_certificate_fuzzer.Process(); return 0; }