]> git.mar77i.info Git - ga-cli/commitdiff
break up and clean b32_decode a bit master
authormar77i <mar77i@protonmail.ch>
Wed, 22 May 2024 10:05:28 +0000 (12:05 +0200)
committermar77i <mar77i@protonmail.ch>
Wed, 22 May 2024 10:05:28 +0000 (12:05 +0200)
totp.c
totp_args.c

diff --git a/totp.c b/totp.c
index 3eda6889af1f17f3b8934658620012735100e0d1..27138d01bd709737ea7b1783836282ca450a049d 100644 (file)
--- a/totp.c
+++ b/totp.c
 
 #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;
     }
index ee28501d76eb36e0ebfe9a6febc0218f9fc177a1..4810a04465ef2c609c076c6a0051ee16d7d34efe 100644 (file)
@@ -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");