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 "group_auth_data_operation.h"
17 #include "common_defs.h"
18 #include "device_auth.h"
19 #include "device_auth_defines.h"
20 #include "hc_dev_info.h"
21 #include "hc_log.h"
22 #include "hc_string.h"
23 #include "hc_types.h"
24 #include "hc_vector.h"
25 
GaDeepCopyDeviceEntry(const TrustedDeviceEntry * entry,TrustedDeviceEntry * returnEntry)26 static bool GaDeepCopyDeviceEntry(const TrustedDeviceEntry *entry, TrustedDeviceEntry *returnEntry)
27 {
28     returnEntry->groupEntry = NULL;
29     if (!StringSet(&returnEntry->groupId, entry->groupId)) {
30         LOGE("[GA]: Failed to copy udid!");
31         return false;
32     }
33     if (!StringSet(&returnEntry->udid, entry->udid)) {
34         LOGE("[GA]: Failed to copy udid!");
35         return false;
36     }
37     if (!StringSet(&returnEntry->authId, entry->authId)) {
38         LOGE("[GA]: Failed to copy authId!");
39         return false;
40     }
41     if (!StringSet(&returnEntry->serviceType, entry->serviceType)) {
42         LOGE("[GA]: Failed to copy serviceType!");
43         return false;
44     }
45     if (!StringSet(&returnEntry->userId, entry->userId)) {
46         LOGE("[GA]: Failed to copy userId!");
47         return false;
48     }
49     returnEntry->credential = entry->credential;
50     returnEntry->devType = entry->devType;
51     returnEntry->lastTm = entry->lastTm;
52     returnEntry->source = entry->source;
53     returnEntry->upgradeFlag = entry->upgradeFlag;
54     return true;
55 }
56 
GaDeepCopyGroupEntry(const TrustedGroupEntry * entry,TrustedGroupEntry * returnEntry)57 static bool GaDeepCopyGroupEntry(const TrustedGroupEntry *entry, TrustedGroupEntry *returnEntry)
58 {
59     if (HC_VECTOR_SIZE(&entry->managers) <= 0) {
60         LOGE("[GA]: The group owner is lost!");
61         return false;
62     }
63     HcString entryOwner = HC_VECTOR_GET(&entry->managers, 0);
64     if (!StringSet(&returnEntry->name, entry->name)) {
65         LOGE("[GA]: Failed to copy groupName!");
66         return false;
67     }
68     if (!StringSet(&returnEntry->id, entry->id)) {
69         LOGE("[GA]: Failed to copy groupId!");
70         return false;
71     }
72     if (!StringSet(&returnEntry->userId, entry->userId)) {
73         LOGE("[GA]: Failed to copy userId!");
74         return false;
75     }
76     returnEntry->type = entry->type;
77     returnEntry->visibility = entry->visibility;
78     returnEntry->expireTime = entry->expireTime;
79     HcString ownerName = CreateString();
80     if (!StringSet(&ownerName, entryOwner)) {
81         LOGE("[GA]: Failed to copy groupOwner!");
82         DeleteString(&ownerName);
83         return false;
84     }
85     if (returnEntry->managers.pushBack(&returnEntry->managers, &ownerName) == NULL) {
86         LOGE("[GA]: Failed to push groupOwner to managers!");
87         DeleteString(&ownerName);
88         return false;
89     }
90     return true;
91 }
92 
GetGroupEntryById(int32_t osAccountId,const char * groupId,TrustedGroupEntry * returnEntry)93 static int32_t GetGroupEntryById(int32_t osAccountId, const char *groupId, TrustedGroupEntry *returnEntry)
94 {
95     uint32_t groupIndex;
96     TrustedGroupEntry **entry = NULL;
97     GroupEntryVec groupEntryVec = CreateGroupEntryVec();
98     QueryGroupParams groupParams = InitQueryGroupParams();
99     groupParams.groupId = groupId;
100     if (QueryGroups(osAccountId, &groupParams, &groupEntryVec) != HC_SUCCESS) {
101         LOGE("query groups failed!");
102         ClearGroupEntryVec(&groupEntryVec);
103         return HC_ERR_GROUP_NOT_EXIST;
104     }
105     FOR_EACH_HC_VECTOR(groupEntryVec, groupIndex, entry) {
106         if (!GaDeepCopyGroupEntry(*entry, returnEntry)) {
107             ClearGroupEntryVec(&groupEntryVec);
108             return HC_ERR_GROUP_NOT_EXIST;
109         }
110         ClearGroupEntryVec(&groupEntryVec);
111         return HC_SUCCESS;
112     }
113     ClearGroupEntryVec(&groupEntryVec);
114     return HC_ERR_GROUP_NOT_EXIST;
115 }
116 
GaIsGroupAccessible(int32_t osAccountId,const char * groupId,const char * appId)117 bool GaIsGroupAccessible(int32_t osAccountId, const char *groupId, const char *appId)
118 {
119     if ((groupId == NULL) || (appId == NULL)) {
120         LOGE("The input groupId or appId is NULL!");
121         return false;
122     }
123     TrustedGroupEntry *entry = CreateGroupEntry();
124     if (entry == NULL) {
125         LOGE("Failed to create group entry!");
126         return false;
127     }
128     int32_t res = GetGroupEntryById(osAccountId, groupId, entry);
129     if (res != HC_SUCCESS) {
130         LOGE("Failed to get group entry by groupId!");
131         DestroyGroupEntry(entry);
132         return false;
133     }
134     DestroyGroupEntry(entry);
135     return true;
136 }
137 
GaGetTrustedDeviceEntryById(int32_t osAccountId,const char * deviceId,bool isUdid,const char * groupId,TrustedDeviceEntry * returnDeviceEntry)138 int32_t GaGetTrustedDeviceEntryById(int32_t osAccountId, const char *deviceId,
139     bool isUdid, const char *groupId, TrustedDeviceEntry *returnDeviceEntry)
140 {
141     if (returnDeviceEntry == NULL) {
142         LOGE("The input returnEntry is NULL!");
143         return HC_ERR_INVALID_PARAMS;
144     }
145     uint32_t index;
146     TrustedDeviceEntry **deviceEntry = NULL;
147     DeviceEntryVec deviceEntryVec = CREATE_HC_VECTOR(DeviceEntryVec);
148     QueryDeviceParams params = InitQueryDeviceParams();
149     params.groupId = groupId;
150     if (isUdid) {
151         params.udid = deviceId;
152     } else {
153         params.authId = deviceId;
154     }
155     if (QueryDevices(osAccountId, &params, &deviceEntryVec) != HC_SUCCESS) {
156         LOGE("query trusted devices failed!");
157         ClearDeviceEntryVec(&deviceEntryVec);
158         return HC_ERR_DEVICE_NOT_EXIST;
159     }
160     FOR_EACH_HC_VECTOR(deviceEntryVec, index, deviceEntry) {
161         if (!GaDeepCopyDeviceEntry(*deviceEntry, returnDeviceEntry)) {
162             ClearDeviceEntryVec(&deviceEntryVec);
163             return HC_ERR_GROUP_NOT_EXIST;
164         }
165         ClearDeviceEntryVec(&deviceEntryVec);
166         return HC_SUCCESS;
167     }
168     ClearDeviceEntryVec(&deviceEntryVec);
169     return HC_ERR_DEVICE_NOT_EXIST;
170 }
171 
GaIsDeviceInGroup(int32_t groupType,int32_t osAccountId,const char * peerUdid,const char * peerAuthId,const char * groupId)172 bool GaIsDeviceInGroup(int32_t groupType, int32_t osAccountId, const char *peerUdid, const char *peerAuthId,
173     const char *groupId)
174 {
175     int32_t res;
176     int32_t authForm = GroupTypeToAuthForm(groupType);
177     if ((authForm == AUTH_FORM_ACROSS_ACCOUNT) || (authForm == AUTH_FORM_IDENTICAL_ACCOUNT)) {
178         LOGD("Auth for account related type.");
179         return true; /* Do not check  whether account related devices is in account. */
180     }
181     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
182     if (deviceEntry == NULL) {
183         LOGE("Failed to allocate memory for deviceEntry!");
184         return false;
185     }
186     if (peerUdid != NULL) {
187         res = GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, deviceEntry);
188     } else if (peerAuthId != NULL) {
189         res = GaGetTrustedDeviceEntryById(osAccountId, peerAuthId, false, groupId, deviceEntry);
190     } else {
191         LOGE("Both the input udid and authId is null!");
192         res = HC_ERROR;
193     }
194     DestroyDeviceEntry(deviceEntry);
195     if (res != HC_SUCCESS) {
196         return false;
197     }
198     return true;
199 }
200 
GaGetLocalDeviceInfo(int32_t osAccountId,const char * groupId,TrustedDeviceEntry * localAuthInfo)201 int32_t GaGetLocalDeviceInfo(int32_t osAccountId, const char *groupId, TrustedDeviceEntry *localAuthInfo)
202 {
203     char *localUdid = (char *)HcMalloc(INPUT_UDID_LEN, 0);
204     if (localUdid == NULL) {
205         LOGE("Failed to malloc for local udid!");
206         return HC_ERR_ALLOC_MEMORY;
207     }
208     int32_t res = HcGetUdid((uint8_t *)localUdid, INPUT_UDID_LEN);
209     if (res != HC_SUCCESS) {
210         LOGE("Failed to get local udid!");
211         HcFree(localUdid);
212         return res;
213     }
214     PRINT_SENSITIVE_DATA("SelfUdid", localUdid);
215     res = GaGetTrustedDeviceEntryById(osAccountId, localUdid, true, groupId, localAuthInfo);
216     HcFree(localUdid);
217     if (res != HC_SUCCESS) {
218         LOGE("Failed to get local device info from database!");
219     }
220     return res;
221 }
222 
AuthFormToGroupType(int32_t authForm)223 int32_t AuthFormToGroupType(int32_t authForm)
224 {
225     int32_t groupType;
226     switch (authForm) {
227         case AUTH_FORM_ACCOUNT_UNRELATED:
228             groupType = PEER_TO_PEER_GROUP;
229             break;
230         case AUTH_FORM_IDENTICAL_ACCOUNT:
231             groupType = IDENTICAL_ACCOUNT_GROUP;
232             break;
233         case AUTH_FORM_ACROSS_ACCOUNT:
234             groupType = ACROSS_ACCOUNT_AUTHORIZE_GROUP;
235             break;
236         default:
237             LOGE("Invalid auth form!");
238             groupType = GROUP_TYPE_INVALID;
239             break;
240     }
241     return groupType;
242 }
243 
GroupTypeToAuthForm(int32_t groupType)244 int32_t GroupTypeToAuthForm(int32_t groupType)
245 {
246     int32_t authForm;
247     switch (groupType) {
248         case PEER_TO_PEER_GROUP:
249             authForm = AUTH_FORM_ACCOUNT_UNRELATED;
250             break;
251         case IDENTICAL_ACCOUNT_GROUP:
252             authForm = AUTH_FORM_IDENTICAL_ACCOUNT;
253             break;
254         case ACROSS_ACCOUNT_AUTHORIZE_GROUP:
255             authForm = AUTH_FORM_ACROSS_ACCOUNT;
256             break;
257         default:
258             LOGE("Invalid group type!");
259             authForm = AUTH_FORM_INVALID_TYPE;
260             break;
261     }
262     return authForm;
263 }
264