token_info.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "token_info.h"
  2. #include <furi_hal.h>
  3. #include <base32.h>
  4. #include <base64.h>
  5. #include <memset_s.h>
  6. #include <strnlen.h>
  7. #include "common.h"
  8. #include "../services/crypto/crypto.h"
  9. TokenInfo* token_info_alloc() {
  10. TokenInfo* tokenInfo = malloc(sizeof(TokenInfo));
  11. furi_check(tokenInfo != NULL);
  12. tokenInfo->algo = SHA1;
  13. tokenInfo->digits = TOTP_6_DIGITS;
  14. tokenInfo->duration = TOTP_TOKEN_DURATION_DEFAULT;
  15. tokenInfo->automation_features = TOKEN_AUTOMATION_FEATURE_NONE;
  16. return tokenInfo;
  17. }
  18. void token_info_free(TokenInfo* token_info) {
  19. if(token_info == NULL) return;
  20. free(token_info->name);
  21. free(token_info->token);
  22. free(token_info);
  23. }
  24. bool token_info_set_secret(
  25. TokenInfo* token_info,
  26. const char* plain_token_secret,
  27. size_t token_secret_length,
  28. PlainTokenSecretEncoding plain_token_secret_encoding,
  29. const uint8_t* iv) {
  30. if(token_secret_length == 0) return false;
  31. uint8_t* plain_secret;
  32. size_t plain_secret_length;
  33. size_t plain_secret_size;
  34. if(plain_token_secret_encoding == PLAIN_TOKEN_ENCODING_BASE32) {
  35. plain_secret_size = token_secret_length;
  36. plain_secret = malloc(plain_secret_size);
  37. furi_check(plain_secret != NULL);
  38. plain_secret_length =
  39. base32_decode((const uint8_t*)plain_token_secret, plain_secret, plain_secret_size);
  40. } else if(plain_token_secret_encoding == PLAIN_TOKEN_ENCODING_BASE64) {
  41. plain_secret_length = 0;
  42. plain_secret = base64_decode(
  43. (const uint8_t*)plain_token_secret,
  44. token_secret_length,
  45. &plain_secret_length,
  46. &plain_secret_size);
  47. furi_check(plain_secret != NULL);
  48. } else {
  49. return false;
  50. }
  51. bool result;
  52. if(plain_secret_length > 0) {
  53. token_info->token =
  54. totp_crypto_encrypt(plain_secret, plain_secret_length, iv, &token_info->token_length);
  55. result = true;
  56. } else {
  57. result = false;
  58. }
  59. memset_s(plain_secret, plain_secret_size, 0, plain_secret_size);
  60. free(plain_secret);
  61. return result;
  62. }
  63. bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
  64. switch(digits) {
  65. case 5:
  66. token_info->digits = TOTP_5_DIGITS;
  67. return true;
  68. case 6:
  69. token_info->digits = TOTP_6_DIGITS;
  70. return true;
  71. case 8:
  72. token_info->digits = TOTP_8_DIGITS;
  73. return true;
  74. default:
  75. break;
  76. }
  77. return false;
  78. }
  79. bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration) {
  80. if(duration >= 15) {
  81. token_info->duration = duration;
  82. return true;
  83. }
  84. return false;
  85. }
  86. bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) {
  87. if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA1_NAME) == 0) {
  88. token_info->algo = SHA1;
  89. return true;
  90. }
  91. if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA256_NAME) == 0) {
  92. token_info->algo = SHA256;
  93. return true;
  94. }
  95. if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA512_NAME) == 0) {
  96. token_info->algo = SHA512;
  97. return true;
  98. }
  99. if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_STEAM_NAME) == 0) {
  100. token_info->algo = STEAM;
  101. return true;
  102. }
  103. return false;
  104. }
  105. char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
  106. switch(token_info->algo) {
  107. case SHA1:
  108. return TOTP_TOKEN_ALGO_SHA1_NAME;
  109. case SHA256:
  110. return TOTP_TOKEN_ALGO_SHA256_NAME;
  111. case SHA512:
  112. return TOTP_TOKEN_ALGO_SHA512_NAME;
  113. case STEAM:
  114. return TOTP_TOKEN_ALGO_STEAM_NAME;
  115. default:
  116. break;
  117. }
  118. return NULL;
  119. }
  120. bool token_info_set_automation_feature_from_str(TokenInfo* token_info, const FuriString* str) {
  121. if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME) == 0) {
  122. token_info->automation_features |= TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END;
  123. return true;
  124. }
  125. if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME) == 0) {
  126. token_info->automation_features |= TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END;
  127. return true;
  128. }
  129. if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME) == 0) {
  130. token_info->automation_features |= TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER;
  131. return true;
  132. }
  133. if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME) == 0) {
  134. token_info->automation_features = TOKEN_AUTOMATION_FEATURE_NONE;
  135. return true;
  136. }
  137. return false;
  138. }
  139. TokenInfo* token_info_clone(const TokenInfo* src) {
  140. TokenInfo* clone = token_info_alloc();
  141. memcpy(clone, src, sizeof(TokenInfo));
  142. clone->token = malloc(src->token_length);
  143. furi_check(clone->token != NULL);
  144. memcpy(clone->token, src->token, src->token_length);
  145. int name_length = strnlen(src->name, TOTP_TOKEN_MAX_LENGTH);
  146. clone->name = malloc(name_length + 1);
  147. furi_check(clone->name != NULL);
  148. strlcpy(clone->name, src->name, name_length + 1);
  149. return clone;
  150. }