1 /*
2 * Copyright (c) 2021-2022 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 #include "hks_test_file_operator.h"
17
18 #ifndef __LITEOS_M__
19 #include <dirent.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <limits.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25
26 /* use product definitions temporarily */
27 #define DEFAULT_FILE_PERMISSION 0666
28 #else
29
30 #include <utils_file.h>
31
32 #endif /* _STORAGE_LITE_ */
33
34
35 #include "hks_param.h"
36 #include "hks_test_log.h"
37 #include "hks_test_mem.h"
38 #include "hks_type.h"
39 #include "securec.h"
40
41 #define HKS_MAX_FILE_NAME_LEN 512
42
GetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)43 static int32_t GetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
44 {
45 if (path != NULL) {
46 if (strncpy_s(fullFileName, fullFileNameLen, path, strlen(path)) != EOK) {
47 return HKS_ERROR_INTERNAL_ERROR;
48 }
49
50 if (path[strlen(path) - 1] != '/') {
51 if (strncat_s(fullFileName, fullFileNameLen, "/", strlen("/")) != EOK) {
52 return HKS_ERROR_INTERNAL_ERROR;
53 }
54 }
55
56 if (strncat_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
57 return HKS_ERROR_INTERNAL_ERROR;
58 }
59 } else {
60 if (strncpy_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
61 return HKS_ERROR_INTERNAL_ERROR;
62 }
63 }
64
65 return HKS_SUCCESS;
66 }
67
GetFullFileName(const char * path,const char * fileName,char ** fullFileName)68 static int32_t GetFullFileName(const char *path, const char *fileName, char **fullFileName)
69 {
70 uint32_t nameLen = HKS_MAX_FILE_NAME_LEN;
71 char *tmpFileName = (char *)HksTestMalloc(nameLen);
72 if (tmpFileName == NULL) {
73 return HKS_ERROR_MALLOC_FAIL;
74 }
75 (void)memset_s(tmpFileName, nameLen, 0, nameLen);
76
77 int32_t ret = GetFileName(path, fileName, tmpFileName, nameLen);
78 if (ret != HKS_SUCCESS) {
79 HKS_TEST_LOG_E("get full fileName failed");
80 HksTestFree(tmpFileName);
81 return ret;
82 }
83
84 *fullFileName = tmpFileName;
85 return HKS_SUCCESS;
86 }
87
88 #ifndef __LITEOS_M__
IsFileExist(const char * fileName)89 static int32_t IsFileExist(const char *fileName)
90 {
91 if (access(fileName, F_OK) != 0) {
92 return HKS_ERROR_NOT_EXIST;
93 }
94
95 return HKS_SUCCESS;
96 }
97
FileRead(const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)98 static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
99 {
100 (void)offset;
101 if (IsFileExist(fileName) != HKS_SUCCESS) {
102 return 0;
103 }
104
105 char filePath[PATH_MAX + 1] = {0};
106 (void)realpath(fileName, filePath);
107 if (strstr(filePath, "../") != NULL) {
108 HKS_TEST_LOG_E("invalid filePath, path %s", filePath);
109 return 0;
110 }
111
112 FILE *fp = fopen(filePath, "rb");
113 if (fp == NULL) {
114 HKS_TEST_LOG_E("failed to open file");
115 return 0;
116 }
117
118 uint32_t size = fread(buf, 1, len, fp);
119 if (fclose(fp) < 0) {
120 HKS_TEST_LOG_E("failed to close file");
121 return 0;
122 }
123
124 return size;
125 }
126
FileSize(const char * fileName)127 static uint32_t FileSize(const char *fileName)
128 {
129 if (IsFileExist(fileName) != HKS_SUCCESS) {
130 return 0;
131 }
132
133 struct stat fileStat;
134 (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
135 if (stat(fileName, &fileStat) != 0) {
136 HKS_TEST_LOG_E("file stat fail.");
137 return 0;
138 }
139
140 return fileStat.st_size;
141 }
142
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)143 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
144 {
145 (void)offset;
146 char filePath[PATH_MAX + 1] = {0};
147 if (memcpy_s(filePath, sizeof(filePath) - 1, fileName, strlen(fileName)) != EOK) {
148 return HKS_ERROR_BAD_STATE;
149 }
150 (void)realpath(fileName, filePath);
151 if (strstr(filePath, "../") != NULL) {
152 HKS_TEST_LOG_E("invalid filePath, path %s", filePath);
153 return HKS_ERROR_INVALID_KEY_FILE;
154 }
155
156 /* caller function ensures that the folder exists */
157 FILE *fp = fopen(filePath, "wb+");
158 if (fp == NULL) {
159 HKS_TEST_LOG_E("open file fail");
160 return HKS_ERROR_OPEN_FILE_FAIL;
161 }
162
163 if (chmod(filePath, S_IRUSR | S_IWUSR) < 0) {
164 HKS_TEST_LOG_E("chmod file fail.");
165 fclose(fp);
166 return HKS_ERROR_OPEN_FILE_FAIL;
167 }
168
169 uint32_t size = fwrite(buf, 1, len, fp);
170 if (size != len) {
171 HKS_TEST_LOG_E("write file size fail.");
172 fclose(fp);
173 return HKS_ERROR_WRITE_FILE_FAIL;
174 }
175
176 if (fclose(fp) < 0) {
177 HKS_TEST_LOG_E("failed to close file");
178 return HKS_ERROR_CLOSE_FILE_FAIL;
179 }
180
181 return HKS_SUCCESS;
182 }
183
HksIsFileExist(const char * path,const char * fileName)184 int32_t HksIsFileExist(const char *path, const char *fileName)
185 {
186 if (fileName == NULL) {
187 return HKS_ERROR_NULL_POINTER;
188 }
189
190 char *fullFileName = NULL;
191 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
192 if (ret != HKS_SUCCESS) {
193 return ret;
194 }
195
196 ret = IsFileExist(fullFileName);
197 HksTestFree(fullFileName);
198 return ret;
199 }
200 #else
FileRead(const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)201 static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
202 {
203 /* now offset is 0, but we maybe extend hi1131 file interfaces in the future */
204 if (offset != 0) {
205 return HKS_ERROR_INVALID_ARGUMENT;
206 }
207
208 unsigned int fileSize;
209 int32_t ret = UtilsFileStat(fileName, &fileSize);
210 if (ret < 0) {
211 HKS_TEST_LOG_E("stat file failed, errno = 0x%x", ret);
212 return 0;
213 }
214
215 if (len > fileSize) {
216 HKS_TEST_LOG_E("read data over file size!\n, file size = %d\n, buf len = %d\n", fileSize, len);
217 return 0;
218 }
219
220 int fd = UtilsFileOpen(fileName, O_RDONLY_FS, 0);
221 if (fd < 0) {
222 HKS_TEST_LOG_E("failed to open file, errno = 0x%x", fd);
223 return 0;
224 }
225
226 ret = UtilsFileRead(fd, buf, len);
227 UtilsFileClose(fd);
228 if (ret < 0) {
229 HKS_TEST_LOG_E("failed to read file, errno = 0x%x", ret);
230 return 0;
231 }
232
233 return len;
234 }
235
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)236 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
237 {
238 /* now offset is 0, but we maybe extend hi1131 file interfaces in the future */
239 if (offset != 0) {
240 return HKS_ERROR_INVALID_ARGUMENT;
241 }
242
243 int fd = UtilsFileOpen(fileName, O_CREAT_FS | O_TRUNC_FS | O_RDWR_FS, 0);
244 if (fd < 0) {
245 HKS_TEST_LOG_E("failed to open key file, errno = 0x%x\n", fd);
246 return HKS_ERROR_OPEN_FILE_FAIL;
247 }
248
249 int32_t ret = UtilsFileWrite(fd, buf, len);
250 if (ret < 0) {
251 HKS_TEST_LOG_E("failed to write key file, errno = 0x%x\n", ret);
252 ret = HKS_ERROR_WRITE_FILE_FAIL;
253 }
254
255 ret = UtilsFileClose(fd);
256 if (ret < 0) {
257 HKS_TEST_LOG_E("failed to close file, errno = 0x%x\n", ret);
258 ret = HKS_ERROR_CLOSE_FILE_FAIL;
259 }
260
261 return ret;
262 }
263
FileSize(const char * fileName)264 static uint32_t FileSize(const char *fileName)
265 {
266 unsigned int fileSize;
267 int32_t ret = UtilsFileStat(fileName, &fileSize);
268 if (ret < 0) {
269 HKS_TEST_LOG_E("stat file failed, errno = 0x%x", ret);
270 return 0;
271 }
272 return fileSize;
273 }
274
HksTestFileRemove(const char * path,const char * fileName)275 int32_t HksTestFileRemove(const char *path, const char *fileName)
276 {
277 char *fullFileName = NULL;
278 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
279 if (ret != HKS_SUCCESS) {
280 return 0;
281 }
282
283 return UtilsFileDelete(fullFileName);
284 }
285
286 #endif
HksTestFileRead(const char * path,const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)287 uint32_t HksTestFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
288 {
289 if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
290 return 0;
291 }
292
293 char *fullFileName = NULL;
294 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
295 if (ret != HKS_SUCCESS) {
296 return 0;
297 }
298
299 uint32_t size = FileRead(fullFileName, offset, buf, len);
300 HksTestFree(fullFileName);
301 return size;
302 }
303
HksTestFileWrite(const char * path,const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)304 int32_t HksTestFileWrite(const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
305 {
306 if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
307 return HKS_ERROR_INVALID_ARGUMENT;
308 }
309
310 char *fullFileName = NULL;
311 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
312 if (ret != HKS_SUCCESS) {
313 return ret;
314 }
315
316 ret = FileWrite(fullFileName, offset, buf, len);
317 HksTestFree(fullFileName);
318 return ret;
319 }
320
HksTestFileSize(const char * path,const char * fileName)321 uint32_t HksTestFileSize(const char *path, const char *fileName)
322 {
323 if (fileName == NULL) {
324 return 0;
325 }
326
327 char *fullFileName = NULL;
328 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
329 if (ret != HKS_SUCCESS) {
330 return 0;
331 }
332
333 uint32_t size = FileSize(fullFileName);
334 HksTestFree(fullFileName);
335 return size;
336 }
337