otp: Some base32-decoding fixes to match what Google Authenticator expects. default tip
authorRyan C. Gordon <icculus@icculus.org>
Thu, 09 Apr 2020 02:15:46 -0400
changeset 60 a0629a9e3ee6
parent 59 b734b1727389
otp: Some base32-decoding fixes to match what Google Authenticator expects.
otp.c
--- a/otp.c	Thu Apr 09 02:02:11 2020 -0400
+++ b/otp.c	Thu Apr 09 02:15:46 2020 -0400
@@ -5,6 +5,16 @@
 #include "sha1.h"
 #include "otp.h"
 
+static uint8_t sanitize_base32_input(const char ch)
+{
+    /* Google Authenticator checks for these values and corrects them,
+       assuming this was a human error */
+    if (ch == '0') return (uint8_t) 'O';
+    else if (ch == '1') return (uint8_t) 'L';
+    else if (ch == '8') return (uint8_t) 'B';
+    return (uint8_t) ch;
+}
+
 static int base32_decode(const char *src, const int srclen, uint8_t *dst, const int dstlen)
 {
     const int len = srclen == -1 ? strlen((const char *) src) : srclen;
@@ -14,7 +24,7 @@
     int i;
 
     for (i = 0; i < len; i++) {
-        const uint8_t ch = (uint8_t) src[i];
+        const uint8_t ch = sanitize_base32_input(src[i]);
         uint8_t val;
 
         if ((ch >= 'A') && (ch <= 'Z')) {
@@ -46,6 +56,7 @@
         }
     }
 
+#if 0   // Apparently for Google Authenticator, we just drop extra bits...?
     if (shifter > 0) {
         if (retval > dstlen) {
             return -1;  /* dst too small */
@@ -53,6 +64,7 @@
         dst[retval] = (uint8_t) (accum & 0xFF);
         retval++;
     }
+#endif
 
     return retval;
 }