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