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_storage.h"
17
18 #include "securec.h"
19
20 #include "cert_manager_file_operator.h"
21 #include "cert_manager_mem.h"
22 #include "cert_manager_uri.h"
23 #include "cm_log.h"
24 #include "cm_type.h"
25
GetRootPath(uint32_t store,char * rootPath,uint32_t pathLen)26 int32_t GetRootPath(uint32_t store, char *rootPath, uint32_t pathLen)
27 {
28 errno_t ret;
29
30 /* keep \0 at end */
31 switch (store) {
32 case CM_CREDENTIAL_STORE:
33 ret = memcpy_s(rootPath, pathLen - 1, CREDNTIAL_STORE, strlen(CREDNTIAL_STORE));
34 break;
35 case CM_SYSTEM_TRUSTED_STORE:
36 ret = memcpy_s(rootPath, pathLen - 1, SYSTEM_CA_STORE, strlen(SYSTEM_CA_STORE));
37 break;
38 case CM_USER_TRUSTED_STORE:
39 ret = memcpy_s(rootPath, pathLen - 1, USER_CA_STORE, strlen(USER_CA_STORE));
40 break;
41 case CM_PRI_CREDENTIAL_STORE:
42 ret = memcpy_s(rootPath, pathLen - 1, PRI_CREDNTIAL_STORE, strlen(PRI_CREDNTIAL_STORE));
43 break;
44 default:
45 return CMR_ERROR_INVALID_ARGUMENT;
46 }
47
48 if (ret != EOK) {
49 CM_LOG_E("copy path failed, store = %u", store);
50 return CMR_ERROR_INVALID_OPERATION;
51 }
52
53 return CM_SUCCESS;
54 }
55
ConstructUserIdPath(const struct CmContext * context,uint32_t store,char * userIdPath,uint32_t pathLen)56 int32_t ConstructUserIdPath(const struct CmContext *context, uint32_t store,
57 char *userIdPath, uint32_t pathLen)
58 {
59 char rootPath[CERT_MAX_PATH_LEN] = { 0 };
60 int32_t ret = GetRootPath(store, rootPath, CERT_MAX_PATH_LEN);
61 if (ret != CM_SUCCESS) {
62 return ret;
63 }
64
65 if (snprintf_s(userIdPath, pathLen, pathLen - 1, "%s/%u", rootPath, context->userId) < 0) {
66 CM_LOG_E("construct user id path failed");
67 return CMR_ERROR_INVALID_OPERATION;
68 }
69
70 ret = CmMakeDir(userIdPath);
71 if (ret == CMR_ERROR_MAKE_DIR_FAIL) {
72 CM_LOG_E("mkdir userId path failed");
73 return ret;
74 } /* ret may be CMR_ERROR_ALREADY_EXISTS */
75
76 return CM_SUCCESS;
77 }
78
ConstructUidPath(const struct CmContext * context,uint32_t store,char * uidPath,uint32_t pathLen)79 int32_t ConstructUidPath(const struct CmContext *context, uint32_t store,
80 char *uidPath, uint32_t pathLen)
81 {
82 char userIdPath[CERT_MAX_PATH_LEN] = { 0 };
83 int32_t ret = ConstructUserIdPath(context, store, userIdPath, CERT_MAX_PATH_LEN);
84 if (ret != CM_SUCCESS) {
85 return ret;
86 }
87
88 if (snprintf_s(uidPath, pathLen, pathLen - 1, "%s/%u", userIdPath, context->uid) < 0) {
89 CM_LOG_E("construct uid path failed");
90 return CMR_ERROR_INVALID_OPERATION;
91 }
92
93 ret = CmMakeDir(uidPath);
94 if (ret == CMR_ERROR_MAKE_DIR_FAIL) {
95 CM_LOG_E("mkdir uid path failed");
96 return ret;
97 } /* ret may be CMR_ERROR_ALREADY_EXISTS */
98
99 return CM_SUCCESS;
100 }
101
ConstructAuthListPath(const struct CmContext * context,uint32_t store,char * authListPath,uint32_t pathLen)102 int32_t ConstructAuthListPath(const struct CmContext *context, uint32_t store,
103 char *authListPath, uint32_t pathLen)
104 {
105 char uidPath[CERT_MAX_PATH_LEN] = { 0 };
106 int32_t ret = ConstructUidPath(context, store, uidPath, CERT_MAX_PATH_LEN);
107 if (ret != CM_SUCCESS) {
108 return ret;
109 }
110
111 if (snprintf_s(authListPath, pathLen, pathLen - 1, "%s/%s", uidPath, "authlist") < 0) {
112 CM_LOG_E("construct authlist failed");
113 return CMR_ERROR_INVALID_OPERATION;
114 }
115
116 ret = CmMakeDir(authListPath);
117 if (ret == CMR_ERROR_MAKE_DIR_FAIL) {
118 CM_LOG_E("mkdir auth list path failed");
119 return ret;
120 } /* ret may be CMR_ERROR_ALREADY_EXISTS */
121
122 return CM_SUCCESS;
123 }
124
CmStorageGetBuf(const char * path,const char * fileName,struct CmBlob * storageBuf)125 int32_t CmStorageGetBuf(const char *path, const char *fileName, struct CmBlob *storageBuf)
126 {
127 uint32_t fileSize = CmFileSize(path, fileName);
128 if (fileSize == 0 || fileSize > MAX_OUT_BLOB_SIZE) {
129 CM_LOG_E("file size[%u] invalid", fileSize);
130 return CMR_ERROR_INVALID_OPERATION;
131 }
132
133 uint8_t *data = (uint8_t *)CMMalloc(fileSize);
134 if (data == NULL) {
135 CM_LOG_E("malloc file buffer failed");
136 return CMR_ERROR_MALLOC_FAIL;
137 }
138
139 uint32_t readSize = CmFileRead(path, fileName, 0, data, fileSize);
140 if (readSize == 0) {
141 CM_LOG_E("read file size 0 invalid");
142 CMFree(data);
143 return CMR_ERROR_INVALID_OPERATION;
144 }
145
146 storageBuf->data = data;
147 storageBuf->size = fileSize;
148 return CM_SUCCESS;
149 }
150
CmStorageGetAppCert(const struct CmContext * context,uint32_t store,const struct CmBlob * keyUri,struct CmBlob * certBlob)151 int32_t CmStorageGetAppCert(const struct CmContext *context, uint32_t store,
152 const struct CmBlob *keyUri, struct CmBlob *certBlob)
153 {
154 uint32_t uid = 0;
155 int32_t ret = CertManagerGetUidFromUri(keyUri, &uid);
156 if (ret != CM_SUCCESS) {
157 return ret;
158 }
159
160 struct CmContext uriContext = { context->userId, uid, { 0 } };
161 char uidPath[CERT_MAX_PATH_LEN] = { 0 };
162 ret = ConstructUidPath(&uriContext, store, uidPath, CERT_MAX_PATH_LEN);
163 if (ret != CM_SUCCESS) {
164 return ret;
165 }
166
167 return CmStorageGetBuf(uidPath, (const char *)keyUri->data, certBlob);
168 }
169
CmGetCertFilePath(const struct CmContext * context,uint32_t store,struct CmMutableBlob * pathBlob)170 int32_t CmGetCertFilePath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob)
171 {
172 char pathPtr[CERT_MAX_PATH_LEN] = {0};
173
174 if ((pathBlob == NULL) || (pathBlob->data == NULL)) {
175 CM_LOG_E("Null pointer failure");
176 return CMR_ERROR_NULL_POINTER;
177 }
178
179 int32_t ret = ConstructUidPath(context, store, pathPtr, CERT_MAX_PATH_LEN);
180 if (ret != CM_SUCCESS) {
181 CM_LOG_E("Get file path faild");
182 return CM_FAILURE;
183 }
184
185 char *path = (char *)pathBlob->data;
186 if (sprintf_s(path, CERT_MAX_PATH_LEN, "%s", pathPtr) < 0) {
187 return CM_FAILURE;
188 }
189 pathBlob->size = strlen(path) + 1;
190
191 return CM_SUCCESS;
192 }
193
194