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