otp.c
changeset 60 a0629a9e3ee6
parent 57 4974e5368a29
equal deleted inserted replaced
59:b734b1727389 60:a0629a9e3ee6
     2 #include <stdint.h>
     2 #include <stdint.h>
     3 #include <string.h>
     3 #include <string.h>
     4 #include <time.h>
     4 #include <time.h>
     5 #include "sha1.h"
     5 #include "sha1.h"
     6 #include "otp.h"
     6 #include "otp.h"
       
     7 
       
     8 static uint8_t sanitize_base32_input(const char ch)
       
     9 {
       
    10     /* Google Authenticator checks for these values and corrects them,
       
    11        assuming this was a human error */
       
    12     if (ch == '0') return (uint8_t) 'O';
       
    13     else if (ch == '1') return (uint8_t) 'L';
       
    14     else if (ch == '8') return (uint8_t) 'B';
       
    15     return (uint8_t) ch;
       
    16 }
     7 
    17 
     8 static int base32_decode(const char *src, const int srclen, uint8_t *dst, const int dstlen)
    18 static int base32_decode(const char *src, const int srclen, uint8_t *dst, const int dstlen)
     9 {
    19 {
    10     const int len = srclen == -1 ? strlen((const char *) src) : srclen;
    20     const int len = srclen == -1 ? strlen((const char *) src) : srclen;
    11     int retval = 0;
    21     int retval = 0;
    12     uint32_t accum = 0;
    22     uint32_t accum = 0;
    13     int shifter = 0;
    23     int shifter = 0;
    14     int i;
    24     int i;
    15 
    25 
    16     for (i = 0; i < len; i++) {
    26     for (i = 0; i < len; i++) {
    17         const uint8_t ch = (uint8_t) src[i];
    27         const uint8_t ch = sanitize_base32_input(src[i]);
    18         uint8_t val;
    28         uint8_t val;
    19 
    29 
    20         if ((ch >= 'A') && (ch <= 'Z')) {
    30         if ((ch >= 'A') && (ch <= 'Z')) {
    21             val = ch - 'A';
    31             val = ch - 'A';
    22         } else if ((ch >= '2') && (ch <= '7')) {
    32         } else if ((ch >= '2') && (ch <= '7')) {
    44             retval++;
    54             retval++;
    45             shifter -= 8;
    55             shifter -= 8;
    46         }
    56         }
    47     }
    57     }
    48 
    58 
       
    59 #if 0   // Apparently for Google Authenticator, we just drop extra bits...?
    49     if (shifter > 0) {
    60     if (shifter > 0) {
    50         if (retval > dstlen) {
    61         if (retval > dstlen) {
    51             return -1;  /* dst too small */
    62             return -1;  /* dst too small */
    52         }
    63         }
    53         dst[retval] = (uint8_t) (accum & 0xFF);
    64         dst[retval] = (uint8_t) (accum & 0xFF);
    54         retval++;
    65         retval++;
    55     }
    66     }
       
    67 #endif
    56 
    68 
    57     return retval;
    69     return retval;
    58 }
    70 }
    59 
    71 
    60 int totp(const char *base32_secret, char *dst, int dstlen)
    72 int totp(const char *base32_secret, char *dst, int dstlen)