• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21 
22 #include "hks_file_operator.h"
23 
24 #include <dirent.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 
30 #include "hks_log.h"
31 #include "hks_mem.h"
32 #include "hks_template.h"
33 #include "securec.h"
34 
GetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)35 static int32_t GetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
36 {
37     if (path != NULL) {
38         if (strncpy_s(fullFileName, fullFileNameLen, path, strlen(path)) != EOK) {
39             return HKS_ERROR_INTERNAL_ERROR;
40         }
41 
42         if (path[strlen(path) - 1] != '/') {
43             if (strncat_s(fullFileName, fullFileNameLen, "/", strlen("/")) != EOK) {
44                 return HKS_ERROR_INTERNAL_ERROR;
45             }
46         }
47 
48         if (strncat_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
49             return HKS_ERROR_INTERNAL_ERROR;
50         }
51     } else {
52         if (strncpy_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
53             return HKS_ERROR_INTERNAL_ERROR;
54         }
55     }
56 
57     return HKS_SUCCESS;
58 }
59 
GetFullFileName(const char * path,const char * fileName,char ** fullFileName)60 static int32_t GetFullFileName(const char *path, const char *fileName, char **fullFileName)
61 {
62     uint32_t nameLen = HKS_MAX_FILE_NAME_LEN;
63     char *tmpFileName = (char *)HksMalloc(nameLen);
64     HKS_IF_NULL_RETURN(tmpFileName, HKS_ERROR_MALLOC_FAIL)
65     (void)memset_s(tmpFileName, nameLen, 0, nameLen);
66 
67     int32_t ret = GetFileName(path, fileName, tmpFileName, nameLen);
68     if (ret != HKS_SUCCESS) {
69         HKS_LOG_E("get full fileName failed");
70         HKS_FREE_PTR(tmpFileName);
71         return ret;
72     }
73 
74     *fullFileName = tmpFileName;
75     return HKS_SUCCESS;
76 }
77 
IsFileExist(const char * fileName)78 static int32_t IsFileExist(const char *fileName)
79 {
80     if (access(fileName, F_OK) != 0) {
81         return HKS_ERROR_NOT_EXIST;
82     }
83 
84     return HKS_SUCCESS;
85 }
86 
FileRead(const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)87 static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
88 {
89     (void)offset;
90     HKS_IF_NOT_SUCC_RETURN(IsFileExist(fileName), 0)
91 
92     char filePath[PATH_MAX + 1] = {0};
93     (void)realpath(fileName, filePath);
94     if (strstr(filePath, "../") != NULL) {
95         HKS_LOG_E("invalid filePath, path %" LOG_PUBLIC "s", filePath);
96         return 0;
97     }
98 
99     FILE *fp = fopen(filePath, "rb");
100     HKS_IF_NULL_LOGE_RETURN(fp, 0, "failed to open file, errno = 0x%" LOG_PUBLIC "x", errno)
101 
102     uint32_t size = fread(buf, 1, len, fp);
103     if (fclose(fp) < 0) {
104         HKS_LOG_E("failed to close file, errno = 0x%" LOG_PUBLIC "x", errno);
105         return 0;
106     }
107 
108     return size;
109 }
110 
FileSize(const char * fileName)111 static uint32_t FileSize(const char *fileName)
112 {
113     HKS_IF_NOT_SUCC_RETURN(IsFileExist(fileName), 0)
114 
115     struct stat fileStat;
116     (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
117     if (stat(fileName, &fileStat) != 0) {
118         HKS_LOG_E("file stat fail, errno = 0x%" LOG_PUBLIC "x", errno);
119         return 0;
120     }
121 
122     return fileStat.st_size;
123 }
124 
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)125 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
126 {
127     (void)offset;
128     char filePath[PATH_MAX + 1] = {0};
129     if (memcpy_s(filePath, sizeof(filePath) - 1, fileName, strlen(fileName)) != EOK) {
130         return HKS_ERROR_INSUFFICIENT_MEMORY;
131     }
132     (void)realpath(fileName, filePath);
133     if (strstr(filePath, "../") != NULL) {
134         HKS_LOG_E("invalid filePath!");
135         return HKS_ERROR_INVALID_KEY_FILE;
136     }
137 
138     /* caller function ensures that the folder exists */
139     FILE *fp = fopen(filePath, "wb+");
140     HKS_IF_NULL_LOGE_RETURN(fp, HKS_ERROR_OPEN_FILE_FAIL, "open file fail, errno = 0x%" LOG_PUBLIC "x", errno)
141 
142     if (chmod(filePath, S_IRUSR | S_IWUSR) < 0) {
143         HKS_LOG_E("chmod file fail, errno = 0x%" LOG_PUBLIC "x", errno);
144         fclose(fp);
145         return HKS_ERROR_OPEN_FILE_FAIL;
146     }
147 
148     uint32_t size = fwrite(buf, 1, len, fp);
149     if (size != len) {
150         HKS_LOG_E("write file size fail, errno = 0x%" LOG_PUBLIC "x", errno);
151         fclose(fp);
152         return HKS_ERROR_WRITE_FILE_FAIL;
153     }
154 
155     if (fflush(fp) < 0) {
156         HKS_LOG_E("fflush file fail, errno = 0x%" LOG_PUBLIC "x", errno);
157         fclose(fp);
158         return HKS_ERROR_WRITE_FILE_FAIL;
159     }
160 
161     int fd = fileno(fp);
162     if (fd < 0) {
163         HKS_LOG_E("fileno fail, errno = 0x%" LOG_PUBLIC "x", errno);
164         fclose(fp);
165         return HKS_ERROR_WRITE_FILE_FAIL;
166     }
167 
168     if (fsync(fd) < 0) {
169         HKS_LOG_E("sync file fail, errno = 0x%" LOG_PUBLIC "x", errno);
170         fclose(fp);
171         return HKS_ERROR_WRITE_FILE_FAIL;
172     }
173 
174     if (fclose(fp) < 0) {
175         HKS_LOG_E("failed to close file, errno = 0x%" LOG_PUBLIC "x", errno);
176         return HKS_ERROR_CLOSE_FILE_FAIL;
177     }
178 
179     return HKS_SUCCESS;
180 }
181 
FileRemove(const char * fileName)182 static int32_t FileRemove(const char *fileName)
183 {
184     int32_t ret = IsFileExist(fileName);
185     HKS_IF_NOT_SUCC_RETURN(ret, HKS_SUCCESS) /* if file not exist, return ok */
186 
187     struct stat tmp;
188     if (stat(fileName, &tmp) != 0) {
189         return HKS_ERROR_INTERNAL_ERROR;
190     }
191 
192     if (S_ISDIR(tmp.st_mode)) {
193         return HKS_ERROR_INVALID_ARGUMENT;
194     }
195 
196     if ((unlink(fileName) != 0) && (errno != ENOENT)) {
197         HKS_LOG_E("failed to remove file: errno = 0x%" LOG_PUBLIC "x", errno);
198         return HKS_ERROR_REMOVE_FILE_FAIL;
199     }
200 
201     return HKS_SUCCESS;
202 }
203 
HksFileRemove(const char * path,const char * fileName)204 int32_t HksFileRemove(const char *path, const char *fileName)
205 {
206     HKS_IF_NULL_RETURN(fileName, HKS_ERROR_INVALID_ARGUMENT)
207 
208     char *fullFileName = NULL;
209     int32_t ret = GetFullFileName(path, fileName, &fullFileName);
210     HKS_IF_NOT_SUCC_RETURN(ret, ret)
211 
212     ret = FileRemove(fullFileName);
213     HKS_FREE_PTR(fullFileName);
214     return ret;
215 }
216 
HksIsFileExist(const char * path,const char * fileName)217 int32_t HksIsFileExist(const char *path, const char *fileName)
218 {
219     HKS_IF_NULL_RETURN(fileName, HKS_ERROR_NULL_POINTER)
220 
221     char *fullFileName = NULL;
222     int32_t ret = GetFullFileName(path, fileName, &fullFileName);
223     HKS_IF_NOT_SUCC_RETURN(ret, ret)
224 
225     ret = IsFileExist(fullFileName);
226     HKS_FREE_PTR(fullFileName);
227     return ret;
228 }
229 
HksIsDirExist(const char * path)230 int32_t HksIsDirExist(const char *path)
231 {
232     HKS_IF_NULL_RETURN(path, HKS_ERROR_NULL_POINTER)
233     return IsFileExist(path);
234 }
235 
HksMakeDir(const char * path)236 int32_t HksMakeDir(const char *path)
237 {
238     int result = mkdir(path, S_IRWXU);
239     if (result == 0) {
240         return HKS_SUCCESS;
241     } else {
242         switch (errno) {
243             case EEXIST:
244                 return HKS_ERROR_ALREADY_EXISTS;
245             default:
246                 return HKS_ERROR_MAKE_DIR_FAIL;
247         }
248     }
249 }
250 
HksOpenDir(const char * path)251 void *HksOpenDir(const char *path)
252 {
253     return (void *)opendir(path);
254 }
255 
HksCloseDir(void * dirp)256 int32_t HksCloseDir(void *dirp)
257 {
258     return closedir((DIR *)dirp);
259 }
260 
HksGetDirFile(void * dirp,struct HksFileDirentInfo * direntInfo)261 int32_t HksGetDirFile(void *dirp, struct HksFileDirentInfo *direntInfo)
262 {
263     DIR *dir = (DIR *)dirp;
264     struct dirent *dire = readdir(dir);
265 
266     while (dire != NULL) {
267         if (dire->d_type != DT_REG) { /* only care about files. */
268             dire = readdir(dir);
269             continue;
270         }
271 
272         uint32_t len = strlen(dire->d_name);
273         if (memcpy_s(direntInfo->fileName, sizeof(direntInfo->fileName) - 1, dire->d_name, len) != EOK) {
274             return HKS_ERROR_INSUFFICIENT_MEMORY;
275         }
276         direntInfo->fileName[len] = '\0';
277         return HKS_SUCCESS;
278     }
279 
280     return HKS_ERROR_NOT_EXIST;
281 }
282 
HksGetStoragePath(enum HksStoragePathType pathType,char * path,uint32_t * len)283 int32_t HksGetStoragePath(enum HksStoragePathType pathType, char *path, uint32_t *len)
284 {
285     if ((path == NULL) || (len == NULL) || (*len <= 1)) {
286         return HKS_ERROR_INVALID_ARGUMENT;
287     }
288     errno_t ret;
289     uint32_t pathLen;
290     if (pathType == HKS_STORAGE_MAIN_PATH) {
291         pathLen = strlen(HKS_KEY_STORE_PATH);
292         ret = memcpy_s(path, *len - 1, HKS_KEY_STORE_PATH, pathLen);
293     } else if (pathType == HKS_STORAGE_BACKUP_PATH) {
294         pathLen = strlen(HKS_KEY_STORE_BAK_PATH);
295         ret = memcpy_s(path, *len - 1, HKS_KEY_STORE_BAK_PATH, pathLen);
296     } else {
297         return HKS_ERROR_INVALID_ARGUMENT;
298     }
299     if (ret != EOK) {
300         HKS_LOG_E("memcpy failed");
301         return HKS_ERROR_INSUFFICIENT_MEMORY;
302     }
303     path[pathLen] = '\0';
304     *len = pathLen + 1;
305     return HKS_SUCCESS;
306 }
307 
HksRemoveDir(const char * dirPath)308 int32_t HksRemoveDir(const char *dirPath)
309 {
310     struct stat fileStat;
311     int32_t ret = stat(dirPath, &fileStat);
312     if (ret != 0) {
313         HKS_LOG_E("file stat failed");
314         return HKS_FAILURE;
315     }
316 
317     if (!S_ISDIR(fileStat.st_mode)) {
318         HKS_LOG_E("path is not dir");
319         return HKS_FAILURE;
320     }
321 
322     DIR *dir = opendir(dirPath);
323     HKS_IF_NULL_LOGE_RETURN(dir, HKS_ERROR_OPEN_FILE_FAIL, "open dir failed")
324 
325     struct dirent *dire = readdir(dir);
326     while (dire != NULL) {
327         if (dire->d_type == DT_REG) { /* only care about files. */
328             ret = HksFileRemove(dirPath, dire->d_name);
329             HKS_IF_NOT_SUCC_LOGE(ret, "remove file failed when remove dir files, ret = %" LOG_PUBLIC "d.", ret)
330         }
331         dire = readdir(dir);
332     }
333 
334     closedir(dir);
335     return HKS_SUCCESS;
336 }
337 
HksDeletDirPartTwo(const char * path)338 static int32_t HksDeletDirPartTwo(const char *path)
339 {
340     int32_t ret;
341     char deletePath[HKS_MAX_FILE_NAME_LEN] = {0};
342     DIR *dir = opendir(path);
343     HKS_IF_NULL_LOGE_RETURN(dir, HKS_ERROR_OPEN_FILE_FAIL, "open dir failed")
344     struct dirent *dire = readdir(dir);
345     while (dire != NULL) {
346         if (strncpy_s(deletePath, sizeof(deletePath), path, strlen(path)) != EOK) {
347             closedir(dir);
348             return HKS_ERROR_INTERNAL_ERROR;
349         }
350 
351         if (deletePath[strlen(deletePath) - 1] != '/') {
352             if (strncat_s(deletePath, sizeof(deletePath), "/", strlen("/")) != EOK) {
353                 closedir(dir);
354                 return HKS_ERROR_INTERNAL_ERROR;
355             }
356         }
357 
358         if (strncat_s(deletePath, sizeof(deletePath), dire->d_name, strlen(dire->d_name)) != EOK) {
359             closedir(dir);
360             return HKS_ERROR_INTERNAL_ERROR;
361         }
362 
363         if ((strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) {
364             (void)remove(deletePath);
365         }
366         dire = readdir(dir);
367     }
368     closedir(dir);
369     ret = remove(path);
370     return ret;
371 }
372 
HksDeletDirPartOne(const char * path)373 static int32_t HksDeletDirPartOne(const char *path)
374 {
375     int32_t ret;
376     char deletePath[HKS_MAX_FILE_NAME_LEN] = {0};
377     DIR *dir = opendir(path);
378     HKS_IF_NULL_LOGE_RETURN(dir, HKS_ERROR_OPEN_FILE_FAIL, "open dir failed")
379     struct dirent *dire = readdir(dir);
380     while (dire != NULL) {
381         if (strncpy_s(deletePath, sizeof(deletePath), path, strlen(path)) != EOK) {
382             closedir(dir);
383             return HKS_ERROR_INTERNAL_ERROR;
384         }
385 
386         if (deletePath[strlen(deletePath) - 1] != '/') {
387             if (strncat_s(deletePath, sizeof(deletePath), "/", strlen("/")) != EOK) {
388                 closedir(dir);
389                 return HKS_ERROR_INTERNAL_ERROR;
390             }
391         }
392 
393         if (strncat_s(deletePath, sizeof(deletePath), dire->d_name, strlen(dire->d_name)) != EOK) {
394             closedir(dir);
395             return HKS_ERROR_INTERNAL_ERROR;
396         }
397 
398         if (dire->d_type == DT_DIR && (strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) {
399             HksDeletDirPartTwo(deletePath);
400         } else if (dire->d_type != DT_DIR) {
401             (void)remove(deletePath);
402         }
403         dire = readdir(dir);
404     }
405     closedir(dir);
406     ret = remove(path);
407     return ret;
408 }
409 
HksDeleteDir(const char * path)410 int32_t HksDeleteDir(const char *path)
411 {
412     int32_t ret;
413     char deletePath[HKS_MAX_FILE_NAME_LEN] = { 0 };
414 
415     DIR *dir = opendir(path);
416     HKS_IF_NULL_LOGE_RETURN(dir, HKS_ERROR_OPEN_FILE_FAIL, "open dir failed")
417     struct dirent *dire = readdir(dir);
418     while (dire != NULL) {
419         if (strncpy_s(deletePath, sizeof(deletePath), path, strlen(path)) != EOK) {
420             closedir(dir);
421             return HKS_ERROR_INTERNAL_ERROR;
422         }
423 
424         if (deletePath[strlen(deletePath) - 1] != '/') {
425             if (strncat_s(deletePath, sizeof(deletePath), "/", strlen("/")) != EOK) {
426                 closedir(dir);
427                 return HKS_ERROR_INTERNAL_ERROR;
428             }
429         }
430 
431         if (strncat_s(deletePath, sizeof(deletePath), dire->d_name, strlen(dire->d_name)) != EOK) {
432             closedir(dir);
433             return HKS_ERROR_INTERNAL_ERROR;
434         }
435 
436         if (dire->d_type == DT_DIR && (strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) {
437             HksDeletDirPartOne(deletePath);
438         } else if (dire->d_type != DT_DIR) {
439             (void)remove(deletePath);
440         }
441         dire = readdir(dir);
442     }
443     closedir(dir);
444     ret = remove(path);
445     return ret;
446 }
447 
HksFileRead(const char * path,const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)448 uint32_t HksFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
449 {
450     if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
451         return 0;
452     }
453 
454     char *fullFileName = NULL;
455     int32_t ret = GetFullFileName(path, fileName, &fullFileName);
456     HKS_IF_NOT_SUCC_RETURN(ret, 0)
457 
458     uint32_t size = FileRead(fullFileName, offset, buf, len);
459     HKS_FREE_PTR(fullFileName);
460     return size;
461 }
462 
HksFileWrite(const char * path,const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)463 int32_t HksFileWrite(const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
464 {
465     if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
466         return HKS_ERROR_INVALID_ARGUMENT;
467     }
468 
469     char *fullFileName = NULL;
470     int32_t ret = GetFullFileName(path, fileName, &fullFileName);
471     HKS_IF_NOT_SUCC_RETURN(ret, ret)
472 
473     ret = FileWrite(fullFileName, offset, buf, len);
474     HKS_FREE_PTR(fullFileName);
475     return ret;
476 }
477 
HksFileSize(const char * path,const char * fileName)478 uint32_t HksFileSize(const char *path, const char *fileName)
479 {
480     HKS_IF_NULL_RETURN(fileName, 0)
481 
482     char *fullFileName = NULL;
483     int32_t ret = GetFullFileName(path, fileName, &fullFileName);
484     HKS_IF_NOT_SUCC_RETURN(ret, 0)
485 
486     uint32_t size = FileSize(fullFileName);
487     HKS_FREE_PTR(fullFileName);
488     return size;
489 }
490 
HksGetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)491 int32_t HksGetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
492 {
493     return GetFileName(path, fileName, fullFileName, fullFileNameLen);
494 }