Eunomia  0.1.0
A lightweight eBPF-based CloudNative Monitor tool for Container Security and Observability
base64.h
Go to the documentation of this file.
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 // 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string
10 // instead of a buffer allocated with malloc.
11 
12 #ifndef BASE64_H
13 #define BASE64_H
14 /*
15  * Base64 encoding/decoding (RFC1341)
16  * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
17  *
18  * This software may be distributed under the terms of the BSD license.
19  * See README for more details.
20  */
21 
22 #include <string>
23 #include <vector>
24 #include <cstdlib>
25 
26 static const unsigned char base64_table[65] =
27  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
28 
41 static std::string base64_encode(const unsigned char *src, size_t len)
42 {
43  unsigned char *out, *pos;
44  const unsigned char *end, *in;
45  std::string str ={};
46  size_t olen;
47  int line_len;
48 
49  olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
50  olen += olen / 72; /* line feeds */
51  olen++; /* nul termination */
52  if (olen < len)
53  return str; /* integer overflow */
54  out = (unsigned char*)malloc(olen);
55  if (out == NULL)
56  return str;
57 
58  end = src + len;
59  in = src;
60  pos = out;
61  line_len = 0;
62  while (end - in >= 3) {
63  *pos++ = base64_table[in[0] >> 2];
64  *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
65  *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
66  *pos++ = base64_table[in[2] & 0x3f];
67  in += 3;
68  line_len += 4;
69  if (line_len >= 72) {
70  *pos++ = '\n';
71  line_len = 0;
72  }
73  }
74 
75  if (end - in) {
76  *pos++ = base64_table[in[0] >> 2];
77  if (end - in == 1) {
78  *pos++ = base64_table[(in[0] & 0x03) << 4];
79  *pos++ = '=';
80  } else {
81  *pos++ = base64_table[((in[0] & 0x03) << 4) |
82  (in[1] >> 4)];
83  *pos++ = base64_table[(in[1] & 0x0f) << 2];
84  }
85  *pos++ = '=';
86  line_len += 4;
87  }
88 
89  if (line_len)
90  *pos++ = '\n';
91 
92  *pos = '\0';
93  auto out_len = pos - out;
94  str = std::string(reinterpret_cast<char*>(out), out_len);
95  free(out);
96  return str;
97 }
98 
99 
110 static std::vector<char> base64_decode(const unsigned char *src, size_t len)
111 {
112  std::vector<char> str = {};
113  unsigned char dtable[256], *out, *pos, block[4], tmp;
114  size_t i, count, olen;
115  int pad = 0;
116 
117  memset(dtable, 0x80, 256);
118  for (i = 0; i < sizeof(base64_table) - 1; i++)
119  dtable[base64_table[i]] = (unsigned char) i;
120  dtable['='] = 0;
121 
122  count = 0;
123  for (i = 0; i < len; i++) {
124  if (dtable[src[i]] != 0x80)
125  count++;
126  }
127 
128  if (count == 0 || count % 4)
129  return str;
130 
131  olen = count / 4 * 3;
132  pos = out = (unsigned char*)malloc(olen);
133  if (out == NULL)
134  return str;
135 
136  count = 0;
137  for (i = 0; i < len; i++) {
138  tmp = dtable[src[i]];
139  if (tmp == 0x80)
140  continue;
141 
142  if (src[i] == '=')
143  pad++;
144  block[count] = tmp;
145  count++;
146  if (count == 4) {
147  *pos++ = (block[0] << 2) | (block[1] >> 4);
148  *pos++ = (block[1] << 4) | (block[2] >> 2);
149  *pos++ = (block[2] << 6) | block[3];
150  count = 0;
151  if (pad) {
152  if (pad == 1)
153  pos--;
154  else if (pad == 2)
155  pos -= 2;
156  else {
157  /* Invalid padding */
158  free(out);
159  return str;
160  }
161  break;
162  }
163  }
164  }
165 
166  auto out_len = pos - out;
167  str = std::vector<char>(out, out + out_len);
168  free(out);
169  return str;
170 }
171 
172 #endif // BASE64_H