1 /*
2  * Copyright (c) 2020 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 #if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
17 
18 #include <string.h>
19 #include "securec.h"
20 #include "jsonutil.h"
21 #include "commonutil.h"
22 #include "exchange_auth_info.h"
23 #include "log.h"
24 #include "key_agreement_version.h"
25 
free_single_buff(void * obj)26 static void free_single_buff(void *obj)
27 {
28     if (obj != NULL) {
29         struct uint8_buff *data = (struct uint8_buff *)obj;
30         if (data->val) {
31             FREE(data->val);
32             data->val = NULL;
33         }
34         FREE(data);
35     }
36 }
37 
get_single_json_from_buff(const char * payload,const char * name,enum json_object_data_type data_type)38 static void *get_single_json_from_buff(const char *payload, const char *name, enum json_object_data_type data_type)
39 {
40     struct uint8_buff *request_data = (struct uint8_buff *)MALLOC(sizeof(struct uint8_buff));
41     if (request_data == NULL) {
42         LOGE("MALLOC failed");
43         return NULL;
44     }
45 
46     json_handle obj = parse_payload(payload, data_type);
47     if (obj == NULL) {
48         goto error;
49     }
50     /* authData */
51     const char *client_chall = get_json_string(obj, name);
52     if (client_chall == NULL) {
53         goto error;
54     }
55 
56     int32_t json_data_len = strlen(client_chall);
57     if ((json_data_len / BYTE_TO_HEX_OPER_LENGTH) > HC_AUTH_DATA_BUFF_LEN) { /* hex to byte length */
58         goto error;
59     }
60     request_data->size = json_data_len / BYTE_TO_HEX_OPER_LENGTH; /* hex to byte length */
61     request_data->length = json_data_len / BYTE_TO_HEX_OPER_LENGTH; /* hex to byte length */
62     request_data->val = (uint8_t *)MALLOC(request_data->size);
63     if (request_data->val == NULL) {
64         goto error;
65     }
66     if (hex_string_to_byte(client_chall, json_data_len, request_data->val) != HC_OK) {
67         goto error;
68     }
69     free_payload(obj, data_type);
70     return (void *)request_data;
71 
72 error:
73     free_payload(obj, data_type);
74     free_single_buff(request_data);
75     return NULL;
76 }
77 
make_single_json_data(void * data,const char * name,int32_t msg_code)78 static char *make_single_json_data(void *data, const char *name, int32_t msg_code)
79 {
80     struct uint8_buff *src_data = data;
81     uint8_t *tmp_data_hex = raw_byte_to_hex_string(src_data->val, src_data->length);
82     if (tmp_data_hex == NULL) {
83         return NULL;
84     }
85 
86     char *ret_str = (char *)MALLOC(RET_STR_LENGTH);
87     if (ret_str == NULL) {
88         FREE(tmp_data_hex);
89         return NULL;
90     }
91 
92     (void)memset_s(ret_str, RET_STR_LENGTH, 0, RET_STR_LENGTH);
93     if (snprintf_s(ret_str, RET_STR_LENGTH, RET_STR_LENGTH - 1, "{\"%s\":%d,\"%s\":{\"%s\":\"%s\"}}", FIELD_MESSAGE,
94         msg_code, FIELD_PAYLOAD, name, tmp_data_hex) < 0) {
95         LOGE("String generate failed");
96         FREE(ret_str);
97         ret_str = NULL;
98     }
99     FREE(tmp_data_hex);
100     return ret_str;
101 }
102 
make_single_json_data_srv_proof(void * data,const char * name,int32_t msg_code)103 static char *make_single_json_data_srv_proof(void *data, const char *name, int32_t msg_code)
104 {
105     struct uint8_buff *src_data = data;
106     char *ret_str = (char *)MALLOC(RET_STR_LENGTH);
107     if (ret_str == NULL) {
108         return NULL;
109     }
110     (void)memset_s(ret_str, RET_STR_LENGTH, 0, RET_STR_LENGTH);
111     if (snprintf_s(ret_str, RET_STR_LENGTH, RET_STR_LENGTH - 1, "{\"%s\":%d,\"%s\":{\"%s\":%s}}", FIELD_MESSAGE,
112         msg_code, FIELD_PAYLOAD, name, src_data->val) < 0) {
113         LOGE("String generate failed");
114         FREE(ret_str);
115         ret_str = NULL;
116     }
117 
118     return ret_str;
119 }
120 
sec_clone_parse_client_request(const char * payload,enum json_object_data_type data_type)121 void *sec_clone_parse_client_request(const char *payload, enum json_object_data_type data_type)
122 {
123     return get_single_json_from_buff(payload, "clientChallenge", data_type);
124 }
125 
sec_clone_free_client_request(void * obj)126 void sec_clone_free_client_request(void *obj)
127 {
128     free_single_buff(obj);
129 }
130 
sec_clone_make_srv_proof(void * data)131 char *sec_clone_make_srv_proof(void *data)
132 {
133     return make_single_json_data_srv_proof(data, "serverProof", SEC_CLONE_START_RESPONSE);
134 }
135 
sec_clone_parse_client_ack(const char * payload,enum json_object_data_type data_type)136 void *sec_clone_parse_client_ack(const char *payload, enum json_object_data_type data_type)
137 {
138     return get_single_json_from_buff(payload, "SecData", data_type);
139 }
140 
sec_clone_free_client_ack(void * obj)141 void sec_clone_free_client_ack(void *obj)
142 {
143     free_single_buff(obj);
144 }
145 
sec_clone_make_clone_ret(void * data)146 char *sec_clone_make_clone_ret(void *data)
147 {
148     return make_single_json_data(data, "cloneReturn", SEC_CLONE_ACK_RESPONSE);
149 }
150 
sec_clone_parse_start_resp(const char * payload,enum json_object_data_type data_type)151 void *sec_clone_parse_start_resp(const char *payload, enum json_object_data_type data_type)
152 {
153     return get_single_json_from_buff(payload, "serverProof", data_type);
154 }
155 
sec_clone_parse_ack_resp(const char * payload,enum json_object_data_type data_type)156 void *sec_clone_parse_ack_resp(const char *payload, enum json_object_data_type data_type)
157 {
158     return get_single_json_from_buff(payload, "cloneReturn", data_type);
159 }
160 #else
161 
162 #define DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(name) \
163     void *sec_clone_parse_##name(const char *payload, enum json_object_data_type data_type) \
164     { \
165         (void)payload; \
166         (void)data_type; \
167         return NULL; \
168     } \
169     void sec_clone_free_##name(void *obj) \
170     { \
171         (void)obj; \
172     } \
173     char *sec_clone_make_##name(void *data) \
174     { \
175         (void)data; \
176         return "Current devices do not support this feature."; \
177     }
178 
179 #include "parsedata.h"
180 DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(client_request)
181 DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(srv_proof)
182 DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(client_ack)
183 DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(clone_ret)
184 DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(start_resp)
185 DEFINE_SEC_CLONE_EMPTY_STRUCT_FUNC(ack_resp)
186 
187 #endif
188