naev 0.12.5
base64.c
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
4/*
5 * compliant with rfc3548
6 */
8#include <stdint.h>
9#include <stdlib.h>
10#include <string.h>
12
13#include "base64.h"
14
15/* encode table - base 64 alphabet as defined by the rfc */
16static const char cb64[64] =
17 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
18/* generate decode table at compile time */
19#define B64( _ ) \
20 ( ( _ ) == 'A' ? 0 \
21 : ( _ ) == 'B' ? 1 \
22 : ( _ ) == 'C' ? 2 \
23 : ( _ ) == 'D' ? 3 \
24 : ( _ ) == 'E' ? 4 \
25 : ( _ ) == 'F' ? 5 \
26 : ( _ ) == 'G' ? 6 \
27 : ( _ ) == 'H' ? 7 \
28 : ( _ ) == 'I' ? 8 \
29 : ( _ ) == 'J' ? 9 \
30 : ( _ ) == 'K' ? 10 \
31 : ( _ ) == 'L' ? 11 \
32 : ( _ ) == 'M' ? 12 \
33 : ( _ ) == 'N' ? 13 \
34 : ( _ ) == 'O' ? 14 \
35 : ( _ ) == 'P' ? 15 \
36 : ( _ ) == 'Q' ? 16 \
37 : ( _ ) == 'R' ? 17 \
38 : ( _ ) == 'S' ? 18 \
39 : ( _ ) == 'T' ? 19 \
40 : ( _ ) == 'U' ? 20 \
41 : ( _ ) == 'V' ? 21 \
42 : ( _ ) == 'W' ? 22 \
43 : ( _ ) == 'X' ? 23 \
44 : ( _ ) == 'Y' ? 24 \
45 : ( _ ) == 'Z' ? 25 \
46 : ( _ ) == 'a' ? 26 \
47 : ( _ ) == 'b' ? 27 \
48 : ( _ ) == 'c' ? 28 \
49 : ( _ ) == 'd' ? 29 \
50 : ( _ ) == 'e' ? 30 \
51 : ( _ ) == 'f' ? 31 \
52 : ( _ ) == 'g' ? 32 \
53 : ( _ ) == 'h' ? 33 \
54 : ( _ ) == 'i' ? 34 \
55 : ( _ ) == 'j' ? 35 \
56 : ( _ ) == 'k' ? 36 \
57 : ( _ ) == 'l' ? 37 \
58 : ( _ ) == 'm' ? 38 \
59 : ( _ ) == 'n' ? 39 \
60 : ( _ ) == 'o' ? 40 \
61 : ( _ ) == 'p' ? 41 \
62 : ( _ ) == 'q' ? 42 \
63 : ( _ ) == 'r' ? 43 \
64 : ( _ ) == 's' ? 44 \
65 : ( _ ) == 't' ? 45 \
66 : ( _ ) == 'u' ? 46 \
67 : ( _ ) == 'v' ? 47 \
68 : ( _ ) == 'w' ? 48 \
69 : ( _ ) == 'x' ? 49 \
70 : ( _ ) == 'y' ? 50 \
71 : ( _ ) == 'z' ? 51 \
72 : ( _ ) == '0' ? 52 \
73 : ( _ ) == '1' ? 53 \
74 : ( _ ) == '2' ? 54 \
75 : ( _ ) == '3' ? 55 \
76 : ( _ ) == '4' ? 56 \
77 : ( _ ) == '5' ? 57 \
78 : ( _ ) == '6' ? 58 \
79 : ( _ ) == '7' ? 59 \
80 : ( _ ) == '8' ? 60 \
81 : ( _ ) == '9' ? 61 \
82 : ( _ ) == '+' ? 62 \
83 : ( _ ) == '/' ? 63 \
84 : -1 )
85static const signed char cd64[256] =
86 { /* makes it much faster */
87 B64( 0 ), B64( 1 ), B64( 2 ), B64( 3 ), B64( 4 ), B64( 5 ),
88 B64( 6 ), B64( 7 ), B64( 8 ), B64( 9 ), B64( 10 ), B64( 11 ),
89 B64( 12 ), B64( 13 ), B64( 14 ), B64( 15 ), B64( 16 ), B64( 17 ),
90 B64( 18 ), B64( 19 ), B64( 20 ), B64( 21 ), B64( 22 ), B64( 23 ),
91 B64( 24 ), B64( 25 ), B64( 26 ), B64( 27 ), B64( 28 ), B64( 29 ),
92 B64( 30 ), B64( 31 ), B64( 32 ), B64( 33 ), B64( 34 ), B64( 35 ),
93 B64( 36 ), B64( 37 ), B64( 38 ), B64( 39 ), B64( 40 ), B64( 41 ),
94 B64( 42 ), B64( 43 ), B64( 44 ), B64( 45 ), B64( 46 ), B64( 47 ),
95 B64( 48 ), B64( 49 ), B64( 50 ), B64( 51 ), B64( 52 ), B64( 53 ),
96 B64( 54 ), B64( 55 ), B64( 56 ), B64( 57 ), B64( 58 ), B64( 59 ),
97 B64( 60 ), B64( 61 ), B64( 62 ), B64( 63 ), B64( 64 ), B64( 65 ),
98 B64( 66 ), B64( 67 ), B64( 68 ), B64( 69 ), B64( 70 ), B64( 71 ),
99 B64( 72 ), B64( 73 ), B64( 74 ), B64( 75 ), B64( 76 ), B64( 77 ),
100 B64( 78 ), B64( 79 ), B64( 80 ), B64( 81 ), B64( 82 ), B64( 83 ),
101 B64( 84 ), B64( 85 ), B64( 86 ), B64( 87 ), B64( 88 ), B64( 89 ),
102 B64( 90 ), B64( 91 ), B64( 92 ), B64( 93 ), B64( 94 ), B64( 95 ),
103 B64( 96 ), B64( 97 ), B64( 98 ), B64( 99 ), B64( 100 ), B64( 101 ),
104 B64( 102 ), B64( 103 ), B64( 104 ), B64( 105 ), B64( 106 ), B64( 107 ),
105 B64( 108 ), B64( 109 ), B64( 110 ), B64( 111 ), B64( 112 ), B64( 113 ),
106 B64( 114 ), B64( 115 ), B64( 116 ), B64( 117 ), B64( 118 ), B64( 119 ),
107 B64( 120 ), B64( 121 ), B64( 122 ), B64( 123 ), B64( 124 ), B64( 125 ),
108 B64( 126 ), B64( 127 ), B64( 128 ), B64( 129 ), B64( 130 ), B64( 131 ),
109 B64( 132 ), B64( 133 ), B64( 134 ), B64( 135 ), B64( 136 ), B64( 137 ),
110 B64( 138 ), B64( 139 ), B64( 140 ), B64( 141 ), B64( 142 ), B64( 143 ),
111 B64( 144 ), B64( 145 ), B64( 146 ), B64( 147 ), B64( 148 ), B64( 149 ),
112 B64( 150 ), B64( 151 ), B64( 152 ), B64( 153 ), B64( 154 ), B64( 155 ),
113 B64( 156 ), B64( 157 ), B64( 158 ), B64( 159 ), B64( 160 ), B64( 161 ),
114 B64( 162 ), B64( 163 ), B64( 164 ), B64( 165 ), B64( 166 ), B64( 167 ),
115 B64( 168 ), B64( 169 ), B64( 170 ), B64( 171 ), B64( 172 ), B64( 173 ),
116 B64( 174 ), B64( 175 ), B64( 176 ), B64( 177 ), B64( 178 ), B64( 179 ),
117 B64( 180 ), B64( 181 ), B64( 182 ), B64( 183 ), B64( 184 ), B64( 185 ),
118 B64( 186 ), B64( 187 ), B64( 188 ), B64( 189 ), B64( 190 ), B64( 191 ),
119 B64( 192 ), B64( 193 ), B64( 194 ), B64( 195 ), B64( 196 ), B64( 197 ),
120 B64( 198 ), B64( 199 ), B64( 200 ), B64( 201 ), B64( 202 ), B64( 203 ),
121 B64( 204 ), B64( 205 ), B64( 206 ), B64( 207 ), B64( 208 ), B64( 209 ),
122 B64( 210 ), B64( 211 ), B64( 212 ), B64( 213 ), B64( 214 ), B64( 215 ),
123 B64( 216 ), B64( 217 ), B64( 218 ), B64( 219 ), B64( 220 ), B64( 221 ),
124 B64( 222 ), B64( 223 ), B64( 224 ), B64( 225 ), B64( 226 ), B64( 227 ),
125 B64( 228 ), B64( 229 ), B64( 230 ), B64( 231 ), B64( 232 ), B64( 233 ),
126 B64( 234 ), B64( 235 ), B64( 236 ), B64( 237 ), B64( 238 ), B64( 239 ),
127 B64( 240 ), B64( 241 ), B64( 242 ), B64( 243 ), B64( 244 ), B64( 245 ),
128 B64( 246 ), B64( 247 ), B64( 248 ), B64( 249 ), B64( 250 ), B64( 251 ),
129 B64( 252 ), B64( 253 ), B64( 254 ), B64( 255 ) };
130
131/*
132 * encodes src of sz length storing the new length in len
133 */
134char *base64_encode( size_t *len, const char *src, size_t sz )
135{
136 char *r;
137 size_t i, c;
138 uint32_t n;
139 uint8_t ch[4], pad;
140
141 /* create r */
142 c = ( sz + 2 ) / 3 * 4;
143 c += ( c - 1 ) / 76 + 1; /* newlines, null byte */
144 r = malloc( c );
145
146 /* setup padding */
147 pad = ( ( sz % 3 ) == 0 ) ? 0 : 3 - sz % 3;
148
149 /* time to do the bulk work */
150 i = 0;
151 for ( c = 0; c < sz; c += 3 ) {
152
153 /* specification wants newline after every 76 characters */
154 if ( ( c > 0 ) && ( ( c / 3 * 4 ) % 76 == 0 ) )
155 r[i++] = '\n';
156
157 /* n is 24 bits */
158 n = ( (uint8_t)src[c] << 16 );
159 n += ( c + 1 < sz ) ? ( (uint8_t)src[c + 1] << 8 )
160 : 0; /* may be out of range */
161 n += ( c + 2 < sz ) ? ( (uint8_t)src[c + 2] << 0 )
162 : 0; /* may be out of range */
163
164 /* ch[0-3] are 6 bits each */
165 ch[0] = ( n >> 18 ) & 63;
166 ch[1] = ( n >> 12 ) & 63;
167 ch[2] = ( n >> 6 ) & 63;
168 ch[3] = ( n >> 0 ) & 63;
169
170 /* add to str */
171 r[i++] = cb64[ch[0]];
172 r[i++] = cb64[ch[1]];
173 r[i++] = cb64[ch[2]];
174 r[i++] = cb64[ch[3]];
175 }
176
177 for ( c = 0; c < pad; c++ )
178 r[i - c - 1] = '=';
179 r[i] = '\0'; /* it'll be a valid string */
180 ( *len ) = i;
181
182 return r;
183}
184
185/*
186 * decode the buffer, same syntax as base64_encode
187 */
188#define dec_valid( inp ) ( cd64[(int)inp] == -1 ) ? 0 : 1
189#define dec_ch( inp ) cd64[(int)inp]
190char *base64_decode( size_t *len, const char *src, size_t sz )
191{
192 char *r, *dat, pad;
193 size_t c, i, j;
194
195 /* allocate r */
196 c = sz * 3 / 4 + 2;
197 r = malloc( c );
198
199 /* create a clean version of the text */
200 pad = 0;
201 dat = malloc( sz );
202 j = 0;
203 for ( i = 0; i < sz; i++ ) {
204 if ( src[i] == '=' ) /* control padding */
205 pad++;
206 if ( dec_valid( src[i] ) ) /* only allow valid characters */
207 dat[j++] = src[i];
208 }
209
210 /* fill r */
211 i = 0;
212 for ( c = 0; c < j; c += 4 ) {
213 /* process the input from base 64 */
214 uint32_t n = dec_ch( dat[c + 0] ) << 18; /* guaranteed to be valid */
215 n += ( c + 1 < j ) ? ( dec_ch( dat[c + 1] ) << 12 )
216 : 0; /* check if inbounds */
217 n += ( c + 2 < j ) ? ( dec_ch( dat[c + 2] ) << 6 ) : 0;
218 n += ( c + 3 < j ) ? ( dec_ch( dat[c + 3] ) << 0 ) : 0;
219
220 /* convert the 24 bits of encoded data into 3 8 bit chunks */
221 r[i++] = ( n >> 16 ) & 255;
222 r[i++] = ( n >> 8 ) & 255;
223 r[i++] = ( n >> 0 ) & 255;
224 }
225
226 /* cleanup */
227 free( dat );
228
229 ( *len ) = i - pad; /* must decount the padding */
230 return r;
231}
232
233/*
234 * encodes src of sz length storing the new length in len
235 */
236char *base64_encode_to_cstr( const char *src, size_t sz )
237{
238 size_t len;
239 return base64_encode( &len, src, sz );
240}
241
242/*
243 * encodes src of sz length storing the new length in len
244 */
245char *base64_decode_cstr( size_t *len, const char *src )
246{
247 return base64_decode( len, src, strlen( src ) );
248}
static const double c[]
Definition rng.c:256