1 /*
2 * Copyright (c) 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_security_guard_info.h"
17
18 #include "cm_log.h"
19 #include "cm_mem.h"
20 #include "cm_security_guard_report.h"
21
22 #ifdef SUPPORT_SECURITY_GUARD
23 #define CM_INVALID_NAME "nameInvalid"
24 #define CM_DELETE_ALL_NAME "deleteAll"
25 #define CM_REPORT_MAX_NAME_LEN 256
26
IsNameValid(const struct CmBlob * name)27 static bool IsNameValid(const struct CmBlob *name)
28 {
29 if ((CmCheckBlob(name) != CM_SUCCESS) || (name->size >= CM_REPORT_MAX_NAME_LEN)) {
30 return false;
31 }
32
33 for (uint32_t i = 1; i < name->size; ++i) { /* from index 1 has '\0' */
34 if (name->data[i] == 0) {
35 return true;
36 }
37 }
38 return false;
39 }
40
41 #define ANONYMOUS_LEN 4
42
AnonymousName(char * name,uint32_t nameLen)43 static void AnonymousName(char *name, uint32_t nameLen)
44 {
45 char p = '*';
46 uint32_t offset = strlen("o=");
47 char *substr = strstr(name, "o=");
48 if (substr == NULL || strlen(substr) == offset) {
49 if (nameLen <= ANONYMOUS_LEN) {
50 (void)memset_s(name, nameLen, p, nameLen);
51 } else {
52 (void)memset_s(name + nameLen - ANONYMOUS_LEN, ANONYMOUS_LEN, p, ANONYMOUS_LEN);
53 }
54 return;
55 }
56
57 uint32_t substrLen = strlen(substr);
58 if (substrLen <= ANONYMOUS_LEN + offset) {
59 (void)memset_s(substr + offset, substrLen - offset, p, substrLen - offset);
60 } else {
61 (void)memset_s(substr + offset, ANONYMOUS_LEN, p, ANONYMOUS_LEN);
62 }
63 }
64
ConstructInfoName(const struct CmBlob * input,char ** name)65 static int32_t ConstructInfoName(const struct CmBlob *input, char **name)
66 {
67 bool isNameValid = IsNameValid(input);
68 uint32_t nameLen = isNameValid ? input->size : strlen(CM_INVALID_NAME) + 1;
69 *name = (char *)CmMalloc(nameLen);
70 if (*name == NULL) {
71 return CMR_ERROR_MALLOC_FAIL;
72 }
73 (void)memset_s(*name, nameLen, 0, nameLen); /* initialized to 0 to avoid that input does not end with '\0' */
74 (void)strcpy_s(*name, nameLen, isNameValid ? (char *)input->data : CM_INVALID_NAME);
75
76 if (isNameValid) {
77 AnonymousName(*name, nameLen - 1); /* nameLen is bigger than 1 and exclude end '\0' */
78 }
79 return CM_SUCCESS;
80 }
81
ConstructInfoAndReport(const struct CmBlob * input,const char * action,struct CmReportSGInfo * info)82 static void ConstructInfoAndReport(const struct CmBlob *input, const char *action, struct CmReportSGInfo *info)
83 {
84 if (strcpy_s(info->action, sizeof(info->action), action) != EOK) {
85 return;
86 }
87 if (ConstructInfoName(input, &info->name) != CM_SUCCESS) {
88 return;
89 }
90 CmReportSGRecord(info);
91 CM_FREE_PTR(info->name);
92 }
93 #endif
94
CmReportSGSetCertStatus(const struct CmBlob * certUri,uint32_t store,uint32_t status,int32_t result)95 void CmReportSGSetCertStatus(const struct CmBlob *certUri, uint32_t store, uint32_t status, int32_t result)
96 {
97 #ifdef SUPPORT_SECURITY_GUARD
98 struct CmReportSGInfo info;
99 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
100
101 info.result = result;
102 info.uid = CmGetCallingUid();
103 info.isSetGrantUid = false;
104 info.isSetStatus = true;
105 info.status = (status == 0) ? true : false; /* 0 indicates the certificate enabled status */
106
107 char *action = (store == CM_SYSTEM_TRUSTED_STORE) ? "CmSetSystemCertStatus" : "CmSetUserCertStatus";
108 ConstructInfoAndReport(certUri, action, &info);
109 #else
110 (void)certUri;
111 (void)store;
112 (void)status;
113 (void)result;
114 #endif
115 }
116
CmReportSGInstallUserCert(const struct CmBlob * certAlias,int32_t result)117 void CmReportSGInstallUserCert(const struct CmBlob *certAlias, int32_t result)
118 {
119 #ifdef SUPPORT_SECURITY_GUARD
120 struct CmReportSGInfo info;
121 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
122
123 info.result = result;
124 info.uid = CmGetCallingUid();
125 info.isSetGrantUid = false;
126 info.isSetStatus = false;
127
128 char *action = "CmInstallUserCert";
129 ConstructInfoAndReport(certAlias, action, &info);
130 #else
131 (void)certAlias;
132 (void)result;
133 #endif
134 }
135
CmReportSGUninstallUserCert(const struct CmBlob * certUri,bool isUninstallAll,int32_t result)136 void CmReportSGUninstallUserCert(const struct CmBlob *certUri, bool isUninstallAll, int32_t result)
137 {
138 #ifdef SUPPORT_SECURITY_GUARD
139 struct CmReportSGInfo info;
140 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
141
142 info.result = result;
143 info.uid = CmGetCallingUid();
144 info.isSetGrantUid = false;
145 info.isSetStatus = false;
146
147 if (isUninstallAll) {
148 if (strcpy_s(info.action, sizeof(info.action), "CmUninstallAllUserCert") != EOK) {
149 return;
150 }
151 info.name = CM_DELETE_ALL_NAME;
152 return CmReportSGRecord(&info);
153 }
154
155 char *action = "CmUninstallUserCert";
156 ConstructInfoAndReport(certUri, action, &info);
157 #else
158 (void)certUri;
159 (void)isUninstallAll;
160 (void)result;
161 #endif
162 }
163
CmReportSGInstallAppCert(const struct CmBlob * certAlias,uint32_t store,int32_t result)164 void CmReportSGInstallAppCert(const struct CmBlob *certAlias, uint32_t store, int32_t result)
165 {
166 #ifdef SUPPORT_SECURITY_GUARD
167 struct CmReportSGInfo info;
168 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
169
170 info.result = result;
171 info.uid = CmGetCallingUid();
172 info.isSetGrantUid = false;
173 info.isSetStatus = false;
174
175 char *action = (store == CM_CREDENTIAL_STORE) ? "CmInstallAppCert" : "CmInstallPriAppCert";
176 ConstructInfoAndReport(certAlias, action, &info);
177 #else
178 (void)certAlias;
179 (void)store;
180 (void)result;
181 #endif
182 }
183
CmReportSGUninstallAppCert(const struct CmBlob * keyUri,uint32_t store,bool isUninstallAll,int32_t result)184 void CmReportSGUninstallAppCert(const struct CmBlob *keyUri, uint32_t store, bool isUninstallAll, int32_t result)
185 {
186 #ifdef SUPPORT_SECURITY_GUARD
187 struct CmReportSGInfo info;
188 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
189
190 info.result = result;
191 info.uid = CmGetCallingUid();
192 info.isSetGrantUid = false;
193 info.isSetStatus = false;
194
195 if (isUninstallAll) {
196 if (strcpy_s(info.action, sizeof(info.action), "CmUninstallAllAppCert") != EOK) {
197 return;
198 }
199 info.name = CM_DELETE_ALL_NAME;
200 return CmReportSGRecord(&info);
201 }
202
203 char *action = (store == CM_CREDENTIAL_STORE) ? "CmUninstallAppCert" : "CmUninstallPriAppCert";
204 ConstructInfoAndReport(keyUri, action, &info);
205 #else
206 (void)keyUri;
207 (void)store;
208 (void)isUninstallAll;
209 (void)result;
210 #endif
211 }
212
CmReportSGGrantAppCert(const struct CmBlob * keyUri,uint32_t appUid,bool isRemove,int32_t result)213 void CmReportSGGrantAppCert(const struct CmBlob *keyUri, uint32_t appUid, bool isRemove, int32_t result)
214 {
215 #ifdef SUPPORT_SECURITY_GUARD
216 struct CmReportSGInfo info;
217 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
218
219 info.result = result;
220 info.uid = CmGetCallingUid();
221 info.isSetStatus = false;
222 info.isSetGrantUid = true;
223 info.grantUid = appUid;
224
225 char *action = isRemove ? "CmRemoveGrantedAppUid" : "CmGrantAppCert";
226 ConstructInfoAndReport(keyUri, action, &info);
227 #else
228 (void)keyUri;
229 (void)appUid;
230 (void)isRemove;
231 (void)result;
232 #endif
233 }
234