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