luat_lib_iotauth.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. // IoT鉴权函数, 用于生成各种云平台的参数
  2. #include "luat_base.h"
  3. #include "luat_crypto.h"
  4. #include "luat_malloc.h"
  5. #include "time.h"
  6. #define LUAT_LOG_TAG "iotauth"
  7. #include "luat_log.h"
  8. typedef struct onenet_msg{
  9. const char* produt_id;
  10. const char* device_name;
  11. const char* key;
  12. const char* method;
  13. const char* version;
  14. long long time;
  15. }onenet_msg_t;
  16. typedef struct {
  17. char et[32];
  18. char *version;
  19. char *method;
  20. char res[128];
  21. char sign[128];
  22. } sign_msg;
  23. typedef struct {
  24. char* old_str;
  25. char* str;
  26. }URL_PARAMETES;
  27. static void HexDump(char *pData, uint16_t len){
  28. for (int i = 0; i < len; i++) {
  29. printf("0x%02.2x ", (unsigned char)pData[i]);
  30. }
  31. printf("\n");
  32. }
  33. static int url_encoding_for_token(sign_msg* msg,char *token){
  34. int i,j,k,slen;
  35. sign_msg* temp_msg = msg;
  36. URL_PARAMETES url_patametes[] = {
  37. {"+","%2B"},
  38. {" ","%20"},
  39. {"/","%2F"},
  40. {"?","%3F"},
  41. {"%","%25"},
  42. {"#","%23"},
  43. {"&","%26"},
  44. {"=","%3D"},
  45. };
  46. char temp[128] = {0};
  47. slen = strlen(temp_msg->res);
  48. for (i = 0,j = 0; i < slen; i++) {
  49. for(k = 0; k < 8; k++){
  50. if(temp_msg->res[i] == url_patametes[k].old_str[0]) {
  51. memcpy(&temp[j],url_patametes[k].str,strlen(url_patametes[k].str));
  52. j+=3;
  53. break;
  54. }
  55. }
  56. if (k == 8) {
  57. temp[j++] = temp_msg->res[i];
  58. }
  59. }
  60. memcpy(temp_msg->res,temp,strlen(temp));
  61. temp_msg->res[strlen(temp)] = 0;
  62. memset(temp,0x00,sizeof(temp));
  63. slen = strlen(temp_msg->sign);
  64. for (i = 0,j = 0; i < slen; i++) {
  65. for(k = 0; k < 8; k++){
  66. if(temp_msg->sign[i] == url_patametes[k].old_str[0]) {
  67. memcpy(&temp[j],url_patametes[k].str,strlen(url_patametes[k].str));
  68. j+=3;
  69. break;
  70. }
  71. }
  72. if(k == 8){
  73. temp[j++] = temp_msg->sign[i];
  74. }
  75. }
  76. memcpy(temp_msg->sign,temp,strlen(temp));
  77. temp_msg->sign[strlen(temp)] = 0;
  78. sprintf(token, "version=%s&res=%s&et=%s&method=%s&sign=%s", temp_msg->version, temp_msg->res, temp_msg->et, temp_msg->method, temp_msg->sign);
  79. return strlen(token);
  80. }
  81. int onenet_token(onenet_msg_t* msg, long long time,char * method,char * version,char *token){
  82. size_t declen = 0, enclen = 0;
  83. char plaintext[64] = { 0 };
  84. char hmac[64] = { 0 };
  85. char StringForSignature[256] = { 0 };
  86. sign_msg sign = {0};
  87. sign.method = method;
  88. sign.version = version;
  89. sprintf(sign.et,"%lld",time);
  90. sprintf(sign.res,"products/%s/devices/%s",msg->produt_id,msg->device_name);
  91. luat_str_base64_decode((unsigned char *)plaintext, sizeof(plaintext), &declen, (const unsigned char * )msg->key, strlen((char*)msg->key));
  92. sprintf(StringForSignature, "%s\n%s\n%s\n%s", sign.et, sign.method, sign.res, sign.version);
  93. printf("StringForSignature:%d\n%s\n",declen,StringForSignature);
  94. if (!strcmp("md5", method)) {
  95. luat_crypto_hmac_md5_simple(plaintext, declen,StringForSignature, strlen(StringForSignature), hmac);
  96. }else if (!strcmp("sha1", method)) {
  97. luat_crypto_hmac_sha1_simple(plaintext, declen,StringForSignature, strlen(StringForSignature), hmac);
  98. }else if (!strcmp("sha256", method)) {
  99. luat_crypto_hmac_sha256_simple(plaintext, declen,StringForSignature, strlen(StringForSignature), hmac);
  100. }else{
  101. LLOGE("not support: %s",method);
  102. return -1;
  103. }
  104. luat_str_base64_encode((unsigned char *)sign.sign, sizeof(sign.sign), &enclen, (const unsigned char * )hmac, strlen(hmac));
  105. return url_encoding_for_token(&sign,token);
  106. }
  107. static int l_iotauth_aliyun(lua_State *L) {
  108. return 0;
  109. }
  110. static int l_iotauth_onenet(lua_State *L) {
  111. char token[200]={0};
  112. size_t len;
  113. onenet_msg_t onenet;
  114. onenet.device_name = luaL_checklstring(L, 1, &len);
  115. onenet.produt_id = luaL_checklstring(L, 2, &len);
  116. onenet.key = luaL_checklstring(L, 3, &len);
  117. onenet.method = luaL_optlstring(L, 4, "sha256", &len);
  118. onenet.time = luaL_optinteger(L, 5,time(NULL) + 3600);
  119. onenet.version = luaL_optlstring(L, 6, "2018-10-31", &len);
  120. len = onenet_token(&onenet, onenet.time,onenet.method,onenet.version,token);
  121. lua_pushlstring(L, token, len);
  122. return 1;
  123. }
  124. static int l_iotauth_iotda(lua_State *L) {
  125. return 0;
  126. }
  127. /* Max size of base64 encoded PSK = 64, after decode: 64/4*3 = 48*/
  128. #define DECODE_PSK_LENGTH 48
  129. /* Max size of conn Id */
  130. #define MAX_CONN_ID_LEN (6)
  131. static void get_next_conn_id(char *conn_id)
  132. {
  133. int i;
  134. srand((unsigned)luat_mcu_ticks());
  135. for (i = 0; i < MAX_CONN_ID_LEN - 1; i++) {
  136. int flag = rand() % 3;
  137. switch (flag) {
  138. case 0:
  139. conn_id[i] = (rand() % 26) + 'a';
  140. break;
  141. case 1:
  142. conn_id[i] = (rand() % 26) + 'A';
  143. break;
  144. case 2:
  145. conn_id[i] = (rand() % 10) + '0';
  146. break;
  147. }
  148. }
  149. conn_id[MAX_CONN_ID_LEN - 1] = '\0';
  150. }
  151. int qcloud_token(const char* product_id,const char* device_name,const char* device_secret,long long cur_timestamp,const char* method,const char* sdk_appid,const char* token){
  152. char *username = NULL;
  153. int username_len = 0;
  154. char conn_id[MAX_CONN_ID_LEN] = {};
  155. char username_sign[41] = {0};
  156. char psk_base64decode[DECODE_PSK_LENGTH];
  157. size_t psk_base64decode_len = 0;
  158. luat_str_base64_decode((unsigned char *)psk_base64decode, DECODE_PSK_LENGTH, &psk_base64decode_len,(unsigned char *)device_secret, strlen(device_secret));
  159. username_len = strlen(product_id) + strlen(device_name) + strlen(sdk_appid) + MAX_CONN_ID_LEN + 20;
  160. username = (char *)luat_heap_malloc(username_len);
  161. if (username == NULL) {
  162. printf("malloc username failed!\r\n");
  163. return -1;
  164. }
  165. get_next_conn_id(conn_id);
  166. printf("conn_id %s\n",conn_id);
  167. snprintf(username, username_len, "%s%s;%s;%s;%ld", product_id, device_name, sdk_appid,conn_id, cur_timestamp);
  168. if (!strcmp("sha1", method)) {
  169. luat_crypto_hmac_sha1_simple(username, strlen(username),psk_base64decode, psk_base64decode_len, username_sign);
  170. }else if (!strcmp("sha256", method)) {
  171. luat_crypto_hmac_sha256_simple(username, strlen(username),psk_base64decode, psk_base64decode_len, username_sign);
  172. }else{
  173. LLOGE("not support: %s",method);
  174. return -1;
  175. }
  176. char *username_sign_hex = (char *)luat_heap_malloc(strlen(username_sign)*2+1);
  177. memset(username_sign_hex, 0, strlen(username_sign)*2+1);
  178. luat_str_tohex(username_sign, strlen(username_sign), username_sign_hex);
  179. sprintf(token, "%s;hmacsha1", username_sign_hex);
  180. luat_heap_free(username);
  181. luat_heap_free(username_sign_hex);
  182. return strlen(token);
  183. }
  184. static int l_iotauth_qcloud(lua_State *L) {
  185. char token[200]={0};
  186. size_t len;
  187. const char* product_id = luaL_checklstring(L, 1, &len);
  188. const char* device_name = luaL_checklstring(L, 2, &len);
  189. const char* device_secret = luaL_checklstring(L, 3, &len);
  190. const char* method = luaL_optlstring(L, 4, "sha256", &len);
  191. long long cur_timestamp = luaL_optinteger(L, 5,time(NULL) + 3600);
  192. const char* sdk_appid = luaL_optlstring(L, 6, "12010126", &len);
  193. len = qcloud_token(product_id, device_name,device_secret,cur_timestamp,method,sdk_appid,token);
  194. lua_pushlstring(L, token, len);
  195. return 1;
  196. }
  197. int tuya_token(const char* device_id,const char* device_secret,long long cur_timestamp,const char* token){
  198. char hmac[64] = {0};
  199. char *token_temp = (char *)luat_heap_malloc(100);
  200. memset(token_temp, 0, 100);
  201. snprintf(token_temp, 100, "deviceId=%s,timestamp=%ld,secureMode=1,accessType=1", device_id, cur_timestamp);
  202. luat_crypto_hmac_sha256_simple(token_temp, strlen(token_temp),device_secret, strlen(device_secret), hmac);
  203. luat_str_tohex(hmac, strlen(hmac), token);
  204. luat_heap_free(token_temp);
  205. return strlen(token);
  206. }
  207. static int l_iotauth_tuya(lua_State *L) {
  208. char token[200]={0};
  209. size_t len;
  210. const char* device_id = luaL_checklstring(L, 1, &len);
  211. const char* device_secret = luaL_checklstring(L, 2, &len);
  212. long long cur_timestamp = luaL_optinteger(L, 3,time(NULL) + 3600);
  213. len = tuya_token(device_id,device_secret,cur_timestamp,token);
  214. lua_pushlstring(L, token, len);
  215. return 1;
  216. }
  217. static int baidu_token(const char* device_key,const char* device_secret,const char* method,long long cur_timestamp,const char* token){
  218. char crypto[64] = {0};
  219. char *token_temp = (char *)luat_heap_malloc(100);
  220. memset(token_temp, 0, 100);
  221. snprintf(token_temp, 100, "%s&%lld&%s%s",device_key,cur_timestamp,method,device_secret);
  222. if (!strcmp("MD5", method)) {
  223. luat_crypto_md5_simple(token_temp, strlen(token_temp),crypto);
  224. }else if (!strcmp("SHA256", method)) {
  225. luat_crypto_sha256_simple(token_temp, strlen(token_temp),crypto);
  226. }else{
  227. LLOGE("not support: %s",method);
  228. return -1;
  229. }
  230. luat_str_tohex(crypto, strlen(crypto), token);
  231. luat_heap_free(token_temp);
  232. return strlen(token);
  233. }
  234. static int l_iotauth_baidu(lua_State *L) {
  235. char token[200]={0};
  236. size_t len;
  237. const char* device_key = luaL_checklstring(L, 1, &len);
  238. const char* device_secret = luaL_checklstring(L, 2, &len);
  239. const char* method = luaL_optlstring(L, 3, "SHA256", &len);
  240. long long cur_timestamp = luaL_optinteger(L, 4,time(NULL) + 3600);
  241. len = baidu_token(device_key,device_secret,method,cur_timestamp,token);
  242. lua_pushlstring(L, token, len);
  243. return 1;
  244. }
  245. static int l_iotauth_aws(lua_State *L) {
  246. return 0;
  247. }
  248. #include "rotable2.h"
  249. static const rotable_Reg_t reg_iotauth[] =
  250. {
  251. { "aliyun" , ROREG_FUNC(l_iotauth_aliyun)},
  252. { "onenet" , ROREG_FUNC(l_iotauth_onenet)},
  253. { "iotda" , ROREG_FUNC(l_iotauth_iotda)},
  254. { "qcloud" , ROREG_FUNC(l_iotauth_qcloud)},
  255. { "tuya" , ROREG_FUNC(l_iotauth_tuya)},
  256. { "baidu" , ROREG_FUNC(l_iotauth_baidu)},
  257. { "aws" , ROREG_FUNC(l_iotauth_aws)},
  258. { NULL, ROREG_INT(0)}
  259. };
  260. LUAMOD_API int luaopen_iotauth( lua_State *L ) {
  261. luat_newlib2(L, reg_iotauth);
  262. return 1;
  263. }