1 /*
2 * Copyright (C) 2023-2025 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 "creds_manager.h"
17 #include "asy_token_manager.h"
18 #include "cert_operation.h"
19 #include "pseudonym_manager.h"
20
21 #define FIELD_SP_CMDS "spCmds"
22
23 #include "hc_log.h"
24
IsDirectAuth(const CJson * context)25 static bool IsDirectAuth(const CJson *context)
26 {
27 bool isDirectAuth = false;
28 (void)GetBoolFromJson(context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
29 return isDirectAuth;
30 }
31
IsDeviceLevelAuth(const CJson * context)32 static bool IsDeviceLevelAuth(const CJson *context)
33 {
34 bool isDeviceLevel = false;
35 (void)GetBoolFromJson(context, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
36 return isDeviceLevel;
37 }
38
IsPinAuth(const CJson * context,const Uint8Buff * presharedUrl)39 static bool IsPinAuth(const CJson *context, const Uint8Buff *presharedUrl)
40 {
41 const char *pinCode = GetStringFromJson(context, FIELD_PIN_CODE);
42 if (pinCode != NULL) {
43 return true;
44 }
45
46 CJson *urlJson = CreateJsonFromString((const char *)presharedUrl->val);
47 if (urlJson == NULL) {
48 LOGE("Failed to create url json!");
49 return false;
50 }
51 int32_t keyType = 0;
52 if (GetIntFromJson(urlJson, PRESHARED_URL_KEY_TYPE, &keyType) != HC_SUCCESS) {
53 LOGE("Failed to get trust type!");
54 FreeJson(urlJson);
55 return false;
56 }
57
58 int32_t trustType = 0;
59 if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
60 LOGE("Failed to get trust type!");
61 FreeJson(urlJson);
62 return false;
63 }
64 FreeJson(urlJson);
65
66 return (keyType == KEY_TYPE_SYM) && (trustType == TRUST_TYPE_PIN);
67 }
68
getAuthIdentity(const CJson * in,const Uint8Buff * presharedUrl)69 static const AuthIdentity *getAuthIdentity(const CJson *in, const Uint8Buff *presharedUrl)
70 {
71 AuthIdentityType identityType = AUTH_IDENTITY_TYPE_INVALID;
72
73 if (IsPinAuth(in, presharedUrl)) {
74 identityType = AUTH_IDENTITY_TYPE_PIN;
75 } else {
76 if (IsDirectAuth(in)) {
77 identityType = AUTH_IDENTITY_TYPE_P2P;
78 } else {
79 bool isCredAuth = false;
80 (void)GetBoolFromJson(in, FIELD_IS_CRED_AUTH, &isCredAuth);
81 identityType = isCredAuth ? AUTH_IDENTITY_TYPE_CRED : AUTH_IDENTITY_TYPE_GROUP;
82 }
83 }
84 LOGD("AuthIdentityType: %" LOG_PUB "d", identityType);
85
86 if (identityType == AUTH_IDENTITY_TYPE_INVALID) {
87 LOGE("invalid AuthIdentityType !");
88 return NULL;
89 }
90 return GetAuthIdentityByType(identityType);
91 }
92
GetCredInfosByPeerIdentity(CJson * in,IdentityInfoVec * vec)93 int32_t GetCredInfosByPeerIdentity(CJson *in, IdentityInfoVec *vec)
94 {
95 if (in == NULL || vec == NULL) {
96 LOGE("Invalid input params!");
97 return HC_ERR_INVALID_PARAMS;
98 }
99 AuthIdentityType identityType = AUTH_IDENTITY_TYPE_INVALID;
100 const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
101 if (pinCode != NULL) {
102 identityType = AUTH_IDENTITY_TYPE_PIN;
103 } else {
104 if (IsDirectAuth(in)) {
105 identityType = AUTH_IDENTITY_TYPE_P2P;
106 } else {
107 bool isCredAuth = false;
108 (void)GetBoolFromJson(in, FIELD_IS_CRED_AUTH, &isCredAuth);
109 identityType = isCredAuth ? AUTH_IDENTITY_TYPE_CRED : AUTH_IDENTITY_TYPE_GROUP;
110 }
111 }
112 if (identityType == AUTH_IDENTITY_TYPE_INVALID) {
113 LOGE("invalid AuthIdentityType !");
114 return HC_ERR_INVALID_PARAMS;
115 }
116 LOGD("AuthIdentityType: %" LOG_PUB "d", identityType);
117 const AuthIdentity *authIdentity = GetAuthIdentityByType(identityType);
118 if (authIdentity == NULL) {
119 LOGI("getAuthIdentity failed.");
120 return HC_ERR_INVALID_PARAMS;
121 }
122 int32_t ret = authIdentity->getCredInfosByPeerIdentity(in, vec);
123 if (!IsDeviceLevelAuth(in) || identityType != AUTH_IDENTITY_TYPE_GROUP) {
124 return ret;
125 }
126 // Device level auth also need to try auth with the direct auth identityInfo
127 uint32_t identityCount = HC_VECTOR_SIZE(vec);
128 authIdentity = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_P2P);
129 if (authIdentity == NULL) {
130 LOGE("get p2p auth identity failed!");
131 return ret;
132 }
133 // Device level auth comes from old api: authDevice, it's context
134 // does not contain acquireType, so we need add it into context here.
135 if (AddIntToJson(in, FIELD_ACQURIED_TYPE, P2P_BIND) != HC_SUCCESS) {
136 LOGE("Device level auth, add acquire type to context failed!");
137 return ret;
138 }
139 int32_t res = authIdentity->getCredInfosByPeerIdentity(in, vec);
140 if (res != HC_SUCCESS && (identityCount > 0)) {
141 return HC_SUCCESS;
142 }
143 return res;
144 }
145
GetCredInfoByPeerUrl(const CJson * in,const Uint8Buff * presharedUrl,IdentityInfo ** returnInfo)146 int32_t GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)
147 {
148 if (in == NULL || presharedUrl == NULL || returnInfo == NULL) {
149 LOGE("Invalid input params!");
150 return HC_ERR_INVALID_PARAMS;
151 }
152
153 const AuthIdentity *authIdentity = getAuthIdentity(in, presharedUrl);
154 if (!authIdentity) {
155 LOGI("getAuthIdentity failed.");
156 return HC_ERR_INVALID_PARAMS;
157 }
158
159 return authIdentity->getCredInfoByPeerUrl(in, presharedUrl, returnInfo);
160 }
161
GetSharedSecretByUrl(const CJson * in,const Uint8Buff * presharedUrl,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)162 int32_t GetSharedSecretByUrl(
163 const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
164 {
165 if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
166 LOGE("Invalid input params!");
167 return HC_ERR_INVALID_PARAMS;
168 }
169
170 #ifdef DEV_AUTH_FUNC_TEST // Add for coverage test
171 const AuthIdentity *authIdentityTest = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_P2P);
172 if (authIdentityTest == NULL) {
173 return HC_ERR_INVALID_PARAMS;
174 }
175 authIdentityTest->getSharedSecretByUrl(in, presharedUrl, protocolType, sharedSecret);
176
177 authIdentityTest = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_PIN);
178 if (authIdentityTest == NULL) {
179 return HC_ERR_INVALID_PARAMS;
180 }
181 authIdentityTest->getSharedSecretByUrl(in, presharedUrl, protocolType, sharedSecret);
182 #endif
183
184 const AuthIdentity *authIdentity = getAuthIdentity(in, presharedUrl);
185 if (!authIdentity) {
186 LOGI("getAuthIdentity failed.");
187 return HC_ERR_INVALID_PARAMS;
188 }
189
190 return authIdentity->getSharedSecretByUrl(in, presharedUrl, protocolType, sharedSecret);
191 }
192
GetCredInfoByPeerCert(const CJson * in,const CertInfo * certInfo,IdentityInfo ** returnInfo)193 int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
194 {
195 if (in == NULL || certInfo == NULL || returnInfo == NULL) {
196 LOGE("Invalid input params!");
197 return HC_ERR_INVALID_PARAMS;
198 }
199
200 #ifdef DEV_AUTH_FUNC_TEST // Add for coverage test
201 const AuthIdentity *authIdentityTest = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_P2P);
202 if (authIdentityTest == NULL) {
203 return HC_ERR_INVALID_PARAMS;
204 }
205 authIdentityTest->getCredInfoByPeerCert(in, certInfo, returnInfo);
206
207 authIdentityTest = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_PIN);
208 if (authIdentityTest == NULL) {
209 return HC_ERR_INVALID_PARAMS;
210 }
211 authIdentityTest->getCredInfoByPeerCert(in, certInfo, returnInfo);
212 #endif
213
214 bool isCredAuth = false;
215 (void)GetBoolFromJson(in, FIELD_IS_CRED_AUTH, &isCredAuth);
216 AuthIdentityType identityType = isCredAuth ? AUTH_IDENTITY_TYPE_CRED : AUTH_IDENTITY_TYPE_GROUP;
217 const AuthIdentity *authIdentity = GetAuthIdentityByType(identityType);
218 if (authIdentity == NULL) {
219 return HC_ERR_INVALID_PARAMS;
220 }
221 return authIdentity->getCredInfoByPeerCert(in, certInfo, returnInfo);
222 }
223
GetSharedSecretByPeerCert(const CJson * in,const CertInfo * peerCertInfo,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)224 int32_t GetSharedSecretByPeerCert(
225 const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
226 {
227 if (in == NULL || peerCertInfo == NULL || sharedSecret == NULL) {
228 LOGE("Invalid input params!");
229 return HC_ERR_INVALID_PARAMS;
230 }
231
232 #ifdef DEV_AUTH_FUNC_TEST // Add for coverage test
233 const AuthIdentity *authIdentityTest = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_P2P);
234 if (authIdentityTest == NULL) {
235 return HC_ERR_INVALID_PARAMS;
236 }
237 authIdentityTest->getSharedSecretByPeerCert(in, peerCertInfo, protocolType, sharedSecret);
238
239 authIdentityTest = GetAuthIdentityByType(AUTH_IDENTITY_TYPE_PIN);
240 if (authIdentityTest == NULL) {
241 return HC_ERR_INVALID_PARAMS;
242 }
243 authIdentityTest->getSharedSecretByPeerCert(in, peerCertInfo, protocolType, sharedSecret);
244 #endif
245
246 bool isCredAuth = false;
247 (void)GetBoolFromJson(in, FIELD_IS_CRED_AUTH, &isCredAuth);
248 AuthIdentityType identityType = isCredAuth ? AUTH_IDENTITY_TYPE_CRED : AUTH_IDENTITY_TYPE_GROUP;
249 const AuthIdentity *authIdentity = GetAuthIdentityByType(identityType);
250 if (authIdentity == NULL) {
251 return HC_ERR_INVALID_PARAMS;
252 }
253 return authIdentity->getSharedSecretByPeerCert(in, peerCertInfo, protocolType, sharedSecret);
254 }