12ee81decSopenharmony_ci/* 22ee81decSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 32ee81decSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42ee81decSopenharmony_ci * you may not use this file except in compliance with the License. 52ee81decSopenharmony_ci * You may obtain a copy of the License at 62ee81decSopenharmony_ci * 72ee81decSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82ee81decSopenharmony_ci * 92ee81decSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102ee81decSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112ee81decSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122ee81decSopenharmony_ci * See the License for the specific language governing permissions and 132ee81decSopenharmony_ci * limitations under the License. 142ee81decSopenharmony_ci */ 152ee81decSopenharmony_ci 162ee81decSopenharmony_ci#include "dslm_msg_utils.h" 172ee81decSopenharmony_ci 182ee81decSopenharmony_ci#include <string.h> 192ee81decSopenharmony_ci 202ee81decSopenharmony_ci#include "securec.h" 212ee81decSopenharmony_ci 222ee81decSopenharmony_ci#include "device_security_defines.h" 232ee81decSopenharmony_ci#include "dslm_core_defines.h" 242ee81decSopenharmony_ci#include "dslm_credential.h" 252ee81decSopenharmony_ci#include "utils_base64.h" 262ee81decSopenharmony_ci#include "utils_hexstring.h" 272ee81decSopenharmony_ci#include "utils_json.h" 282ee81decSopenharmony_ci#include "utils_log.h" 292ee81decSopenharmony_ci#include "utils_mem.h" 302ee81decSopenharmony_ci 312ee81decSopenharmony_ci#define CHALLENGE_STRING_LENGTH 32 322ee81decSopenharmony_ci 332ee81decSopenharmony_cistatic uint8_t *GenerateSecInfoResponseJson(uint64_t challenge, const DslmCredBuff *cred) 342ee81decSopenharmony_ci{ 352ee81decSopenharmony_ci uint8_t *credBase64Str = NULL; 362ee81decSopenharmony_ci uint8_t *out = NULL; 372ee81decSopenharmony_ci 382ee81decSopenharmony_ci DslmJsonHandle head = DslmCreateJson(NULL); 392ee81decSopenharmony_ci if (head == NULL) { 402ee81decSopenharmony_ci return NULL; 412ee81decSopenharmony_ci } 422ee81decSopenharmony_ci 432ee81decSopenharmony_ci DslmJsonHandle body = DslmCreateJson(NULL); 442ee81decSopenharmony_ci if (body == NULL) { 452ee81decSopenharmony_ci DslmDestroyJson(head); 462ee81decSopenharmony_ci return NULL; 472ee81decSopenharmony_ci } 482ee81decSopenharmony_ci 492ee81decSopenharmony_ci DslmAddFieldIntToJson(head, FIELD_MESSAGE, MSG_TYPE_DSLM_CRED_RESPONSE); 502ee81decSopenharmony_ci DslmAddFieldJsonToJson(head, FIELD_PAYLOAD, body); 512ee81decSopenharmony_ci 522ee81decSopenharmony_ci DslmAddFieldIntToJson(body, FIELD_VERSION, (int32_t)GetCurrentVersion()); 532ee81decSopenharmony_ci DslmAddFieldIntToJson(body, FIELD_CRED_TYPE, cred->type); 542ee81decSopenharmony_ci 552ee81decSopenharmony_ci char challengeStr[CHALLENGE_STRING_LENGTH] = {0}; 562ee81decSopenharmony_ci char *nonce = &challengeStr[0]; 572ee81decSopenharmony_ci DslmByteToHexString((uint8_t *)&challenge, sizeof(challenge), (uint8_t *)nonce, CHALLENGE_STRING_LENGTH); 582ee81decSopenharmony_ci challengeStr[CHALLENGE_STRING_LENGTH - 1] = 0; 592ee81decSopenharmony_ci DslmAddFieldStringToJson(body, FIELD_CHALLENGE, nonce); 602ee81decSopenharmony_ci 612ee81decSopenharmony_ci credBase64Str = Base64EncodeApp(cred->credVal, cred->credLen); 622ee81decSopenharmony_ci // it is ok when credBase64Str is NULL 632ee81decSopenharmony_ci DslmAddFieldStringToJson(body, FIELD_CRED_INFO, (char *)credBase64Str); 642ee81decSopenharmony_ci out = (uint8_t *)DslmConvertJsonToString(head); 652ee81decSopenharmony_ci 662ee81decSopenharmony_ci if (head != NULL) { 672ee81decSopenharmony_ci DslmDestroyJson(head); 682ee81decSopenharmony_ci body = NULL; // no need to free body 692ee81decSopenharmony_ci } 702ee81decSopenharmony_ci 712ee81decSopenharmony_ci if (body != NULL) { 722ee81decSopenharmony_ci DslmDestroyJson(body); 732ee81decSopenharmony_ci } 742ee81decSopenharmony_ci if (credBase64Str != NULL) { 752ee81decSopenharmony_ci FREE(credBase64Str); 762ee81decSopenharmony_ci } 772ee81decSopenharmony_ci return out; 782ee81decSopenharmony_ci} 792ee81decSopenharmony_ci 802ee81decSopenharmony_cistatic uint8_t *GenerateSecInfoRequestJson(uint64_t challenge) 812ee81decSopenharmony_ci{ 822ee81decSopenharmony_ci DslmJsonHandle head = DslmCreateJson(NULL); 832ee81decSopenharmony_ci if (head == NULL) { 842ee81decSopenharmony_ci return NULL; 852ee81decSopenharmony_ci } 862ee81decSopenharmony_ci DslmJsonHandle body = DslmCreateJson(NULL); 872ee81decSopenharmony_ci if (body == NULL) { 882ee81decSopenharmony_ci DslmDestroyJson(head); 892ee81decSopenharmony_ci return NULL; 902ee81decSopenharmony_ci } 912ee81decSopenharmony_ci 922ee81decSopenharmony_ci char challengeStr[CHALLENGE_STRING_LENGTH] = {0}; 932ee81decSopenharmony_ci char *nonce = &challengeStr[0]; 942ee81decSopenharmony_ci DslmByteToHexString((uint8_t *)&challenge, sizeof(challenge), (uint8_t *)nonce, CHALLENGE_STRING_LENGTH); 952ee81decSopenharmony_ci challengeStr[CHALLENGE_STRING_LENGTH - 1] = 0; 962ee81decSopenharmony_ci 972ee81decSopenharmony_ci DslmAddFieldIntToJson(head, FIELD_MESSAGE, MSG_TYPE_DSLM_CRED_REQUEST); 982ee81decSopenharmony_ci DslmAddFieldJsonToJson(head, FIELD_PAYLOAD, body); 992ee81decSopenharmony_ci DslmAddFieldIntToJson(body, FIELD_VERSION, (int32_t)GetCurrentVersion()); 1002ee81decSopenharmony_ci 1012ee81decSopenharmony_ci DslmAddFieldStringToJson(body, FIELD_CHALLENGE, nonce); 1022ee81decSopenharmony_ci 1032ee81decSopenharmony_ci CredType credTypeArray[MAX_CRED_ARRAY_SIZE] = {0}; 1042ee81decSopenharmony_ci int32_t arraySize = GetSupportedCredTypes(credTypeArray, MAX_CRED_ARRAY_SIZE); 1052ee81decSopenharmony_ci DslmAddFieldIntArrayToJson(body, FIELD_SUPPORT, (const int32_t *)credTypeArray, arraySize); 1062ee81decSopenharmony_ci 1072ee81decSopenharmony_ci uint8_t *out = (uint8_t *)DslmConvertJsonToString(head); 1082ee81decSopenharmony_ci 1092ee81decSopenharmony_ci if (head != NULL) { 1102ee81decSopenharmony_ci DslmDestroyJson(head); 1112ee81decSopenharmony_ci body = NULL; // no need to free body 1122ee81decSopenharmony_ci } 1132ee81decSopenharmony_ci 1142ee81decSopenharmony_ci if (body != NULL) { 1152ee81decSopenharmony_ci DslmDestroyJson(body); 1162ee81decSopenharmony_ci } 1172ee81decSopenharmony_ci return out; 1182ee81decSopenharmony_ci} 1192ee81decSopenharmony_ci 1202ee81decSopenharmony_ciint32_t BuildDeviceSecInfoRequest(uint64_t challenge, MessageBuff **msg) 1212ee81decSopenharmony_ci{ 1222ee81decSopenharmony_ci if ((msg == NULL) || (*msg != NULL)) { 1232ee81decSopenharmony_ci return ERR_INVALID_PARA; 1242ee81decSopenharmony_ci } 1252ee81decSopenharmony_ci 1262ee81decSopenharmony_ci MessageBuff *out = MALLOC(sizeof(MessageBuff)); 1272ee81decSopenharmony_ci if (out == NULL) { 1282ee81decSopenharmony_ci return ERR_NO_MEMORY; 1292ee81decSopenharmony_ci } 1302ee81decSopenharmony_ci (void)memset_s(out, sizeof(MessageBuff), 0, sizeof(MessageBuff)); 1312ee81decSopenharmony_ci 1322ee81decSopenharmony_ci out->buff = GenerateSecInfoRequestJson(challenge); 1332ee81decSopenharmony_ci if (out->buff == NULL) { 1342ee81decSopenharmony_ci FREE(out); 1352ee81decSopenharmony_ci return ERR_JSON_ERR; 1362ee81decSopenharmony_ci } 1372ee81decSopenharmony_ci out->length = strlen((char *)out->buff) + 1; 1382ee81decSopenharmony_ci *msg = out; 1392ee81decSopenharmony_ci return SUCCESS; 1402ee81decSopenharmony_ci} 1412ee81decSopenharmony_ci 1422ee81decSopenharmony_ciint32_t ParseDeviceSecInfoRequest(const MessageBuff *msg, RequestObject *obj) 1432ee81decSopenharmony_ci{ 1442ee81decSopenharmony_ci if (msg == NULL || obj == NULL || msg->buff == NULL) { 1452ee81decSopenharmony_ci return ERR_INVALID_PARA; 1462ee81decSopenharmony_ci } 1472ee81decSopenharmony_ci SECURITY_LOG_DEBUG("ParseDeviceSecInfoRequest msg is %s", (char *)msg->buff); 1482ee81decSopenharmony_ci 1492ee81decSopenharmony_ci DslmJsonHandle handle = DslmCreateJson((const char *)msg->buff); 1502ee81decSopenharmony_ci if (handle == NULL) { 1512ee81decSopenharmony_ci return ERR_INVALID_PARA; 1522ee81decSopenharmony_ci } 1532ee81decSopenharmony_ci 1542ee81decSopenharmony_ci const char *nonceStr = DslmGetJsonFieldString(handle, FIELD_CHALLENGE); 1552ee81decSopenharmony_ci if (nonceStr == NULL) { 1562ee81decSopenharmony_ci DslmDestroyJson(handle); 1572ee81decSopenharmony_ci return ERR_NO_CHALLENGE; 1582ee81decSopenharmony_ci } 1592ee81decSopenharmony_ci 1602ee81decSopenharmony_ci int32_t ret = DslmHexStringToByte(nonceStr, strlen(nonceStr), (uint8_t *)&obj->challenge, sizeof(obj->challenge)); 1612ee81decSopenharmony_ci if (ret != 0) { 1622ee81decSopenharmony_ci DslmDestroyJson(handle); 1632ee81decSopenharmony_ci return ERR_NO_CHALLENGE; 1642ee81decSopenharmony_ci } 1652ee81decSopenharmony_ci 1662ee81decSopenharmony_ci obj->version = (uint32_t)DslmGetJsonFieldInt(handle, FIELD_VERSION); 1672ee81decSopenharmony_ci obj->arraySize = DslmGetJsonFieldIntArray(handle, FIELD_SUPPORT, (int32_t *)obj->credArray, MAX_CRED_ARRAY_SIZE); 1682ee81decSopenharmony_ci 1692ee81decSopenharmony_ci DslmDestroyJson(handle); 1702ee81decSopenharmony_ci 1712ee81decSopenharmony_ci return SUCCESS; 1722ee81decSopenharmony_ci} 1732ee81decSopenharmony_ci 1742ee81decSopenharmony_ciint32_t BuildDeviceSecInfoResponse(uint64_t challenge, const DslmCredBuff *cred, MessageBuff **msg) 1752ee81decSopenharmony_ci{ 1762ee81decSopenharmony_ci if ((cred == NULL) || (msg == NULL) || (*msg != NULL)) { 1772ee81decSopenharmony_ci return ERR_INVALID_PARA; 1782ee81decSopenharmony_ci } 1792ee81decSopenharmony_ci MessageBuff *out = MALLOC(sizeof(MessageBuff)); 1802ee81decSopenharmony_ci if (out == NULL) { 1812ee81decSopenharmony_ci return ERR_NO_MEMORY; 1822ee81decSopenharmony_ci } 1832ee81decSopenharmony_ci 1842ee81decSopenharmony_ci out->buff = GenerateSecInfoResponseJson(challenge, cred); 1852ee81decSopenharmony_ci if (out->buff == NULL) { 1862ee81decSopenharmony_ci FREE(out); 1872ee81decSopenharmony_ci return ERR_JSON_ERR; 1882ee81decSopenharmony_ci } 1892ee81decSopenharmony_ci out->length = strlen((char *)out->buff) + 1; 1902ee81decSopenharmony_ci 1912ee81decSopenharmony_ci *msg = out; 1922ee81decSopenharmony_ci return SUCCESS; 1932ee81decSopenharmony_ci} 1942ee81decSopenharmony_ci 1952ee81decSopenharmony_ciint32_t ParseDeviceSecInfoResponse(const MessageBuff *msg, uint64_t *challenge, uint32_t *version, DslmCredBuff **cred) 1962ee81decSopenharmony_ci{ 1972ee81decSopenharmony_ci if (msg == NULL || challenge == NULL || version == NULL || cred == NULL) { 1982ee81decSopenharmony_ci return ERR_INVALID_PARA; 1992ee81decSopenharmony_ci } 2002ee81decSopenharmony_ci 2012ee81decSopenharmony_ci if (msg->buff == NULL || *cred != NULL) { 2022ee81decSopenharmony_ci return ERR_INVALID_PARA; 2032ee81decSopenharmony_ci } 2042ee81decSopenharmony_ci 2052ee81decSopenharmony_ci DslmJsonHandle handle = DslmCreateJson((const char *)msg->buff); 2062ee81decSopenharmony_ci if (handle == NULL) { 2072ee81decSopenharmony_ci return ERR_INVALID_PARA; 2082ee81decSopenharmony_ci } 2092ee81decSopenharmony_ci 2102ee81decSopenharmony_ci const char *nonceStr = DslmGetJsonFieldString(handle, FIELD_CHALLENGE); 2112ee81decSopenharmony_ci if (nonceStr == NULL) { 2122ee81decSopenharmony_ci DslmDestroyJson(handle); 2132ee81decSopenharmony_ci return ERR_NO_CHALLENGE; 2142ee81decSopenharmony_ci } 2152ee81decSopenharmony_ci uint64_t nonceNum = 0; 2162ee81decSopenharmony_ci int32_t ret = DslmHexStringToByte(nonceStr, strlen(nonceStr), (uint8_t *)&nonceNum, sizeof(uint64_t)); 2172ee81decSopenharmony_ci if (ret != 0) { 2182ee81decSopenharmony_ci DslmDestroyJson(handle); 2192ee81decSopenharmony_ci return ERR_NO_CHALLENGE; 2202ee81decSopenharmony_ci } 2212ee81decSopenharmony_ci 2222ee81decSopenharmony_ci uint32_t type = (uint32_t)DslmGetJsonFieldInt(handle, FIELD_CRED_TYPE); 2232ee81decSopenharmony_ci uint32_t verNum = (uint32_t)DslmGetJsonFieldInt(handle, FIELD_VERSION); 2242ee81decSopenharmony_ci 2252ee81decSopenharmony_ci const char *credStr = DslmGetJsonFieldString(handle, FIELD_CRED_INFO); 2262ee81decSopenharmony_ci if (credStr == NULL) { 2272ee81decSopenharmony_ci DslmDestroyJson(handle); 2282ee81decSopenharmony_ci return ERR_NO_CRED; 2292ee81decSopenharmony_ci } 2302ee81decSopenharmony_ci 2312ee81decSopenharmony_ci uint8_t *credBuf = NULL; 2322ee81decSopenharmony_ci uint32_t credLen = (uint32_t)Base64DecodeApp((uint8_t *)credStr, &credBuf); 2332ee81decSopenharmony_ci if (credBuf == NULL) { 2342ee81decSopenharmony_ci DslmDestroyJson(handle); 2352ee81decSopenharmony_ci return ERR_NO_CRED; 2362ee81decSopenharmony_ci } 2372ee81decSopenharmony_ci 2382ee81decSopenharmony_ci DslmCredBuff *out = CreateDslmCred((CredType)type, credLen, credBuf); 2392ee81decSopenharmony_ci if (out == NULL) { 2402ee81decSopenharmony_ci DslmDestroyJson(handle); 2412ee81decSopenharmony_ci FREE(credBuf); 2422ee81decSopenharmony_ci return ERR_NO_MEMORY; 2432ee81decSopenharmony_ci } 2442ee81decSopenharmony_ci 2452ee81decSopenharmony_ci DslmDestroyJson(handle); 2462ee81decSopenharmony_ci FREE(credBuf); 2472ee81decSopenharmony_ci *version = verNum; 2482ee81decSopenharmony_ci *challenge = nonceNum; 2492ee81decSopenharmony_ci *cred = out; 2502ee81decSopenharmony_ci return SUCCESS; 2512ee81decSopenharmony_ci} 252