• 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_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 CmMessage type,const uint32_t store,struct CertList * certificateList)54 static int32_t GetCertificateList(enum CmMessage type, const uint32_t store,
55     struct CertList *certificateList)
56 {
57     int32_t ret;
58     struct CmBlob outBlob = { 0, NULL };
59     const struct CmContext context = {0};
60     struct CmBlob parcelBlob = { 0, NULL };
61     struct CmParamSet *sendParamSet = NULL;
62     struct CmParam params[] = {
63         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
64     };
65 
66     do {
67         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
68         if (ret != CM_SUCCESS) {
69             CM_LOG_E("get system cert list sendParcel failed");
70             break;
71         }
72 
73         ret = GetCertListInitOutData(&outBlob);
74         if (ret != CM_SUCCESS) {
75             CM_LOG_E("malloc cert list outdata failed");
76             break;
77         }
78 
79         ret = SendRequest(type, &parcelBlob, &outBlob);
80         if (ret != CM_SUCCESS) {
81             CM_LOG_E("GetCertificateList request fail");
82             break;
83         }
84 
85         ret = CmCertificateListUnpackFromService(&outBlob, false, &context, certificateList);
86     } while (0);
87     CmFreeParamSet(&sendParamSet);
88     CM_FREE_BLOB(outBlob);
89     return ret;
90 }
91 
CmClientGetCertList(const uint32_t store,struct CertList * certificateList)92 int32_t CmClientGetCertList(const uint32_t store, struct CertList *certificateList)
93 {
94     return GetCertificateList(CM_MSG_GET_CERTIFICATE_LIST, store, certificateList);
95 }
96 
GetCertInfoInitOutData(struct CmBlob * outInfoBlob)97 static int32_t GetCertInfoInitOutData(struct CmBlob *outInfoBlob)
98 {
99     /* buff struct: certDataBlob + status + aliasBlob */
100     uint32_t buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t) +
101         MAX_LEN_CERT_ALIAS + sizeof(uint32_t);
102 
103     outInfoBlob->data = (uint8_t *)CmMalloc(buffSize);
104     if (outInfoBlob->data == NULL) {
105         return CMR_ERROR_MALLOC_FAIL;
106     }
107     outInfoBlob->size = buffSize;
108 
109     return CM_SUCCESS;
110 }
111 
GetCertificateInfo(enum CmMessage type,const struct CmBlob * certUri,const uint32_t store,struct CertInfo * certificateInfo)112 static int32_t GetCertificateInfo(enum CmMessage type, const struct CmBlob *certUri,
113     const uint32_t store, struct CertInfo *certificateInfo)
114 {
115     int32_t ret = CM_SUCCESS;
116     struct CmBlob outBlob = { 0, NULL };
117     struct CmBlob parcelBlob = { 0, NULL };
118     struct CmParamSet *sendParamSet = NULL;
119     struct CmParam params[] = {
120         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
121         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
122     };
123 
124     do {
125         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
126         if (ret != CM_SUCCESS) {
127             CM_LOG_E("get system cert info sendParcel failed");
128             break;
129         }
130 
131         ret = GetCertInfoInitOutData(&outBlob);
132         if (ret != CM_SUCCESS) {
133             CM_LOG_E("malloc system cert info outdata failed");
134             break;
135         }
136 
137         ret = SendRequest(type, &parcelBlob, &outBlob);
138         if (ret != CM_SUCCESS) {
139             CM_LOG_E("get system cert info send request fail");
140             break;
141         }
142 
143         ret = CmCertificateInfoUnpackFromService(&outBlob, certUri, certificateInfo);
144         if (ret != CM_SUCCESS) {
145             CM_LOG_E("GetCertificateInfo unpack failed, ret = %d", ret);
146             break;
147         }
148     } while (0);
149     CmFreeParamSet(&sendParamSet);
150     CM_FREE_BLOB(outBlob);
151     return ret;
152 }
153 
CmClientGetCertInfo(const struct CmBlob * certUri,const uint32_t store,struct CertInfo * certificateInfo)154 int32_t CmClientGetCertInfo(const struct CmBlob *certUri, const uint32_t store,
155     struct CertInfo *certificateInfo)
156 {
157     return GetCertificateInfo(CM_MSG_GET_CERTIFICATE_INFO, certUri, store, certificateInfo);
158 }
159 
SetCertificateStatus(enum CmMessage type,const struct CmBlob * certUri,const uint32_t store,const uint32_t status)160 static int32_t SetCertificateStatus(enum CmMessage type, const struct CmBlob *certUri,
161     const uint32_t store, const uint32_t status)
162 {
163     int32_t ret = CM_SUCCESS;
164     struct CmBlob parcelBlob = { 0, NULL };
165     struct CmParamSet *sendParamSet = NULL;
166     struct CmParam params[] = {
167         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *certUri },
168         { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
169         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = status },
170     };
171 
172     do {
173         ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &parcelBlob, &sendParamSet);
174         if (ret != CM_SUCCESS) {
175             CM_LOG_E("set system cert status sendParcel failed");
176             break;
177         }
178 
179         ret = SendRequest(type, &parcelBlob, NULL);
180         if (ret != CM_SUCCESS) {
181             CM_LOG_E("set system cert status send request fail");
182             break;
183         }
184     } while (0);
185     CmFreeParamSet(&sendParamSet);
186     return ret;
187 }
188 
CmClientSetCertStatus(const struct CmBlob * certUri,const uint32_t store,const uint32_t status)189 int32_t CmClientSetCertStatus(const struct CmBlob *certUri, const uint32_t store,
190     const uint32_t status)
191 {
192     return SetCertificateStatus(CM_MSG_SET_CERTIFICATE_STATUS, certUri, store, status);
193 }
194 
InstallAppCert(const struct CmBlob * appCert,const struct CmBlob * appCertPwd,const struct CmBlob * certAlias,const uint32_t store,struct CmBlob * keyUri)195 static int32_t InstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd,
196     const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri)
197 {
198     int32_t ret;
199     struct CmParamSet *sendParamSet = NULL;
200     struct CmParam params[] = {
201         { .tag = CM_TAG_PARAM0_BUFFER,
202           .blob = *appCert },
203         { .tag = CM_TAG_PARAM1_BUFFER,
204           .blob = *appCertPwd },
205         { .tag = CM_TAG_PARAM2_BUFFER,
206           .blob = *certAlias },
207         { .tag = CM_TAG_PARAM3_UINT32,
208           .uint32Param = store },
209     };
210     do {
211         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
212         if (ret != CM_SUCCESS) {
213             CM_LOG_E("CmParamSetPack fail");
214             break;
215         }
216 
217         struct CmBlob parcelBlob = {
218             .size = sendParamSet->paramSetSize,
219             .data = (uint8_t *)sendParamSet
220         };
221 
222         ret = SendRequest(CM_MSG_INSTALL_APP_CERTIFICATE, &parcelBlob, keyUri);
223         if (ret != CM_SUCCESS) {
224             CM_LOG_E("CmParamSet send fail");
225             break;
226         }
227     } while (0);
228 
229     CmFreeParamSet(&sendParamSet);
230     return ret;
231 }
232 
CmClientInstallAppCert(const struct CmBlob * appCert,const struct CmBlob * appCertPwd,const struct CmBlob * certAlias,const uint32_t store,struct CmBlob * keyUri)233 int32_t CmClientInstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd,
234     const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri)
235 {
236     return InstallAppCert(appCert, appCertPwd, certAlias, store, keyUri);
237 }
238 
UninstallAppCert(enum CmMessage type,const struct CmBlob * keyUri,const uint32_t store)239 static int32_t UninstallAppCert(enum CmMessage type, const struct CmBlob *keyUri, 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 CmMessage type)279 int32_t CmClientUninstallAllAppCert(enum CmMessage 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 CmMessage type,const uint32_t store,struct CredentialList * certificateList)383 static int32_t GetAppCertList(enum CmMessage type, const uint32_t store, 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 
GetAppCertInitBlob(struct CmBlob * outBlob)435 static int32_t GetAppCertInitBlob(struct CmBlob *outBlob)
436 {
437     uint32_t buffSize = sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME +
438         sizeof(uint32_t) + MAX_LEN_CERT_ALIAS + sizeof(uint32_t) + MAX_LEN_URI +
439         sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_CERTIFICATE_CHAIN;
440 
441     outBlob->data = (uint8_t *)CmMalloc(buffSize);
442     if (outBlob->data == NULL) {
443         return CMR_ERROR_MALLOC_FAIL;
444     }
445     outBlob->size = buffSize;
446 
447     return CM_SUCCESS;
448 }
449 
CmGetAppCertFromBuffer(struct Credential * certificateInfo,const struct CmBlob * outData,uint32_t * offset)450 static int32_t CmGetAppCertFromBuffer(struct Credential *certificateInfo,
451     const struct CmBlob *outData, uint32_t *offset)
452 {
453     struct CmBlob blob;
454     int32_t ret = CmGetBlobFromBuffer(&blob, outData, offset);
455     if (ret != CM_SUCCESS) {
456         CM_LOG_E("Get type blob failed");
457         return ret;
458     }
459     if (memcpy_s(certificateInfo->type, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) {
460         CM_LOG_E("copy type failed");
461         return CMR_ERROR_INVALID_OPERATION;
462     }
463 
464     ret = CmGetBlobFromBuffer(&blob, outData, offset);
465     if (ret != CM_SUCCESS) {
466         CM_LOG_E("Get keyUri blob failed");
467         return ret;
468     }
469     if (memcpy_s(certificateInfo->keyUri, MAX_LEN_URI, blob.data, blob.size) != EOK) {
470         CM_LOG_E("copy keyUri failed");
471         return CMR_ERROR_INVALID_OPERATION;
472     }
473 
474     ret = CmGetBlobFromBuffer(&blob, outData, offset);
475     if (ret != CM_SUCCESS) {
476         CM_LOG_E("Get alias blob failed");
477         return ret;
478     }
479     if (memcpy_s(certificateInfo->alias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) {
480         CM_LOG_E("copy alias failed");
481         return CMR_ERROR_INVALID_OPERATION;
482     }
483 
484     return ret;
485 }
486 
CmAppCertInfoUnpackFromService(const struct CmBlob * outData,struct Credential * certificateInfo)487 static int32_t CmAppCertInfoUnpackFromService(const struct CmBlob *outData, struct Credential *certificateInfo)
488 {
489     uint32_t offset = 0;
490     struct CmBlob blob = { 0, NULL };
491 
492     if ((outData == NULL) || (certificateInfo == NULL) || (outData->data == NULL) ||
493         (certificateInfo->credData.data == NULL)) {
494         return CMR_ERROR_NULL_POINTER;
495     }
496 
497     int32_t ret = GetUint32FromBuffer(&certificateInfo->isExist, outData, &offset);
498     if (ret != CM_SUCCESS || certificateInfo->isExist == 0) {
499         CM_LOG_E("Get certificateInfo->isExist failed ret:%d, is exist:%u", ret, certificateInfo->isExist);
500         return ret;
501     }
502 
503     ret = CmGetAppCertFromBuffer(certificateInfo, outData, &offset);
504     if (ret != CM_SUCCESS) {
505         CM_LOG_E("Get AppCert failed");
506         return ret;
507     }
508 
509     ret = GetUint32FromBuffer(&certificateInfo->certNum, outData, &offset);
510     if (ret != CM_SUCCESS) {
511         CM_LOG_E("Get certificateInfo->certNum failed");
512         return ret;
513     }
514 
515     ret = GetUint32FromBuffer(&certificateInfo->keyNum, outData, &offset);
516     if (ret != CM_SUCCESS) {
517         CM_LOG_E("Get certificateInfo->keyNum failed");
518         return ret;
519     }
520 
521     ret = CmGetBlobFromBuffer(&blob, outData, &offset);
522     if (ret != CM_SUCCESS) {
523         CM_LOG_E("Get certificateInfo->credData failed");
524         return ret;
525     }
526 
527     if ((blob.size > certificateInfo->credData.size) || memcpy_s(certificateInfo->credData.data,
528         certificateInfo->credData.size, blob.data, blob.size) != EOK) {
529         CM_LOG_E("copy credData failed");
530         return CMR_ERROR_INVALID_OPERATION;
531     }
532     certificateInfo->credData.size = blob.size;
533 
534     return CM_SUCCESS;
535 }
536 
GetAppCert(enum CmMessage type,const struct CmBlob * certUri,const uint32_t store,struct Credential * certificate)537 static int32_t GetAppCert(enum CmMessage type, const struct CmBlob *certUri, const uint32_t store,
538     struct Credential *certificate)
539 {
540     int32_t ret;
541     struct CmBlob outBlob = { 0, NULL };
542     struct CmParamSet *sendParamSet = NULL;
543 
544     struct CmParam params[] = {
545         { .tag = CM_TAG_PARAM0_BUFFER,
546           .blob = *certUri },
547         { .tag = CM_TAG_PARAM0_UINT32,
548           .uint32Param = store },
549     };
550     do {
551         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
552         if (ret != CM_SUCCESS) {
553             CM_LOG_E("GetAppCert CmParamSetPack fail");
554             break;
555         }
556 
557         struct CmBlob parcelBlob = {
558             .size = sendParamSet->paramSetSize,
559             .data = (uint8_t *)sendParamSet
560         };
561 
562         ret = GetAppCertInitBlob(&outBlob);
563         if (ret != CM_SUCCESS) {
564             CM_LOG_E("GetAppCertInitBlob fail");
565             break;
566         }
567 
568         ret = SendRequest(type, &parcelBlob, &outBlob);
569         if (ret != CM_SUCCESS) {
570             CM_LOG_E("GetAppCert request fail");
571             break;
572         }
573 
574         ret = CmAppCertInfoUnpackFromService(&outBlob, certificate);
575         if (ret != CM_SUCCESS) {
576             CM_LOG_E("CmAppCertInfoUnpackFromService fail");
577         }
578     } while (0);
579 
580     CmFreeParamSet(&sendParamSet);
581     CM_FREE_BLOB(outBlob);
582     return ret;
583 }
584 
CmClientGetAppCert(const struct CmBlob * keyUri,const uint32_t store,struct Credential * certificate)585 int32_t CmClientGetAppCert(const struct CmBlob *keyUri, const uint32_t store, struct Credential *certificate)
586 {
587     return GetAppCert(CM_MSG_GET_APP_CERTIFICATE, keyUri, store, certificate);
588 }
589 
ClientSerializationAndSend(enum CmMessage message,struct CmParam * params,uint32_t paramCount,struct CmBlob * outBlob)590 static int32_t ClientSerializationAndSend(enum CmMessage message, struct CmParam *params,
591     uint32_t paramCount, struct CmBlob *outBlob)
592 {
593     struct CmParamSet *sendParamSet = NULL;
594     int32_t ret = CmParamsToParamSet(params, paramCount, &sendParamSet);
595     if (ret != CM_SUCCESS) {
596         CM_LOG_E("pack params failed, ret = %d", ret);
597         return ret;
598     }
599 
600     struct CmBlob parcelBlob = { sendParamSet->paramSetSize, (uint8_t *)sendParamSet };
601     ret = SendRequest(message, &parcelBlob, outBlob);
602     if (ret != CM_SUCCESS) {
603         CM_LOG_E("send request failed, ret = %d", ret);
604     }
605     CmFreeParamSet(&sendParamSet);
606 
607     return ret;
608 }
609 
FormatAppUidList(const struct CmBlob * replyBlob,struct CmAppUidList * appUidList)610 static int32_t FormatAppUidList(const struct CmBlob *replyBlob, struct CmAppUidList *appUidList)
611 {
612     if (replyBlob->size < sizeof(uint32_t)) { /* app uid count: 4 bytes */
613         CM_LOG_E("invalid reply size[%u]", replyBlob->size);
614         return CMR_ERROR_INVALID_ARGUMENT;
615     }
616 
617     /* get app uid count */
618     uint32_t count = 0;
619     (void)memcpy_s(&count, sizeof(uint32_t), replyBlob->data, sizeof(uint32_t));
620     uint32_t offset = sizeof(uint32_t);
621 
622     /* check reply total len */
623     if ((count > MAX_OUT_BLOB_SIZE) || (replyBlob->size < (sizeof(uint32_t) + count * sizeof(uint32_t)))) {
624         CM_LOG_E("invalid reply size[%u]", replyBlob->size);
625         return CMR_ERROR_INVALID_ARGUMENT;
626     }
627 
628     if (appUidList->appUidCount < count) {
629         CM_LOG_E("input app list count[%u] too small", appUidList->appUidCount);
630         return CMR_ERROR_BUFFER_TOO_SMALL;
631     }
632 
633     if (count != 0) {
634         if (appUidList->appUid == NULL) {
635             CM_LOG_E("input appUid NULL");
636             return CMR_ERROR_INVALID_ARGUMENT;
637         }
638         uint32_t uidListSize = count * sizeof(uint32_t);
639         (void)memcpy_s(appUidList->appUid, uidListSize, replyBlob->data + offset, uidListSize);
640     }
641     appUidList->appUidCount = count;
642     return CM_SUCCESS;
643 }
644 
CmClientGrantAppCertificate(const struct CmBlob * keyUri,uint32_t appUid,struct CmBlob * authUri)645 int32_t CmClientGrantAppCertificate(const struct CmBlob *keyUri, uint32_t appUid, struct CmBlob *authUri)
646 {
647     if (CmCheckBlob(keyUri) != CM_SUCCESS || CmCheckBlob(authUri) != CM_SUCCESS) {
648         CM_LOG_E("invalid keyUri or authUri");
649         return CMR_ERROR_INVALID_ARGUMENT;
650     }
651 
652     struct CmParam params[] = {
653         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
654         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = appUid },
655     };
656 
657     int32_t ret = ClientSerializationAndSend(CM_MSG_GRANT_APP_CERT, params, CM_ARRAY_SIZE(params), authUri);
658     if (ret != CM_SUCCESS) {
659         CM_LOG_E("grant app serialization and send failed, ret = %d", ret);
660     }
661     return ret;
662 }
663 
CmClientGetAuthorizedAppList(const struct CmBlob * keyUri,struct CmAppUidList * appUidList)664 int32_t CmClientGetAuthorizedAppList(const struct CmBlob *keyUri, struct CmAppUidList *appUidList)
665 {
666     if (CmCheckBlob(keyUri) != CM_SUCCESS) {
667         CM_LOG_E("invalid keyUri");
668         return CMR_ERROR_INVALID_ARGUMENT;
669     }
670 
671     if (appUidList->appUidCount > MAX_OUT_BLOB_SIZE) { /* ensure not out of bounds */
672         CM_LOG_E("invalid app uid list count[%u]", appUidList->appUidCount);
673         return CMR_ERROR_INVALID_ARGUMENT;
674     }
675 
676     uint32_t outLen = sizeof(uint32_t) + appUidList->appUidCount * sizeof(uint32_t);
677     uint8_t *outData = CmMalloc(outLen);
678     if (outData == NULL) {
679         CM_LOG_E("malloc out data failed");
680         return CMR_ERROR_MALLOC_FAIL;
681     }
682     (void)memset_s(outData, outLen, 0, outLen);
683     struct CmBlob outBlob = { outLen, outData };
684 
685     struct CmParam params[] = {
686         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
687     };
688 
689     int32_t ret = ClientSerializationAndSend(CM_MSG_GET_AUTHED_LIST, params, CM_ARRAY_SIZE(params), &outBlob);
690     if (ret != CM_SUCCESS) {
691         CM_LOG_E("get authed list serialization and send failed, ret = %d", ret);
692         CmFree(outData);
693         return ret;
694     }
695 
696     ret = FormatAppUidList(&outBlob, appUidList);
697     CmFree(outData);
698     return ret;
699 }
700 
CmClientIsAuthorizedApp(const struct CmBlob * authUri)701 int32_t CmClientIsAuthorizedApp(const struct CmBlob *authUri)
702 {
703     if (CmCheckBlob(authUri) != CM_SUCCESS) {
704         CM_LOG_E("invalid authUri");
705         return CMR_ERROR_INVALID_ARGUMENT;
706     }
707 
708     struct CmParam params[] = {
709         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri },
710     };
711 
712     struct CmBlob outBlob = { 0, NULL };
713     int32_t ret = ClientSerializationAndSend(CM_MSG_CHECK_IS_AUTHED_APP, params, CM_ARRAY_SIZE(params), &outBlob);
714     if (ret != CM_SUCCESS) {
715         CM_LOG_E("check is authed serialization and send failed, ret = %d", ret);
716     }
717     return ret;
718 }
719 
CmClientRemoveGrantedApp(const struct CmBlob * keyUri,uint32_t appUid)720 int32_t CmClientRemoveGrantedApp(const struct CmBlob *keyUri, uint32_t appUid)
721 {
722     if (CmCheckBlob(keyUri) != CM_SUCCESS) {
723         CM_LOG_E("invalid keyUri");
724         return CMR_ERROR_INVALID_ARGUMENT;
725     }
726 
727     struct CmParam params[] = {
728         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
729         { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = appUid },
730     };
731 
732     struct CmBlob outBlob = { 0, NULL };
733     int32_t ret = ClientSerializationAndSend(CM_MSG_REMOVE_GRANT_APP, params, CM_ARRAY_SIZE(params), &outBlob);
734     if (ret != CM_SUCCESS) {
735         CM_LOG_E("remove granted app serialization and send failed, ret = %d", ret);
736     }
737     return ret;
738 }
739 
CmClientInit(const struct CmBlob * authUri,const struct CmSignatureSpec * spec,struct CmBlob * handle)740 int32_t CmClientInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle)
741 {
742     if (CmCheckBlob(authUri) != CM_SUCCESS || CmCheckBlob(handle) != CM_SUCCESS) {
743         CM_LOG_E("invalid handle or inData");
744         return CMR_ERROR_INVALID_ARGUMENT;
745     }
746 
747     struct CmBlob signSpec = { sizeof(struct CmSignatureSpec), (uint8_t *)spec };
748     struct CmParam params[] = {
749         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri },
750         { .tag = CM_TAG_PARAM1_BUFFER, .blob = signSpec },
751     };
752 
753     int32_t ret = ClientSerializationAndSend(CM_MSG_INIT, params, CM_ARRAY_SIZE(params), handle);
754     if (ret != CM_SUCCESS) {
755         CM_LOG_E("update serialization and send failed, ret = %d", ret);
756     }
757     return ret;
758 }
759 
CmClientUpdate(const struct CmBlob * handle,const struct CmBlob * inData)760 int32_t CmClientUpdate(const struct CmBlob *handle, const struct CmBlob *inData)
761 {
762     if (CmCheckBlob(handle) != CM_SUCCESS || CmCheckBlob(inData) != CM_SUCCESS) {
763         CM_LOG_E("invalid handle or inData");
764         return CMR_ERROR_INVALID_ARGUMENT;
765     }
766 
767     struct CmParam params[] = {
768         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
769         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData },
770     };
771 
772     struct CmBlob outBlob = { 0, NULL };
773     int32_t ret = ClientSerializationAndSend(CM_MSG_UPDATE, params, CM_ARRAY_SIZE(params), &outBlob);
774     if (ret != CM_SUCCESS) {
775         CM_LOG_E("update serialization and send failed, ret = %d", ret);
776     }
777     return ret;
778 }
779 
CmClientFinish(const struct CmBlob * handle,const struct CmBlob * inData,struct CmBlob * outData)780 int32_t CmClientFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData)
781 {
782     if (CmCheckBlob(handle) != CM_SUCCESS) { /* finish: inData and outData can be {0, NULL} */
783         CM_LOG_E("invalid handle");
784         return CMR_ERROR_INVALID_ARGUMENT;
785     }
786 
787     struct CmParam params[] = {
788         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
789         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData },
790     };
791 
792     int32_t ret = ClientSerializationAndSend(CM_MSG_FINISH, params, CM_ARRAY_SIZE(params), outData);
793     if (ret != CM_SUCCESS) {
794         CM_LOG_E("finish serialization and send failed, ret = %d", ret);
795     }
796     return ret;
797 }
798 
CmClientAbort(const struct CmBlob * handle)799 int32_t CmClientAbort(const struct CmBlob *handle)
800 {
801     if (CmCheckBlob(handle) != CM_SUCCESS) {
802         CM_LOG_E("invalid handle");
803         return CMR_ERROR_INVALID_ARGUMENT;
804     }
805 
806     struct CmParam params[] = {
807         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
808     };
809 
810     struct CmBlob outBlob = { 0, NULL };
811     int32_t ret = ClientSerializationAndSend(CM_MSG_ABORT, params, CM_ARRAY_SIZE(params), &outBlob);
812     if (ret != CM_SUCCESS) {
813         CM_LOG_E("abort serialization and send failed, ret = %d", ret);
814     }
815     return ret;
816 }
817 
GetUserCertList(enum CmMessage type,const uint32_t store,struct CertList * certificateList)818 static int32_t GetUserCertList(enum CmMessage type, const uint32_t store,
819     struct CertList *certificateList)
820 {
821     int32_t ret = CM_SUCCESS;
822     struct CmBlob outBlob = {0, NULL};
823     struct CmBlob parcelBlob = {0, NULL};
824     const struct CmContext context = {0};
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, false, &context, 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 CmMessage type,const struct CmBlob * certUri,const uint32_t store,struct CertInfo * userCertInfo)866 static int32_t GetUserCertInfo(enum CmMessage 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 CmMessage type,const struct CmBlob * certUri,const uint32_t store,const uint32_t status)914 static int32_t SetUserCertStatus(enum CmMessage 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 CmMessage type,const struct CmBlob * userCert,const struct CmBlob * certAlias,struct CmBlob * certUri)949 static int32_t InstallUserCert(enum CmMessage type, const struct CmBlob *userCert, const struct CmBlob *certAlias,
950     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 CmMessage type,const struct CmBlob * certUri)983 static int32_t UninstallUserCert(enum CmMessage 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 CmMessage type)1014 static int32_t UninstallAllUserCert(enum CmMessage 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