libubox
C utility functions for OpenWrt.
base64.c File Reference
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "assert.h"
#include "utils.h"

Go to the source code of this file.

Functions

int b64_encode (const void *_src, size_t srclength, void *dest, size_t targsize)
 
int b64_decode (const void *_src, void *dest, size_t targsize)
 

Variables

static const char Base64 []
 
static const char Pad64 = '='
 

Function Documentation

◆ b64_decode()

int b64_decode ( const void *  _src,
void *  dest,
size_t  targsize 
)

Definition at line 203 of file base64.c.

204 {
205  const char *src = _src;
206  unsigned char *target = dest;
207  int state, ch;
208  size_t tarindex;
209  u_char nextbyte;
210  char *pos;
211 
212  state = 0;
213  tarindex = 0;
214 
215  assert(dest && targsize > 0);
216 
217  while ((ch = (unsigned char)*src++) != '\0') {
218  if (isspace(ch)) /* Skip whitespace anywhere. */
219  continue;
220 
221  if (ch == Pad64)
222  break;
223 
224  pos = strchr(Base64, ch);
225  if (pos == 0) /* A non-base64 character. */
226  return (-1);
227 
228  switch (state) {
229  case 0:
230  if (target) {
231  if (tarindex >= targsize)
232  return (-1);
233  target[tarindex] = (pos - Base64) << 2;
234  }
235  state = 1;
236  break;
237  case 1:
238  if (target) {
239  if (tarindex >= targsize)
240  return (-1);
241  target[tarindex] |= (pos - Base64) >> 4;
242  nextbyte = ((pos - Base64) & 0x0f) << 4;
243  if (tarindex + 1 < targsize)
244  target[tarindex+1] = nextbyte;
245  else if (nextbyte)
246  return (-1);
247  }
248  tarindex++;
249  state = 2;
250  break;
251  case 2:
252  if (target) {
253  if (tarindex >= targsize)
254  return (-1);
255  target[tarindex] |= (pos - Base64) >> 2;
256  nextbyte = ((pos - Base64) & 0x03) << 6;
257  if (tarindex + 1 < targsize)
258  target[tarindex+1] = nextbyte;
259  else if (nextbyte)
260  return (-1);
261  }
262  tarindex++;
263  state = 3;
264  break;
265  case 3:
266  if (target) {
267  if (tarindex >= targsize)
268  return (-1);
269  target[tarindex] |= (pos - Base64);
270  }
271  tarindex++;
272  state = 0;
273  break;
274  }
275  }
276 
277  /*
278  * We are done decoding Base-64 chars. Let's see if we ended
279  * on a byte boundary, and/or with erroneous trailing characters.
280  */
281 
282  if (ch == Pad64) { /* We got a pad char. */
283  ch = (unsigned char)*src++; /* Skip it, get next. */
284  switch (state) {
285  case 0: /* Invalid = in first position */
286  case 1: /* Invalid = in second position */
287  return (-1);
288 
289  case 2: /* Valid, means one byte of info */
290  /* Skip any number of spaces. */
291  for (; ch != '\0'; ch = (unsigned char)*src++)
292  if (!isspace(ch))
293  break;
294  /* Make sure there is another trailing = sign. */
295  if (ch != Pad64)
296  return (-1);
297  ch = (unsigned char)*src++; /* Skip the = */
298  /* Fall through to "single trailing =" case. */
299  /* FALLTHROUGH */
300 
301  case 3: /* Valid, means two bytes of info */
302  /*
303  * We know this char is an =. Is there anything but
304  * whitespace after it?
305  */
306  for (; ch != '\0'; ch = (unsigned char)*src++)
307  if (!isspace(ch))
308  return (-1);
309 
310  /*
311  * Now make sure for cases 2 and 3 that the "extra"
312  * bits that slopped past the last full byte were
313  * zeros. If we don't check them, they become a
314  * subliminal channel.
315  */
316  if (target && tarindex < targsize &&
317  target[tarindex] != 0)
318  return (-1);
319  }
320  } else {
321  /*
322  * We ended by seeing the end of the string. Make sure we
323  * have no partial bytes lying around.
324  */
325  if (state != 0)
326  return (-1);
327  }
328 
329  /* Null-terminate if we have room left */
330  if (tarindex < targsize)
331  target[tarindex] = 0;
332 
333  return (tarindex);
334 }
static const char Base64[]
Definition: base64.c:72
static const char Pad64
Definition: base64.c:74
static lua_State * state
Definition: uloop.c:54
Here is the caller graph for this function:

◆ b64_encode()

int b64_encode ( const void *  _src,
size_t  srclength,
void *  dest,
size_t  targsize 
)

Definition at line 139 of file base64.c.

141 {
142  const unsigned char *src = _src;
143  char *target = dest;
144  size_t datalength = 0;
145  u_char input[3] = {0};
146  u_char output[4];
147  size_t i;
148 
149  assert(dest && targsize > 0);
150 
151  while (2 < srclength) {
152  input[0] = *src++;
153  input[1] = *src++;
154  input[2] = *src++;
155  srclength -= 3;
156 
157  output[0] = input[0] >> 2;
158  output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
159  output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
160  output[3] = input[2] & 0x3f;
161 
162  if (datalength + 4 > targsize)
163  return (-1);
164  target[datalength++] = Base64[output[0]];
165  target[datalength++] = Base64[output[1]];
166  target[datalength++] = Base64[output[2]];
167  target[datalength++] = Base64[output[3]];
168  }
169 
170  /* Now we worry about padding. */
171  if (0 != srclength) {
172  /* Get what's left. */
173  input[0] = input[1] = input[2] = '\0';
174  for (i = 0; i < srclength; i++)
175  input[i] = *src++;
176 
177  output[0] = input[0] >> 2;
178  output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
179  output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
180 
181  if (datalength + 4 > targsize)
182  return (-1);
183  target[datalength++] = Base64[output[0]];
184  target[datalength++] = Base64[output[1]];
185  if (srclength == 1)
186  target[datalength++] = Pad64;
187  else
188  target[datalength++] = Base64[output[2]];
189  target[datalength++] = Pad64;
190  }
191  if (datalength >= targsize)
192  return (-1);
193  target[datalength] = '\0'; /* Returned value doesn't count \0. */
194  return (datalength);
195 }
Here is the caller graph for this function:

Variable Documentation

◆ Base64

const char Base64[]
static
Initial value:
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Definition at line 72 of file base64.c.

◆ Pad64

const char Pad64 = '='
static

Definition at line 74 of file base64.c.