* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "cmappcert_fuzzer.h"
#include "cm_fuzz_test_common.h"
#include "cm_test_common.h"
#include "cm_cert_data_rsa.h"
#include "cm_ipc_client_serialization.h"
#include "cm_ipc_service.h"
#include "cm_param.h"
#include "cert_manager_api.h"
#include "cm_type.h"
using namespace CmFuzzTest;
namespace OHOS {
constexpr uint32_t TEST_USERID = 100;
constexpr uint32_t MIN_DATA_USE_TIME = 4;
static bool InstallAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store,
struct CmBlob *keyUri)
{
uint8_t certAliasBuf[] = "keyA";
struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf };
if (TenPercentChanceOfBeingTrue(tmpData, remainSize, offset)) {
if (!GetCmBlobFromBuffer(tmpData, remainSize, offset, keyUri)) {
return false;
}
}
const struct CmBlob appCert = { sizeof(g_rsa2048P12CertInfo), const_cast<uint8_t *>(g_rsa2048P12CertInfo) };
const struct CmBlob appCertPwd = { sizeof(g_certPwd), const_cast<uint8_t *>(g_certPwd) };
struct CmParam params01[] = {
{ .tag = CM_TAG_PARAM0_BUFFER, .blob = appCert },
{ .tag = CM_TAG_PARAM1_BUFFER, .blob = appCertPwd },
{ .tag = CM_TAG_PARAM2_BUFFER, .blob = certAlias },
{ .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
{ .tag = CM_TAG_PARAM1_UINT32, .uint32Param = TEST_USERID },
};
struct CmParamSet *paramSet01 = NULL;
int32_t ret = CmParamsToParamSet(params01, CM_ARRAY_SIZE(params01), ¶mSet01);
if (ret != CM_SUCCESS) {
return false;
}
struct CmBlob paramSetBlob = { paramSet01->paramSetSize, reinterpret_cast<uint8_t *>(paramSet01) };
(void)CmIpcServiceInstallAppCert(¶mSetBlob, keyUri, nullptr);
CmFreeParamSet(¶mSet01);
return true;
}
static bool GetAllAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store)
{
struct CmParam params02[] = { { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store } };
struct CmParamSet *paramSet02 = NULL;
int32_t ret = CmParamsToParamSet(params02, CM_ARRAY_SIZE(params02), ¶mSet02);
if (ret != CM_SUCCESS) {
return false;
}
struct CmBlob paramSetBlob = { paramSet02->paramSetSize, reinterpret_cast<uint8_t *>(paramSet02) };
(void)CmIpcServiceGetAppCertList(¶mSetBlob, nullptr, nullptr);
CmFreeParamSet(¶mSet02);
return true;
}
static bool GetAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store,
struct CmBlob *keyUri)
{
if (TenPercentChanceOfBeingTrue(tmpData, remainSize, offset)) {
if (!GetCmBlobFromBuffer(tmpData, remainSize, offset, keyUri)) {
return false;
}
}
struct CmParam params03[] = {
{ .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
{ .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
};
struct CmParamSet *paramSet03 = NULL;
int32_t ret = CmParamsToParamSet(params03, CM_ARRAY_SIZE(params03), ¶mSet03);
if (ret != CM_SUCCESS) {
return false;
}
struct CmBlob paramSetBlob = { paramSet03->paramSetSize, reinterpret_cast<uint8_t *>(paramSet03) };
(void)CmIpcServiceGetAppCert(¶mSetBlob, nullptr, nullptr);
CmFreeParamSet(¶mSet03);
return true;
}
static bool UnInstallAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store,
struct CmBlob *keyUri)
{
if (TenPercentChanceOfBeingTrue(tmpData, remainSize, offset)) {
if (!GetCmBlobFromBuffer(tmpData, remainSize, offset, keyUri)) {
return false;
}
}
struct CmParam params04[] = {
{ .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
{ .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
};
struct CmParamSet *paramSet04 = NULL;
int32_t ret = CmParamsToParamSet(params04, CM_ARRAY_SIZE(params04), ¶mSet04);
if (ret != CM_SUCCESS) {
return false;
}
struct CmBlob paramSetBlob = { paramSet04->paramSetSize, reinterpret_cast<uint8_t *>(paramSet04) };
(void)CmIpcServiceUninstallAppCert(¶mSetBlob, nullptr, nullptr);
CmFreeParamSet(¶mSet04);
return true;
}
bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
{
uint8_t *tmpData = nullptr;
if (!CopyMyData(data, size, sizeof(uint32_t) * MIN_DATA_USE_TIME, &tmpData)) {
return false;
}
uint32_t remainSize = static_cast<uint32_t>(size);
uint32_t offset = 0;
CertmanagerTest::MockHapToken mockHap;
uint32_t store;
if (!GetUintFromBuffer(tmpData, &remainSize, &offset, &store)) {
CmFree(tmpData);
return false;
}
store %= CM_SYS_CREDENTIAL_STORE + 1;
bool ret = false;
uint8_t uriBuf[MAX_LEN_URI] = {0};
struct CmBlob keyUri = { sizeof(uriBuf), uriBuf };
do {
if (!InstallAppCert(tmpData, &remainSize, &offset, store, &keyUri)) {
break;
}
if (!GetAllAppCert(tmpData, &remainSize, &offset, store)) {
break;
}
if (!GetAppCert(tmpData, &remainSize, &offset, store, &keyUri)) {
break;
}
if (!UnInstallAppCert(tmpData, &remainSize, &offset, store, &keyUri)) {
break;
}
ret = true;
} while (0);
(void)CmIpcServiceUninstallAllAppCert(nullptr, nullptr, nullptr);
CmFree(tmpData);
return ret;
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
OHOS::DoSomethingInterestingWithMyAPI(data, size);
return 0;
}