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 "cm_ipc_service_serialization.h"
17
18 #include "cm_log.h"
19 #include "cm_mem.h"
20 #include "cm_param.h"
21
22 #include "cert_manager_check.h"
23 #include "cert_manager_query.h"
24
CopyUint32ToBuffer(uint32_t value,const struct CmBlob * destBlob,uint32_t * destOffset)25 int32_t CopyUint32ToBuffer(uint32_t value, const struct CmBlob *destBlob, uint32_t *destOffset)
26 {
27 if (CmCheckBlob(destBlob) != CM_SUCCESS || destOffset == NULL) {
28 return CMR_ERROR_INVALID_ARGUMENT;
29 }
30 if ((*destOffset > destBlob->size) || ((destBlob->size - *destOffset) < sizeof(value))) {
31 return CMR_ERROR_BUFFER_TOO_SMALL;
32 }
33
34 if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &value, sizeof(value)) != EOK) {
35 return CMR_ERROR_INVALID_OPERATION;
36 }
37 *destOffset += sizeof(value);
38 return CM_SUCCESS;
39 }
40
CopyBlobToBuffer(const struct CmBlob * blob,const struct CmBlob * destBlob,uint32_t * destOffset)41 int32_t CopyBlobToBuffer(const struct CmBlob *blob, const struct CmBlob *destBlob, uint32_t *destOffset)
42 {
43 if (CmCheckBlob(blob) != CM_SUCCESS || CmCheckBlob(destBlob) != CM_SUCCESS || destOffset == NULL) {
44 return CMR_ERROR_INVALID_ARGUMENT;
45 }
46 if ((*destOffset > destBlob->size) ||
47 ((destBlob->size - *destOffset) < (sizeof(blob->size) + ALIGN_SIZE(blob->size)))) {
48 return CMR_ERROR_BUFFER_TOO_SMALL;
49 }
50
51 if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset,
52 &(blob->size), sizeof(blob->size)) != EOK) {
53 return CMR_ERROR_INVALID_OPERATION;
54 }
55 *destOffset += sizeof(blob->size);
56
57 if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, blob->data, blob->size) != EOK) {
58 *destOffset -= sizeof(blob->size);
59 return CMR_ERROR_INVALID_OPERATION;
60 }
61 *destOffset += ALIGN_SIZE(blob->size);
62 return CM_SUCCESS;
63 }
64
GetNormalParam(const struct CmParam * param,struct CmParamOut * outParams)65 static int32_t GetNormalParam(const struct CmParam *param, struct CmParamOut *outParams)
66 {
67 switch (GetTagType(outParams->tag)) {
68 case CM_TAG_TYPE_INT:
69 *(outParams->int32Param) = param->int32Param;
70 break;
71 case CM_TAG_TYPE_UINT:
72 *(outParams->uint32Param) = param->uint32Param;
73 break;
74 case CM_TAG_TYPE_ULONG:
75 *(outParams->uint64Param) = param->uint64Param;
76 break;
77 case CM_TAG_TYPE_BOOL:
78 *(outParams->boolParam) = param->boolParam;
79 break;
80 case CM_TAG_TYPE_BYTES:
81 *(outParams->blob) = param->blob;
82 break;
83 default:
84 CM_LOG_E("invalid tag type:%x", GetTagType(outParams->tag));
85 return CMR_ERROR_INVALID_ARGUMENT;
86 }
87 return CM_SUCCESS;
88 }
89
GetNullBlobParam(const struct CmParamSet * paramSet,struct CmParamOut * outParams)90 static int32_t GetNullBlobParam(const struct CmParamSet *paramSet, struct CmParamOut *outParams)
91 {
92 if (GetTagType(outParams->tag) != CM_TAG_TYPE_BYTES) {
93 CM_LOG_E("param tag[0x%x] is not bytes", outParams->tag);
94 return CMR_ERROR_PARAM_NOT_EXIST;
95 }
96
97 struct CmParam *param = NULL;
98 int32_t ret = CmGetParam(paramSet, outParams->tag + CM_PARAM_BUFFER_NULL_INTERVAL, ¶m);
99 if (ret != CM_SUCCESS) {
100 CM_LOG_E("get param tag[0x%x] from ipc buffer failed", outParams->tag + CM_PARAM_BUFFER_NULL_INTERVAL);
101 return ret;
102 }
103
104 outParams->blob->data = NULL;
105 outParams->blob->size = 0;
106 return CM_SUCCESS;
107 }
108
CmParamSetToParams(const struct CmParamSet * paramSet,struct CmParamOut * outParams,uint32_t cnt)109 int32_t CmParamSetToParams(const struct CmParamSet *paramSet, struct CmParamOut *outParams, uint32_t cnt)
110 {
111 if (paramSet == NULL || outParams == NULL) {
112 return CMR_ERROR_INVALID_ARGUMENT;
113 }
114 struct CmParam *param = NULL;
115 for (uint32_t i = 0; i < cnt; i++) {
116 int32_t ret = CmGetParam(paramSet, outParams[i].tag, ¶m);
117 if (ret == CM_SUCCESS) {
118 ret = GetNormalParam(param, &outParams[i]);
119 } else {
120 ret = GetNullBlobParam(paramSet, &outParams[i]);
121 }
122 if (ret != CM_SUCCESS) {
123 CM_LOG_E("get param failed, ret = %d", ret);
124 return ret;
125 }
126 }
127 return CM_SUCCESS;
128 }
129
CmGetCertListPack(const struct CertBlob * certBlob,uint32_t * status,uint32_t certCount,struct CmBlob * certificateList)130 static int32_t CmGetCertListPack(const struct CertBlob *certBlob, uint32_t *status, uint32_t certCount,
131 struct CmBlob *certificateList)
132 {
133 uint32_t offset = 0;
134 uint32_t buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) +
135 sizeof(uint32_t) + MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE;
136 if (certificateList->size < buffSize) {
137 CM_LOG_E("outdata size too small");
138 return CMR_ERROR_BUFFER_TOO_SMALL;
139 }
140 certificateList->size = buffSize;
141
142 int32_t ret = CopyUint32ToBuffer(certCount, certificateList, &offset);
143 if (ret != CM_SUCCESS) {
144 CM_LOG_E("Copy cert count failed");
145 return ret;
146 }
147
148 for (uint32_t i = 0; i < certCount; i++) {
149 ret = CopyBlobToBuffer(&(certBlob->subjectName[i]), certificateList, &offset);
150 if (ret != CM_SUCCESS) {
151 CM_LOG_E("Copy certificate subject failed");
152 return ret;
153 }
154 ret = CopyUint32ToBuffer(status[i], certificateList, &offset);
155 if (ret != CM_SUCCESS) {
156 CM_LOG_E("Copy certificate status failed");
157 return ret;
158 }
159 ret = CopyBlobToBuffer(&(certBlob->uri[i]), certificateList, &offset);
160 if (ret != CM_SUCCESS) {
161 CM_LOG_E("Copy certificate uri failed");
162 return ret;
163 }
164 ret = CopyBlobToBuffer(&(certBlob->certAlias[i]), certificateList, &offset);
165 if (ret != CM_SUCCESS) {
166 CM_LOG_E("Copy certificate certAlias failed");
167 return ret;
168 }
169 }
170 return ret;
171 }
172
CmServiceGetCertListPack(const struct CmContext * context,uint32_t store,const struct CmMutableBlob * certFileList,struct CmBlob * certificateList)173 int32_t CmServiceGetCertListPack(const struct CmContext *context, uint32_t store,
174 const struct CmMutableBlob *certFileList, struct CmBlob *certificateList)
175 {
176 if (context == NULL || certFileList == NULL || CmCheckBlob(certificateList) != CM_SUCCESS) {
177 return CMR_ERROR_INVALID_ARGUMENT;
178 }
179 uint32_t status[MAX_COUNT_CERTIFICATE] = {0};
180 struct CertBlob certBlob;
181 (void)memset_s(&certBlob, sizeof(struct CertBlob), 0, sizeof(struct CertBlob));
182 int32_t ret = CmGetCertListInfo(context, store, certFileList, &certBlob, status);
183 if (ret != CM_SUCCESS) {
184 CM_LOG_E("CmGetCertListInfo fail");
185 CmFreeCertBlob(&certBlob);
186 return ret;
187 }
188
189 ret = CmGetCertListPack(&certBlob, status, certFileList->size, certificateList);
190 if (ret != CM_SUCCESS) {
191 CM_LOG_E("CmGetCertListPack fail");
192 CmFreeCertBlob(&certBlob);
193 return ret;
194 }
195
196 CmFreeCertBlob(&certBlob);
197 return ret;
198 }
199
CmServiceGetCertInfoPack(const uint32_t store,const struct CmBlob * certificateData,uint32_t status,const struct CmBlob * certUri,struct CmBlob * certificateInfo)200 int32_t CmServiceGetCertInfoPack(const uint32_t store, const struct CmBlob *certificateData,
201 uint32_t status, const struct CmBlob *certUri, struct CmBlob *certificateInfo)
202 {
203 if (certificateData != NULL && certificateData->size == 0) {
204 CM_LOG_D("cert file is not exist");
205 return CM_SUCCESS;
206 }
207 if (CmCheckBlob(certificateData) != CM_SUCCESS || CmCheckBlob(certUri) != CM_SUCCESS ||
208 CmCheckBlob(certificateInfo) != CM_SUCCESS) {
209 return CMR_ERROR_INVALID_ARGUMENT;
210 }
211
212 uint32_t buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t) +
213 MAX_LEN_CERT_ALIAS + sizeof(uint32_t);
214 if (certificateInfo->size < buffSize) {
215 CM_LOG_E("outdata size too small");
216 return CMR_ERROR_MALLOC_FAIL;
217 }
218 certificateInfo->size = buffSize;
219
220 uint32_t offset = 0;
221 int32_t ret = CopyBlobToBuffer(certificateData, certificateInfo, &offset); /* certData */
222 if (ret != CM_SUCCESS) {
223 CM_LOG_E("copy cert data failed");
224 return ret;
225 }
226
227 ret = CopyUint32ToBuffer(status, certificateInfo, &offset); /* status */
228 if (ret != CM_SUCCESS) {
229 CM_LOG_E("copy cert status failed");
230 return ret;
231 }
232
233 struct CmBlob certAlias;
234 certAlias.size = MAX_LEN_CERT_ALIAS;
235 certAlias.data = (uint8_t *)CmMalloc(MAX_LEN_CERT_ALIAS);
236 if (certAlias.data == NULL) {
237 return CMR_ERROR_MALLOC_FAIL;
238 }
239 (void)memset_s(certAlias.data, MAX_LEN_CERT_ALIAS, 0, MAX_LEN_CERT_ALIAS);
240
241 ret = CmGetCertAlias(store, (char *)certUri->data, certificateData, &(certAlias));
242 if (ret != CM_SUCCESS) {
243 CM_LOG_E("Failed to get cert certAlias");
244 CM_FREE_BLOB(certAlias);
245 return CM_FAILURE;
246 }
247
248 ret = CopyBlobToBuffer(&certAlias, certificateInfo, &offset); /* certAlias */
249 if (ret != CM_SUCCESS) {
250 CM_LOG_E("copy cert data failed");
251 CM_FREE_BLOB(certAlias);
252 return ret;
253 }
254 CM_FREE_BLOB(certAlias);
255 return ret;
256 }
257
258