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 "cert_manager_check.h"
17
18 #include <ctype.h>
19
20 #include "cert_manager.h"
21 #include "cert_manager_permission_check.h"
22 #include "cert_manager_uri.h"
23 #include "cm_log.h"
24
CheckUri(const struct CmBlob * keyUri)25 int32_t CheckUri(const struct CmBlob *keyUri)
26 {
27 if (CmCheckBlob(keyUri) != CM_SUCCESS) {
28 CM_LOG_E("invalid uri");
29 return CMR_ERROR_INVALID_ARGUMENT;
30 }
31
32 if (keyUri->size > MAX_AUTH_LEN_URI) {
33 CM_LOG_E("invalid uri len:%u", keyUri->size);
34 return CMR_ERROR_INVALID_ARGUMENT;
35 }
36
37 for (uint32_t i = 1; i < keyUri->size; ++i) { /* from index 1 has '\0' */
38 if (keyUri->data[i] == 0) {
39 return CM_SUCCESS;
40 }
41 }
42 return CMR_ERROR_INVALID_ARGUMENT;
43 }
44
CmServiceGetSystemCertListCheck(const uint32_t store)45 int32_t CmServiceGetSystemCertListCheck(const uint32_t store)
46 {
47 if (store != CM_SYSTEM_TRUSTED_STORE) {
48 CM_LOG_E("invalid input arguments store:%u", store);
49 return CMR_ERROR_INVALID_ARGUMENT;
50 }
51
52 if (!CmHasCommonPermission()) {
53 CM_LOG_E("permission check failed");
54 return CMR_ERROR_PERMISSION_DENIED;
55 }
56
57 return CM_SUCCESS;
58 }
59
CmServiceGetSystemCertCheck(const uint32_t store,const struct CmBlob * certUri)60 int32_t CmServiceGetSystemCertCheck(const uint32_t store, const struct CmBlob *certUri)
61 {
62 if (store != CM_SYSTEM_TRUSTED_STORE) {
63 CM_LOG_E("invalid input arguments store:%u", store);
64 return CMR_ERROR_INVALID_ARGUMENT;
65 }
66
67 if (CheckUri(certUri) != CM_SUCCESS) {
68 CM_LOG_E("invalid input arguments");
69 return CMR_ERROR_INVALID_ARGUMENT;
70 }
71
72 if (!CmHasCommonPermission()) {
73 CM_LOG_E("permission check failed");
74 return CMR_ERROR_PERMISSION_DENIED;
75 }
76
77 return CM_SUCCESS;
78 }
79
CmServiceSetCertStatusCheck(const uint32_t store,const struct CmBlob * certUri,const uint32_t status)80 int32_t CmServiceSetCertStatusCheck(const uint32_t store, const struct CmBlob *certUri, const uint32_t status)
81 {
82 if (store != CM_SYSTEM_TRUSTED_STORE) {
83 CM_LOG_E("invalid input arguments store:%u", store);
84 return CMR_ERROR_INVALID_ARGUMENT;
85 }
86
87 if (CheckUri(certUri) != CM_SUCCESS) {
88 CM_LOG_E("invalid input arguments");
89 return CMR_ERROR_INVALID_ARGUMENT;
90 }
91
92 if ((status != 0) && (status != 1)) {
93 CM_LOG_E("invalid input status:%u", status);
94 return CMR_ERROR_INVALID_ARGUMENT;
95 }
96
97 if (!CmHasPrivilegedPermission() || !CmHasCommonPermission()) {
98 CM_LOG_E("permission check failed");
99 return CMR_ERROR_PERMISSION_DENIED;
100 }
101
102 if (!CmIsSystemApp()) {
103 CM_LOG_E("set cert status: caller is not system app");
104 return CMR_ERROR_NOT_SYSTEMP_APP;
105 }
106
107 return CM_SUCCESS;
108 }
109
CmCheckAppCert(const struct CmBlob * appCert)110 static int32_t CmCheckAppCert(const struct CmBlob *appCert)
111 {
112 if (CmCheckBlob(appCert) != CM_SUCCESS) {
113 CM_LOG_E("appCert blob is invalid");
114 return CMR_ERROR_INVALID_ARGUMENT;
115 }
116
117 if (appCert->size > MAX_LEN_APP_CERT) {
118 CM_LOG_E("appCert size max check fail, appCert size:%u", appCert->size);
119 return CMR_ERROR_INVALID_ARGUMENT;
120 }
121 return CM_SUCCESS;
122 }
123
CmCheckAppCertPwd(const struct CmBlob * appCertPwd)124 static int32_t CmCheckAppCertPwd(const struct CmBlob *appCertPwd)
125 {
126 if (CmCheckBlob(appCertPwd) != CM_SUCCESS) {
127 CM_LOG_E("appCertPwd blob is invalid");
128 return CMR_ERROR_INVALID_ARGUMENT;
129 }
130
131 if (appCertPwd->size > MAX_LEN_APP_CERT_PASSWD) {
132 CM_LOG_E("appCertPwd size max check fail, appCertPwd size:%u", appCertPwd->size);
133 return CMR_ERROR_INVALID_ARGUMENT;
134 }
135
136 if (CheckUri(appCertPwd) != CM_SUCCESS) {
137 CM_LOG_E("appCertPwd data check fail");
138 return CMR_ERROR_INVALID_ARGUMENT;
139 }
140 return CM_SUCCESS;
141 }
142
AppCertCheckBlobValid(const struct CmBlob * data)143 static bool AppCertCheckBlobValid(const struct CmBlob *data)
144 {
145 for (uint32_t i = 0; i < data->size; i++) {
146 if ((i > 0) && (data->data[i] == '\0')) { /* from index 1 has '\0' */
147 CM_LOG_D("data has string end character");
148 return true;
149 }
150
151 if ((!isalnum(data->data[i])) && (data->data[i] != '_')) { /* has invalid character */
152 CM_LOG_E("data include invalid character");
153 return false;
154 }
155 }
156
157 CM_LOG_E("data has no string end character");
158 return false;
159 }
160
CmCheckCertAlias(const struct CmBlob * certAlias,uint32_t store)161 static int32_t CmCheckCertAlias(const struct CmBlob *certAlias, uint32_t store)
162 {
163 if (CmCheckBlob(certAlias) != CM_SUCCESS) {
164 CM_LOG_E("certAlias blob is invalid");
165 return CMR_ERROR_INVALID_ARGUMENT;
166 }
167
168 if (certAlias->size > MAX_LEN_CERT_ALIAS) {
169 CM_LOG_E("alias size is too large");
170 return CMR_ERROR_INVALID_ARGUMENT;
171 }
172
173 if ((store == CM_PRI_CREDENTIAL_STORE) && (certAlias->size > MAX_LEN_PRI_CRED_ALIAS)) {
174 CM_LOG_E("pri_cred: alias size is too large");
175 return CMR_ERROR_INVALID_ARGUMENT;
176 }
177
178 if ((store != CM_PRI_CREDENTIAL_STORE) && (strcmp("", (char *)certAlias->data) == 0)) {
179 CM_LOG_D("cert alias is empty string");
180 return CM_SUCCESS;
181 }
182
183 if (!AppCertCheckBlobValid(certAlias)) {
184 CM_LOG_E("certAlias data check fail");
185 return CMR_ERROR_INVALID_ARGUMENT;
186 }
187 return CM_SUCCESS;
188 }
189
CmCheckUserIdAndUpdateContext(const uint32_t inputUserId,uint32_t * callerUserId)190 static bool CmCheckUserIdAndUpdateContext(const uint32_t inputUserId, uint32_t *callerUserId)
191 {
192 if (*callerUserId == 0) { /* caller is sa */
193 if (inputUserId == 0 || inputUserId == INIT_INVALID_VALUE) {
194 CM_LOG_E("caller is sa, input userId %u is invalid", inputUserId);
195 return false;
196 }
197 CM_LOG_D("update caller userId from %u to %u", *callerUserId, inputUserId);
198 *callerUserId = inputUserId;
199 return true;
200 }
201
202 /* caller is hap */
203 if (inputUserId != INIT_INVALID_VALUE) {
204 CM_LOG_E("caller is hap, input userId %u is not supported", inputUserId);
205 return false;
206 }
207 return true;
208 }
209
CmServiceInstallAppCertCheck(const struct CmAppCertParam * certParam,struct CmContext * cmContext)210 int32_t CmServiceInstallAppCertCheck(const struct CmAppCertParam *certParam, struct CmContext *cmContext)
211 {
212 if ((certParam == NULL) || (cmContext == NULL)) {
213 return CMR_ERROR_INVALID_ARGUMENT;
214 }
215
216 if (CM_STORE_CHECK(certParam->store)) {
217 CM_LOG_E("CmInstallAppCertCheck store check fail, store:%u", certParam->store);
218 return CMR_ERROR_INVALID_ARGUMENT;
219 }
220
221 int32_t ret = CmCheckAppCert(certParam->appCert);
222 if (ret != CM_SUCCESS) {
223 return ret;
224 }
225
226 ret = CmCheckAppCertPwd(certParam->appCertPwd);
227 if (ret != CM_SUCCESS) {
228 return ret;
229 }
230
231 ret = CmCheckCertAlias(certParam->certAlias, certParam->store);
232 if (ret != CM_SUCCESS) {
233 return ret;
234 }
235
236 if (certParam->store == CM_SYS_CREDENTIAL_STORE &&
237 !CmCheckUserIdAndUpdateContext(certParam->userId, &(cmContext->userId))) {
238 CM_LOG_E("input userId is invalid");
239 return CMR_ERROR_INVALID_ARGUMENT;
240 }
241
242 if (!CmPermissionCheck(certParam->store)) {
243 CM_LOG_E("permission check failed");
244 return CMR_ERROR_PERMISSION_DENIED;
245 }
246
247 if (!CmIsSystemAppByStoreType(certParam->store)) {
248 CM_LOG_E("install app cert: caller is not system app");
249 return CMR_ERROR_NOT_SYSTEMP_APP;
250 }
251
252 return CM_SUCCESS;
253 }
254
checkCallerAndUri(struct CmContext * cmContext,const struct CmBlob * uri,const uint32_t type,bool isCheckUid)255 static int32_t checkCallerAndUri(struct CmContext *cmContext, const struct CmBlob *uri,
256 const uint32_t type, bool isCheckUid)
257 {
258 struct CMUri uriObj;
259 int32_t ret = CertManagerUriDecode(&uriObj, (char *)uri->data);
260 if (ret != CM_SUCCESS) {
261 CM_LOG_E("Failed to decode uri, ret = %d", ret);
262 return ret;
263 }
264
265 if ((uriObj.object == NULL) || (uriObj.user == NULL) || (uriObj.app == NULL) || (uriObj.type != type)) {
266 CM_LOG_E("uri format is invalid");
267 (void)CertManagerFreeUri(&uriObj);
268 return CMR_ERROR_INVALID_ARGUMENT;
269 }
270
271 uint32_t userId = (uint32_t)atoi(uriObj.user);
272 uint32_t uid = (uint32_t)atoi(uriObj.app);
273 (void)CertManagerFreeUri(&uriObj);
274 if ((cmContext->userId != 0) && (cmContext->userId != userId)) {
275 CM_LOG_E("caller userid is not producer");
276 return CMR_ERROR_INVALID_ARGUMENT;
277 }
278
279 if ((isCheckUid) && (cmContext->userId == 0) && (cmContext->uid != uid)) {
280 CM_LOG_E("caller uid is not producer");
281 return CMR_ERROR_INVALID_ARGUMENT;
282 }
283
284 cmContext->userId = userId;
285 cmContext->uid = uid;
286 return CM_SUCCESS;
287 }
288
CmServiceUninstallAppCertCheck(struct CmContext * cmContext,const uint32_t store,const struct CmBlob * keyUri)289 int32_t CmServiceUninstallAppCertCheck(struct CmContext *cmContext,
290 const uint32_t store, const struct CmBlob *keyUri)
291 {
292 if (CM_STORE_CHECK(store)) {
293 CM_LOG_E("invalid input arguments store:%u", store);
294 return CMR_ERROR_INVALID_ARGUMENT;
295 }
296
297 if (CheckUri(keyUri) != CM_SUCCESS) {
298 CM_LOG_E("invalid input arguments");
299 return CMR_ERROR_INVALID_ARGUMENT;
300 }
301
302 if (!CmPermissionCheck(store)) {
303 CM_LOG_E("permission check failed");
304 return CMR_ERROR_PERMISSION_DENIED;
305 }
306
307 if (!CmIsSystemAppByStoreType(store)) {
308 CM_LOG_E("uninstall app cert: caller is not system app");
309 return CMR_ERROR_NOT_SYSTEMP_APP;
310 }
311
312 if (store == CM_SYS_CREDENTIAL_STORE) {
313 return checkCallerAndUri(cmContext, keyUri, CM_URI_TYPE_SYS_KEY, true);
314 }
315
316 return CM_SUCCESS;
317 }
318
CmGetSysAppCertListCheck(const struct CmContext * cmContext,const uint32_t store)319 static int32_t CmGetSysAppCertListCheck(const struct CmContext *cmContext, const uint32_t store)
320 {
321 if (cmContext->userId == 0) {
322 CM_LOG_E("get sys app cert list: caller is not hap");
323 return CMR_ERROR_INVALID_ARGUMENT;
324 }
325
326 if (!CmHasCommonPermission()) {
327 CM_LOG_E("permission check failed");
328 return CMR_ERROR_PERMISSION_DENIED;
329 }
330
331 if (!CmIsSystemApp()) {
332 CM_LOG_E("get sys app cert list: caller is not system app");
333 return CMR_ERROR_NOT_SYSTEMP_APP;
334 }
335 return CM_SUCCESS;
336 }
337
CmServiceGetAppCertListCheck(const struct CmContext * cmContext,const uint32_t store)338 int32_t CmServiceGetAppCertListCheck(const struct CmContext *cmContext, const uint32_t store)
339 {
340 if (CM_STORE_CHECK(store)) {
341 CM_LOG_E("invalid input arguments store:%u", store);
342 return CMR_ERROR_INVALID_ARGUMENT;
343 }
344
345 if (store == CM_SYS_CREDENTIAL_STORE) {
346 return CmGetSysAppCertListCheck(cmContext, store);
347 }
348
349 if (!CmHasPrivilegedPermission() || !CmHasCommonPermission()) {
350 CM_LOG_E("permission check failed");
351 return CMR_ERROR_PERMISSION_DENIED;
352 }
353
354 if (!CmIsSystemApp()) {
355 CM_LOG_E("get app cert list: caller is not system app");
356 return CMR_ERROR_NOT_SYSTEMP_APP;
357 }
358
359 return CM_SUCCESS;
360 }
361
CmServiceGetCallingAppCertListCheck(const struct CmContext * cmContext,const uint32_t store)362 int32_t CmServiceGetCallingAppCertListCheck(const struct CmContext *cmContext, const uint32_t store)
363 {
364 if (CM_STORE_CHECK(store)) {
365 CM_LOG_E("invalid input arguments store:%u", store);
366 return CMR_ERROR_INVALID_ARGUMENT;
367 }
368
369 if (store == CM_SYS_CREDENTIAL_STORE) {
370 return CmGetSysAppCertListCheck(cmContext, store);
371 }
372
373 if (!CmHasCommonPermission()) {
374 CM_LOG_E("permission check failed");
375 return CMR_ERROR_PERMISSION_DENIED;
376 }
377
378 if (store == CM_PRI_CREDENTIAL_STORE) {
379 return CM_SUCCESS;
380 }
381
382 if (!CmHasPrivilegedPermission()) {
383 CM_LOG_E("permission check failed");
384 return CMR_ERROR_PERMISSION_DENIED;
385 }
386
387 if (!CmIsSystemApp()) {
388 CM_LOG_E("get app cert list: caller is not system app");
389 return CMR_ERROR_NOT_SYSTEMP_APP;
390 }
391
392 return CM_SUCCESS;
393 }
394
CmServiceGetAppCertCheck(struct CmContext * cmContext,const uint32_t store,const struct CmBlob * keyUri)395 int32_t CmServiceGetAppCertCheck(struct CmContext *cmContext, const uint32_t store, const struct CmBlob *keyUri)
396 {
397 if (CM_STORE_CHECK(store)) {
398 CM_LOG_E("invalid input arguments store:%u", store);
399 return CMR_ERROR_INVALID_ARGUMENT;
400 }
401
402 if (CheckUri(keyUri) != CM_SUCCESS) {
403 CM_LOG_E("invalid input arguments");
404 return CMR_ERROR_INVALID_ARGUMENT;
405 }
406
407 if (!CmHasCommonPermission()) {
408 CM_LOG_E("permission check failed");
409 return CMR_ERROR_PERMISSION_DENIED;
410 }
411
412 if (store == CM_SYS_CREDENTIAL_STORE) {
413 int32_t ret = checkCallerAndUri(cmContext, keyUri, CM_URI_TYPE_SYS_KEY, false);
414 if (ret != CM_SUCCESS) {
415 CM_LOG_E("get type and userid from uri error");
416 return ret;
417 }
418
419 if (!CmHasSystemAppPermission()) {
420 CM_LOG_E("sys ca store check failed");
421 return CMR_ERROR_PERMISSION_DENIED;
422 }
423 if (!CmIsSystemApp()) {
424 CM_LOG_E("GetAppCertCheck: caller is not system app");
425 return CMR_ERROR_NOT_SYSTEMP_APP;
426 }
427 }
428
429 return CM_SUCCESS;
430 }
431
CmCheckAndUpdateCallerUserId(const uint32_t inputUserId,uint32_t * callerUserId)432 static bool CmCheckAndUpdateCallerUserId(const uint32_t inputUserId, uint32_t *callerUserId)
433 {
434 if (*callerUserId == 0) { /* caller is sa */
435 if (inputUserId == INIT_INVALID_VALUE) {
436 CM_LOG_D("caller is sa");
437 return true;
438 }
439 CM_LOG_D("sa designates the userid: update caller userId from %u to %u", *callerUserId, inputUserId);
440 *callerUserId = inputUserId;
441 return true;
442 }
443
444 /* caller is hap, callerUserId is not 0 */
445 if (inputUserId != INIT_INVALID_VALUE) {
446 CM_LOG_E("caller is hap, input userId %u is not supported", inputUserId);
447 return false;
448 }
449 return true;
450 }
451
CmServiceInstallUserCertCheck(struct CmContext * cmContext,const struct CmBlob * userCert,const struct CmBlob * certAlias,const uint32_t userId)452 int32_t CmServiceInstallUserCertCheck(struct CmContext *cmContext, const struct CmBlob *userCert,
453 const struct CmBlob *certAlias, const uint32_t userId)
454 {
455 if (cmContext == NULL) {
456 CM_LOG_E("CmServiceInstallUserCertCheck: context is null");
457 return CMR_ERROR_INVALID_ARGUMENT;
458 }
459
460 if ((CmCheckBlob(userCert) != CM_SUCCESS) || userCert->size > MAX_LEN_CERTIFICATE) {
461 CM_LOG_E("input params userCert is invalid");
462 return CMR_ERROR_INVALID_ARGUMENT;
463 }
464
465 int32_t ret = CmCheckCertAlias(certAlias, CM_USER_TRUSTED_STORE);
466 if (ret != CM_SUCCESS) {
467 return ret;
468 }
469
470 if (!CmHasCommonPermission() || !CmHasUserTrustedPermission()) {
471 CM_LOG_E("install user cert: caller no permission");
472 return CMR_ERROR_PERMISSION_DENIED;
473 }
474
475 if (!CmIsSystemApp()) {
476 CM_LOG_E("install user cert: caller is not system app");
477 return CMR_ERROR_NOT_SYSTEMP_APP;
478 }
479
480 if (!CmCheckAndUpdateCallerUserId(userId, &(cmContext->userId))) {
481 CM_LOG_E("input userId is invalid");
482 return CMR_ERROR_INVALID_ARGUMENT;
483 }
484 return CM_SUCCESS;
485 }
486
CmServiceUninstallUserCertCheck(struct CmContext * cmContext,const struct CmBlob * certUri)487 int32_t CmServiceUninstallUserCertCheck(struct CmContext *cmContext, const struct CmBlob *certUri)
488 {
489 if (cmContext == NULL) {
490 CM_LOG_E("CmServiceUninstallUserCertCheck: context is null");
491 return CMR_ERROR_INVALID_ARGUMENT;
492 }
493
494 if (CmCheckBlob(certUri) != CM_SUCCESS || CheckUri(certUri) != CM_SUCCESS) {
495 CM_LOG_E("certUri is invalid");
496 return CMR_ERROR_INVALID_ARGUMENT;
497 }
498
499 if (!CmHasCommonPermission() || !CmHasUserTrustedPermission()) {
500 CM_LOG_E("uninstall user cert: caller no permission");
501 return CMR_ERROR_PERMISSION_DENIED;
502 }
503
504 if (!CmIsSystemApp()) {
505 CM_LOG_E("uninstall user cert: caller is not system app");
506 return CMR_ERROR_NOT_SYSTEMP_APP;
507 }
508
509 int32_t ret = checkCallerAndUri(cmContext, certUri, CM_URI_TYPE_CERTIFICATE, true);
510 if (ret != CM_SUCCESS) {
511 CM_LOG_E("uninstall user cert: caller and uri check fail");
512 return ret;
513 }
514 return CM_SUCCESS;
515 }
516