18e920a95Sopenharmony_ci/* 28e920a95Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 38e920a95Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48e920a95Sopenharmony_ci * you may not use this file except in compliance with the License. 58e920a95Sopenharmony_ci * You may obtain a copy of the License at 68e920a95Sopenharmony_ci * 78e920a95Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88e920a95Sopenharmony_ci * 98e920a95Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108e920a95Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118e920a95Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128e920a95Sopenharmony_ci * See the License for the specific language governing permissions and 138e920a95Sopenharmony_ci * limitations under the License. 148e920a95Sopenharmony_ci */ 158e920a95Sopenharmony_ci 168e920a95Sopenharmony_ci#ifndef CODE_SIGN_FSVERITY_UTILS_HELPER_H 178e920a95Sopenharmony_ci#define CODE_SIGN_FSVERITY_UTILS_HELPER_H 188e920a95Sopenharmony_ci 198e920a95Sopenharmony_ci#include <cerrno> 208e920a95Sopenharmony_ci#include <cstdint> 218e920a95Sopenharmony_ci#include <cstdlib> 228e920a95Sopenharmony_ci#include <cstring> 238e920a95Sopenharmony_ci#include <fcntl.h> 248e920a95Sopenharmony_ci#include <libfsverity.h> 258e920a95Sopenharmony_ci#include <sys/stat.h> 268e920a95Sopenharmony_ci#include <unistd.h> 278e920a95Sopenharmony_ci 288e920a95Sopenharmony_ci#include "errcode.h" 298e920a95Sopenharmony_ci#include "byte_buffer.h" 308e920a95Sopenharmony_ci#include "log.h" 318e920a95Sopenharmony_ci 328e920a95Sopenharmony_cinamespace OHOS { 338e920a95Sopenharmony_cinamespace Security { 348e920a95Sopenharmony_cinamespace CodeSign { 358e920a95Sopenharmony_ciclass FsverityUtilsHelper { 368e920a95Sopenharmony_cipublic: 378e920a95Sopenharmony_ci static FsverityUtilsHelper &GetInstance(); 388e920a95Sopenharmony_ci bool GenerateFormattedDigest(const char *path, ByteBuffer &ret); 398e920a95Sopenharmony_ci static void ErrorMsgLogCallback(const char *msg); 408e920a95Sopenharmony_ci 418e920a95Sopenharmony_ciprivate: 428e920a95Sopenharmony_ci FsverityUtilsHelper(); 438e920a95Sopenharmony_ci ~FsverityUtilsHelper(); 448e920a95Sopenharmony_ci 458e920a95Sopenharmony_ci FsverityUtilsHelper(const FsverityUtilsHelper &source) = delete; 468e920a95Sopenharmony_ci FsverityUtilsHelper &operator = (const FsverityUtilsHelper &source) = delete; 478e920a95Sopenharmony_ci 488e920a95Sopenharmony_ci void Init(); 498e920a95Sopenharmony_ci bool ComputeDigest(const char *path, struct libfsverity_digest **digest); 508e920a95Sopenharmony_ci bool FormatDigest(libfsverity_digest *digest, uint8_t *buffer); 518e920a95Sopenharmony_ci 528e920a95Sopenharmony_ci class FileReader { 538e920a95Sopenharmony_ci public: 548e920a95Sopenharmony_ci bool Open(const char *path) 558e920a95Sopenharmony_ci { 568e920a95Sopenharmony_ci if (fd_ > 0) { 578e920a95Sopenharmony_ci LOG_ERROR("File is already opened."); 588e920a95Sopenharmony_ci return false; 598e920a95Sopenharmony_ci } 608e920a95Sopenharmony_ci fd_ = open(path, O_RDONLY); 618e920a95Sopenharmony_ci if (fd_ <= 0) { 628e920a95Sopenharmony_ci LOG_ERROR("Open file failed, path = %{public}s, errno = <%{public}d, %{public}s>", 638e920a95Sopenharmony_ci path, errno, strerror(errno)); 648e920a95Sopenharmony_ci return false; 658e920a95Sopenharmony_ci } 668e920a95Sopenharmony_ci return true; 678e920a95Sopenharmony_ci } 688e920a95Sopenharmony_ci 698e920a95Sopenharmony_ci bool GetFileSize(uint64_t *size) 708e920a95Sopenharmony_ci { 718e920a95Sopenharmony_ci struct stat st; 728e920a95Sopenharmony_ci if (fstat(fd_, &st) != 0) { 738e920a95Sopenharmony_ci LOG_ERROR("Stat file failed, errno = <%{public}d, %{public}s>", 748e920a95Sopenharmony_ci errno, strerror(errno)); 758e920a95Sopenharmony_ci return false; 768e920a95Sopenharmony_ci } 778e920a95Sopenharmony_ci *size = st.st_size; 788e920a95Sopenharmony_ci return true; 798e920a95Sopenharmony_ci } 808e920a95Sopenharmony_ci 818e920a95Sopenharmony_ci ~FileReader() 828e920a95Sopenharmony_ci { 838e920a95Sopenharmony_ci if (fd_ > 0) { 848e920a95Sopenharmony_ci close(fd_); 858e920a95Sopenharmony_ci fd_ = -1; 868e920a95Sopenharmony_ci } 878e920a95Sopenharmony_ci } 888e920a95Sopenharmony_ci 898e920a95Sopenharmony_ci static int ReadFileCallback(void *f, void *buf, size_t count) 908e920a95Sopenharmony_ci { 918e920a95Sopenharmony_ci FileReader *reader = static_cast<FileReader *>(f); 928e920a95Sopenharmony_ci return reader->ReadBytes(static_cast<uint8_t *>(buf), count); 938e920a95Sopenharmony_ci } 948e920a95Sopenharmony_ci 958e920a95Sopenharmony_ci private: 968e920a95Sopenharmony_ci int ReadBytes(uint8_t *buf, size_t count) 978e920a95Sopenharmony_ci { 988e920a95Sopenharmony_ci if (fd_ <= 0) { 998e920a95Sopenharmony_ci return CS_ERR_FILE_READ; 1008e920a95Sopenharmony_ci } 1018e920a95Sopenharmony_ci while (count) { 1028e920a95Sopenharmony_ci ssize_t bytesRead = read(fd_, buf, count); 1038e920a95Sopenharmony_ci if (bytesRead <= 0) { 1048e920a95Sopenharmony_ci return CS_ERR_FILE_READ; 1058e920a95Sopenharmony_ci } 1068e920a95Sopenharmony_ci buf += bytesRead; 1078e920a95Sopenharmony_ci count -= static_cast<size_t>(bytesRead); 1088e920a95Sopenharmony_ci } 1098e920a95Sopenharmony_ci return CS_SUCCESS; 1108e920a95Sopenharmony_ci } 1118e920a95Sopenharmony_ci 1128e920a95Sopenharmony_ci int fd_ = -1; 1138e920a95Sopenharmony_ci }; 1148e920a95Sopenharmony_ci}; 1158e920a95Sopenharmony_ci} 1168e920a95Sopenharmony_ci} 1178e920a95Sopenharmony_ci} 1188e920a95Sopenharmony_ci#endif