Changeset 776 in openpam for trunk/lib/liboath/oath_base64.c


Ignore:
Timestamp:
Mar 9, 2014, 12:48:48 PM (7 years ago)
Author:
Dag-Erling Smørgrav
Message:

Encoder:

  • Return the desired length when the buffer is too small.
  • Annotate the switch so Bullseye doesn't complain about an uncovered default case.

Decoder:

  • The table approach was a good idea, but there was no way to tell the difference between a character that decodes as 0 and an invalid character. Modify the tables so an invalid character is indicated by 0xff instead of 0x00.
  • Check that padding starts in a valid position. Note that we still don't check for left-over bits.
  • The overflow test always failed, because we set *olen = len before comparing them.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/liboath/oath_base64.c

    r772 r776  
    4141#include <security/oath.h>
    4242
     43#include "oath_impl.h"
     44
    4345static const char b64enc[] =
    4446    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     
    4749
    4850static const char b64dec[256] = {
    49         ['A'] =  0, ['B'] =  1, ['C'] =  2, ['D'] =  3,
    50         ['E'] =  4, ['F'] =  5, ['G'] =  6, ['H'] =  7,
    51         ['I'] =  8, ['J'] =  9, ['K'] = 10, ['L'] = 11,
    52         ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15,
    53         ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19,
    54         ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23,
    55         ['Y'] = 24, ['Z'] = 25, ['a'] = 26, ['b'] = 27,
    56         ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31,
    57         ['g'] = 32, ['h'] = 33, ['i'] = 34, ['j'] = 35,
    58         ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39,
    59         ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43,
    60         ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47,
    61         ['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51,
    62         ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55,
    63         ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59,
    64         ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63,
     51        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     52        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     53        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     54        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     55        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     56        0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
     57        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
     58        0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     59        0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
     60        0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
     61        0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
     62        0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
     63        0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
     64        0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
     65        0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
     66        0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
     67        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     68        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     69        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     70        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     71        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     72        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     73        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     74        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     75        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     76        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     77        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     78        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     79        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     80        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     81        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     82        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    6583};
    6684
     
    7492        uint32_t bits;
    7593
    76         if (*olen <= base64_enclen(ilen))
     94        if (*olen <= base64_enclen(ilen)) {
     95                *olen = base64_enclen(ilen) + 1;
     96                errno = ENOSPC;
    7797                return (-1);
     98        }
    7899        *olen = 0;
    79100        while (ilen >= 3) {
     
    98119                case 1:
    99120                        bits |= (uint32_t)in[0] << 16;
     121                COVERAGE_NO_DEFAULT_CASE
    100122                }
    101123                out[0] = b64enc[bits >> 18 & 0x3f];
     
    137159                        /* consume */
    138160                        continue;
    139                 } else if (!padding && b64dec[(int)*in]) {
     161                } else if (!padding && b64dec[(int)*in] >= 0) {
    140162                        /* shift into accumulator */
    141163                        shift += 6;
    142164                        bits = bits << 6 | b64dec[(int)*in];
    143                 } else if (!padding && shift && *in == '=') {
     165                } else if (!padding && shift > 0 && shift != 6 && *in == '=') {
    144166                        /* final byte */
    145167                        shift = 0;
     
    159181        }
    160182        /* report decoded length */
    161         *olen = len;
    162183        if (len > *olen) {
    163184                /* overflow */
     185                *olen = len;
    164186                errno = ENOSPC;
    165187                return (-1);
    166188        }
     189        *olen = len;
    167190        return (0);
    168191}
Note: See TracChangeset for help on using the changeset viewer.