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