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 "group_auth_data_operation.h"
17#include "hc_dev_info.h"
18#include "hc_log.h"
19#include "hc_vector.h"
20#include "identity_manager.h"
21
22static void UpperToLowercase(Uint8Buff *hex)
23{
24    for (uint32_t i = 0; i < hex->length; i++) {
25        if (hex->val[i] >= 'A' && hex->val[i] <= 'F') {
26            hex->val[i] += ASCII_CASE_DIFFERENCE_VALUE;
27        }
28    }
29}
30
31int32_t ConvertPsk(const Uint8Buff *srcPsk, Uint8Buff *sharedSecret)
32{
33    uint32_t len = PAKE_PSK_LEN * BYTE_TO_HEX_OPER_LENGTH;
34    sharedSecret->val = (uint8_t *)HcMalloc(len + 1, 0);
35    if (sharedSecret->val == NULL) {
36        LOGE("Failed to alloc memory for sharedSecret!");
37        return HC_ERR_ALLOC_MEMORY;
38    }
39
40    if (ByteToHexString(srcPsk->val, srcPsk->length, (char *)sharedSecret->val, len + 1) != HC_SUCCESS) {
41        LOGE("Convert psk from byte to hex string failed!");
42        HcFree(sharedSecret->val);
43        return HC_ERR_CONVERT_FAILED;
44    }
45    sharedSecret->length = len;
46    (void)UpperToLowercase(sharedSecret);
47    return HC_SUCCESS;
48}
49
50int32_t SetPreSharedUrlForProof(const char *urlStr, Uint8Buff *preSharedUrl)
51{
52    uint32_t urlLen = HcStrlen(urlStr);
53    preSharedUrl->val = (uint8_t *)HcMalloc(urlLen + 1, 0);
54    if (preSharedUrl->val == NULL) {
55        LOGE("Failed to alloc preSharedUrl memory!");
56        return HC_ERR_ALLOC_MEMORY;
57    }
58    if (memcpy_s(preSharedUrl->val, urlLen + 1, urlStr, urlLen) != EOK) {
59        LOGE("Failed to copy url string to preSharedUrl");
60        HcFree(preSharedUrl->val);
61        preSharedUrl->val = NULL;
62        return HC_ERR_MEMORY_COPY;
63    }
64    preSharedUrl->length = urlLen + 1;
65    return HC_SUCCESS;
66}
67
68CJson *CreateCredUrlJson(int32_t credentailType, int32_t keyType, int32_t trustType)
69{
70    CJson *urlJson = CreateJson();
71    if (urlJson == NULL) {
72        LOGE("Failed to create url json!");
73        return NULL;
74    }
75    if (AddIntToJson(urlJson, PRESHARED_URL_CREDENTIAL_TYPE, credentailType) != HC_SUCCESS) {
76        LOGE("Failed to add credential type!");
77        FreeJson(urlJson);
78        return NULL;
79    }
80    if (AddIntToJson(urlJson, PRESHARED_URL_KEY_TYPE, keyType) != HC_SUCCESS) {
81        LOGE("Failed to add key type!");
82        FreeJson(urlJson);
83        return NULL;
84    }
85    if (AddIntToJson(urlJson, PRESHARED_URL_TRUST_TYPE, trustType) != HC_SUCCESS) {
86        LOGE("Failed to add trust type!");
87        FreeJson(urlJson);
88        return NULL;
89    }
90
91    return urlJson;
92}
93
94#if 1
95
96IMPLEMENT_HC_VECTOR(ProtocolEntityVec, ProtocolEntity *, 1)
97IMPLEMENT_HC_VECTOR(IdentityInfoVec, IdentityInfo *, 1)
98
99int32_t GetSelfDeviceEntry(int32_t osAccountId, const char *groupId, TrustedDeviceEntry *deviceEntry)
100{
101    char selfUdid[INPUT_UDID_LEN] = { 0 };
102    int32_t ret = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
103    if (ret != HC_SUCCESS) {
104        LOGE("Failed to get local udid!");
105        return ret;
106    }
107    return GaGetTrustedDeviceEntryById(osAccountId, selfUdid, true, groupId, deviceEntry);
108}
109
110const char *GetPeerDevIdFromJson(const CJson *in, bool *isUdid)
111{
112    const char *deviceId = GetStringFromJson(in, FIELD_PEER_UDID);
113    if (deviceId != NULL) {
114        *isUdid = true;
115        return deviceId;
116    }
117    return GetStringFromJson(in, FIELD_PEER_AUTH_ID);
118}
119
120int32_t GetPeerDeviceEntry(
121    int32_t osAccountId, const CJson *in, const char *groupId, TrustedDeviceEntry *returnDeviceEntry)
122{
123    bool isUdid = false;
124    const char *peerDeviceId = GetPeerDevIdFromJson(in, &isUdid);
125    if (peerDeviceId == NULL) {
126        LOGE("Failed to get peer deviceId!");
127        return HC_ERR_JSON_GET;
128    }
129    return GaGetTrustedDeviceEntryById(osAccountId, peerDeviceId, isUdid, groupId, returnDeviceEntry);
130}
131
132void FreeBuffData(Uint8Buff *buff)
133{
134    if (buff == NULL) {
135        return;
136    }
137    HcFree(buff->val);
138    buff->val = NULL;
139    buff->length = 0;
140}
141
142IdentityInfo *CreateIdentityInfo(void)
143{
144    IdentityInfo *info = (IdentityInfo *)HcMalloc(sizeof(IdentityInfo), 0);
145    if (info == NULL) {
146        LOGE("Failed to alloc memory for identity info!");
147        return NULL;
148    }
149    info->protocolVec = CreateProtocolEntityVec();
150    return info;
151}
152
153void DestroyIdentityInfo(IdentityInfo *info)
154{
155    if (info == NULL) {
156        return;
157    }
158
159    FreeBuffData(&info->proof.preSharedUrl);
160    FreeBuffData(&info->proof.certInfo.pkInfoStr);
161    FreeBuffData(&info->proof.certInfo.pkInfoSignature);
162    ClearProtocolEntityVec(&info->protocolVec);
163
164    HcFree(info);
165}
166
167void ClearIdentityInfoVec(IdentityInfoVec *vec)
168{
169    uint32_t index;
170    IdentityInfo **info;
171    FOR_EACH_HC_VECTOR(*vec, index, info)
172    {
173        DestroyIdentityInfo(*info);
174    }
175    DESTROY_HC_VECTOR(IdentityInfoVec, vec);
176}
177
178void ClearProtocolEntityVec(ProtocolEntityVec *vec)
179{
180    uint32_t index;
181    ProtocolEntity **entity;
182    FOR_EACH_HC_VECTOR(*vec, index, entity)
183    {
184        HcFree(*entity);
185    }
186    DESTROY_HC_VECTOR(ProtocolEntityVec, vec);
187}
188
189#endif