1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 
6 #include <stdlib.h>
7 #include <time.h>
8 #include "alcs_internal.h"
9 #include "linkkit/alcs_api.h"
10 #include "alcs_coap.h"
11 #include "alcs_api_internal.h"
12 #include "CoAPPlatform.h"
13 #include "CoAPObserve.h"
14 
15 LIST_HEAD(secure_resource_cb_head);
16 
17 static bool is_inited = 0;
18 #ifdef SUPPORT_MULTI_DEVICES
19 LIST_HEAD(device_list);
20 
get_device(CoAPContext * context)21 device_auth_list *get_device(CoAPContext *context)
22 {
23     device_auth_list *node = NULL, *next = NULL;
24     list_for_each_entry_safe(node, next, &device_list, lst, device_auth_list)
25     {
26         if (node->context == context) {
27             return node;
28         }
29     }
30     return NULL;
31 }
32 
get_list(CoAPContext * context)33 auth_list *get_list(CoAPContext *context)
34 {
35     device_auth_list *dev_lst = get_device(context);
36     return dev_lst ? &dev_lst->lst_auth : NULL;
37 }
38 
39 #ifdef ALCS_CLIENT_ENABLED
get_ctl_session_list(CoAPContext * context)40 struct list_head *get_ctl_session_list(CoAPContext *context)
41 {
42     device_auth_list *dev_lst = get_device(context);
43     if (!dev_lst || !(dev_lst->role & ROLE_CLIENT)) {
44         return NULL;
45     }
46     return &dev_lst->lst_ctl_sessions;
47 }
48 #endif
49 #ifdef ALCS_SERVER_ENABLED
get_svr_session_list(CoAPContext * context)50 struct list_head *get_svr_session_list(CoAPContext *context)
51 {
52     device_auth_list *dev_lst = get_device(context);
53     return dev_lst && (dev_lst->role & ROLE_SERVER) ? &dev_lst->lst_svr_sessions
54                                                     : NULL;
55 }
56 #endif
57 
58 #else
59 device_auth_list _device;
60 #endif
61 
remove_session(CoAPContext * ctx,session_item * session)62 void remove_session(CoAPContext *ctx, session_item *session)
63 {
64     COAP_INFO("remove_session");
65     if (session) {
66         CoapObsServerAll_delete(ctx, &session->addr);
67         list_del(&session->lst);
68         coap_free(session);
69     }
70 }
71 
get_session_by_checksum(struct list_head * sessions,NetworkAddr * addr,char ck[PK_DN_CHECKSUM_LEN])72 session_item *get_session_by_checksum(struct list_head *sessions,
73                                       NetworkAddr *addr,
74                                       char ck[PK_DN_CHECKSUM_LEN])
75 {
76     session_item *node = NULL, *next = NULL;
77     if (!sessions || !ck) {
78         return NULL;
79     }
80     list_for_each_entry_safe(node, next, sessions, lst, session_item)
81     {
82         if (is_networkadd_same(addr, &node->addr) &&
83             strncmp(node->pk_dn, ck, PK_DN_CHECKSUM_LEN) == 0) {
84             COAP_DEBUG("find node, sessionid:%d", node->sessionId);
85             return node;
86         }
87     }
88     return NULL;
89 }
90 
get_session(struct list_head * sessions,AlcsDeviceKey * devKey)91 static session_item *get_session(struct list_head *sessions,
92                                  AlcsDeviceKey *devKey)
93 {
94     char ck[PK_DN_CHECKSUM_LEN] = { 0 };
95     char path[100] = { 0 };
96     if (!sessions || !devKey || !devKey->pk || !devKey->dn) {
97         return NULL;
98     }
99     HAL_Snprintf(path, sizeof(path), "%s%s", devKey->pk, devKey->dn);
100     CoAPPathMD5_sum(path, strlen(path), ck, PK_DN_CHECKSUM_LEN);
101 
102     return get_session_by_checksum(sessions, &devKey->addr, ck);
103 }
104 
105 #ifdef ALCS_CLIENT_ENABLED
get_ctl_session(CoAPContext * ctx,AlcsDeviceKey * devKey)106 session_item *get_ctl_session(CoAPContext *ctx, AlcsDeviceKey *devKey)
107 {
108     struct list_head *sessions = get_ctl_session_list(ctx);
109     COAP_DEBUG("get_ctl_session");
110     return get_session(sessions, devKey);
111 }
112 
113 #endif
114 
115 #ifdef ALCS_SERVER_ENABLED
get_svr_session(CoAPContext * ctx,AlcsDeviceKey * devKey)116 session_item *get_svr_session(CoAPContext *ctx, AlcsDeviceKey *devKey)
117 {
118     struct list_head *sessions = get_svr_session_list(ctx);
119     return get_session(sessions, devKey);
120 }
121 #endif
122 
get_auth_session(CoAPContext * ctx,AlcsDeviceKey * devKey)123 static session_item *get_auth_session(CoAPContext *ctx, AlcsDeviceKey *devKey)
124 {
125 #ifdef ALCS_CLIENT_ENABLED
126     session_item *node = get_ctl_session(ctx, devKey);
127     if (node && node->sessionId) {
128         return node;
129     }
130 #endif
131 #ifdef ALCS_SERVER_ENABLED
132     session_item *node1 = get_svr_session(ctx, devKey);
133     if (node1 && node1->sessionId) {
134         return node1;
135     }
136 #endif
137 
138     return NULL;
139 }
140 
get_auth_session_by_checksum(CoAPContext * ctx,NetworkAddr * addr,char ck[])141 static session_item *get_auth_session_by_checksum(CoAPContext *ctx,
142                                                   NetworkAddr *addr, char ck[])
143 {
144 #ifdef ALCS_CLIENT_ENABLED
145     struct list_head *sessions = get_ctl_session_list(ctx);
146     session_item *node = get_session_by_checksum(sessions, addr, ck);
147     if (node && node->sessionId) {
148         return node;
149     }
150 #endif
151 #ifdef ALCS_SERVER_ENABLED
152     struct list_head *sessions1 = get_svr_session_list(ctx);
153     session_item *node1 = get_session_by_checksum(sessions1, addr, ck);
154     if (node1 && node1->sessionId) {
155         return node1;
156     }
157 #endif
158 
159     return NULL;
160 }
161 
gen_random_key(unsigned char random[],int len)162 void gen_random_key(unsigned char random[], int len)
163 {
164     int i = 0, flag = 0;
165 
166     memset(random, 0x00, len);
167     srand((unsigned)time(NULL));
168 
169     for (i = 0; i < len - 1; i++) {
170         flag = rand() % 3;
171         switch (flag) {
172         case 0:
173             random[i] = 'A' + rand() % 26;
174             break;
175         case 1:
176             random[i] = 'a' + rand() % 26;
177             break;
178         case 2:
179             random[i] = '0' + rand() % 10;
180             break;
181         default:
182             random[i] = 'x';
183             break;
184         }
185     }
186 }
187 
188 #ifdef ALCS_SERVER_ENABLED
189 extern void alcs_rec_auth_select(CoAPContext *context, const char *paths,
190                                  NetworkAddr *remote, CoAPMessage *request);
191 extern void alcs_rec_auth(CoAPContext *context, const char *paths,
192                           NetworkAddr *remote, CoAPMessage *request);
193 extern void alcs_rec_heart_beat(CoAPContext *context, const char *paths,
194                                 NetworkAddr *remote, CoAPMessage *request);
195 #endif
196 
alcs_auth_init(CoAPContext * ctx,const char * productKey,const char * deviceName,char role)197 int alcs_auth_init(CoAPContext *ctx, const char *productKey,
198                    const char *deviceName, char role)
199 {
200     device_auth_list *dev;
201 #ifdef ALCS_SERVER_ENABLED
202     char path[256];
203 #endif
204     if (is_inited) {
205         return 0;
206     }
207     is_inited = 1;
208 
209     /* auth_list* lst_auth; */
210 
211 #ifdef SUPPORT_MULTI_DEVICES
212     INIT_LIST_HEAD(&device_list);
213 
214     dev = coap_malloc(sizeof(device_auth_list));
215     list_add_tail(&dev->lst, &device_list);
216 #else
217     dev = &_device;
218 #endif
219     dev->context = ctx;
220     dev->seq = 1;
221     dev->role = role;
222     memset(&dev->lst_auth, 0, sizeof(auth_list));
223     /* strcpy (dev->deviceName, deviceName); */
224     /* strcpy (dev->productKey, productKey); */
225 
226     INIT_LIST_HEAD(&dev->lst);
227     INIT_LIST_HEAD(&secure_resource_cb_head);
228 
229     if (role & ROLE_SERVER) {
230 #ifdef ALCS_SERVER_ENABLED
231         INIT_LIST_HEAD(&dev->lst_svr_sessions);
232         INIT_LIST_HEAD(&dev->lst_auth.lst_svr);
233 
234         HAL_Snprintf(path, sizeof(path), "/dev/%s/%s/core/service/auth",
235                      productKey, deviceName);
236         alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET,
237                                COAP_CT_APP_JSON, 60, 0, alcs_rec_auth);
238         strcat(path, "/select");
239         alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET,
240                                COAP_CT_APP_JSON, 60, 0, alcs_rec_auth_select);
241         alcs_resource_register(ctx, productKey, deviceName,
242                                "/dev/core/service/heartBeat", COAP_PERM_GET,
243                                COAP_CT_APP_JSON, 60, 0, alcs_rec_heart_beat);
244 #endif
245     }
246 
247     if (role & ROLE_CLIENT) {
248 #ifdef ALCS_CLIENT_ENABLED
249         INIT_LIST_HEAD(&dev->lst_ctl_sessions);
250         INIT_LIST_HEAD(&dev->lst_auth.lst_ctl);
251 #endif
252     }
253 
254     INIT_LIST_HEAD(&dev->lst_auth.lst_ctl_group);
255     INIT_LIST_HEAD(&dev->lst_auth.lst_svr_group);
256     dev->lst_auth.list_mutex = HAL_MutexCreate();
257 
258     return COAP_SUCCESS;
259 }
260 
alcs_auth_subdev_init(CoAPContext * ctx,const char * productKey,const char * deviceName)261 void alcs_auth_subdev_init(CoAPContext *ctx, const char *productKey,
262                            const char *deviceName)
263 {
264     char path[256];
265     HAL_Snprintf(path, sizeof(path), "/dev/%s/%s/core/service/auth", productKey,
266                  deviceName);
267     alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET,
268                            COAP_CT_APP_JSON, 60, 0, alcs_rec_auth);
269     strcat(path, "/select");
270     alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET,
271                            COAP_CT_APP_JSON, 60, 0, alcs_rec_auth_select);
272 }
273 
alcs_auth_deinit(void)274 void alcs_auth_deinit(void)
275 {
276 #ifdef SUPPORT_MULTI_DEVICES
277     device_auth_list *node = NULL, *next = NULL;
278 #endif
279     if (is_inited == 0) {
280         return;
281     }
282     is_inited = 0;
283 
284     alcs_resource_cb_deinit();
285     alcs_auth_list_deinit();
286 
287 #ifdef SUPPORT_MULTI_DEVICES
288     list_for_each_entry_safe(node, next, &device_list, lst, device_auth_list)
289     {
290         if (node->lst_auth.list_mutex) {
291             HAL_MutexDestroy(node->lst_auth.list_mutex);
292             node->lst_auth.list_mutex = NULL;
293         }
294     }
295 #else
296     if (_device.lst_auth.list_mutex) {
297         HAL_MutexDestroy(_device.lst_auth.list_mutex);
298         _device.lst_auth.list_mutex = NULL;
299     }
300 #endif
301 }
302 
is_networkadd_same(NetworkAddr * addr1,NetworkAddr * addr2)303 bool is_networkadd_same(NetworkAddr *addr1, NetworkAddr *addr2)
304 {
305     if (!addr1 || !addr2) {
306         return 0;
307     }
308     COAP_DEBUG("compare addr1:%s,addr2:%s", addr1->addr, addr2->addr);
309     return addr1->port == addr2->port &&
310            !strcmp((const char *)addr1->addr, (const char *)addr2->addr);
311 }
312 
alcs_encrypt(const char * src,int len,const char * key,void * out)313 int alcs_encrypt(const char *src, int len, const char *key, void *out)
314 {
315     char *iv = "a1b1c1d1e1f1g1h1";
316 
317     int len1 = len & 0xfffffff0;
318     int len2 = len1 + 16;
319     int pad = len2 - len;
320     int ret = 0;
321 
322     if (len1) {
323         p_Aes128_t aes_e_h =
324             infra_aes128_init((uint8_t *)key, (uint8_t *)iv, AES_ENCRYPTION);
325         ret = infra_aes128_cbc_encrypt(aes_e_h, src, len1 >> 4, out);
326         infra_aes128_destroy(aes_e_h);
327     }
328     if (!ret && pad) {
329         char buf[16];
330         p_Aes128_t aes_e_h = NULL;
331         memcpy(buf, src + len1, len - len1);
332         memset(buf + len - len1, pad, pad);
333         aes_e_h =
334             infra_aes128_init((uint8_t *)key, (uint8_t *)iv, AES_ENCRYPTION);
335         ret = infra_aes128_cbc_encrypt(aes_e_h, buf, 1, (uint8_t *)out + len1);
336         infra_aes128_destroy(aes_e_h);
337     }
338 
339     COAP_DEBUG("to encrypt src:%s, len:%d", src, len2);
340     return ret == 0 ? len2 : 0;
341 }
342 
alcs_decrypt(const char * src,int len,const char * key,void * out)343 int alcs_decrypt(const char *src, int len, const char *key, void *out)
344 {
345     char *iv = "a1b1c1d1e1f1g1h1";
346     p_Aes128_t aes_d_h;
347     int n = len >> 4;
348     char *out_c = NULL;
349     int offset = 0;
350     int ret = 0;
351     char pad = 0;
352 
353     COAP_DEBUG("to decrypt len:%d", len);
354 
355     do {
356         if (n > 1) {
357             aes_d_h = infra_aes128_init((uint8_t *)key, (uint8_t *)iv,
358                                         AES_DECRYPTION);
359             if (!aes_d_h) {
360                 COAP_ERR("fail to decrypt init");
361                 break;
362             }
363 
364             ret = infra_aes128_cbc_decrypt(aes_d_h, src, n - 1, out);
365             infra_aes128_destroy(aes_d_h);
366 
367             if (ret != 0) {
368                 COAP_ERR("fail to decrypt");
369                 break;
370             }
371         }
372 
373         out_c = (char *)out;
374         offset = n > 0 ? ((n - 1) << 4) : 0;
375         out_c[offset] = 0;
376 
377         aes_d_h =
378             infra_aes128_init((uint8_t *)key, (uint8_t *)iv, AES_DECRYPTION);
379         if (!aes_d_h) {
380             COAP_ERR("fail to decrypt init");
381             break;
382         }
383 
384         ret =
385             infra_aes128_cbc_decrypt(aes_d_h, src + offset, 1, out_c + offset);
386         infra_aes128_destroy(aes_d_h);
387 
388         if (ret != 0) {
389             COAP_ERR("fail to decrypt remain data");
390             break;
391         }
392 
393         pad = out_c[len - 1];
394         out_c[len - pad] = 0;
395         COAP_DEBUG("decrypt data:%s, len:%d", out_c, len - pad);
396         return len - pad;
397     } while (0);
398 
399     return 0;
400 }
401 
alcs_is_auth(CoAPContext * ctx,AlcsDeviceKey * devKey)402 bool alcs_is_auth(CoAPContext *ctx, AlcsDeviceKey *devKey)
403 {
404     return get_auth_session(ctx, devKey) != NULL;
405 }
406 
407 /*---------------------------------------------------------*/
408 typedef struct {
409     void *orig_user_data;
410     char pk_dn[PK_DN_CHECKSUM_LEN];
411     CoAPSendMsgHandler orig_handler;
412 } secure_send_item;
413 
do_secure_send(CoAPContext * ctx,NetworkAddr * addr,CoAPMessage * message,const char * key,char * buf)414 static int do_secure_send(CoAPContext *ctx, NetworkAddr *addr,
415                           CoAPMessage *message, const char *key, char *buf)
416 {
417     int ret = COAP_SUCCESS;
418     void *payload_old = message->payload;
419     int len_old = message->payloadlen;
420 
421     COAP_DEBUG("do_secure_send");
422 
423     message->payload = (unsigned char *)buf;
424     message->payloadlen =
425         alcs_encrypt((const char *)payload_old, len_old, key, message->payload);
426     ret = CoAPMessage_send(ctx, addr, message);
427 
428     message->payload = payload_old;
429     message->payloadlen = len_old;
430 
431     return ret;
432 }
433 
434 void secure_sendmsg_handler(CoAPContext *context, CoAPReqResult result,
435                             void *userdata, NetworkAddr *remote,
436                             CoAPMessage *message);
internal_secure_send(CoAPContext * ctx,session_item * session,NetworkAddr * addr,CoAPMessage * message,char observe,CoAPSendMsgHandler handler)437 int internal_secure_send(CoAPContext *ctx, session_item *session,
438                          NetworkAddr *addr, CoAPMessage *message, char observe,
439                          CoAPSendMsgHandler handler)
440 {
441     int encryptlen = 0;
442 
443     COAP_DEBUG("internal_secure_send");
444     if (!ctx || !session || !addr || !message) {
445         COAP_ERR("parameter is null");
446         return COAP_ERROR_INVALID_PARAM;
447     }
448 
449     if (handler) {
450         secure_send_item *item =
451             (secure_send_item *)coap_malloc(sizeof(secure_send_item));
452         item->orig_user_data = message->user;
453         item->orig_handler = handler;
454         memcpy(item->pk_dn, session->pk_dn, PK_DN_CHECKSUM_LEN);
455 
456         message->handler = secure_sendmsg_handler;
457         message->user = item;
458     }
459 
460     if (observe == 0) {
461         CoAPUintOption_add(message, COAP_OPTION_OBSERVE, observe);
462     }
463     CoAPUintOption_add(message, COAP_OPTION_CONTENT_FORMAT,
464                        COAP_CT_APP_OCTET_STREAM);
465     CoAPUintOption_add(message, COAP_OPTION_SESSIONID, session->sessionId);
466     COAP_DEBUG("secure_send sessionId:%d", session->sessionId);
467 
468     encryptlen = (message->payloadlen & 0xfffffff0) + 16;
469     if (encryptlen > 64) {
470         char *buf = (char *)coap_malloc(encryptlen);
471         int rt = do_secure_send(ctx, addr, message, session->sessionKey, buf);
472         coap_free(buf);
473         return rt;
474     } else {
475         char buf[64];
476         return do_secure_send(ctx, addr, message, session->sessionKey, buf);
477     }
478 }
479 
call_cb(CoAPContext * context,NetworkAddr * remote,CoAPMessage * message,const char * key,char * buf,secure_send_item * send_item)480 static void call_cb(CoAPContext *context, NetworkAddr *remote,
481                     CoAPMessage *message, const char *key, char *buf,
482                     secure_send_item *send_item)
483 {
484     if (send_item->orig_handler) {
485         int len = alcs_decrypt((const char *)message->payload,
486                                message->payloadlen, key, buf);
487         CoAPMessage tmpMsg;
488         memcpy(&tmpMsg, message, sizeof(CoAPMessage));
489         tmpMsg.payload = (unsigned char *)buf;
490         tmpMsg.payloadlen = len;
491         send_item->orig_handler(context, COAP_REQUEST_SUCCESS,
492                                 send_item->orig_user_data, remote, &tmpMsg);
493     }
494 }
495 
secure_sendmsg_handler(CoAPContext * context,CoAPReqResult result,void * userdata,NetworkAddr * remote,CoAPMessage * message)496 void secure_sendmsg_handler(CoAPContext *context, CoAPReqResult result,
497                             void *userdata, NetworkAddr *remote,
498                             CoAPMessage *message)
499 {
500     secure_send_item *send_item = (secure_send_item *)userdata;
501     session_item *session = NULL;
502     unsigned int obsVal;
503 
504     if (!context || !userdata || !remote) {
505         return;
506     }
507     if (result == COAP_RECV_RESP_TIMEOUT) {
508         if (send_item->orig_handler) {
509             send_item->orig_handler(context, COAP_RECV_RESP_TIMEOUT,
510                                     send_item->orig_user_data, remote, NULL);
511         }
512         COAP_INFO("secure_sendmsg_handler timeout");
513     } else {
514         unsigned int sessionId = 0;
515         CoAPUintOption_get(message, COAP_OPTION_SESSIONID, &sessionId);
516         COAP_DEBUG("secure_sendmsg_handler, sessionID:%d", (int)sessionId);
517 
518         session =
519             get_auth_session_by_checksum(context, remote, send_item->pk_dn);
520 
521         if (!session || session->sessionId != sessionId) {
522             COAP_ERR("secure_sendmsg_handler, need auth, from:%s",
523                      remote->addr);
524             /* todo */
525         } else {
526             session->heart_time = HAL_UptimeMs();
527             if (message->payloadlen < 128) {
528                 char buf[128];
529                 call_cb(context, remote, message, session->sessionKey, buf,
530                         send_item);
531             } else {
532                 char *buf = (char *)coap_malloc(message->payloadlen);
533                 if (buf) {
534                     call_cb(context, remote, message, session->sessionKey, buf,
535                             send_item);
536                     coap_free(buf);
537                 }
538             }
539         }
540     }
541 
542     if (CoAPUintOption_get(message, COAP_OPTION_OBSERVE, &obsVal) !=
543         COAP_SUCCESS) {
544         coap_free(send_item);
545     }
546 }
547 
alcs_sendmsg_secure(CoAPContext * ctx,AlcsDeviceKey * devKey,CoAPMessage * message,char observe,CoAPSendMsgHandler handler)548 int alcs_sendmsg_secure(CoAPContext *ctx, AlcsDeviceKey *devKey,
549                         CoAPMessage *message, char observe,
550                         CoAPSendMsgHandler handler)
551 {
552     session_item *session = NULL;
553 
554     if (!ctx || !devKey || !message) {
555         return COAP_ERROR_INVALID_PARAM;
556     }
557 
558     session = get_auth_session(ctx, devKey);
559     if (!session) {
560         COAP_DEBUG("alcs_sendmsg_secure, session not found");
561         return ALCS_ERR_AUTH_UNAUTH;
562     }
563 
564     return internal_secure_send(ctx, session, &devKey->addr, message, observe,
565                                 handler);
566 }
567 
alcs_sendrsp_secure(CoAPContext * ctx,AlcsDeviceKey * devKey,CoAPMessage * message,char observe,unsigned short msgid,CoAPLenString * token)568 int alcs_sendrsp_secure(CoAPContext *ctx, AlcsDeviceKey *devKey,
569                         CoAPMessage *message, char observe,
570                         unsigned short msgid, CoAPLenString *token)
571 {
572     session_item *session = NULL;
573 
574     COAP_DEBUG("alcs_sendrsp_secure");
575     if (!ctx || !devKey || !message) {
576         return COAP_ERROR_INVALID_PARAM;
577     }
578 
579     if (msgid == 0) {
580         message->header.msgid = CoAPMessageId_gen(ctx);
581     } else {
582         message->header.msgid = msgid;
583     }
584 
585     if (token) {
586         message->header.tokenlen = token->len;
587         memcpy(&message->token, token->data, token->len);
588     }
589 
590     session = get_auth_session(ctx, devKey);
591     if (!session) {
592         COAP_DEBUG("alcs_sendrsp_secure, session not found");
593         return ALCS_ERR_AUTH_UNAUTH;
594     }
595 
596     return internal_secure_send(ctx, session, &devKey->addr, message, observe,
597                                 NULL);
598 }
599 
req_payload_parser(const char * payload,int len,char ** seq,int * seqlen,char ** data,int * datalen)600 bool req_payload_parser(const char *payload, int len, char **seq, int *seqlen,
601                         char **data, int *datalen)
602 {
603     if (!payload || !len || !seq || !seqlen || !datalen || !data) {
604         return 0;
605     }
606 
607     *seq = json_get_value_by_name((char *)payload, len, "id", seqlen, NULL);
608 
609     *data =
610         json_get_value_by_name((char *)payload, len, "params", datalen, NULL);
611     return *data && datalen;
612 }
613 
on_auth_timer(void * param)614 void on_auth_timer(void *param)
615 {
616     CoAPContext *ctx = NULL;
617     if (!is_inited) {
618         return;
619     }
620 
621     ctx = (CoAPContext *)param;
622 #ifdef ALCS_CLIENT_ENABLED
623     {
624         extern void on_client_auth_timer(CoAPContext *);
625         on_client_auth_timer(ctx);
626     }
627 #endif
628 #ifdef ALCS_SERVER_ENABLED
629     {
630         extern void on_svr_auth_timer(CoAPContext *);
631         on_svr_auth_timer(ctx);
632     }
633 #endif
634 }
635 
alcs_add_ctl_group(CoAPContext * context,const char * groupid,const char * accesskey,const char * accesstoken)636 int alcs_add_ctl_group(CoAPContext *context, const char *groupid,
637                        const char *accesskey, const char *accesstoken)
638 {
639     ctl_group_item *item = NULL;
640     auth_list *lst = get_list(context);
641     if (!lst || lst->ctl_group_count >= KEY_MAXCOUNT) {
642         return COAP_ERROR_INVALID_LENGTH;
643     }
644 
645     item = (ctl_group_item *)coap_malloc(sizeof(ctl_group_item));
646     if (!item) {
647         return COAP_ERROR_MALLOC;
648     }
649     memset(item, 0, sizeof(ctl_group_item));
650 
651     do {
652         item->id = (char *)coap_malloc(strlen(groupid) + 1);
653         if (!item->id) {
654             break;
655         }
656 
657         item->accessKey = (char *)coap_malloc(strlen(accesskey) + 1);
658         if (!item->accessKey) {
659             break;
660         }
661 
662         item->accessToken = (char *)coap_malloc(strlen(accesstoken) + 1);
663         if (!item->accessToken) {
664             break;
665         }
666 
667         strcpy(item->accessKey, accesskey);
668         strcpy(item->accessToken, accesstoken);
669         strcpy(item->id, groupid);
670 
671         HAL_MutexLock(lst->list_mutex);
672         list_add_tail(&item->lst, &lst->lst_ctl_group);
673         ++lst->ctl_group_count;
674         HAL_MutexUnlock(lst->list_mutex);
675 
676         return 0;
677 
678     } while (0);
679 
680     if (item->id) {
681         coap_free(item->id);
682     }
683     if (item->accessKey) {
684         coap_free(item->accessKey);
685     }
686     if (item->accessToken) {
687         coap_free(item->accessToken);
688     }
689     coap_free(item);
690 
691     return COAP_ERROR_MALLOC;
692 }
693 
alcs_remove_ctl_group(CoAPContext * context,const char * groupid)694 int alcs_remove_ctl_group(CoAPContext *context, const char *groupid)
695 {
696     return 0;
697 }
698 
alcs_add_svr_group(CoAPContext * context,const char * groupid,const char * keyprefix,const char * secret)699 int alcs_add_svr_group(CoAPContext *context, const char *groupid,
700                        const char *keyprefix, const char *secret)
701 {
702     svr_group_item *item = NULL;
703     auth_list *lst = get_list(context);
704     if (!lst || lst->svr_group_count >= KEY_MAXCOUNT) {
705         return COAP_ERROR_INVALID_LENGTH;
706     }
707 
708     item = (svr_group_item *)coap_malloc(sizeof(svr_group_item));
709     if (!item) {
710         return COAP_ERROR_MALLOC;
711     }
712     memset(item, 0, sizeof(svr_group_item));
713 
714     do {
715         item->id = (char *)coap_malloc(strlen(groupid) + 1);
716         if (!item->id) {
717             break;
718         }
719 
720         item->keyInfo.secret = (char *)coap_malloc(strlen(secret) + 1);
721         if (!item->keyInfo.secret) {
722             break;
723         }
724 
725         strncpy(item->keyInfo.keyprefix, keyprefix,
726                 sizeof(item->keyInfo.keyprefix) - 1);
727         strcpy(item->keyInfo.secret, secret);
728         strcpy(item->id, groupid);
729 
730         HAL_MutexLock(lst->list_mutex);
731         list_add_tail(&item->lst, &lst->lst_svr_group);
732         ++lst->svr_group_count;
733         HAL_MutexUnlock(lst->list_mutex);
734 
735         return 0;
736 
737     } while (0);
738 
739     if (item->id) {
740         coap_free(item->id);
741     }
742     if (item->keyInfo.secret) {
743         coap_free(item->keyInfo.secret);
744     }
745     coap_free(item);
746 
747     return COAP_ERROR_MALLOC;
748 }
749 
alcs_remove_svr_group(CoAPContext * context,const char * groupid)750 int alcs_remove_svr_group(CoAPContext *context, const char *groupid)
751 {
752     return 0;
753 }
754 
alcs_utils_md5_hexstr(unsigned char input[16],unsigned char output[32])755 void alcs_utils_md5_hexstr(unsigned char input[16], unsigned char output[32])
756 {
757     unsigned char idx = 0;
758     unsigned char output_char = 0;
759 
760     for (idx = 0; idx < 16; idx++) {
761         if (((input[idx] >> 4) & 0x0F) <= 0x09) {
762             output_char = ((input[idx] >> 4) & 0x0F) + '0';
763         } else if (((input[idx] >> 4) & 0x0F) >= 0x0A) {
764             output_char = ((input[idx] >> 4) & 0x0F) + 'a' - 0x0A;
765         }
766         output[2 * idx] = output_char;
767 
768         if (((input[idx]) & 0x0F) <= 0x09) {
769             output_char = ((input[idx]) & 0x0F) + '0';
770         } else if (((input[idx]) & 0x0F) >= 0x0A) {
771             output_char = ((input[idx]) & 0x0F) + 'a' - 0x0A;
772         }
773         output[2 * idx + 1] = output_char;
774     }
775 }
776