From: mar77i Date: Wed, 22 May 2024 10:05:28 +0000 (+0200) Subject: break up and clean b32_decode a bit X-Git-Url: https://git.mar77i.info/?a=commitdiff_plain;h=3e60ba90a1023dc2d8ffd8366b6da1b8aefb264b;p=ga-cli break up and clean b32_decode a bit --- diff --git a/totp.c b/totp.c index 3eda688..27138d0 100644 --- a/totp.c +++ b/totp.c @@ -20,127 +20,125 @@ #define INTERVAL_SECONDS 30 -int b32_decode(char *buf, size_t *len) { +static inline char *b32_advance_inptr(char *inptr) { + while (isspace(*inptr) || *inptr == '\n') + inptr++; + return inptr; +} + +static inline uint8_t b32_decode_char(uint8_t c) { const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; - size_t i = 0, used = 0; + char *ptr = strchr(alphabet, toupper(c)); + if (ptr == NULL || *ptr == '\0') { + fprintf( + stderr, + "Error: %s: invalid input: '%c' (%02X)\n", + __func__, + c, + c + ); + return UINT8_MAX; + } + return ptr - alphabet; +} + +static inline int b32_decode(char *buf, size_t *len) { + size_t used; uint8_t x; - char *ptr, *output = buf; - for(;;) { - while(isspace(buf[i]) || buf[i] == '\n') - i++; - if(buf[i] == '\0' || buf[i] == '=') + char *outptr = buf, *inptr = buf; + for (used = 0;; used = (used + 1) & 7) { + inptr = b32_advance_inptr(inptr); + if (*inptr == '\0' || *inptr == '=') break; - ptr = strchr(alphabet, toupper(buf[i])); - if(ptr == NULL || *ptr == '\0') { - fprintf( - stderr, - "Error: invalid input: '%c' (%02X)\n", - buf[i], - (uint8_t)buf[i] - ); + x = b32_decode_char(*inptr++); + if (x == UINT8_MAX) return -1; - } - i++; - x = ptr - alphabet; - switch(used++ % 8) { + switch (used) { case 0: - *output = x << 3; + *outptr = x << 3; break; case 1: - *output |= x >> 2; - output++; - *output = x << 6; + *outptr |= x >> 2; + outptr++; + *outptr = x << 6; break; case 2: - *output |= x << 1; + *outptr |= x << 1; break; case 3: - *output |= x >> 4; - output++; - *output = x << 4; + *outptr |= x >> 4; + outptr++; + *outptr = x << 4; break; case 4: - *output |= x >> 1; - output++; - *output = x << 7; + *outptr |= x >> 1; + outptr++; + *outptr = x << 7; break; case 5: - *output |= x << 2; + *outptr |= x << 2; break; case 6: - *output |= x >> 3; - output++; - *output = x << 5; + *outptr |= x >> 3; + outptr++; + *outptr = x << 5; break; case 7: - *output |= x; - output++; + *outptr |= x; + outptr++; break; } } - if(len != NULL) - *len = output - buf; + if (len != NULL) + *len = outptr - buf; return 0; } -static inline uint8_t *pack_be64( - uint8_t data[], - uint64_t value -) { +static inline uint8_t *pack_be64(uint8_t data[], uint64_t value) { size_t i; - for(i = 0; i < sizeof value; i++) - data[i] = (value >> ((sizeof value - 1 - i) * CHAR_BIT)) & 0xff; + for (i = 0; i < sizeof value; i++) + data[i] = value >> ((sizeof value - 1 - i) * CHAR_BIT); return data; } -int calculate_totp(const char *line, const char *search) { +static inline int calculate_totp(const char *line, const char *search) { size_t len = 0; unsigned int hmac_len = 0, label_len; - uint8_t data[sizeof(uint64_t)], i; - char *ptr, *find; - if(line == NULL) + uint8_t data[sizeof (uint64_t)], i, *ptr8; + char *find, *ptr = line ? strrchr(line, ':') : NULL; + if (ptr == NULL) return -1; - if(strlen(line) < 2) + if (strlen(line) < 2) return 0; - ptr = strrchr(line, ':'); - if(ptr == NULL) - return -1; label_len = ptr - line; if (search != NULL) { find = strcasestr(line, search); - if (find == NULL || find + strlen(search) - line > label_len) + if (find == NULL || find + strlen(search) > ptr) return 0; } ptr++; - if(b32_decode(ptr, &len) < 0) { - fprintf(stderr, "Error: b32_decode.\n"); + if (b32_decode(ptr, &len) < 0) return -1; - } // fill data with the current time divided by INTERVAL_SECONDS pack_be64(data, time(NULL) / INTERVAL_SECONDS); - if( - HMAC( - EVP_sha1(), - ptr, - len, - data, - sizeof data, - (uint8_t*)ptr, - &hmac_len - ) == NULL + ptr8 = (uint8_t*)ptr; + if ( + HMAC(EVP_sha1(), ptr, len, data, sizeof data, ptr8, &hmac_len) == NULL ) { fprintf(stderr, "\nError: hmac.\n"); return -1; } - i = ptr[hmac_len - 1] & 0xf; + i = ptr8[hmac_len - 1] & 0xf; printf( "%.*s: %06"PRIu32"\n", label_len, line, ( - (((uint8_t)ptr[i] & 0x7f) << 24) | ((uint8_t)ptr[i + 1] << 16) | - ((uint8_t)ptr[i + 2] << 8) | (uint8_t)ptr[i + 3] + ((ptr8[i] & 0x7f) << 24) + | (ptr8[i + 1] << 16) + | (ptr8[i + 2] << 8) + | ptr8[i + 3] ) % 1000000 ); return 0; @@ -157,10 +155,10 @@ int main(int argc, char *argv[]) { case -1: goto error; } - while(fgets(buf, sizeof buf, ta.fh) != NULL) - if(calculate_totp(buf, ta.search) < 0) + while (fgets(buf, sizeof buf, ta.fh) != NULL) + if (calculate_totp(buf, ta.search) < 0) goto error; - if(ferror(ta.fh)) { + if (ferror(ta.fh)) { fprintf(stderr, "Error: read error.\n"); goto error; } diff --git a/totp_args.c b/totp_args.c index ee28501..4810a04 100644 --- a/totp_args.c +++ b/totp_args.c @@ -50,7 +50,6 @@ static inline int parse_arg_file(struct totp_args *ta) { } #define TOTP_DEFAULT_FILE "/.otp_secrets" - static inline char *get_otp_secrets_path(void) { size_t len; char *ptr, *env = getenv("OTP_SECRETS");