1 /* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef CODE_SIGN_FSVERITY_UTILS_HELPER_H 17 #define CODE_SIGN_FSVERITY_UTILS_HELPER_H 18 19 #include <cerrno> 20 #include <cstdint> 21 #include <cstdlib> 22 #include <cstring> 23 #include <fcntl.h> 24 #include <libfsverity.h> 25 #include <sys/stat.h> 26 #include <unistd.h> 27 28 #include "errcode.h" 29 #include "byte_buffer.h" 30 #include "log.h" 31 32 namespace OHOS { 33 namespace Security { 34 namespace CodeSign { 35 class FsverityUtilsHelper { 36 public: 37 static FsverityUtilsHelper &GetInstance(); 38 bool GenerateFormattedDigest(const char *path, ByteBuffer &ret); 39 static void ErrorMsgLogCallback(const char *msg); 40 41 private: 42 FsverityUtilsHelper(); 43 ~FsverityUtilsHelper(); 44 45 FsverityUtilsHelper(const FsverityUtilsHelper &source) = delete; 46 FsverityUtilsHelper &operator = (const FsverityUtilsHelper &source) = delete; 47 48 void Init(); 49 bool ComputeDigest(const char *path, struct libfsverity_digest **digest); 50 bool FormatDigest(libfsverity_digest *digest, uint8_t *buffer); 51 52 class FileReader { 53 public: Open(const char * path)54 bool Open(const char *path) 55 { 56 if (fd_ > 0) { 57 LOG_ERROR("File is already opened."); 58 return false; 59 } 60 fd_ = open(path, O_RDONLY); 61 if (fd_ <= 0) { 62 LOG_ERROR("Open file failed, path = %{public}s, errno = <%{public}d, %{public}s>", 63 path, errno, strerror(errno)); 64 return false; 65 } 66 return true; 67 } 68 GetFileSize(uint64_t * size)69 bool GetFileSize(uint64_t *size) 70 { 71 struct stat st; 72 if (fstat(fd_, &st) != 0) { 73 LOG_ERROR("Stat file failed, errno = <%{public}d, %{public}s>", 74 errno, strerror(errno)); 75 return false; 76 } 77 *size = st.st_size; 78 return true; 79 } 80 ~FileReader()81 ~FileReader() 82 { 83 if (fd_ > 0) { 84 close(fd_); 85 fd_ = -1; 86 } 87 } 88 ReadFileCallback(void * f,void * buf,size_t count)89 static int ReadFileCallback(void *f, void *buf, size_t count) 90 { 91 FileReader *reader = static_cast<FileReader *>(f); 92 return reader->ReadBytes(static_cast<uint8_t *>(buf), count); 93 } 94 95 private: ReadBytes(uint8_t * buf,size_t count)96 int ReadBytes(uint8_t *buf, size_t count) 97 { 98 if (fd_ <= 0) { 99 return CS_ERR_FILE_READ; 100 } 101 while (count) { 102 ssize_t bytesRead = read(fd_, buf, count); 103 if (bytesRead <= 0) { 104 return CS_ERR_FILE_READ; 105 } 106 buf += bytesRead; 107 count -= static_cast<size_t>(bytesRead); 108 } 109 return CS_SUCCESS; 110 } 111 112 int fd_ = -1; 113 }; 114 }; 115 } 116 } 117 } 118 #endif