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