* Copyright (c) 2023-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 "cert_path.h"
#include <sys/types.h>
#include <fcntl.h>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <sys/ioctl.h>
#include <chrono>
#include <thread>
#include <parameters.h>
#include <parameter.h>
#include "log_rust.h"
#include "fdsan.h"
#include "errcode.h"
#define BMS_ENTERPRISE_PARAM "const.edm.is_enterprise_device"
#define ENTERPRISE_PARAM_WAIT_TIMEOUT_SECONDS 600
#define ENTERPRISE_PARAM_WAIT_TIME_MILLISECONDS 200
using namespace OHOS::Security::CodeSign;
static int IoctlCertOperation(const void *arg, int cmd, const char *operation)
{
int fd = open(CERT_DEVICE_PATH, O_WRONLY);
if (fd == -1) {
LOG_ERROR(LABEL, "Error opening device, errno = <%{public}d, %{public}s>", errno, strerror(errno));
return CS_ERR_FILE_OPEN;
}
FDSAN_MARK(fd);
int ret = ioctl(fd, cmd, arg);
if (ret < 0) {
LOG_ERROR(
LABEL, "%s cert ioctl error, errno = <%{public}d, %{public}s>", operation, errno, strerror(errno));
FDSAN_CLOSE(fd);
return ret;
}
FDSAN_CLOSE(fd);
return CS_SUCCESS;
}
int AddCertPath(const CertPathInfo &info)
{
return IoctlCertOperation(&info, ADD_CERT_PATH_CMD, "add");
}
int RemoveCertPath(const CertPathInfo &info)
{
return IoctlCertOperation(&info, REMOVE_CERT_PATH_CMD, "remove");
}
bool IsDeveloperModeOn()
{
bool ret = false;
if (OHOS::system::GetBoolParameter("const.security.developermode.state", false)) {
ret = true;
}
return ret;
}
int CodeSignGetUdid(char *udid)
{
return GetDevUdid(udid, UDID_SIZE);
}
int ActivateCert(const CertActivationInfo &info)
{
return IoctlCertOperation(&info, ACTIVATE_CERT_PATH_CMD, "activate");
}
int AddEnterpriseResignCert(const EnterpriseResignCertInfo &info)
{
return IoctlCertOperation(&info, ADD_ENTERPRISE_RESIGN_CERT_CMD, "add_enterprise_cert");
}
int RemoveEnterpriseResignCert(const EnterpriseResignCertInfo &info)
{
return IoctlCertOperation(&info, REMOVE_ENTERPRISE_RESIGN_CERT_CMD, "remove_enterprise_cert");
}
bool IsEnterpriseDevice()
{
return OHOS::system::GetBoolParameter(BMS_ENTERPRISE_PARAM, false);
}
bool WaitForEnterpriseParam()
{
const auto start = std::chrono::system_clock::now();
while (OHOS::system::GetParameter(BMS_ENTERPRISE_PARAM, "") == "") {
std::this_thread::sleep_for(std::chrono::milliseconds(ENTERPRISE_PARAM_WAIT_TIME_MILLISECONDS));
const auto now = std::chrono::system_clock::now();
const std::chrono::duration<double> duration = now - start;
if (duration.count() > ENTERPRISE_PARAM_WAIT_TIMEOUT_SECONDS) {
LOG_ERROR(LABEL, "Wait for enterprise sysparam timeout");
return false;
}
}
const auto param = OHOS::system::GetParameter(BMS_ENTERPRISE_PARAM, "");
LOG_INFO(LABEL, "Get enterprise sysparam %{public}s", param.c_str());
return true;
}