• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_ohos_request.h"
17 
18 #include <stdio.h>
19 #include <stdbool.h>
20 #include <string.h>
21 
22 #include "securec.h"
23 
24 #include "external_interface_adapter.h"
25 #include "utils_hexstring.h"
26 #include "utils_json.h"
27 #include "utils_log.h"
28 #include "utils_mem.h"
29 
30 #define DSLM_CRED_CFG_FILE_POSITION "/system/etc/dslm_finger.cfg"
31 #define DSLM_CRED_STR_LEN_MAX 4096
32 #define CHALLENGE_STRING_LENGTH 32
33 #define UDID_STRING_LENGTH 65
34 
35 #define DEVAUTH_JSON_KEY_CHALLENGE "challenge"
36 #define DEVAUTH_JSON_KEY_PK_INFO_LIST "pkInfoList"
37 
TransToJsonStr(const char * challengeStr,const char * pkInfoListStr,char ** nonceStr)38 static int32_t TransToJsonStr(const char *challengeStr, const char *pkInfoListStr, char **nonceStr)
39 {
40     JsonHandle json = CreateJson(NULL);
41     if (json == NULL) {
42         return ERR_INVALID_PARA;
43     }
44 
45     // add challenge
46     AddFieldStringToJson(json, DEVAUTH_JSON_KEY_CHALLENGE, challengeStr);
47 
48     // add pkInfoList
49     AddFieldStringToJson(json, DEVAUTH_JSON_KEY_PK_INFO_LIST, pkInfoListStr);
50 
51     // tran to json
52     *nonceStr = ConvertJsonToString(json);
53     if (*nonceStr == NULL) {
54         DestroyJson(json);
55         return ERR_JSON_ERR;
56     }
57     DestroyJson(json);
58     return SUCCESS;
59 }
60 
GenerateDslmCertChain(const DeviceIdentify * device,const RequestObject * obj,char * credStr,uint8_t ** certChain,uint32_t * certChainLen)61 static int32_t GenerateDslmCertChain(const DeviceIdentify *device, const RequestObject *obj, char *credStr,
62     uint8_t **certChain, uint32_t *certChainLen)
63 {
64     char *pkInfoListStr = NULL;
65     char *nonceStr = NULL;
66     char challengeStr[CHALLENGE_STRING_LENGTH] = {0};
67     ByteToHexString((uint8_t *)&(obj->challenge), sizeof(obj->challenge), (uint8_t *)challengeStr,
68         CHALLENGE_STRING_LENGTH);
69     char udidStr[UDID_STRING_LENGTH] = {0};
70     if (memcpy_s(udidStr, UDID_STRING_LENGTH, device->identity, device->length) != EOK) {
71         return ERR_MEMORY_ERR;
72     }
73     int32_t ret = ERR_DEFAULT;
74     do {
75         ret = GetPkInfoListStr(true, udidStr, &pkInfoListStr);
76         if (ret != SUCCESS) {
77             SECURITY_LOG_ERROR("GetPkInfoListStr failed");
78             break;
79         }
80 
81         ret = TransToJsonStr(challengeStr, pkInfoListStr, &nonceStr);
82         if (ret != SUCCESS) {
83             SECURITY_LOG_ERROR("TransToJsonStr failed");
84             break;
85         }
86         struct DslmInfoInCertChain saveInfo = {.credStr = credStr, .nonceStr = nonceStr, .udidStr = udidStr};
87         ret = DslmCredAttestAdapter(&saveInfo, certChain, certChainLen);
88         if (ret != SUCCESS) {
89             SECURITY_LOG_ERROR("DslmCredAttestAdapter failed");
90             break;
91         }
92     } while (0);
93 
94     if (pkInfoListStr != NULL) {
95         FREE(pkInfoListStr);
96     }
97     if (nonceStr != NULL) {
98         FREE(nonceStr);
99     }
100     return ret;
101 }
102 
SelectDslmCredType(const DeviceIdentify * device,const RequestObject * obj,uint32_t * type)103 static int32_t SelectDslmCredType(const DeviceIdentify *device, const RequestObject *obj, uint32_t *type)
104 {
105     (void)device;
106     (void)obj;
107     if (HksAttestIsReadyAdapter() != SUCCESS) {
108         *type = CRED_TYPE_SMALL;
109     } else {
110         *type = CRED_TYPE_STANDARD;
111     }
112     return SUCCESS;
113 }
114 
RequestSmallDslmCred(uint8_t * data,uint32_t dataLen,DslmCredBuff ** credBuff)115 static int32_t RequestSmallDslmCred(uint8_t *data, uint32_t dataLen, DslmCredBuff **credBuff)
116 {
117     DslmCredBuff *out = CreateDslmCred(CRED_TYPE_SMALL, dataLen, data);
118     if (out == NULL) {
119         SECURITY_LOG_ERROR("CreateDslmCred failed");
120         return ERR_MEMORY_ERR;
121     }
122     *credBuff = out;
123     SECURITY_LOG_INFO("success");
124     return SUCCESS;
125 }
126 
RequestStandardDslmCred(const DeviceIdentify * device,const RequestObject * obj,char * credStr,DslmCredBuff ** credBuff)127 static int32_t RequestStandardDslmCred(const DeviceIdentify *device, const RequestObject *obj, char *credStr,
128     DslmCredBuff **credBuff)
129 {
130     uint8_t *certChain = NULL;
131     uint32_t certChainLen = 0;
132     int32_t ret = GenerateDslmCertChain(device, obj, credStr, &certChain, &certChainLen);
133     if (ret != SUCCESS) {
134         SECURITY_LOG_ERROR("GenerateDslmCertChain failed");
135         return ret;
136     }
137     DslmCredBuff *out = CreateDslmCred(CRED_TYPE_STANDARD, certChainLen, certChain);
138     if (out == NULL) {
139         FREE(certChain);
140         SECURITY_LOG_ERROR("CreateDslmCred failed");
141         return ERR_MEMORY_ERR;
142     }
143     FREE(certChain);
144     *credBuff = out;
145     SECURITY_LOG_INFO("success");
146     return SUCCESS;
147 }
148 
GetCredFromCurrentDevice(char * credStr,uint32_t maxLen)149 int32_t GetCredFromCurrentDevice(char *credStr, uint32_t maxLen)
150 {
151     if (credStr == NULL || maxLen == 0) {
152         return ERR_INVALID_PARA;
153     }
154     FILE *fp = NULL;
155     fp = fopen(DSLM_CRED_CFG_FILE_POSITION, "r");
156     if (fp == NULL) {
157         SECURITY_LOG_ERROR("fopen cred file failed");
158         return ERR_INVALID_PARA;
159     }
160     int32_t ret = fscanf_s(fp, "%s", credStr, maxLen);
161     if (ret <= 0) {
162         SECURITY_LOG_ERROR("fscanf_s cred file failed");
163         ret = ERR_INVALID_PARA;
164     } else {
165         ret = SUCCESS;
166     }
167     if (fclose(fp) != 0) {
168         SECURITY_LOG_ERROR("fclose cred file failed");
169         ret = ERR_INVALID_PARA;
170     }
171     return ret;
172 }
173 
RequestOhosDslmCred(const DeviceIdentify * device,const RequestObject * obj,DslmCredBuff ** credBuff)174 int32_t RequestOhosDslmCred(const DeviceIdentify *device, const RequestObject *obj, DslmCredBuff **credBuff)
175 {
176     SECURITY_LOG_INFO("start");
177     uint32_t credType = 0;
178     char credStr[DSLM_CRED_STR_LEN_MAX] = {0};
179     int32_t ret = GetCredFromCurrentDevice(credStr, DSLM_CRED_STR_LEN_MAX);
180     if (ret != SUCCESS) {
181         SECURITY_LOG_ERROR("read cred data from file failed");
182         return ret;
183     }
184     ret = SelectDslmCredType(device, obj, &credType);
185     if (ret != SUCCESS) {
186         SECURITY_LOG_ERROR("SelectDslmCredType failed");
187         return ret;
188     }
189     switch (credType) {
190         case CRED_TYPE_SMALL:
191             return RequestSmallDslmCred((uint8_t *)credStr, strlen(credStr) + 1, credBuff);
192         case CRED_TYPE_STANDARD:
193             return RequestStandardDslmCred(device, obj, credStr, credBuff);
194         default:
195             SECURITY_LOG_ERROR("invalid cred type");
196             return ERR_INVALID_PARA;
197     }
198 
199     return SUCCESS;
200 }
201