• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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_MEM_OPERATION_COPY;
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_MEM_OPERATION_COPY;
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_MEM_OPERATION_COPY;
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_PARAMSET_ARG;
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, &param);
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, &param);
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     if (certCount > MAX_COUNT_CERTIFICATE_ALL) {
135         CM_LOG_E("cert count is too large");
136         return CMR_ERROR_MAX_CERT_COUNT_REACHED;
137     }
138     uint32_t buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) +
139         sizeof(uint32_t) + MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * certCount;
140     if (certificateList->size < buffSize) {
141         CM_LOG_E("outdata size too small");
142         return CMR_ERROR_BUFFER_TOO_SMALL;
143     }
144     certificateList->size = buffSize;
145 
146     int32_t ret = CopyUint32ToBuffer(certCount, certificateList, &offset);
147     if (ret != CM_SUCCESS) {
148         CM_LOG_E("Copy cert count failed");
149         return ret;
150     }
151     uint32_t *unpackCertCount = (uint32_t *)certificateList->data;
152     for (uint32_t i = 0; i < certCount; i++) {
153         if (certBlob->uri[i].size == 0) {
154             (*unpackCertCount)--;
155             continue;
156         }
157         ret = CopyBlobToBuffer(&(certBlob->subjectName[i]), certificateList, &offset);
158         if (ret != CM_SUCCESS) {
159             CM_LOG_E("Copy certificate subject failed");
160             return ret;
161         }
162         ret = CopyUint32ToBuffer(status[i], certificateList, &offset);
163         if (ret != CM_SUCCESS) {
164             CM_LOG_E("Copy certificate status failed");
165             return ret;
166         }
167         ret = CopyBlobToBuffer(&(certBlob->uri[i]), certificateList, &offset);
168         if (ret != CM_SUCCESS) {
169             CM_LOG_E("Copy certificate uri failed");
170             return ret;
171         }
172         ret = CopyBlobToBuffer(&(certBlob->certAlias[i]), certificateList, &offset);
173         if (ret != CM_SUCCESS) {
174             CM_LOG_E("Copy certificate certAlias failed");
175             return ret;
176         }
177     }
178 
179     /* Avoid returning too large a size */
180     certificateList->size = offset;
181     return ret;
182 }
183 
CmServiceGetCertListPack(const struct CmContext * context,uint32_t store,const struct CmMutableBlob * certFileList,struct CmBlob * certificateList)184 int32_t CmServiceGetCertListPack(const struct CmContext *context, uint32_t store,
185     const struct CmMutableBlob *certFileList, struct CmBlob *certificateList)
186 {
187     if (context == NULL || certFileList == NULL || CmCheckBlob(certificateList) != CM_SUCCESS) {
188         return CMR_ERROR_INVALID_ARGUMENT;
189     }
190     uint32_t status[MAX_COUNT_CERTIFICATE_ALL] = {0};
191     struct CertBlob certBlob;
192     (void)memset_s(&certBlob, sizeof(struct CertBlob), 0, sizeof(struct CertBlob));
193     int32_t ret = CmGetCertListInfo(context, store, certFileList, &certBlob, status);
194     if (ret != CM_SUCCESS) {
195         CM_LOG_E("CmGetCertListInfo fail");
196         CmFreeCertBlob(&certBlob);
197         return ret;
198     }
199 
200     ret = CmGetCertListPack(&certBlob, status, certFileList->size, certificateList);
201     if (ret != CM_SUCCESS) {
202         CM_LOG_E("CmGetCertListPack fail");
203         CmFreeCertBlob(&certBlob);
204         return ret;
205     }
206 
207     CmFreeCertBlob(&certBlob);
208     return ret;
209 }
210 
CmServiceGetCertInfoPack(const uint32_t store,const struct CmBlob * certificateData,uint32_t status,const struct CmBlob * certUri,struct CmBlob * certificateInfo)211 int32_t CmServiceGetCertInfoPack(const uint32_t store, const struct CmBlob *certificateData,
212     uint32_t status, const struct CmBlob *certUri, struct CmBlob *certificateInfo)
213 {
214     if (certificateData != NULL && certificateData->size == 0) {
215         CM_LOG_D("cert file is not exist");
216         return CM_SUCCESS;
217     }
218     if (CmCheckBlob(certificateData) != CM_SUCCESS || CmCheckBlob(certUri) != CM_SUCCESS ||
219         CmCheckBlob(certificateInfo) != CM_SUCCESS) {
220         return CMR_ERROR_INVALID_ARGUMENT;
221     }
222 
223     uint32_t buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t) +
224         MAX_LEN_CERT_ALIAS + sizeof(uint32_t);
225     if (certificateInfo->size < buffSize) {
226         CM_LOG_E("outdata size too small");
227         return CMR_ERROR_BUFFER_TOO_SMALL;
228     }
229     certificateInfo->size = buffSize;
230 
231     uint32_t offset = 0;
232     int32_t ret = CopyBlobToBuffer(certificateData, certificateInfo, &offset); /* certData */
233     if (ret != CM_SUCCESS) {
234         CM_LOG_E("copy cert data failed");
235         return ret;
236     }
237 
238     ret = CopyUint32ToBuffer(status, certificateInfo, &offset); /* status */
239     if (ret != CM_SUCCESS) {
240         CM_LOG_E("copy cert status failed");
241         return ret;
242     }
243 
244     struct CmBlob certAlias;
245     certAlias.size = MAX_LEN_CERT_ALIAS;
246     certAlias.data = (uint8_t *)CmMalloc(MAX_LEN_CERT_ALIAS);
247     if (certAlias.data == NULL) {
248         return CMR_ERROR_MALLOC_FAIL;
249     }
250     (void)memset_s(certAlias.data, MAX_LEN_CERT_ALIAS, 0, MAX_LEN_CERT_ALIAS);
251 
252     ret = CmGetCertAlias(store, (char *)certUri->data, certificateData, &(certAlias));
253     if (ret != CM_SUCCESS) {
254         CM_LOG_E("Failed to get cert certAlias");
255         CM_FREE_BLOB(certAlias);
256         return ret;
257     }
258 
259     ret = CopyBlobToBuffer(&certAlias, certificateInfo, &offset); /* certAlias */
260     if (ret != CM_SUCCESS) {
261         CM_LOG_E("copy cert data failed");
262         CM_FREE_BLOB(certAlias);
263         return ret;
264     }
265     CM_FREE_BLOB(certAlias);
266     return ret;
267 }
268 
269