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