• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "dslm_msg_utils.h"
17 
18 #include <securec.h>
19 #include <string.h>
20 
21 #include "utils_base64.h"
22 #include "utils_hexstring.h"
23 #include "utils_json.h"
24 #include "utils_log.h"
25 #include "utils_mem.h"
26 
27 #include "device_security_defines.h"
28 #include "dslm_core_defines.h"
29 #include "dslm_credential.h"
30 
31 #define CHALLENGE_STRING_LENGTH 32
32 
GenerateSecInfoResponseJson(uint64_t challenge,const DslmCredBuff * cred)33 static uint8_t *GenerateSecInfoResponseJson(uint64_t challenge, const DslmCredBuff *cred)
34 {
35     uint8_t *credBase64Str = NULL;
36     uint8_t *out = NULL;
37 
38     JsonHandle head = CreateJson(NULL);
39     if (head == NULL) {
40         return NULL;
41     }
42 
43     JsonHandle body = CreateJson(NULL);
44     if (body == NULL) {
45         DestroyJson(head);
46         return NULL;
47     }
48 
49     AddFieldIntToJson(head, FIELD_MESSAGE, MSG_TYPE_DSLM_CRED_RESPONSE);
50     AddFieldJsonToJson(head, FIELD_PAYLOAD, body);
51 
52     AddFieldIntToJson(body, FIELD_VERSION, GetCurrentVersion());
53     AddFieldIntToJson(body, FIELD_CRED_TYPE, cred->type);
54 
55     char challengeStr[CHALLENGE_STRING_LENGTH] = {0};
56     char *nonce = &challengeStr[0];
57     ByteToHexString((uint8_t *)&challenge, sizeof(challenge), (uint8_t *)nonce, CHALLENGE_STRING_LENGTH);
58     challengeStr[CHALLENGE_STRING_LENGTH - 1] = 0;
59     AddFieldStringToJson(body, FIELD_CHALLENGE, nonce);
60 
61     credBase64Str = Base64EncodeApp(cred->credVal, cred->credLen);
62     // it is ok when credBase64Str is NULL
63     AddFieldStringToJson(body, FIELD_CRED_INFO, (char *)credBase64Str);
64     out = (uint8_t *)ConvertJsonToString(head);
65 
66     if (head != NULL) {
67         DestroyJson(head);
68         body = NULL; // no need to free body
69     }
70 
71     if (body != NULL) {
72         DestroyJson(body);
73     }
74     if (credBase64Str != NULL) {
75         FREE(credBase64Str);
76     }
77     return out;
78 }
79 
GenerateSecInfoRequestJson(uint64_t challenge)80 static uint8_t *GenerateSecInfoRequestJson(uint64_t challenge)
81 {
82     JsonHandle head = CreateJson(NULL);
83     if (head == NULL) {
84         return NULL;
85     }
86     JsonHandle body = CreateJson(NULL);
87     if (body == NULL) {
88         DestroyJson(head);
89         return NULL;
90     }
91 
92     char challengeStr[CHALLENGE_STRING_LENGTH] = {0};
93     char *nonce = &challengeStr[0];
94     ByteToHexString((uint8_t *)&challenge, sizeof(challenge), (uint8_t *)nonce, CHALLENGE_STRING_LENGTH);
95     challengeStr[CHALLENGE_STRING_LENGTH - 1] = 0;
96 
97     AddFieldIntToJson(head, FIELD_MESSAGE, MSG_TYPE_DSLM_CRED_REQUEST);
98     AddFieldJsonToJson(head, FIELD_PAYLOAD, body);
99     AddFieldIntToJson(body, FIELD_VERSION, GetCurrentVersion());
100 
101     AddFieldStringToJson(body, FIELD_CHALLENGE, nonce);
102 
103     CredType credTypeArray[MAX_CRED_ARRAY_SIZE] = {0};
104     int32_t arraySize = GetSupportedCredTypes(credTypeArray, MAX_CRED_ARRAY_SIZE);
105     AddFieldIntArrayToJson(body, FIELD_SUPPORT, (const int32_t *)credTypeArray, arraySize);
106 
107     uint8_t *out = (uint8_t *)ConvertJsonToString(head);
108 
109     if (head != NULL) {
110         DestroyJson(head);
111         body = NULL; // no need to free body
112     }
113 
114     if (body != NULL) {
115         DestroyJson(body);
116     }
117     return out;
118 }
119 
BuildDeviceSecInfoRequest(uint64_t challenge,MessageBuff ** msg)120 int32_t BuildDeviceSecInfoRequest(uint64_t challenge, MessageBuff **msg)
121 {
122     if ((msg == NULL) || (*msg != NULL)) {
123         return ERR_INVALID_PARA;
124     }
125 
126     MessageBuff *out = MALLOC(sizeof(MessageBuff));
127     if (out == NULL) {
128         return ERR_NO_MEMORY;
129     }
130     memset_s(out, sizeof(MessageBuff), 0, sizeof(MessageBuff));
131 
132     out->buff = GenerateSecInfoRequestJson(challenge);
133     if (out->buff == NULL) {
134         FREE(out);
135         return ERR_JSON_ERR;
136     }
137     out->length = strlen((char *)out->buff) + 1;
138     *msg = out;
139     return SUCCESS;
140 }
141 
ParseDeviceSecInfoRequest(const MessageBuff * buff,RequestObject * obj)142 int32_t ParseDeviceSecInfoRequest(const MessageBuff *buff, RequestObject *obj)
143 {
144     if (buff == NULL || obj == NULL || buff->buff == NULL) {
145         return ERR_INVALID_PARA;
146     }
147     SECURITY_LOG_DEBUG("ParseDeviceSecInfoRequest msg is %s", (char *)buff->buff);
148 
149     JsonHandle handle = CreateJson((const char *)buff->buff);
150     if (handle == NULL) {
151         return ERR_INVALID_PARA;
152     }
153 
154     const char *nonceStr = GetJsonFieldString(handle, FIELD_CHALLENGE);
155     if (nonceStr == NULL) {
156         DestroyJson(handle);
157         return ERR_NO_CHALLENGE;
158     }
159 
160     int32_t ret = HexStringToByte(nonceStr, strlen(nonceStr), (uint8_t *)&obj->challenge, sizeof(obj->challenge));
161     if (ret != 0) {
162         DestroyJson(handle);
163         return ERR_NO_CHALLENGE;
164     }
165 
166     obj->version = (uint32_t)GetJsonFieldInt(handle, FIELD_VERSION);
167     obj->arraySize = GetJsonFieldIntArray(handle, FIELD_SUPPORT, (int32_t *)obj->credArray, MAX_CRED_ARRAY_SIZE);
168 
169     DestroyJson(handle);
170 
171     return SUCCESS;
172 }
173 
BuildDeviceSecInfoResponse(uint64_t challenge,const DslmCredBuff * cred,MessageBuff ** msg)174 int32_t BuildDeviceSecInfoResponse(uint64_t challenge, const DslmCredBuff *cred, MessageBuff **msg)
175 {
176     if ((cred == NULL) || (msg == NULL) || (*msg != NULL)) {
177         return ERR_INVALID_PARA;
178     }
179     MessageBuff *out = MALLOC(sizeof(MessageBuff));
180     if (out == NULL) {
181         return ERR_NO_MEMORY;
182     }
183 
184     out->buff = (uint8_t *)GenerateSecInfoResponseJson(challenge, cred);
185     if (out->buff == NULL) {
186         FREE(out);
187         return ERR_JSON_ERR;
188     }
189     out->length = strlen((char *)out->buff) + 1;
190 
191     *msg = out;
192     return SUCCESS;
193 }
194 
ParseDeviceSecInfoResponse(const MessageBuff * msg,uint64_t * challenge,uint32_t * version,DslmCredBuff ** cred)195 int32_t ParseDeviceSecInfoResponse(const MessageBuff *msg, uint64_t *challenge, uint32_t *version, DslmCredBuff **cred)
196 {
197     if (msg == NULL || challenge == NULL || version == NULL || cred == NULL) {
198         return ERR_INVALID_PARA;
199     }
200 
201     if (msg->buff == NULL || *cred != NULL) {
202         return ERR_INVALID_PARA;
203     }
204 
205     JsonHandle handle = CreateJson((const char *)msg->buff);
206     if (handle == NULL) {
207         return ERR_INVALID_PARA;
208     }
209 
210     const char *nonceStr = GetJsonFieldString(handle, FIELD_CHALLENGE);
211     if (nonceStr == NULL) {
212         DestroyJson(handle);
213         return ERR_NO_CHALLENGE;
214     }
215     uint64_t nonceNum = 0;
216     int32_t ret = HexStringToByte(nonceStr, strlen(nonceStr), (uint8_t *)&nonceNum, sizeof(uint64_t));
217     if (ret != 0) {
218         DestroyJson(handle);
219         return ERR_NO_CHALLENGE;
220     }
221 
222     uint32_t type = (uint32_t)GetJsonFieldInt(handle, FIELD_CRED_TYPE);
223     uint32_t verNum = (uint32_t)GetJsonFieldInt(handle, FIELD_VERSION);
224 
225     const char *credStr = GetJsonFieldString(handle, FIELD_CRED_INFO);
226     if (credStr == NULL) {
227         DestroyJson(handle);
228         return ERR_NO_CRED;
229     }
230 
231     uint8_t *credBuf = NULL;
232     uint32_t credLen = (uint32_t)Base64DecodeApp((uint8_t *)credStr, &credBuf);
233     if (credBuf == NULL) {
234         DestroyJson(handle);
235         return ERR_NO_CRED;
236     }
237 
238     DslmCredBuff *out = CreateDslmCred((CredType)type, credLen, credBuf);
239     if (out == NULL) {
240         DestroyJson(handle);
241         FREE(credBuf);
242         return ERR_NO_MEMORY;
243     }
244 
245     DestroyJson(handle);
246     FREE(credBuf);
247     *version = verNum;
248     *challenge = nonceNum;
249     *cred = out;
250     return SUCCESS;
251 }
252