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