token_info.c 5.0 KB

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