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 #include "cert_manager_file.h"
17
18 #include "securec.h"
19
20 #include "cert_manager_file_operator.h"
21 #include "cert_manager_mem.h"
22 #include "cm_log.h"
23 #include "cm_type.h"
24
CertManagerFileSize(const char * path,const char * fileName)25 inline uint32_t CertManagerFileSize(const char *path, const char *fileName)
26 {
27 return CmFileSize(path, fileName);
28 }
29
CertManagerFileRead(const char * path,const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)30 inline uint32_t CertManagerFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
31 {
32 return CmFileRead(path, fileName, offset, buf, len);
33 }
34
CertManagerFileWrite(const char * path,const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)35 inline int32_t CertManagerFileWrite(const char *path, const char *fileName,
36 uint32_t offset, const uint8_t *buf, uint32_t len)
37 {
38 return CmFileWrite(path, fileName, offset, buf, len);
39 }
40
CertManagerFileRemove(const char * path,const char * fileName)41 inline int32_t CertManagerFileRemove(const char *path, const char *fileName)
42 {
43 return CmFileRemove(path, fileName);
44 }
45
GetNumberOfFiles(const char * path)46 static int32_t GetNumberOfFiles(const char *path)
47 {
48 void *dir = CmOpenDir(path);
49 if (dir == NULL) {
50 CM_LOG_W("can't open directory");
51 return -1;
52 }
53
54 int32_t count = 0;
55 struct CmFileDirentInfo dire = {{0}};
56 while (CmGetDirFile(dir, &dire) == CMR_OK) {
57 count++;
58 }
59 (void)CmCloseDir(dir);
60 return count;
61 }
62
FreeFileNames(struct CmMutableBlob * fNames,uint32_t fileCount)63 void FreeFileNames(struct CmMutableBlob *fNames, uint32_t fileCount)
64 {
65 if (fNames == NULL) {
66 return ;
67 }
68
69 for (uint32_t i = 0; i < fileCount; i++) {
70 fNames[i].size = 0;
71 CM_FREE_PTR(fNames[i].data);
72 }
73 CMFree(fNames);
74 }
75
MallocFileNames(struct CmMutableBlob ** fNames,const char * path,uint32_t * fileCount)76 static int32_t MallocFileNames(struct CmMutableBlob **fNames, const char *path, uint32_t *fileCount)
77 {
78 int32_t fileNums = GetNumberOfFiles(path);
79 if (fileNums == 0) {
80 CM_LOG_I("dir is empty");
81 return CM_SUCCESS;
82 }
83
84 if (fileNums < 0) {
85 CM_LOG_E("Failed to obtain number of files from: path");
86 return CM_FAILURE;
87 }
88
89 if (fileNums > MAX_COUNT_CERTIFICATE) {
90 CM_LOG_E("cert count %d beyond MAX", fileNums);
91 return CMR_ERROR_INVALID_ARGUMENT;
92 }
93
94 uint32_t bufSize = sizeof(struct CmMutableBlob) * fileNums;
95 struct CmMutableBlob *temp = (struct CmMutableBlob *)CMMalloc(bufSize);
96 if (temp == NULL) {
97 CM_LOG_E("Failed to allocate memory for file names");
98 return CMR_ERROR_MALLOC_FAIL;
99 }
100 (void)memset_s(temp, bufSize, 0, bufSize);
101
102 *fNames = temp;
103 *fileCount = (uint32_t)fileNums;
104
105 return CM_SUCCESS;
106 }
107
GetFileNames(const char * path,struct CmMutableBlob * fNames,uint32_t fileCount)108 static int32_t GetFileNames(const char *path, struct CmMutableBlob *fNames, uint32_t fileCount)
109 {
110 void *d = CmOpenDir(path);
111 if (d == NULL) {
112 CM_LOG_E("Failed to open directory");
113 return CM_FAILURE;
114 }
115
116 int32_t ret = CM_SUCCESS;
117 uint32_t i = 0;
118 struct CmFileDirentInfo dire = {0};
119 while (CmGetDirFile(d, &dire) == CMR_OK) {
120 /* get fileCount files first, verify in follow-up process, no need return err code */
121 if (i >= fileCount) {
122 CM_LOG_I("only get %u certfiles", fileCount);
123 break;
124 }
125
126 uint32_t nameSize = strlen(dire.fileName) + 1; /* include '\0' at end */
127 fNames[i].data = (uint8_t *)CMMalloc(nameSize); /* uniformly free memory by caller */
128 if (fNames[i].data == NULL) {
129 CM_LOG_E("malloc file name data failed");
130 ret = CMR_ERROR_MALLOC_FAIL;
131 break;
132 }
133
134 fNames[i].size = nameSize;
135 (void)memset_s(fNames[i].data, nameSize, 0, nameSize);
136 if (sprintf_s((char *)fNames[i].data, nameSize, "%s", dire.fileName) < 0) {
137 CM_LOG_E("copy file name failed");
138 ret = CM_FAILURE;
139 break;
140 }
141
142 i++;
143 }
144
145 (void) CmCloseDir(d);
146 if (i != fileCount) {
147 CM_LOG_E("get certfiles no enough");
148 ret = CM_FAILURE;
149 }
150
151 return ret;
152 }
153
CertManagerGetFilenames(struct CmMutableBlob * fileNames,const char * path)154 int32_t CertManagerGetFilenames(struct CmMutableBlob *fileNames, const char *path)
155 {
156 if ((fileNames == NULL) || (path == NULL)) {
157 CM_LOG_E("invalid parameters");
158 return CMR_ERROR_INVALID_ARGUMENT;
159 }
160
161 uint32_t fileCount = 0;
162 struct CmMutableBlob *fNames = NULL;
163 int32_t ret = MallocFileNames(&fNames, path, &fileCount);
164 if (ret != CM_SUCCESS) {
165 CM_LOG_E("Failed to malloc memory for files name");
166 return ret;
167 }
168
169 ret = GetFileNames(path, fNames, fileCount);
170 if (ret != CM_SUCCESS) {
171 CM_LOG_E("get file name failed");
172 FreeFileNames(fNames, fileCount);
173 return ret;
174 }
175
176 fileNames->data = (uint8_t *)fNames;
177 fileNames->size = fileCount;
178 return ret;
179 }
180
GetNumberOfDirs(const char * userIdPath)181 int32_t GetNumberOfDirs(const char *userIdPath)
182 {
183 void *dir = CmOpenDir(userIdPath);
184 if (dir == NULL) {
185 CM_LOG_W("can't open directory");
186 return CM_FAILURE;
187 }
188
189 int32_t fileCount = 0;
190 struct CmFileDirentInfo dire = {{0}};
191 while (CmGetSubDir(dir, &dire) == CMR_OK) {
192 fileCount++;
193 }
194 (void)CmCloseDir(dir);
195 return fileCount;
196 }
197
GetCertCount(const char * path)198 int32_t GetCertCount(const char *path)
199 {
200 return GetNumberOfFiles(path);
201 }