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