• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_param.h"
21 #include "cm_request.h"
22 
GetAppCertInitBlob(struct CmBlob * outBlob)23 static int32_t GetAppCertInitBlob(struct CmBlob *outBlob)
24 {
25     uint32_t buffSize = sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME +
26         sizeof(uint32_t) + MAX_LEN_CERT_ALIAS + sizeof(uint32_t) + MAX_LEN_URI +
27         sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_CERTIFICATE_CHAIN;
28 
29     outBlob->data = (uint8_t *)CmMalloc(buffSize);
30     if (outBlob->data == NULL) {
31         return CMR_ERROR_MALLOC_FAIL;
32     }
33     outBlob->size = buffSize;
34 
35     return CM_SUCCESS;
36 }
37 
CmGetAppCertFromBuffer(struct Credential * certificateInfo,const struct CmBlob * outData,uint32_t * offset)38 static int32_t CmGetAppCertFromBuffer(struct Credential *certificateInfo,
39     const struct CmBlob *outData, uint32_t *offset)
40 {
41     struct CmBlob blob;
42     int32_t ret = CmGetBlobFromBuffer(&blob, outData, offset);
43     if (ret != CM_SUCCESS) {
44         CM_LOG_E("Get type blob failed");
45         return ret;
46     }
47     if (memcpy_s(certificateInfo->type, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) {
48         CM_LOG_E("copy type failed");
49         return CMR_ERROR_INVALID_OPERATION;
50     }
51 
52     ret = CmGetBlobFromBuffer(&blob, outData, offset);
53     if (ret != CM_SUCCESS) {
54         CM_LOG_E("Get keyUri blob failed");
55         return ret;
56     }
57     if (memcpy_s(certificateInfo->keyUri, MAX_LEN_URI, blob.data, blob.size) != EOK) {
58         CM_LOG_E("copy keyUri failed");
59         return CMR_ERROR_INVALID_OPERATION;
60     }
61 
62     ret = CmGetBlobFromBuffer(&blob, outData, offset);
63     if (ret != CM_SUCCESS) {
64         CM_LOG_E("Get alias blob failed");
65         return ret;
66     }
67     if (memcpy_s(certificateInfo->alias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) {
68         CM_LOG_E("copy alias failed");
69         return CMR_ERROR_INVALID_OPERATION;
70     }
71 
72     return ret;
73 }
74 
CmAppCertInfoUnpackFromService(const struct CmBlob * outData,struct Credential * certificateInfo)75 static int32_t CmAppCertInfoUnpackFromService(const struct CmBlob *outData, struct Credential *certificateInfo)
76 {
77     uint32_t offset = 0;
78     struct CmBlob blob = { 0, NULL };
79 
80     if ((outData == NULL) || (certificateInfo == NULL) || (outData->data == NULL) ||
81         (certificateInfo->credData.data == NULL)) {
82         return CMR_ERROR_NULL_POINTER;
83     }
84 
85     int32_t ret = GetUint32FromBuffer(&certificateInfo->isExist, outData, &offset);
86     if (ret != CM_SUCCESS || certificateInfo->isExist == 0) {
87         CM_LOG_E("Get certificateInfo->isExist failed ret:%d, is exist:%u", ret, certificateInfo->isExist);
88         return ret;
89     }
90 
91     ret = CmGetAppCertFromBuffer(certificateInfo, outData, &offset);
92     if (ret != CM_SUCCESS) {
93         CM_LOG_E("Get AppCert failed");
94         return ret;
95     }
96 
97     ret = GetUint32FromBuffer(&certificateInfo->certNum, outData, &offset);
98     if (ret != CM_SUCCESS) {
99         CM_LOG_E("Get certificateInfo->certNum failed");
100         return ret;
101     }
102 
103     ret = GetUint32FromBuffer(&certificateInfo->keyNum, outData, &offset);
104     if (ret != CM_SUCCESS) {
105         CM_LOG_E("Get certificateInfo->keyNum failed");
106         return ret;
107     }
108 
109     ret = CmGetBlobFromBuffer(&blob, outData, &offset);
110     if (ret != CM_SUCCESS) {
111         CM_LOG_E("Get certificateInfo->credData failed");
112         return ret;
113     }
114 
115     if ((blob.size > certificateInfo->credData.size) || memcpy_s(certificateInfo->credData.data,
116         certificateInfo->credData.size, blob.data, blob.size) != EOK) {
117         CM_LOG_E("copy credData failed");
118         return CMR_ERROR_INVALID_OPERATION;
119     }
120     certificateInfo->credData.size = blob.size;
121 
122     return CM_SUCCESS;
123 }
124 
GetAppCert(enum CertManagerInterfaceCode type,const struct CmBlob * certUri,const uint32_t store,struct Credential * certificate)125 static int32_t GetAppCert(enum CertManagerInterfaceCode type, const struct CmBlob *certUri, const uint32_t store,
126     struct Credential *certificate)
127 {
128     int32_t ret;
129     struct CmBlob outBlob = { 0, NULL };
130     struct CmParamSet *sendParamSet = NULL;
131 
132     struct CmParam params[] = {
133         { .tag = CM_TAG_PARAM0_BUFFER,
134           .blob = *certUri },
135         { .tag = CM_TAG_PARAM0_UINT32,
136           .uint32Param = store },
137     };
138     do {
139         ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet);
140         if (ret != CM_SUCCESS) {
141             CM_LOG_E("GetAppCert CmParamSetPack fail");
142             break;
143         }
144 
145         struct CmBlob parcelBlob = {
146             .size = sendParamSet->paramSetSize,
147             .data = (uint8_t *)sendParamSet
148         };
149 
150         ret = GetAppCertInitBlob(&outBlob);
151         if (ret != CM_SUCCESS) {
152             CM_LOG_E("GetAppCertInitBlob fail");
153             break;
154         }
155 
156         ret = SendRequest(type, &parcelBlob, &outBlob);
157         if (ret != CM_SUCCESS) {
158             CM_LOG_E("GetAppCert request fail");
159             break;
160         }
161 
162         ret = CmAppCertInfoUnpackFromService(&outBlob, certificate);
163         if (ret != CM_SUCCESS) {
164             CM_LOG_E("CmAppCertInfoUnpackFromService fail");
165         }
166     } while (0);
167 
168     CmFreeParamSet(&sendParamSet);
169     CM_FREE_BLOB(outBlob);
170     return ret;
171 }
172 
CmClientGetAppCert(const struct CmBlob * keyUri,const uint32_t store,struct Credential * certificate)173 int32_t CmClientGetAppCert(const struct CmBlob *keyUri, const uint32_t store, struct Credential *certificate)
174 {
175     return GetAppCert(CM_MSG_GET_APP_CERTIFICATE, keyUri, store, certificate);
176 }
177 
ClientSerializationAndSend(enum CertManagerInterfaceCode message,struct CmParam * params,uint32_t paramCount,struct CmBlob * outBlob)178 static int32_t ClientSerializationAndSend(enum CertManagerInterfaceCode message, struct CmParam *params,
179     uint32_t paramCount, struct CmBlob *outBlob)
180 {
181     struct CmParamSet *sendParamSet = NULL;
182     int32_t ret = CmParamsToParamSet(params, paramCount, &sendParamSet);
183     if (ret != CM_SUCCESS) {
184         CM_LOG_E("pack params failed, ret = %d", ret);
185         return ret;
186     }
187 
188     struct CmBlob parcelBlob = { sendParamSet->paramSetSize, (uint8_t *)sendParamSet };
189     ret = SendRequest(message, &parcelBlob, outBlob);
190     if (ret != CM_SUCCESS) {
191         CM_LOG_E("send request failed, ret = %d", ret);
192     }
193     CmFreeParamSet(&sendParamSet);
194 
195     return ret;
196 }
197 
CmClientInit(const struct CmBlob * authUri,const struct CmSignatureSpec * spec,struct CmBlob * handle)198 int32_t CmClientInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle)
199 {
200     if (CmCheckBlob(authUri) != CM_SUCCESS || CmCheckBlob(handle) != CM_SUCCESS) {
201         CM_LOG_E("invalid handle or inData");
202         return CMR_ERROR_INVALID_ARGUMENT;
203     }
204 
205     struct CmBlob signSpec = { sizeof(struct CmSignatureSpec), (uint8_t *)spec };
206     struct CmParam params[] = {
207         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri },
208         { .tag = CM_TAG_PARAM1_BUFFER, .blob = signSpec },
209     };
210 
211     int32_t ret = ClientSerializationAndSend(CM_MSG_INIT, params, CM_ARRAY_SIZE(params), handle);
212     if (ret != CM_SUCCESS) {
213         CM_LOG_E("update serialization and send failed, ret = %d", ret);
214     }
215     return ret;
216 }
217 
CmClientUpdate(const struct CmBlob * handle,const struct CmBlob * inData)218 int32_t CmClientUpdate(const struct CmBlob *handle, const struct CmBlob *inData)
219 {
220     if (CmCheckBlob(handle) != CM_SUCCESS || CmCheckBlob(inData) != CM_SUCCESS) {
221         CM_LOG_E("invalid handle or inData");
222         return CMR_ERROR_INVALID_ARGUMENT;
223     }
224 
225     struct CmParam params[] = {
226         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
227         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData },
228     };
229 
230     struct CmBlob outBlob = { 0, NULL };
231     int32_t ret = ClientSerializationAndSend(CM_MSG_UPDATE, params, CM_ARRAY_SIZE(params), &outBlob);
232     if (ret != CM_SUCCESS) {
233         CM_LOG_E("update serialization and send failed, ret = %d", ret);
234     }
235     return ret;
236 }
237 
CmClientFinish(const struct CmBlob * handle,const struct CmBlob * inData,struct CmBlob * outData)238 int32_t CmClientFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData)
239 {
240     if (CmCheckBlob(handle) != CM_SUCCESS) { /* finish: inData and outData can be {0, NULL} */
241         CM_LOG_E("invalid handle");
242         return CMR_ERROR_INVALID_ARGUMENT;
243     }
244 
245     struct CmParam params[] = {
246         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
247         { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData },
248     };
249 
250     int32_t ret = ClientSerializationAndSend(CM_MSG_FINISH, params, CM_ARRAY_SIZE(params), outData);
251     if (ret != CM_SUCCESS) {
252         CM_LOG_E("finish serialization and send failed, ret = %d", ret);
253     }
254     return ret;
255 }
256 
CmClientAbort(const struct CmBlob * handle)257 int32_t CmClientAbort(const struct CmBlob *handle)
258 {
259     if (CmCheckBlob(handle) != CM_SUCCESS) {
260         CM_LOG_E("invalid handle");
261         return CMR_ERROR_INVALID_ARGUMENT;
262     }
263 
264     struct CmParam params[] = {
265         { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle },
266     };
267 
268     struct CmBlob outBlob = { 0, NULL };
269     int32_t ret = ClientSerializationAndSend(CM_MSG_ABORT, params, CM_ARRAY_SIZE(params), &outBlob);
270     if (ret != CM_SUCCESS) {
271         CM_LOG_E("abort serialization and send failed, ret = %d", ret);
272     }
273     return ret;
274 }
275 
276