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