luat_iotauth.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. @module iotauth
  3. @summary IoT鉴权库, 用于生成各种云平台的参数
  4. @version core V0007
  5. @date 2022.08.06
  6. @demo iotauth
  7. @tag LUAT_USE_IOTAUTH
  8. */
  9. #include "luat_base.h"
  10. #include "luat_crypto.h"
  11. #include "luat_mem.h"
  12. #include "time.h"
  13. #include "luat_str.h"
  14. #include "luat_mcu.h"
  15. #include "luat_iotauth.h"
  16. #define LUAT_LOG_TAG "iotauth"
  17. #include "luat_log.h"
  18. static const unsigned char hexchars_s[] = "0123456789abcdef";
  19. static const unsigned char hexchars_u[] = "0123456789ABCDEF";
  20. static void str_tohex(const char* str, size_t str_len, char* hex,uint8_t uppercase) {
  21. const unsigned char* hexchars = NULL;
  22. if (uppercase)
  23. hexchars = hexchars_u;
  24. else
  25. hexchars = hexchars_s;
  26. for (size_t i = 0; i < str_len; i++)
  27. {
  28. char ch = *(str+i);
  29. hex[i*2] = hexchars[(unsigned char)ch >> 4];
  30. hex[i*2+1] = hexchars[(unsigned char)ch & 0xF];
  31. }
  32. }
  33. void luat_aliyun_token(const char* product_key,const char* device_name,const char* device_secret,long long cur_timestamp,const char* method,uint8_t is_tls,char* client_id, char* user_name, char* password){
  34. char deviceId[64] = {0};
  35. char macSrc[200] = {0};
  36. char macRes[32] = {0};
  37. char timestamp_value[20] = {0};
  38. uint8_t securemode = 3;
  39. if (is_tls){
  40. securemode = 2;
  41. }
  42. sprintf_(timestamp_value,"%lld",cur_timestamp);
  43. sprintf_(deviceId,"%s.%s",product_key,device_name);
  44. /* setup clientid */
  45. if (!strcmp("hmacmd5", method)||!strcmp("HMACMD5", method)) {
  46. sprintf_(client_id,"%s|securemode=%d,signmethod=hmacmd5,timestamp=%s|",deviceId,securemode,timestamp_value);
  47. }else if (!strcmp("hmacsha1", method)||!strcmp("HMACSHA1", method)) {
  48. sprintf_(client_id,"%s|securemode=%d,signmethod=hmacsha1,timestamp=%s|",deviceId,securemode,timestamp_value);
  49. }else if (!strcmp("hmacsha256", method)||!strcmp("HMACSHA256", method)) {
  50. sprintf_(client_id,"%s|securemode=%d,signmethod=hmacsha256,timestamp=%s|",deviceId,securemode,timestamp_value);
  51. }else{
  52. LLOGE("not support: %s",method);
  53. return;
  54. }
  55. /* setup username */
  56. sprintf_(user_name,"%s&%s",device_name,product_key);
  57. /* setup password */
  58. memcpy(macSrc, "clientId", strlen("clientId"));
  59. memcpy(macSrc + strlen(macSrc), deviceId, strlen(deviceId));
  60. memcpy(macSrc + strlen(macSrc), "deviceName", strlen("deviceName"));
  61. memcpy(macSrc + strlen(macSrc), device_name, strlen(device_name));
  62. memcpy(macSrc + strlen(macSrc), "productKey", strlen("productKey"));
  63. memcpy(macSrc + strlen(macSrc), product_key, strlen(product_key));
  64. memcpy(macSrc + strlen(macSrc), "timestamp", strlen("timestamp"));
  65. memcpy(macSrc + strlen(macSrc), timestamp_value, strlen(timestamp_value));
  66. if (!strcmp("hmacmd5", method)||!strcmp("HMACMD5", method)) {
  67. luat_crypto_hmac_md5_simple(macSrc, strlen(macSrc),device_secret, strlen(device_secret), macRes);
  68. str_tohex(macRes, 16, password,1);
  69. }else if (!strcmp("hmacsha1", method)||!strcmp("HMACSHA1", method)) {
  70. luat_crypto_hmac_sha1_simple(macSrc, strlen(macSrc),device_secret, strlen(device_secret), macRes);
  71. str_tohex(macRes, 20, password,1);
  72. }else if (!strcmp("hmacsha256", method)||!strcmp("HMACSHA256", method)) {
  73. luat_crypto_hmac_sha256_simple(macSrc, strlen(macSrc),device_secret, strlen(device_secret), macRes);
  74. str_tohex(macRes, 32, password,1);
  75. }else{
  76. LLOGE("not support: %s",method);
  77. return;
  78. }
  79. }
  80. typedef struct {
  81. char et[32];
  82. char version[12];
  83. char method[12];
  84. char res[64];
  85. char sign[64];
  86. } sign_msg;
  87. typedef struct {
  88. char* old_str;
  89. char* str;
  90. }URL_PARAMETES;
  91. static int url_encoding_for_token(sign_msg* msg,char *token){
  92. int i,j,k,slen;
  93. sign_msg* temp_msg = msg;
  94. URL_PARAMETES url_patametes[] = {
  95. {"+","%2B"},
  96. {" ","%20"},
  97. {"/","%2F"},
  98. {"?","%3F"},
  99. {"%","%25"},
  100. {"#","%23"},
  101. {"&","%26"},
  102. {"=","%3D"},
  103. };
  104. char temp[64] = {0};
  105. slen = strlen(temp_msg->res);
  106. for (i = 0,j = 0; i < slen; i++) {
  107. for(k = 0; k < 8; k++){
  108. if(temp_msg->res[i] == url_patametes[k].old_str[0]) {
  109. memcpy(&temp[j],url_patametes[k].str,strlen(url_patametes[k].str));
  110. j+=3;
  111. break;
  112. }
  113. }
  114. if (k == 8) {
  115. temp[j++] = temp_msg->res[i];
  116. }
  117. }
  118. memcpy(temp_msg->res,temp,strlen(temp));
  119. temp_msg->res[strlen(temp)] = 0;
  120. memset(temp,0x00,sizeof(temp));
  121. slen = strlen(temp_msg->sign);
  122. for (i = 0,j = 0; i < slen; i++) {
  123. for(k = 0; k < 8; k++){
  124. if(temp_msg->sign[i] == url_patametes[k].old_str[0]) {
  125. memcpy(&temp[j],url_patametes[k].str,strlen(url_patametes[k].str));
  126. j+=3;
  127. break;
  128. }
  129. }
  130. if(k == 8){
  131. temp[j++] = temp_msg->sign[i];
  132. }
  133. }
  134. memcpy(temp_msg->sign,temp,strlen(temp));
  135. temp_msg->sign[strlen(temp)] = 0;
  136. if(snprintf_(token,PASSWORD_LEN, "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)<0){
  137. return -1;
  138. }
  139. return strlen(token);
  140. }
  141. void luat_onenet_token(const char* product_id,const char* device_name,const char* device_secret,long long cur_timestamp,char * method,char * version,char *token){
  142. size_t declen = 0, enclen = 0,hmac_len = 0;
  143. char plaintext[64] = { 0 };
  144. char hmac[64] = { 0 };
  145. char StringForSignature[256] = { 0 };
  146. sign_msg sign = {0};
  147. memcpy(sign.method, method, strlen(method));
  148. memcpy(sign.version, version, strlen(version));
  149. sprintf_(sign.et,"%lld",cur_timestamp);
  150. sprintf_(sign.res,"products/%s/devices/%s",product_id,device_name);
  151. luat_str_base64_decode((unsigned char *)plaintext, sizeof(plaintext), &declen, (const unsigned char * )device_secret, strlen((char*)device_secret));
  152. sprintf_(StringForSignature, "%s\n%s\n%s\n%s", sign.et, sign.method, sign.res, sign.version);
  153. if (!strcmp("md5", method)||!strcmp("MD5", method)) {
  154. luat_crypto_hmac_md5_simple(StringForSignature, strlen(StringForSignature), plaintext, declen, hmac);
  155. hmac_len = 16;
  156. }else if (!strcmp("sha1", method)||!strcmp("SHA1", method)) {
  157. luat_crypto_hmac_sha1_simple(StringForSignature, strlen(StringForSignature),plaintext, declen, hmac);
  158. hmac_len = 20;
  159. }else if (!strcmp("sha256", method)||!strcmp("SHA256", method)) {
  160. luat_crypto_hmac_sha256_simple(StringForSignature, strlen(StringForSignature),plaintext, declen, hmac);
  161. hmac_len = 32;
  162. }else{
  163. LLOGE("not support: %s",method);
  164. return;
  165. }
  166. luat_str_base64_encode((unsigned char *)sign.sign, sizeof(sign.sign), &enclen, (const unsigned char * )hmac, hmac_len);
  167. url_encoding_for_token(&sign,token);
  168. }
  169. void luat_iotda_token(const char* device_id,const char* device_secret,long long cur_timestamp,int ins_timestamp,char* client_id,const char* password){
  170. char hmac[65] = {0};
  171. char timestamp[11] = {0};
  172. struct tm *timeinfo = localtime( &cur_timestamp );
  173. if(snprintf_(timestamp, 11, "%04d%02d%02d%02d", (timeinfo->tm_year)+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour)<0){
  174. return;
  175. }
  176. snprintf_(client_id, CLIENT_ID_LEN, "%s_0_%d_%s", device_id,ins_timestamp,timestamp);
  177. luat_crypto_hmac_sha256_simple(device_secret, strlen(device_secret),timestamp, strlen(timestamp), hmac);
  178. str_tohex(hmac, 32, password,0);
  179. }
  180. /* Max size of base64 encoded PSK = 64, after decode: 64/4*3 = 48*/
  181. #define DECODE_PSK_LENGTH 48
  182. /* Max size of conn Id */
  183. #define MAX_CONN_ID_LEN (6)
  184. static void get_next_conn_id(char *conn_id){
  185. size_t i;
  186. luat_crypto_trng(conn_id, 5);
  187. for (i = 0; i < MAX_CONN_ID_LEN - 1; i++) {
  188. conn_id[i] = (conn_id[i] % 26) + 'a';
  189. }
  190. conn_id[MAX_CONN_ID_LEN - 1] = '\0';
  191. }
  192. void luat_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,char* username,char* password){
  193. char conn_id[MAX_CONN_ID_LEN] = {0};
  194. char username_sign[41] = {0};
  195. char psk_base64decode[DECODE_PSK_LENGTH] = {0};
  196. size_t psk_base64decode_len = 0;
  197. luat_str_base64_decode((unsigned char *)psk_base64decode, DECODE_PSK_LENGTH, &psk_base64decode_len,(unsigned char *)device_secret, strlen(device_secret));
  198. get_next_conn_id(conn_id);
  199. snprintf_(username, USER_NAME_LEN,"%s%s;%s;%s;%lld", product_id, device_name, sdk_appid,conn_id, cur_timestamp);
  200. if (!strcmp("sha1", method)||!strcmp("SHA1", method)) {
  201. luat_crypto_hmac_sha1_simple(username, strlen(username),psk_base64decode, psk_base64decode_len, username_sign);
  202. }else if (!strcmp("sha256", method)||!strcmp("SHA256", method)) {
  203. luat_crypto_hmac_sha256_simple(username, strlen(username),psk_base64decode, psk_base64decode_len, username_sign);
  204. }else{
  205. LLOGE("not support: %s",method);
  206. return;
  207. }
  208. char username_sign_hex[100] = {0};
  209. if (!strcmp("sha1", method)||!strcmp("SHA1", method)) {
  210. str_tohex(username_sign, 20, username_sign_hex,0);
  211. snprintf_(password, PASSWORD_LEN,"%s;hmacsha1", username_sign_hex);
  212. }else if (!strcmp("sha256", method)||!strcmp("SHA256", method)) {
  213. str_tohex(username_sign, 32, username_sign_hex,0);
  214. snprintf_(password, PASSWORD_LEN,"%s;hmacsha256", username_sign_hex);
  215. }
  216. }
  217. void luat_tuya_token(const char* device_id,const char* device_secret,long long cur_timestamp,const char* password){
  218. char hmac[65] = {0};
  219. char token_temp[100] = {0};
  220. snprintf_(token_temp, 100, "deviceId=%s,timestamp=%lld,secureMode=1,accessType=1", device_id, cur_timestamp);
  221. luat_crypto_hmac_sha256_simple(token_temp, strlen(token_temp),device_secret, strlen(device_secret), hmac);
  222. str_tohex(hmac, 32, password,0);
  223. }
  224. void luat_baidu_token(const char* iot_core_id,const char* device_key,const char* device_secret,const char* method,long long cur_timestamp,char* username,char* password){
  225. char crypto[64] = {0};
  226. char token_temp[100] = {0};
  227. if (!strcmp("MD5", method)||!strcmp("md5", method)) {
  228. if (cur_timestamp){
  229. snprintf_(username,USER_NAME_LEN, "thingidp@%s|%s|%lld|%s",iot_core_id,device_key,cur_timestamp,"MD5");
  230. }else{
  231. snprintf_(username,USER_NAME_LEN, "thingidp@%s|%s|%s",iot_core_id,device_key,"MD5");
  232. }
  233. snprintf_(token_temp, 100, "%s&%lld&%s%s",device_key,cur_timestamp,"MD5",device_secret);
  234. luat_crypto_md5_simple(token_temp, strlen(token_temp),crypto);
  235. str_tohex(crypto, 16, password,0);
  236. }else if (!strcmp("SHA256", method)||!strcmp("sha256", method)) {
  237. if (cur_timestamp){
  238. snprintf_(username,USER_NAME_LEN, "thingidp@%s|%s|%lld|%s",iot_core_id,device_key,cur_timestamp,"SHA256");
  239. }else{
  240. snprintf_(username,USER_NAME_LEN, "thingidp@%s|%s|%s",iot_core_id,device_key,"SHA256");
  241. }
  242. snprintf_(token_temp, 100, "%s&%lld&%s%s",device_key,cur_timestamp,"SHA256",device_secret);
  243. luat_crypto_sha256_simple(token_temp, strlen(token_temp),crypto);
  244. str_tohex(crypto, 32, password,0);
  245. }else{
  246. LLOGE("not support: %s",method);
  247. }
  248. return;
  249. }