66#include < klib/filesystem/virtual_fat.hpp>
77#include < klib/delay.hpp>
88#include < klib/string.hpp>
9+ #include < klib/crypt/base32.hpp>
910
1011#include " screen.hpp"
1112
@@ -193,7 +194,8 @@ namespace menu {
193194 " To create a new profile, add a new line below the CSV header in the following format:\r\n\r\n "
194195 " profile name, interval, digits, key in hex or in string format.\r\n\r\n Example:\r\n "
195196 " test, 30, 6, \" SOMEKEY123\"\r\n test, 30, 6, 0xab 0xcd 0xef 0x12 0x34 0x56 0x78 0x90\r\n "
196- " test, 30, 6, abcdef1234567890\r\n\r\n profile, interval, digits, key\r\n " ;
197+ " test, 30, 6, abcdef1234567890\r\n test, 30, 8, b32\" MFRGGZDFMYYTEMZUGU3DOOBZGA======\" "
198+ " \r\n\r\n profile, interval, digits, key\r\n " ;
197199
198200 constexpr static char config_csv[] = " profile, interval, digits, key\r\n " ;
199201
@@ -360,8 +362,8 @@ namespace menu {
360362 }
361363
362364 // parse the key. The key is till the end of the line. We can either have
363- // a hex array or a string. Hex string needs to have "" around it. Search
364- // for the ""
365+ // a hex array, string or a base32 string. Hex string needs to have "" around
366+ // it. Search for the ""
365367 const auto quotes = std::count (data, data + length, ' "' );
366368
367369 // check if we have a valid entry
@@ -370,18 +372,52 @@ namespace menu {
370372 }
371373
372374 if (quotes) {
373- // we are in string mode
375+ // check if have a base32 string or a hex string
374376 const auto start = std::find (data, data + length, ' "' );
375377 const auto end = std::find (start + 1 , data + length, ' "' );
376378
377- // copy the data directly into our buffer if it fits
378- if ((end - (start + 1 )) >= entry.key .max_size ()) {
379- return parse_result::invalid;
379+ // check for base 32
380+ if ((std::strncmp ((start - 3 ), " b32" , 3 ) == 0 ) ||
381+ (std::strncmp ((start - 3 ), " B32" , 3 ) == 0 ))
382+ {
383+ // support up to 320 bits on the input and output
384+ // input = 320 / 5 = 64 bytes
385+ // output = 320 / 8 = 40 bytes
386+ char input[65 ] = {};
387+ uint8_t buf[40 ];
388+
389+ // check if we can copy it to the local buffer
390+ if ((end - (start + 1 )) >= (sizeof (input) - 1 )) {
391+ return parse_result::invalid;
392+ }
393+
394+ // copy to the local buffer
395+ std::copy_n ((start + 1 ), end - (start + 1 ), input);
396+
397+ // decode the base32 value
398+ const uint32_t size = klib::crypt::base32::decode (input, buf);
399+
400+ // check if the conversion was successfull
401+ if (!size) {
402+ return parse_result::invalid;
403+ }
404+
405+ // copy the bytes to the key
406+ for (uint32_t i = 0 ; i < size; i++) {
407+ entry.key .push_back (buf[i]);
408+ }
380409 }
410+ else {
411+ // we are in string mode. copy the data directly
412+ // into our buffer if it fits
413+ if ((end - (start + 1 )) >= entry.key .max_size ()) {
414+ return parse_result::invalid;
415+ }
381416
382- // add all the characters
383- for (uint32_t i = 0 ; i < (end - (start + 1 )); i++) {
384- entry.key .push_back (start[1 + i]);
417+ // add all the characters
418+ for (uint32_t i = 0 ; i < (end - (start + 1 )); i++) {
419+ entry.key .push_back (start[1 + i]);
420+ }
385421 }
386422
387423 return parse_result::valid;
0 commit comments