Changeset 771 in openpam
 Timestamp:
 Mar 6, 2014, 5:54:58 PM (7 years ago)
 Location:
 trunk/lib/liboath
 Files:

 2 edited
Legend:
 Unmodified
 Added
 Removed

trunk/lib/liboath/oath_base32.c
r770 r771 38 38 #include <errno.h> 39 39 #include <stdint.h> 40 #include <stdio.h> 40 41 41 42 #include <security/oath.h> 42 43 43 static const char b32 [] =44 static const char b32enc[] = 44 45 "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 45 46 47 static const uint8_t b32dec[256] = { 48 ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, 49 ['E'] = 4, ['F'] = 5, ['G'] = 6, ['H'] = 7, 50 ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11, 51 ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15, 52 ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, 53 ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, 54 ['Y'] = 24, ['Z'] = 25, 55 56 ['a'] = 0, ['b'] = 1, ['c'] = 2, ['d'] = 3, 57 ['e'] = 4, ['f'] = 5, ['g'] = 6, ['h'] = 7, 58 ['i'] = 8, ['j'] = 9, ['k'] = 10, ['l'] = 11, 59 ['m'] = 12, ['n'] = 13, ['o'] = 14, ['p'] = 15, 60 ['q'] = 16, ['r'] = 17, ['s'] = 18, ['t'] = 19, 61 ['u'] = 20, ['v'] = 21, ['w'] = 22, ['x'] = 23, 62 ['y'] = 24, ['z'] = 25, 63 64 ['2'] = 26, ['3'] = 27, ['4'] = 28, ['5'] = 29, 65 ['6'] = 30, ['7'] = 31, 66 }; 67 46 68 /* 47 * Encode data in RFC 3548 base 32 representation. The target buffer must69 * Encode data in RFC 4648 base 32 representation. The target buffer must 48 70 * have room for base32_enclen(len) characters and a terminating NUL. 49 71 */ … … 53 75 uint64_t bits; 54 76 55 if (*olen <= base32_enclen(ilen)) 77 if (*olen <= base32_enclen(ilen)) { 78 errno = ENOSPC; 56 79 return (1); 80 } 57 81 *olen = 0; 58 82 while (ilen >= 5) { … … 65 89 ilen = 5; 66 90 in += 5; 67 out[0] = b32 [bits >> 35 & 0x1f];68 out[1] = b32 [bits >> 30 & 0x1f];69 out[2] = b32 [bits >> 25 & 0x1f];70 out[3] = b32 [bits >> 20 & 0x1f];71 out[4] = b32 [bits >> 15 & 0x1f];72 out[5] = b32 [bits >> 10 & 0x1f];73 out[6] = b32 [bits >> 5 & 0x1f];74 out[7] = b32 [bits & 0x1f];91 out[0] = b32enc[bits >> 35 & 0x1f]; 92 out[1] = b32enc[bits >> 30 & 0x1f]; 93 out[2] = b32enc[bits >> 25 & 0x1f]; 94 out[3] = b32enc[bits >> 20 & 0x1f]; 95 out[4] = b32enc[bits >> 15 & 0x1f]; 96 out[5] = b32enc[bits >> 10 & 0x1f]; 97 out[6] = b32enc[bits >> 5 & 0x1f]; 98 out[7] = b32enc[bits & 0x1f]; 75 99 *olen += 8; 76 100 out += 8; … … 88 112 bits = (uint64_t)in[0] << 32; 89 113 } 90 out[0] = b32 [bits >> 35 & 0x1f];91 out[1] = b32 [bits >> 30 & 0x1f];92 out[2] = ilen > 1 ? b32 [bits >> 25 & 0x1f] : '=';93 out[3] = ilen > 1 ? b32 [bits >> 20 & 0x1f] : '=';94 out[4] = ilen > 2 ? b32 [bits >> 15 & 0x1f] : '=';95 out[5] = ilen > 3 ? b32 [bits >> 10 & 0x1f] : '=';96 out[6] = ilen > 3 ? b32 [bits >> 5 & 0x1f] : '=';114 out[0] = b32enc[bits >> 35 & 0x1f]; 115 out[1] = b32enc[bits >> 30 & 0x1f]; 116 out[2] = ilen > 1 ? b32enc[bits >> 25 & 0x1f] : '='; 117 out[3] = ilen > 1 ? b32enc[bits >> 20 & 0x1f] : '='; 118 out[4] = ilen > 2 ? b32enc[bits >> 15 & 0x1f] : '='; 119 out[5] = ilen > 3 ? b32enc[bits >> 10 & 0x1f] : '='; 120 out[6] = ilen > 3 ? b32enc[bits >> 5 & 0x1f] : '='; 97 121 out[7] = '='; 98 122 *olen += 8; … … 105 129 106 130 /* 107 * Decode data in RFC 2548 base 32 representation, stopping at the131 * Decode data in RFC 4648 base 32 representation, stopping at the 108 132 * terminating NUL, the first invalid (nonbase32, nonwhitespace) 109 133 * character or after len characters, whichever comes first. 134 * 135 * Padding is handled sloppily: any padding character following the data 136 * is silently consumed. This not only simplifies the code but ensures 137 * compatibility with implementations which do not emit or understand 138 * padding. 110 139 * 111 140 * The olen argument is used by the caller to pass the size of the buffer … … 118 147 { 119 148 size_t len; 120 uint64_t bits; 121 int shift; 149 int bits, shift, padding; 122 150 123 for (len = 0, bits = 0, shift = 40; ilen && *in && *in != '='; ilen, ++in) { 124 if (*in == ' '  *in == '\t'  *in == '\r'  *in == '\n') { 151 for (bits = shift = padding = len = 0; ilen && *in; ilen, ++in) { 152 if (*in == ' '  *in == '\t'  *in == '\r'  *in == '\n'  153 (padding && *in == '=')) { 154 /* consume */ 125 155 continue; 126 } else if (*in >= 'A' && *in <= 'Z') { 127 shift = 5; 128 bits = (uint64_t)(*in  'A') << shift; 129 } else if (*in >= 'a' && *in <= 'z') { 130 shift = 5; 131 bits = (uint64_t)(*in  'a') << shift; 132 } else if (*in >= '2' && *in <= '7') { 133 shift = 5; 134 bits = (uint64_t)(*in  '2' + 26) << shift; 135 } else if (*in == '=') { 136 /* handled below */ 137 break; 156 } else if (!padding && b32dec[(int)*in]) { 157 /* shift into accumulator */ 158 shift += 5; 159 bits = bits << 5  b32dec[(int)*in]; 160 } else if (!padding && shift && *in == '=') { 161 /* final byte */ 162 shift = 0; 163 padding = 1; 138 164 } else { 139 goto bad; 165 /* error */ 166 *olen = 0; 167 errno = EINVAL; 168 return (1); 140 169 } 141 if (shift == 0) { 142 if ((len += 5) <= *olen) { 143 *out++ = (bits >> 32) & 0xff; 144 *out++ = (bits >> 24) & 0xff; 145 *out++ = (bits >> 16) & 0xff; 146 *out++ = (bits >> 8) & 0xff; 147 *out++ = bits & 0xff; 148 } 149 bits = 0; 150 shift = 40; 170 if (shift >= 8) { 171 /* output accumulated byte */ 172 shift = 8; 173 if (len++ < *olen) 174 *out++ = (bits >> shift) & 0xff; 151 175 } 152 176 } 153 if (ilen && *in == '=' && 154 (shift == 30  shift == 20  shift == 15  shift == 5)) { 155 /* 156 * Padding: 157 * 158 * 00 8 AA====== 30 159 * 00 00 16 AAAA==== 20 160 * 00 00 00 24 AAAAA=== 15 161 * 00 00 00 00 32 AAAAAAA= 5 162 * 163 * XXX We should check that the last few bits before the 164 * padding starts are zero. 165 */ 166 switch (shift) { 167 case 5: 168 if (++len <= *olen) 169 *out++ = (bits >> 32) & 0xff; 170 bits <<= 8; 171 case 15: 172 if (++len <= *olen) 173 *out++ = (bits >> 32) & 0xff; 174 bits <<= 8; 175 case 20: 176 if (++len <= *olen) 177 *out++ = (bits >> 32) & 0xff; 178 bits <<= 8; 179 case 30: 180 if (++len <= *olen) 181 *out++ = (bits >> 32) & 0xff; 182 bits <<= 8; 183 break; 184 default: 185 goto bad; 186 } 187 /* consume remaining padding and whitespace */ 188 for (; ilen && *in; ilen, ++in) { 189 if (*in == ' '  *in == '\t'  *in == '\r'  *in == '\n') 190 continue; 191 else if (*in == '=' && shift) 192 shift = 5; 193 else 194 goto bad; 195 } 177 /* report decoded length */ 178 *olen = len; 179 if (len > *olen) { 180 /* overflow */ 181 errno = ENOSPC; 182 return (1); 196 183 } 197 if (ilen)198 goto bad;199 *olen = len;200 if (len > *olen)201 return (1);202 184 return (0); 203 bad:204 *olen = 0;205 return (1);206 185 } 
trunk/lib/liboath/oath_base64.c
r770 r771 41 41 #include <security/oath.h> 42 42 43 static const char b64 [] =43 static const char b64enc[] = 44 44 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 45 45 "abcdefghijklmnopqrstuvwxyz" 46 46 "0123456789+/"; 47 47 48 static const uint8_t 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, 65 }; 66 48 67 /* 49 * Encode data in RFC 3548 base 64 representation. The target buffer must68 * Encode data in RFC 4648 base 64 representation. The target buffer must 50 69 * have room for base64_enclen(len) characters and a terminating NUL. 51 70 */ … … 65 84 ilen = 3; 66 85 in += 3; 67 out[0] = b64 [bits >> 18 & 0x3f];68 out[1] = b64 [bits >> 12 & 0x3f];69 out[2] = b64 [bits >> 6 & 0x3f];70 out[3] = b64 [bits & 0x3f];86 out[0] = b64enc[bits >> 18 & 0x3f]; 87 out[1] = b64enc[bits >> 12 & 0x3f]; 88 out[2] = b64enc[bits >> 6 & 0x3f]; 89 out[3] = b64enc[bits & 0x3f]; 71 90 *olen += 4; 72 91 out += 4; … … 80 99 bits = (uint32_t)in[0] << 16; 81 100 } 82 out[0] = b64 [bits >> 18 & 0x3f];83 out[1] = b64 [bits >> 12 & 0x3f];84 out[2] = ilen > 1 ? b64 [bits >> 6 & 0x3f] : '=';101 out[0] = b64enc[bits >> 18 & 0x3f]; 102 out[1] = b64enc[bits >> 12 & 0x3f]; 103 out[2] = ilen > 1 ? b64enc[bits >> 6 & 0x3f] : '='; 85 104 out[3] = '='; 86 105 *olen += 4; … … 93 112 94 113 /* 95 * Decode data in RFC 2548 base 64 representation, stopping at the114 * Decode data in RFC 4648 base 64 representation, stopping at the 96 115 * terminating NUL, the first invalid (nonbase64, nonwhitespace) 97 116 * character or after len characters, whichever comes first. 117 * 118 * Padding is handled sloppily: any padding character following the data 119 * is silently consumed. This not only simplifies the code but ensures 120 * compatibility with implementations which do not emit or understand 121 * padding. 98 122 * 99 123 * The olen argument is used by the caller to pass the size of the buffer … … 106 130 { 107 131 size_t len; 108 uint32_t bits; 109 int shift; 132 int bits, shift, padding; 110 133 111 for (len = 0, bits = 0, shift = 24; ilen && *in; ilen, ++in) { 112 if (*in == ' '  *in == '\t'  *in == '\r'  *in == '\n') { 134 for (bits = shift = padding = len = 0; ilen && *in; ilen, ++in) { 135 if (*in == ' '  *in == '\t'  *in == '\r'  *in == '\n'  136 (padding && *in == '=')) { 137 /* consume */ 113 138 continue; 114 } else if (*in >= 'A' && *in <= 'Z') { 115 shift = 6; 116 bits = (uint32_t)(*in  'A') << shift; 117 } else if (*in >= 'a' && *in <= 'z') { 118 shift = 6; 119 bits = (uint32_t)(*in  'a' + 26) << shift; 120 } else if (*in >= '0' && *in <= '9') { 121 shift = 6; 122 bits = (uint32_t)(*in  '0' + 52) << shift; 123 } else if (*in == '+') { 124 shift = 6; 125 bits = (uint32_t)62 << shift; 126 } else if (*in == '/') { 127 shift = 6; 128 bits = (uint32_t)63 << shift; 129 } else if (*in == '=') { 130 /* handled below */ 131 break; 139 } else if (!padding && b64dec[(int)*in]) { 140 /* shift into accumulator */ 141 shift += 6; 142 bits = bits << 6  b64dec[(int)*in]; 143 } else if (!padding && shift && *in == '=') { 144 /* final byte */ 145 shift = 0; 146 padding = 1; 132 147 } else { 133 goto bad; 148 /* error */ 149 *olen = 0; 150 errno = EINVAL; 151 return (1); 134 152 } 135 if (shift == 0) { 136 if ((len += 3) <= *olen) { 137 *out++ = (bits >> 16) & 0xff; 138 *out++ = (bits >> 8) & 0xff; 139 *out++ = bits & 0xff; 140 } 141 bits = 0; 142 shift = 24; 153 if (shift >= 8) { 154 /* output accumulated byte */ 155 shift = 8; 156 if (len++ < *olen) 157 *out++ = (bits >> shift) & 0xff; 143 158 } 144 159 } 145 if (ilen && *in == '=' && (shift == 12  shift == 6)) { 146 /* 147 * Padding: 148 * 149 * 00 8 AA== 12 150 * 00 00 16 AAA= 6 151 * 152 * XXX We should check that the last few bits before the 153 * padding starts are zero. 154 */ 155 switch (shift) { 156 case 6: 157 if (++len <= *olen) 158 *out++ = (bits >> 16) & 0xff; 159 bits <<= 8; 160 case 12: 161 if (++len <= *olen) 162 *out++ = (bits >> 16) & 0xff; 163 bits <<= 8; 164 break; 165 default: 166 goto bad; 167 } 168 /* consume remaining padding and whitespace */ 169 for (; ilen && *in; ilen, ++in) { 170 if (*in == ' '  *in == '\t'  *in == '\r'  *in == '\n') 171 continue; 172 else if (*in == '=' && shift) 173 shift = 6; 174 else 175 goto bad; 176 } 160 /* report decoded length */ 161 *olen = len; 162 if (len > *olen) { 163 /* overflow */ 164 errno = ENOSPC; 165 return (1); 177 166 } 178 if (ilen)179 goto bad;180 *olen = len;181 if (len > *olen)182 return (1);183 167 return (0); 184 bad:185 *olen = 0;186 return (1);187 168 }
Note: See TracChangeset
for help on using the changeset viewer.