• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_client.h"
17 #include "cm_ipc_client_serialization.h"
18 #include "cm_log.h"
19 #include "cm_mem.h"
20 #include "cm_x509.h"
21 #include "cm_param.h"
22 #include "cm_request.h"
23 
CmSendParcelInit(struct CmParam * params,uint32_t paramCount,struct CmBlob * parcelBlob,struct CmParamSet ** sendParamSet)24 static int32_t CmSendParcelInit(struct CmParam *params, uint32_t paramCount,
25     struct CmBlob *parcelBlob, struct CmParamSet **sendParamSet)
26 {
27     int32_t ret = CM_SUCCESS;
28 
29     ret = CmParamsToParamSet(params, paramCount, sendParamSet);
30     if (ret != CM_SUCCESS) {
31         CM_LOG_E("CmParamSetPack fail");
32         return ret;
33     }
34 
35     parcelBlob->size = (*sendParamSet)->paramSetSize;
36     parcelBlob->data = (uint8_t *)*sendParamSet;
37     return ret;
38 }
39 
GetCertListInitOutData(struct CmBlob * outListBlob)40 static int32_t GetCertListInitOutData(struct CmBlob *outListBlob)
41 {
42     /* buff struct: certCount + MAX_CERT_COUNT * (subjectBlob + status + uriBlob + aliasBlob) */
43     uint32_t buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) +
44         sizeof(uint32_t) + MAX_LEN_URI + sizeof(uint32_t) +  MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE;
45     outListBlob->data = (uint8_t *)CmMalloc(buffSize);
46     if (outListBlob->data == NULL) {
47         return CMR_ERROR_MALLOC_FAIL;
48     }
49     outListBlob->size = buffSize;
50 
51     return CM_SUCCESS;
52 }
53 
GetCertificateList(enum CertManagerInterfaceCode type,const uint32_t store,struct CertList * certificateList)54 static int32_t GetCertificateList(enum CertManagerInterfaceCode type, const uint32_t store,
55     struct CertList *certificateList)
56 {
57     int32_t ret;
58     struct CmBlob outBlob = { 0, NULL };
59     struct CmBlob parcelBlob = { 0, NULL };
60     struct CmParamSet *sendParamSet = NULL;
61     struct CmParam params[] = {
62         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
63     };
64 
65     do {
66         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
67         if (ret != CM_SUCCESS) {
68             CM_LOG_E("get system cert list sendParcel failed");
69             break;
70         }
71 
72         ret = GetCertListInitOutData(&outBlob);
73         if (ret != CM_SUCCESS) {
74             CM_LOG_E("malloc cert list outdata failed");
75             break;
76         }
77 
78         ret = SendRequest(type, &parcelBlob, &outBlob);
79         if (ret != CM_SUCCESS) {
80             CM_LOG_E("GetCertificateList request fail");
81             break;
82         }
83 
84         ret = CmCertificateListUnpackFromService(&outBlob, certificateList);
85     } while (0);
86     CmFreeParamSet(&sendParamSet);
87     CM_FREE_BLOB(outBlob);
88     return ret;
89 }
90 
CmClientGetCertList(const uint32_t store,struct CertList * certificateList)91 int32_t CmClientGetCertList(const uint32_t store, struct CertList *certificateList)
92 {
93     return GetCertificateList(CM_MSG_GET_CERTIFICATE_LIST, store, certificateList);
94 }
95 
GetCertInfoInitOutData(struct CmBlob * outInfoBlob)96 static int32_t GetCertInfoInitOutData(struct CmBlob *outInfoBlob)
97 {
98     /* buff struct: certDataBlob + status + aliasBlob */
99     uint32_t buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t) +
100         MAX_LEN_CERT_ALIAS + sizeof(uint32_t);
101 
102     outInfoBlob->data = (uint8_t *)CmMalloc(buffSize);
103     if (outInfoBlob->data == NULL) {
104         return CMR_ERROR_MALLOC_FAIL;
105     }
106     outInfoBlob->size = buffSize;
107 
108     return CM_SUCCESS;
109 }
110 
GetCertificateInfo(enum CertManagerInterfaceCode type,const struct CmBlob * certUri,const uint32_t store,struct CertInfo * certificateInfo)111 static int32_t GetCertificateInfo(enum CertManagerInterfaceCode type, const struct CmBlob *certUri,
112     const uint32_t store, struct CertInfo *certificateInfo)
113 {
114     int32_t ret = CM_SUCCESS;
115     struct CmBlob outBlob = { 0, NULL };
116     struct CmBlob parcelBlob = { 0, NULL };
117     struct CmParamSet *sendParamSet = NULL;
118     struct CmParam params[] = {
119         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
120         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
121     };
122 
123     do {
124         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
125         if (ret != CM_SUCCESS) {
126             CM_LOG_E("get system cert info sendParcel failed");
127             break;
128         }
129 
130         ret = GetCertInfoInitOutData(&outBlob);
131         if (ret != CM_SUCCESS) {
132             CM_LOG_E("malloc system cert info outdata failed");
133             break;
134         }
135 
136         ret = SendRequest(type, &parcelBlob, &outBlob);
137         if (ret != CM_SUCCESS) {
138             CM_LOG_E("get system cert info send request fail");
139             break;
140         }
141 
142         ret = CmCertificateInfoUnpackFromService(&outBlob, certUri, certificateInfo);
143         if (ret != CM_SUCCESS) {
144             CM_LOG_E("GetCertificateInfo unpack failed, ret = %d", ret);
145             break;
146         }
147     } while (0);
148     CmFreeParamSet(&sendParamSet);
149     CM_FREE_BLOB(outBlob);
150     return ret;
151 }
152 
CmClientGetCertInfo(const struct CmBlob * certUri,const uint32_t store,struct CertInfo * certificateInfo)153 int32_t CmClientGetCertInfo(const struct CmBlob *certUri, const uint32_t store,
154     struct CertInfo *certificateInfo)
155 {
156     return GetCertificateInfo(CM_MSG_GET_CERTIFICATE_INFO, certUri, store, certificateInfo);
157 }
158 
SetCertificateStatus(enum CertManagerInterfaceCode type,const struct CmBlob * certUri,const uint32_t store,const uint32_t status)159 static int32_t SetCertificateStatus(enum CertManagerInterfaceCode type, const struct CmBlob *certUri,
160     const uint32_t store, const uint32_t status)
161 {
162     int32_t ret = CM_SUCCESS;
163     struct CmBlob parcelBlob = { 0, NULL };
164     struct CmParamSet *sendParamSet = NULL;
165     struct CmParam params[] = {
166         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
167         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
168         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = status },
169     };
170 
171     do {
172         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
173         if (ret != CM_SUCCESS) {
174             CM_LOG_E("set system cert status sendParcel failed");
175             break;
176         }
177 
178         ret = SendRequest(type, &parcelBlob, NULL);
179         if (ret != CM_SUCCESS) {
180             CM_LOG_E("set system cert status send request fail");
181             break;
182         }
183     } while (0);
184     CmFreeParamSet(&sendParamSet);
185     return ret;
186 }
187 
CmClientSetCertStatus(const struct CmBlob * certUri,const uint32_t store,const uint32_t status)188 int32_t CmClientSetCertStatus(const struct CmBlob *certUri, const uint32_t store,
189     const uint32_t status)
190 {
191     return SetCertificateStatus(CM_MSG_SET_CERTIFICATE_STATUS, certUri, store, status);
192 }
193 
InstallAppCert(const struct CmBlob * appCert,const struct CmBlob * appCertPwd,const struct CmBlob * certAlias,const uint32_t store,struct CmBlob * keyUri)194 static int32_t InstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd,
195     const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri)
196 {
197     int32_t ret;
198     struct CmParamSet *sendParamSet = NULL;
199     struct CmParam params[] = {
200         { .tag = CM_TAG_PARAM0_BUFFER,
201           .blob = *appCert },
202         { .tag = CM_TAG_PARAM1_BUFFER,
203           .blob = *appCertPwd },
204         { .tag = CM_TAG_PARAM2_BUFFER,
205           .blob = *certAlias },
206         { .tag = CM_TAG_PARAM3_UINT32,
207           .uint32Param = store },
208     };
209     do {
210         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
211         if (ret != CM_SUCCESS) {
212             CM_LOG_E("CmParamSetPack fail");
213             break;
214         }
215 
216         struct CmBlob parcelBlob = {
217             .size = sendParamSet->paramSetSize,
218             .data = (uint8_t *)sendParamSet
219         };
220 
221         ret = SendRequest(CM_MSG_INSTALL_APP_CERTIFICATE, &parcelBlob, keyUri);
222         if (ret != CM_SUCCESS) {
223             CM_LOG_E("CmParamSet send fail");
224             break;
225         }
226     } while (0);
227 
228     CmFreeParamSet(&sendParamSet);
229     return ret;
230 }
231 
CmClientInstallAppCert(const struct CmBlob * appCert,const struct CmBlob * appCertPwd,const struct CmBlob * certAlias,const uint32_t store,struct CmBlob * keyUri)232 int32_t CmClientInstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd,
233     const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri)
234 {
235     return InstallAppCert(appCert, appCertPwd, certAlias, store, keyUri);
236 }
237 
UninstallAppCert(enum CertManagerInterfaceCode type,const struct CmBlob * keyUri,const uint32_t store)238 static int32_t UninstallAppCert(enum CertManagerInterfaceCode type, const struct CmBlob *keyUri,
239     const uint32_t store)
240 {
241     int32_t ret;
242     struct CmParamSet *sendParamSet = NULL;
243 
244     struct CmParam params[] = {
245         { .tag = CM_TAG_PARAM0_BUFFER,
246           .blob = *keyUri },
247         { .tag = CM_TAG_PARAM0_UINT32,
248           .uint32Param = store },
249     };
250 
251     do {
252         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
253         if (ret != CM_SUCCESS) {
254             CM_LOG_E("UninstallAppCert CmParamSetPack fail");
255             break;
256         }
257 
258         struct CmBlob parcelBlob = {
259             .size = sendParamSet->paramSetSize,
260             .data = (uint8_t *)sendParamSet
261         };
262 
263         ret = SendRequest(type, &parcelBlob, NULL);
264         if (ret != CM_SUCCESS) {
265             CM_LOG_E("UninstallAppCert CmParamSet send fail");
266             break;
267         }
268     } while (0);
269 
270     CmFreeParamSet(&sendParamSet);
271     return ret;
272 }
273 
CmClientUninstallAppCert(const struct CmBlob * keyUri,const uint32_t store)274 int32_t CmClientUninstallAppCert(const struct CmBlob *keyUri, const uint32_t store)
275 {
276     return UninstallAppCert(CM_MSG_UNINSTALL_APP_CERTIFICATE, keyUri, store);
277 }
278 
CmClientUninstallAllAppCert(enum CertManagerInterfaceCode type)279 int32_t CmClientUninstallAllAppCert(enum CertManagerInterfaceCode type)
280 {
281     int32_t ret;
282     char tempBuff[] = "uninstall all app cert";
283     struct CmBlob parcelBlob = {
284         .size = sizeof(tempBuff),
285         .data = (uint8_t *)tempBuff
286     };
287 
288     ret = SendRequest(type, &parcelBlob, NULL);
289     if (ret != CM_SUCCESS) {
290         CM_LOG_E("UninstallAllAppCert request fail");
291     }
292 
293     return ret;
294 }
295 
GetAppCertListInitBlob(struct CmBlob * outBlob)296 static int32_t GetAppCertListInitBlob(struct CmBlob *outBlob)
297 {
298     uint32_t buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) +
299         MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE;
300     outBlob->data = (uint8_t *)CmMalloc(buffSize);
301     if (outBlob->data == NULL) {
302         return CMR_ERROR_MALLOC_FAIL;
303     }
304     outBlob->size = buffSize;
305 
306     return CM_SUCCESS;
307 }
308 
CmAppCertListGetCertCount(const struct CmBlob * outData,struct CredentialList * certificateList,uint32_t * offset)309 static int32_t CmAppCertListGetCertCount(const struct CmBlob *outData,
310     struct CredentialList *certificateList, uint32_t *offset)
311 {
312     uint32_t credCount = 0;
313     int32_t ret = GetUint32FromBuffer(&credCount, outData, offset);
314     if (ret != CM_SUCCESS) {
315         CM_LOG_E("App cert get list faild ret:%d", ret);
316         return ret;
317     }
318 
319     if (credCount == 0) {
320         CM_LOG_I("App cert list is null");
321     }
322 
323     if (credCount > certificateList->credentialCount) {
324         CM_LOG_E("Caller buff too small count:%u, count:%u", credCount,
325             certificateList->credentialCount);
326         return CMR_ERROR_BUFFER_TOO_SMALL;
327     }
328 
329     certificateList->credentialCount = credCount;
330 
331     return CM_SUCCESS;
332 }
333 
CmAppCertListUnpackFromService(const struct CmBlob * outData,struct CredentialList * certificateList)334 static int32_t CmAppCertListUnpackFromService(const struct CmBlob *outData,
335     struct CredentialList *certificateList)
336 {
337     uint32_t offset = 0;
338     struct CmBlob blob = { 0, NULL };
339     if ((outData == NULL) || (certificateList == NULL) ||
340         (outData->data == NULL) || (certificateList->credentialAbstract == NULL)) {
341         return CMR_ERROR_NULL_POINTER;
342     }
343 
344     int32_t ret = CmAppCertListGetCertCount(outData, certificateList, &offset);
345     if (ret != CM_SUCCESS) {
346         return ret;
347     }
348 
349     for (uint32_t i = 0; i < certificateList->credentialCount; i++) {
350         ret = CmGetBlobFromBuffer(&blob, outData, &offset);
351         if (ret != CM_SUCCESS) {
352             CM_LOG_E("Get type blob failed");
353             return ret;
354         }
355         if (memcpy_s(certificateList->credentialAbstract[i].type, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) {
356             CM_LOG_E("copy type failed");
357             return CMR_ERROR_INVALID_OPERATION;
358         }
359 
360         ret = CmGetBlobFromBuffer(&blob, outData, &offset);
361         if (ret != CM_SUCCESS) {
362             CM_LOG_E("Get keyUri blob failed");
363             return ret;
364         }
365         if (memcpy_s(certificateList->credentialAbstract[i].keyUri, MAX_LEN_URI, blob.data, blob.size) != EOK) {
366             CM_LOG_E("copy keyUri failed");
367             return CMR_ERROR_INVALID_OPERATION;
368         }
369 
370         ret = CmGetBlobFromBuffer(&blob, outData, &offset);
371         if (ret != CM_SUCCESS) {
372             CM_LOG_E("Get alias blob failed");
373             return ret;
374         }
375         if (memcpy_s(certificateList->credentialAbstract[i].alias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) {
376             CM_LOG_E("copy alias failed");
377             return CMR_ERROR_INVALID_OPERATION;
378         }
379     }
380     return CM_SUCCESS;
381 }
382 
GetAppCertList(enum CertManagerInterfaceCode type,const uint32_t store,struct CredentialList * certificateList)383 static int32_t GetAppCertList(enum CertManagerInterfaceCode type, const uint32_t store,
384     struct CredentialList *certificateList)
385 {
386     int32_t ret;
387     struct CmBlob outBlob = { 0, NULL };
388     struct CmParamSet *sendParamSet = NULL;
389 
390     struct CmParam params[] = {
391         { .tag = CM_TAG_PARAM0_UINT32,
392             .uint32Param = store },
393     };
394 
395     do {
396         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
397         if (ret != CM_SUCCESS) {
398             CM_LOG_E("GetAppCertList CmParamSetPack fail");
399             break;
400         }
401 
402         struct CmBlob parcelBlob = {
403             .size = sendParamSet->paramSetSize,
404             .data = (uint8_t *)sendParamSet
405         };
406 
407         ret = GetAppCertListInitBlob(&outBlob);
408         if (ret != CM_SUCCESS) {
409             CM_LOG_E("GetAppCertListInitBlob fail");
410             break;
411         }
412 
413         ret = SendRequest(type, &parcelBlob, &outBlob);
414         if (ret != CM_SUCCESS) {
415             CM_LOG_E("GetAppCertList request fail");
416             break;
417         }
418 
419         ret = CmAppCertListUnpackFromService(&outBlob, certificateList);
420         if (ret != CM_SUCCESS) {
421             CM_LOG_E("CmAppCertListUnpackFromService fail");
422             break;
423         }
424     } while (0);
425 
426     CmFreeParamSet(&sendParamSet);
427     CM_FREE_BLOB(outBlob);
428     return ret;
429 }
430 
CmClientGetAppCertList(const uint32_t store,struct CredentialList * certificateList)431 int32_t CmClientGetAppCertList(const uint32_t store, struct CredentialList *certificateList)
432 {
433     return GetAppCertList(CM_MSG_GET_APP_CERTIFICATE_LIST, store, certificateList);
434 }
435 
GetAppCertInitBlob(struct CmBlob * outBlob)436 static int32_t GetAppCertInitBlob(struct CmBlob *outBlob)
437 {
438     uint32_t buffSize = sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME +
439         sizeof(uint32_t) + MAX_LEN_CERT_ALIAS + sizeof(uint32_t) + MAX_LEN_URI +
440         sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_CERTIFICATE_CHAIN;
441 
442     outBlob->data = (uint8_t *)CmMalloc(buffSize);
443     if (outBlob->data == NULL) {
444         return CMR_ERROR_MALLOC_FAIL;
445     }
446     outBlob->size = buffSize;
447 
448     return CM_SUCCESS;
449 }
450 
CmGetAppCertFromBuffer(struct Credential * certificateInfo,const struct CmBlob * outData,uint32_t * offset)451 static int32_t CmGetAppCertFromBuffer(struct Credential *certificateInfo,
452     const struct CmBlob *outData, uint32_t *offset)
453 {
454     struct CmBlob blob;
455     int32_t ret = CmGetBlobFromBuffer(&blob, outData, offset);
456     if (ret != CM_SUCCESS) {
457         CM_LOG_E("Get type blob failed");
458         return ret;
459     }
460     if (memcpy_s(certificateInfo->type, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) {
461         CM_LOG_E("copy type failed");
462         return CMR_ERROR_INVALID_OPERATION;
463     }
464 
465     ret = CmGetBlobFromBuffer(&blob, outData, offset);
466     if (ret != CM_SUCCESS) {
467         CM_LOG_E("Get keyUri blob failed");
468         return ret;
469     }
470     if (memcpy_s(certificateInfo->keyUri, MAX_LEN_URI, blob.data, blob.size) != EOK) {
471         CM_LOG_E("copy keyUri failed");
472         return CMR_ERROR_INVALID_OPERATION;
473     }
474 
475     ret = CmGetBlobFromBuffer(&blob, outData, offset);
476     if (ret != CM_SUCCESS) {
477         CM_LOG_E("Get alias blob failed");
478         return ret;
479     }
480     if (memcpy_s(certificateInfo->alias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) {
481         CM_LOG_E("copy alias failed");
482         return CMR_ERROR_INVALID_OPERATION;
483     }
484 
485     return ret;
486 }
487 
CmAppCertInfoUnpackFromService(const struct CmBlob * outData,struct Credential * certificateInfo)488 static int32_t CmAppCertInfoUnpackFromService(const struct CmBlob *outData, struct Credential *certificateInfo)
489 {
490     uint32_t offset = 0;
491     struct CmBlob blob = { 0, NULL };
492 
493     if ((outData == NULL) || (certificateInfo == NULL) || (outData->data == NULL) ||
494         (certificateInfo->credData.data == NULL)) {
495         return CMR_ERROR_NULL_POINTER;
496     }
497 
498     int32_t ret = GetUint32FromBuffer(&certificateInfo->isExist, outData, &offset);
499     if (ret != CM_SUCCESS || certificateInfo->isExist == 0) {
500         CM_LOG_E("Get certificateInfo->isExist failed ret:%d, is exist:%u", ret, certificateInfo->isExist);
501         return ret;
502     }
503 
504     ret = CmGetAppCertFromBuffer(certificateInfo, outData, &offset);
505     if (ret != CM_SUCCESS) {
506         CM_LOG_E("Get AppCert failed");
507         return ret;
508     }
509 
510     ret = GetUint32FromBuffer(&certificateInfo->certNum, outData, &offset);
511     if (ret != CM_SUCCESS) {
512         CM_LOG_E("Get certificateInfo->certNum failed");
513         return ret;
514     }
515 
516     ret = GetUint32FromBuffer(&certificateInfo->keyNum, outData, &offset);
517     if (ret != CM_SUCCESS) {
518         CM_LOG_E("Get certificateInfo->keyNum failed");
519         return ret;
520     }
521 
522     ret = CmGetBlobFromBuffer(&blob, outData, &offset);
523     if (ret != CM_SUCCESS) {
524         CM_LOG_E("Get certificateInfo->credData failed");
525         return ret;
526     }
527 
528     if ((blob.size > certificateInfo->credData.size) || memcpy_s(certificateInfo->credData.data,
529         certificateInfo->credData.size, blob.data, blob.size) != EOK) {
530         CM_LOG_E("copy credData failed");
531         return CMR_ERROR_INVALID_OPERATION;
532     }
533     certificateInfo->credData.size = blob.size;
534 
535     return CM_SUCCESS;
536 }
537 
GetAppCert(enum CertManagerInterfaceCode type,const struct CmBlob * certUri,const uint32_t store,struct Credential * certificate)538 static int32_t GetAppCert(enum CertManagerInterfaceCode type, const struct CmBlob *certUri, const uint32_t store,
539     struct Credential *certificate)
540 {
541     int32_t ret;
542     struct CmBlob outBlob = { 0, NULL };
543     struct CmParamSet *sendParamSet = NULL;
544 
545     struct CmParam params[] = {
546         { .tag = CM_TAG_PARAM0_BUFFER,
547           .blob = *certUri },
548         { .tag = CM_TAG_PARAM0_UINT32,
549           .uint32Param = store },
550     };
551     do {
552         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
553         if (ret != CM_SUCCESS) {
554             CM_LOG_E("GetAppCert CmParamSetPack fail");
555             break;
556         }
557 
558         struct CmBlob parcelBlob = {
559             .size = sendParamSet->paramSetSize,
560             .data = (uint8_t *)sendParamSet
561         };
562 
563         ret = GetAppCertInitBlob(&outBlob);
564         if (ret != CM_SUCCESS) {
565             CM_LOG_E("GetAppCertInitBlob fail");
566             break;
567         }
568 
569         ret = SendRequest(type, &parcelBlob, &outBlob);
570         if (ret != CM_SUCCESS) {
571             CM_LOG_E("GetAppCert request fail");
572             break;
573         }
574 
575         ret = CmAppCertInfoUnpackFromService(&outBlob, certificate);
576         if (ret != CM_SUCCESS) {
577             CM_LOG_E("CmAppCertInfoUnpackFromService fail");
578         }
579     } while (0);
580 
581     CmFreeParamSet(&sendParamSet);
582     CM_FREE_BLOB(outBlob);
583     return ret;
584 }
585 
CmClientGetAppCert(const struct CmBlob * keyUri,const uint32_t store,struct Credential * certificate)586 int32_t CmClientGetAppCert(const struct CmBlob *keyUri, const uint32_t store, struct Credential *certificate)
587 {
588     return GetAppCert(CM_MSG_GET_APP_CERTIFICATE, keyUri, store, certificate);
589 }
590 
ClientSerializationAndSend(enum CertManagerInterfaceCode message,struct CmParam * params,uint32_t paramCount,struct CmBlob * outBlob)591 static int32_t ClientSerializationAndSend(enum CertManagerInterfaceCode message, struct CmParam *params,
592     uint32_t paramCount, struct CmBlob *outBlob)
593 {
594     struct CmParamSet *sendParamSet = NULL;
595     int32_t ret = CmParamsToParamSet(params, paramCount, &sendParamSet);
596     if (ret != CM_SUCCESS) {
597         CM_LOG_E("pack params failed, ret = %d", ret);
598         return ret;
599     }
600 
601     struct CmBlob parcelBlob = { sendParamSet->paramSetSize, (uint8_t *)sendParamSet };
602     ret = SendRequest(message, &parcelBlob, outBlob);
603     if (ret != CM_SUCCESS) {
604         CM_LOG_E("send request failed, ret = %d", ret);
605     }
606     CmFreeParamSet(&sendParamSet);
607 
608     return ret;
609 }
610 
FormatAppUidList(const struct CmBlob * replyBlob,struct CmAppUidList * appUidList)611 static int32_t FormatAppUidList(const struct CmBlob *replyBlob, struct CmAppUidList *appUidList)
612 {
613     if (replyBlob->size < sizeof(uint32_t)) { /* app uid count: 4 bytes */
614         CM_LOG_E("invalid reply size[%u]", replyBlob->size);
615         return CMR_ERROR_INVALID_ARGUMENT;
616     }
617 
618     /* get app uid count */
619     uint32_t count = 0;
620     (void)memcpy_s(&count, sizeof(uint32_t), replyBlob->data, sizeof(uint32_t));
621     uint32_t offset = sizeof(uint32_t);
622 
623     /* check reply total len */
624     if ((count > MAX_OUT_BLOB_SIZE) || (replyBlob->size < (sizeof(uint32_t) + count * sizeof(uint32_t)))) {
625         CM_LOG_E("invalid reply size[%u]", replyBlob->size);
626         return CMR_ERROR_INVALID_ARGUMENT;
627     }
628 
629     if (appUidList->appUidCount < count) {
630         CM_LOG_E("input app list count[%u] too small", appUidList->appUidCount);
631         return CMR_ERROR_BUFFER_TOO_SMALL;
632     }
633 
634     if (count != 0) {
635         if (appUidList->appUid == NULL) {
636             CM_LOG_E("input appUid NULL");
637             return CMR_ERROR_INVALID_ARGUMENT;
638         }
639         uint32_t uidListSize = count * sizeof(uint32_t);
640         (void)memcpy_s(appUidList->appUid, uidListSize, replyBlob->data + offset, uidListSize);
641     }
642     appUidList->appUidCount = count;
643     return CM_SUCCESS;
644 }
645 
CmClientGrantAppCertificate(const struct CmBlob * keyUri,uint32_t appUid,struct CmBlob * authUri)646 int32_t CmClientGrantAppCertificate(const struct CmBlob *keyUri, uint32_t appUid, struct CmBlob *authUri)
647 {
648     if (CmCheckBlob(keyUri) != CM_SUCCESS || CmCheckBlob(authUri) != CM_SUCCESS) {
649         CM_LOG_E("invalid keyUri or authUri");
650         return CMR_ERROR_INVALID_ARGUMENT;
651     }
652 
653     struct CmParam params[] = {
654         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
655         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = appUid },
656     };
657 
658     int32_t ret = ClientSerializationAndSend(CM_MSG_GRANT_APP_CERT, params, CM_ARRAY_SIZE(params), authUri);
659     if (ret != CM_SUCCESS) {
660         CM_LOG_E("grant app serialization and send failed, ret = %d", ret);
661     }
662     return ret;
663 }
664 
CmClientGetAuthorizedAppList(const struct CmBlob * keyUri,struct CmAppUidList * appUidList)665 int32_t CmClientGetAuthorizedAppList(const struct CmBlob *keyUri, struct CmAppUidList *appUidList)
666 {
667     if (CmCheckBlob(keyUri) != CM_SUCCESS) {
668         CM_LOG_E("invalid keyUri");
669         return CMR_ERROR_INVALID_ARGUMENT;
670     }
671 
672     if (appUidList->appUidCount > MAX_OUT_BLOB_SIZE) { /* ensure not out of bounds */
673         CM_LOG_E("invalid app uid list count[%u]", appUidList->appUidCount);
674         return CMR_ERROR_INVALID_ARGUMENT;
675     }
676 
677     uint32_t outLen = sizeof(uint32_t) + appUidList->appUidCount * sizeof(uint32_t);
678     uint8_t *outData = CmMalloc(outLen);
679     if (outData == NULL) {
680         CM_LOG_E("malloc out data failed");
681         return CMR_ERROR_MALLOC_FAIL;
682     }
683     (void)memset_s(outData, outLen, 0, outLen);
684     struct CmBlob outBlob = { outLen, outData };
685 
686     struct CmParam params[] = {
687         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
688     };
689 
690     int32_t ret = ClientSerializationAndSend(CM_MSG_GET_AUTHED_LIST, params, CM_ARRAY_SIZE(params), &outBlob);
691     if (ret != CM_SUCCESS) {
692         CM_LOG_E("get authed list serialization and send failed, ret = %d", ret);
693         CmFree(outData);
694         return ret;
695     }
696 
697     ret = FormatAppUidList(&outBlob, appUidList);
698     CmFree(outData);
699     return ret;
700 }
701 
CmClientIsAuthorizedApp(const struct CmBlob * authUri)702 int32_t CmClientIsAuthorizedApp(const struct CmBlob *authUri)
703 {
704     if (CmCheckBlob(authUri) != CM_SUCCESS) {
705         CM_LOG_E("invalid authUri");
706         return CMR_ERROR_INVALID_ARGUMENT;
707     }
708 
709     struct CmParam params[] = {
710         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri },
711     };
712 
713     struct CmBlob outBlob = { 0, NULL };
714     int32_t ret = ClientSerializationAndSend(CM_MSG_CHECK_IS_AUTHED_APP, params, CM_ARRAY_SIZE(params), &outBlob);
715     if (ret != CM_SUCCESS) {
716         CM_LOG_E("check is authed serialization and send failed, ret = %d", ret);
717     }
718     return ret;
719 }
720 
CmClientRemoveGrantedApp(const struct CmBlob * keyUri,uint32_t appUid)721 int32_t CmClientRemoveGrantedApp(const struct CmBlob *keyUri, uint32_t appUid)
722 {
723     if (CmCheckBlob(keyUri) != CM_SUCCESS) {
724         CM_LOG_E("invalid keyUri");
725         return CMR_ERROR_INVALID_ARGUMENT;
726     }
727 
728     struct CmParam params[] = {
729         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
730         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = appUid },
731     };
732 
733     struct CmBlob outBlob = { 0, NULL };
734     int32_t ret = ClientSerializationAndSend(CM_MSG_REMOVE_GRANT_APP, params, CM_ARRAY_SIZE(params), &outBlob);
735     if (ret != CM_SUCCESS) {
736         CM_LOG_E("remove granted app serialization and send failed, ret = %d", ret);
737     }
738     return ret;
739 }
740 
CmClientInit(const struct CmBlob * authUri,const struct CmSignatureSpec * spec,struct CmBlob * handle)741 int32_t CmClientInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle)
742 {
743     if (CmCheckBlob(authUri) != CM_SUCCESS || CmCheckBlob(handle) != CM_SUCCESS) {
744         CM_LOG_E("invalid handle or inData");
745         return CMR_ERROR_INVALID_ARGUMENT;
746     }
747 
748     struct CmBlob signSpec = { sizeof(struct CmSignatureSpec), (uint8_t *)spec };
749     struct CmParam params[] = {
750         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri },
751         { .tag = CM_TAG_PARAM1_BUFFER, .blob = signSpec },
752     };
753 
754     int32_t ret = ClientSerializationAndSend(CM_MSG_INIT, params, CM_ARRAY_SIZE(params), handle);
755     if (ret != CM_SUCCESS) {
756         CM_LOG_E("update serialization and send failed, ret = %d", ret);
757     }
758     return ret;
759 }
760 
CmClientUpdate(const struct CmBlob * handle,const struct CmBlob * inData)761 int32_t CmClientUpdate(const struct CmBlob *handle, const struct CmBlob *inData)
762 {
763     if (CmCheckBlob(handle) != CM_SUCCESS || CmCheckBlob(inData) != CM_SUCCESS) {
764         CM_LOG_E("invalid handle or inData");
765         return CMR_ERROR_INVALID_ARGUMENT;
766     }
767 
768     struct CmParam params[] = {
769         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
770         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData },
771     };
772 
773     struct CmBlob outBlob = { 0, NULL };
774     int32_t ret = ClientSerializationAndSend(CM_MSG_UPDATE, params, CM_ARRAY_SIZE(params), &outBlob);
775     if (ret != CM_SUCCESS) {
776         CM_LOG_E("update serialization and send failed, ret = %d", ret);
777     }
778     return ret;
779 }
780 
CmClientFinish(const struct CmBlob * handle,const struct CmBlob * inData,struct CmBlob * outData)781 int32_t CmClientFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData)
782 {
783     if (CmCheckBlob(handle) != CM_SUCCESS) { /* finish: inData and outData can be {0, NULL} */
784         CM_LOG_E("invalid handle");
785         return CMR_ERROR_INVALID_ARGUMENT;
786     }
787 
788     struct CmParam params[] = {
789         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
790         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData },
791     };
792 
793     int32_t ret = ClientSerializationAndSend(CM_MSG_FINISH, params, CM_ARRAY_SIZE(params), outData);
794     if (ret != CM_SUCCESS) {
795         CM_LOG_E("finish serialization and send failed, ret = %d", ret);
796     }
797     return ret;
798 }
799 
CmClientAbort(const struct CmBlob * handle)800 int32_t CmClientAbort(const struct CmBlob *handle)
801 {
802     if (CmCheckBlob(handle) != CM_SUCCESS) {
803         CM_LOG_E("invalid handle");
804         return CMR_ERROR_INVALID_ARGUMENT;
805     }
806 
807     struct CmParam params[] = {
808         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
809     };
810 
811     struct CmBlob outBlob = { 0, NULL };
812     int32_t ret = ClientSerializationAndSend(CM_MSG_ABORT, params, CM_ARRAY_SIZE(params), &outBlob);
813     if (ret != CM_SUCCESS) {
814         CM_LOG_E("abort serialization and send failed, ret = %d", ret);
815     }
816     return ret;
817 }
818 
GetUserCertList(enum CertManagerInterfaceCode type,const uint32_t store,struct CertList * certificateList)819 static int32_t GetUserCertList(enum CertManagerInterfaceCode type, const uint32_t store,
820     struct CertList *certificateList)
821 {
822     int32_t ret = CM_SUCCESS;
823     struct CmBlob outBlob = {0, NULL};
824     struct CmBlob parcelBlob = {0, NULL};
825     struct CmParamSet *sendParamSet = NULL;
826     struct CmParam params[] = {
827         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
828     };
829 
830     do {
831         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
832         if (ret != CM_SUCCESS) {
833             CM_LOG_E("get cert list sendParcel failed");
834             break;
835         }
836 
837         ret = GetCertListInitOutData(&outBlob);
838         if (ret != CM_SUCCESS) {
839             CM_LOG_E("malloc getcertlist outdata failed");
840             break;
841         }
842 
843         ret = SendRequest(type, &parcelBlob, &outBlob);
844         if (ret != CM_SUCCESS) {
845             CM_LOG_E("GetCertList request failed, ret: %d", ret);
846             break;
847         }
848 
849         ret = CmCertificateListUnpackFromService(&outBlob, certificateList);
850         if (ret != CM_SUCCESS) {
851             CM_LOG_E("getcertlist unpack from service failed");
852             break;
853         }
854     } while (0);
855 
856     CmFreeParamSet(&sendParamSet);
857     CM_FREE_BLOB(outBlob);
858     return ret;
859 }
860 
CmClientGetUserCertList(const uint32_t store,struct CertList * certificateList)861 int32_t CmClientGetUserCertList(const uint32_t store, struct CertList *certificateList)
862 {
863     return GetUserCertList(CM_MSG_GET_USER_CERTIFICATE_LIST, store, certificateList);
864 }
865 
GetUserCertInfo(enum CertManagerInterfaceCode type,const struct CmBlob * certUri,const uint32_t store,struct CertInfo * userCertInfo)866 static int32_t GetUserCertInfo(enum CertManagerInterfaceCode type, const struct CmBlob *certUri,
867     const uint32_t store, struct CertInfo *userCertInfo)
868 {
869     int32_t ret = CM_SUCCESS;
870     struct CmBlob outBlob = {0, NULL};
871     struct CmBlob parcelBlob = {0, NULL};
872     struct CmParamSet *sendParamSet = NULL;
873     struct CmParam params[] = {
874         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
875         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
876     };
877 
878     do {
879         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
880         if (ret != CM_SUCCESS) {
881             CM_LOG_E("get cert info sendParcel failed");
882             break;
883         }
884 
885         ret = GetCertInfoInitOutData(&outBlob);
886         if (ret != CM_SUCCESS) {
887             CM_LOG_E("malloc getcertinfo outdata failed");
888             break;
889         }
890 
891         ret = SendRequest(type, &parcelBlob, &outBlob);
892         if (ret != CM_SUCCESS) {
893             CM_LOG_E("GetCertInfo request failed, ret: %d", ret);
894             break;
895         }
896 
897         ret = CmCertificateInfoUnpackFromService(&outBlob, certUri, userCertInfo);
898         if (ret != CM_SUCCESS) {
899             CM_LOG_E("getcertinfo unpack from service failed");
900             break;
901         }
902     } while (0);
903     CmFreeParamSet(&sendParamSet);
904     CM_FREE_BLOB(outBlob);
905     return ret;
906 }
907 
CmClientGetUserCertInfo(const struct CmBlob * certUri,const uint32_t store,struct CertInfo * certificateInfo)908 int32_t CmClientGetUserCertInfo(const struct CmBlob *certUri, const uint32_t store,
909     struct CertInfo *certificateInfo)
910 {
911     return GetUserCertInfo(CM_MSG_GET_USER_CERTIFICATE_INFO, certUri, store, certificateInfo);
912 }
913 
SetUserCertStatus(enum CertManagerInterfaceCode type,const struct CmBlob * certUri,const uint32_t store,const uint32_t status)914 static int32_t SetUserCertStatus(enum CertManagerInterfaceCode type, const struct CmBlob *certUri,
915     const uint32_t store, const uint32_t status)
916 {
917     int32_t ret = CM_SUCCESS;
918     struct CmBlob parcelBlob = {0, NULL};
919     struct CmParamSet *sendParamSet = NULL;
920     struct CmParam params[] = {
921         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
922         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
923         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = status },
924     };
925 
926     do {
927         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
928         if (ret != CM_SUCCESS) {
929             CM_LOG_E("set cert status sendParcel failed");
930             break;
931         }
932 
933         ret = SendRequest(type, &parcelBlob, NULL);
934         if (ret != CM_SUCCESS) {
935             CM_LOG_E("SetCertStatus request failed, ret: %d", ret);
936             break;
937         }
938     } while (0);
939     CmFreeParamSet(&sendParamSet);
940     return ret;
941 }
942 
CmClientSetUserCertStatus(const struct CmBlob * certUri,const uint32_t store,const uint32_t status)943 int32_t CmClientSetUserCertStatus(const struct CmBlob *certUri, const uint32_t store,
944     const uint32_t status)
945 {
946     return SetUserCertStatus(CM_MSG_SET_USER_CERTIFICATE_STATUS, certUri, store, status);
947 }
948 
InstallUserCert(enum CertManagerInterfaceCode type,const struct CmBlob * userCert,const struct CmBlob * certAlias,struct CmBlob * certUri)949 static int32_t InstallUserCert(enum CertManagerInterfaceCode type, const struct CmBlob *userCert,
950     const struct CmBlob *certAlias, struct CmBlob *certUri)
951 {
952     int32_t ret = CM_SUCCESS;
953     struct CmBlob parcelBlob = {0, NULL};
954     struct CmParamSet *sendParamSet = NULL;
955     struct CmParam params[] = {
956         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *userCert },
957         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *certAlias },
958     };
959 
960     do {
961         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
962         if (ret != CM_SUCCESS) {
963             CM_LOG_E("install user cert sendParcel failed");
964             break;
965         }
966 
967         ret = SendRequest(type, &parcelBlob, certUri);
968         if (ret != CM_SUCCESS) {
969             CM_LOG_E("InstallUserCert request failed, ret: %d", ret);
970             break;
971         }
972     } while (0);
973     CmFreeParamSet(&sendParamSet);
974     return ret;
975 }
976 
CmClientInstallUserTrustedCert(const struct CmBlob * userCert,const struct CmBlob * certAlias,struct CmBlob * certUri)977 int32_t CmClientInstallUserTrustedCert(const struct CmBlob *userCert, const struct CmBlob *certAlias,
978     struct CmBlob *certUri)
979 {
980     return InstallUserCert(CM_MSG_INSTALL_USER_CERTIFICATE, userCert, certAlias, certUri);
981 }
982 
UninstallUserCert(enum CertManagerInterfaceCode type,const struct CmBlob * certUri)983 static int32_t UninstallUserCert(enum CertManagerInterfaceCode type, const struct CmBlob *certUri)
984 {
985     int32_t ret = CM_SUCCESS;
986     struct CmBlob parcelBlob = {0, NULL};
987     struct CmParamSet *sendParamSet = NULL;
988     struct CmParam params[] = {
989         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
990     };
991 
992     do {
993         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
994         if (ret != CM_SUCCESS) {
995             CM_LOG_E("uninstall user cert sendParcel failed");
996             break;
997         }
998 
999         ret = SendRequest(type, &parcelBlob, NULL);
1000         if (ret != CM_SUCCESS) {
1001             CM_LOG_E("UninstallUserCert request failed, ret: %d", ret);
1002             break;
1003         }
1004     } while (0);
1005     CmFreeParamSet(&sendParamSet);
1006     return ret;
1007 }
1008 
CmClientUninstallUserTrustedCert(const struct CmBlob * certUri)1009 int32_t CmClientUninstallUserTrustedCert(const struct CmBlob *certUri)
1010 {
1011     return UninstallUserCert(CM_MSG_UNINSTALL_USER_CERTIFICATE, certUri);
1012 }
1013 
UninstallAllUserCert(enum CertManagerInterfaceCode type)1014 static int32_t UninstallAllUserCert(enum CertManagerInterfaceCode type)
1015 {
1016     int ret = CM_SUCCESS;
1017     uint8_t temp[4] = {0}; /* only use to construct parcelBlob */
1018     struct CmBlob parcelBlob = { sizeof(temp), temp };
1019 
1020     ret = SendRequest(type, &parcelBlob, NULL);
1021     if (ret != CM_SUCCESS) {
1022         CM_LOG_E("UninstallAllUserCert request failed, ret: %d", ret);
1023     }
1024     return ret;
1025 }
1026 
CmClientUninstallAllUserTrustedCert(void)1027 int32_t CmClientUninstallAllUserTrustedCert(void)
1028 {
1029     return UninstallAllUserCert(CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE);
1030 }
1031 
1032