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