1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4 #include "dev_bind_internal.h"
5
6 #define AWSS_DEV_RAND_SIGN_FMT \
7 ",\"random\":\"%s\",\"signMethod\":%d,\"sign\":\"%s\""
8 #define AWSS_DEV_BIND_TOKEN_FMT \
9 ",\"token\":\"%s\",\"remainTime\":%d,\"type\":%d"
10 #define AWSS_SUCCESS_FMT ",\"type\":%d"
11 #define AWSS_DEV_INFO_FMT \
12 "\"awssVer\":%s,\"productKey\":\"%s\",\"deviceName\":\"%s\",\"mac\":\"%" \
13 "s\",\"ip\":\"%s\",\"cipherType\":%d"
14
15 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
16 extern "C" {
17 #endif
18
bind_get_encrypt_type()19 static inline int bind_get_encrypt_type()
20 {
21 return 3;
22 }
23
awss_get_dev_info(void * dev_info,int len)24 static void *awss_get_dev_info(void *dev_info, int len)
25 {
26 char dev_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
27 char mac_str[HAL_MAC_LEN + 1] = { 0 };
28 char pk[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
29 char ip_str[OS_IP_LEN + 1] = { 0 };
30
31 if (dev_info == NULL || len <= 0) {
32 return NULL;
33 }
34
35 HAL_GetProductKey(pk);
36 HAL_GetDeviceName(dev_name);
37 os_wifi_get_mac_str(mac_str);
38 HAL_Wifi_Get_IP(ip_str, NULL);
39 HAL_Snprintf(dev_info, len - 1, AWSS_DEV_INFO_FMT, AWSS_VER, pk, dev_name,
40 mac_str, ip_str, bind_get_encrypt_type());
41
42 return dev_info;
43 }
44
awss_build_dev_info(int type,void * dev_info,int info_len)45 void *awss_build_dev_info(int type, void *dev_info, int info_len)
46 {
47 int len = 0;
48 char *buf = NULL;
49
50 if (dev_info == NULL || info_len <= 0) {
51 return NULL;
52 }
53
54 buf = awss_zalloc(DEV_INFO_LEN_MAX);
55 if (buf == NULL) {
56 return NULL;
57 }
58
59 len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1, "%s",
60 (char *)awss_get_dev_info(buf, DEV_INFO_LEN_MAX));
61 HAL_Free(buf);
62 buf = NULL;
63
64 switch (type) {
65 case AWSS_NOTIFY_DEV_BIND_TOKEN:
66 {
67 char rand_str[(RANDOM_MAX_LEN << 1) + 1] = { 0 };
68 utils_hex_to_str(aes_random, RANDOM_MAX_LEN, rand_str,
69 sizeof(rand_str));
70 len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1,
71 AWSS_DEV_BIND_TOKEN_FMT, rand_str,
72 awss_token_remain_time(), 0);
73 break;
74 }
75 #ifdef WIFI_PROVISION_ENABLED
76 case AWSS_NOTIFY_SUCCESS:
77 {
78 len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1,
79 AWSS_SUCCESS_FMT, 0);
80 break;
81 }
82 case AWSS_NOTIFY_DEV_RAND_SIGN:
83 {
84 char sign_str[DEV_SIGN_SIZE * 2 + 1] = { 0 };
85 char rand_str[(RANDOM_MAX_LEN << 1) + 1] = { 0 };
86 {
87 int txt_len = 80;
88 char txt[80] = { 0 };
89 char key[IOTX_DEVICE_SECRET_LEN + 1] = { 0 };
90 uint8_t sign[DEV_SIGN_SIZE + 1] = { 0 };
91
92 if (bind_get_encrypt_type() == 3) { /* aes-key per product */
93 HAL_GetProductSecret(key);
94 } else { /* aes-key per device */
95 HAL_GetDeviceSecret(key);
96 }
97 awss_build_sign_src(txt, &txt_len);
98 produce_signature(sign, (uint8_t *)txt, txt_len, key);
99 utils_hex_to_str(sign, DEV_SIGN_SIZE, sign_str,
100 sizeof(sign_str));
101 }
102 utils_hex_to_str(aes_random, RANDOM_MAX_LEN, rand_str,
103 sizeof(rand_str));
104 len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1,
105 AWSS_DEV_RAND_SIGN_FMT, rand_str, 0, sign_str);
106 break;
107 }
108 #endif
109 default:
110 break;
111 }
112
113 return dev_info;
114 }
115
116 #ifdef WIFI_PROVISION_ENABLED
awss_build_sign_src(char * sign_src,int * sign_src_len)117 char *awss_build_sign_src(char *sign_src, int *sign_src_len)
118 {
119 char *pk = NULL, *dev_name = NULL;
120 int dev_name_len, pk_len, text_len;
121
122 if (sign_src == NULL || sign_src_len == NULL) {
123 goto build_sign_src_err;
124 }
125
126 pk = awss_zalloc(IOTX_PRODUCT_KEY_LEN + 1);
127 dev_name = awss_zalloc(IOTX_DEVICE_NAME_LEN + 1);
128 if (pk == NULL || dev_name == NULL) {
129 goto build_sign_src_err;
130 }
131
132 HAL_GetProductKey(pk);
133 HAL_GetDeviceName(dev_name);
134
135 pk_len = strlen(pk);
136 dev_name_len = strlen(dev_name);
137
138 text_len = RANDOM_MAX_LEN + dev_name_len + pk_len;
139 if (*sign_src_len < text_len) {
140 goto build_sign_src_err;
141 }
142
143 *sign_src_len = text_len;
144
145 memcpy(sign_src, aes_random, RANDOM_MAX_LEN);
146 memcpy(sign_src + RANDOM_MAX_LEN, dev_name, dev_name_len);
147 memcpy(sign_src + RANDOM_MAX_LEN + dev_name_len, pk, pk_len);
148
149 HAL_Free(pk);
150 HAL_Free(dev_name);
151
152 return sign_src;
153
154 build_sign_src_err:
155 if (pk) {
156 HAL_Free(pk);
157 }
158 if (dev_name) {
159 HAL_Free(dev_name);
160 }
161 return NULL;
162 }
163 #endif
awss_build_topic(const char * topic_fmt,char * topic,uint32_t tlen)164 const char *awss_build_topic(const char *topic_fmt, char *topic, uint32_t tlen)
165 {
166 char pk[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
167 char dev_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
168 if (topic == NULL || topic_fmt == NULL || tlen == 0) {
169 return NULL;
170 }
171
172 HAL_GetProductKey(pk);
173 HAL_GetDeviceName(dev_name);
174
175 HAL_Snprintf(topic, tlen - 1, topic_fmt, pk, dev_name);
176
177 return topic;
178 }
179
awss_build_packet(int type,void * id,void * ver,void * method,void * data,int code,void * packet,int * packet_len)180 int awss_build_packet(int type, void *id, void *ver, void *method, void *data,
181 int code, void *packet, int *packet_len)
182 {
183 int len;
184 if (packet_len == NULL || data == NULL || packet == NULL) {
185 return -1;
186 }
187
188 len = *packet_len;
189 if (len <= 0) {
190 return -1;
191 }
192
193 if (type == AWSS_CMP_PKT_TYPE_REQ) {
194 if (ver == NULL || method == NULL) {
195 return -1;
196 }
197
198 len = HAL_Snprintf(packet, len - 1, AWSS_REQ_FMT, (char *)id,
199 (char *)ver, (char *)method, (char *)data);
200 return 0;
201 } else if (type == AWSS_CMP_PKT_TYPE_RSP) {
202 len = HAL_Snprintf(packet, len - 1, AWSS_ACK_FMT, (char *)id, code,
203 (char *)data);
204 return 0;
205 }
206 return -1;
207 }
208
produce_random(uint8_t * random,uint32_t len)209 void produce_random(uint8_t *random, uint32_t len)
210 {
211 int i = 0;
212 int time = HAL_UptimeMs();
213 HAL_Srandom(time);
214 for (i = 0; i < len; i++) {
215 random[i] = HAL_Random(0xFF);
216 }
217 }
218
219 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
220 }
221 #endif
222