File: | lib/base64.c |
Warning: | line 115, column 9 Value stored to 'line_len' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Base64 encoding/decoding (RFC1341) |
3 | * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi> |
4 | * |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. |
7 | */ |
8 | |
9 | #include <stdlib.h> |
10 | #include <string.h> |
11 | |
12 | #include "base64.h" |
13 | |
14 | static const unsigned char base64_table[65] = |
15 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
16 | |
17 | /* |
18 | * Calculated using: |
19 | * memset(dtable, 0x80, 256); |
20 | * for (i = 0; i < sizeof(base64_table) - 1; i++) |
21 | * dtable[base64_table[i]] = (unsigned char) i; |
22 | * dtable['='] = 0; |
23 | */ |
24 | static const unsigned char base64_decode_table[256] = { |
25 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
26 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
27 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
28 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x3e, 0x80, 0x80, 0x80, 0x3f, |
29 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x80, 0x80, |
30 | 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, |
31 | 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, |
32 | 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, |
33 | 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, |
34 | 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, |
35 | 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
36 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
37 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
38 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
39 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
40 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
41 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
42 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
43 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
44 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
45 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
46 | 0x80, 0x80, 0x80, 0x80}; |
47 | |
48 | bool_Bool |
49 | base64_validate(const unsigned char *src, size_t len) |
50 | { |
51 | for (size_t i = 0; i < len; i++) { |
52 | if (base64_decode_table[src[i]] == 0x80) |
53 | return false0; |
54 | } |
55 | |
56 | return true1; |
57 | } |
58 | |
59 | /** |
60 | * base64_encode - Base64 encode |
61 | * @src: Data to be encoded |
62 | * @len: Length of the data to be encoded |
63 | * @out_len: Pointer to output length variable, or %NULL if not used |
64 | * Returns: Allocated buffer of out_len bytes of encoded data, |
65 | * or %NULL on failure |
66 | * |
67 | * Caller is responsible for freeing the returned buffer. Returned buffer is |
68 | * nul terminated to make it easier to use as a C string. The nul terminator is |
69 | * not included in out_len. |
70 | */ |
71 | unsigned char * |
72 | base64_encode(const unsigned char *src, size_t len, size_t *out_len) |
73 | { |
74 | unsigned char *out, *pos; |
75 | const unsigned char *end, *in; |
76 | size_t olen; |
77 | int line_len; |
78 | |
79 | olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ |
80 | olen += olen / 72; /* line feeds */ |
81 | olen++; /* nul termination */ |
82 | if (olen < len) |
83 | return NULL((void*)0); /* integer overflow */ |
84 | out = malloc(olen); |
85 | if (out == NULL((void*)0)) |
86 | return NULL((void*)0); |
87 | |
88 | end = src + len; |
89 | in = src; |
90 | pos = out; |
91 | line_len = 0; |
92 | while (end - in >= 3) { |
93 | *pos++ = base64_table[in[0] >> 2]; |
94 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; |
95 | *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; |
96 | *pos++ = base64_table[in[2] & 0x3f]; |
97 | in += 3; |
98 | line_len += 4; |
99 | if (line_len >= 72) { |
100 | *pos++ = '\n'; |
101 | line_len = 0; |
102 | } |
103 | } |
104 | |
105 | if (end - in) { |
106 | *pos++ = base64_table[in[0] >> 2]; |
107 | if (end - in == 1) { |
108 | *pos++ = base64_table[(in[0] & 0x03) << 4]; |
109 | *pos++ = '='; |
110 | } else { |
111 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; |
112 | *pos++ = base64_table[(in[1] & 0x0f) << 2]; |
113 | } |
114 | *pos++ = '='; |
115 | line_len += 4; |
Value stored to 'line_len' is never read | |
116 | } |
117 | |
118 | *pos = '\0'; |
119 | if (out_len) |
120 | *out_len = (size_t)(pos - out); |
121 | return out; |
122 | } |
123 | |
124 | /** |
125 | * base64_decode - Base64 decode |
126 | * @src: Data to be decoded |
127 | * @len: Length of the data to be decoded |
128 | * @out_len: Pointer to output length variable |
129 | * Returns: Allocated buffer of out_len bytes of decoded data, |
130 | * or %NULL on failure |
131 | * |
132 | * Caller is responsible for freeing the returned buffer. |
133 | */ |
134 | unsigned char * |
135 | base64_decode(const unsigned char *src, size_t len, size_t *out_len) |
136 | { |
137 | unsigned char *out, *pos, block[4]; |
138 | size_t i, count, olen; |
139 | int pad = 0; |
140 | |
141 | count = 0; |
142 | for (i = 0; i < len; i++) { |
143 | if (base64_decode_table[src[i]] != 0x80) |
144 | count++; |
145 | } |
146 | |
147 | if (count == 0 || count % 4) |
148 | return NULL((void*)0); |
149 | |
150 | olen = (count / 4 * 3) + 1; |
151 | pos = out = malloc(olen); |
152 | if (out == NULL((void*)0)) |
153 | return NULL((void*)0); |
154 | |
155 | count = 0; |
156 | for (i = 0; i < len; i++) { |
157 | unsigned char tmp = base64_decode_table[src[i]]; |
158 | if (tmp == 0x80) |
159 | continue; |
160 | |
161 | if (src[i] == '=') |
162 | pad++; |
163 | block[count] = tmp; |
164 | count++; |
165 | if (count == 4) { |
166 | *pos++ = (unsigned char)((block[0] << 2) | (block[1] >> 4)); |
167 | *pos++ = (unsigned char)((block[1] << 4) | (block[2] >> 2)); |
168 | *pos++ = (unsigned char)((block[2] << 6) | block[3]); |
169 | count = 0; |
170 | if (pad) { |
171 | if (pad == 1) |
172 | pos--; |
173 | else if (pad == 2) |
174 | pos -= 2; |
175 | else { |
176 | /* Invalid padding */ |
177 | free(out); |
178 | return NULL((void*)0); |
179 | } |
180 | break; |
181 | } |
182 | } |
183 | } |
184 | *pos = '\0'; |
185 | |
186 | *out_len = (size_t)(pos - out); |
187 | return out; |
188 | } |