14#ifndef OPENVPN_COMMON_BASE64_H
15#define OPENVPN_COMMON_BASE64_H
76 throw base64_decode_out_of_bound_error();
98 for (i = 0; i < 62; ++i)
108 if (std::strlen(altmap) != 3)
109 throw base64_bad_map();
110 enc[62] = (
unsigned char)altmap[0];
111 enc[63] = (
unsigned char)altmap[1];
112 equal = (
unsigned char)altmap[2];
117 std::memset(
dec, 0xFF, 128);
118 for (
unsigned int i = 0; i < 64; ++i)
120 const unsigned char c =
enc[i];
122 throw base64_bad_map();
123 dec[c] = (
unsigned char)i;
135 return decode_size * 4 / 3 + 4;
138 template <
typename V>
144 const size_t size = data.size();
147 for (i = 0; i < size;)
149 c =
static_cast<unsigned char>(data[i++]) << 8;
151 c +=
static_cast<unsigned char>(data[i]);
155 c +=
static_cast<unsigned char>(data[i]);
157 p[0] =
enc[(c & 0x00fc0000) >> 18];
158 p[1] =
enc[(c & 0x0003f000) >> 12];
159 p[2] =
enc[(c & 0x00000fc0) >> 6];
160 p[3] =
enc[c & 0x0000003f];
168 const std::string
ret(s);
173 std::string
encode(
const void *data,
size_t size)
const
186 size_t decode(
void *data,
size_t len,
const std::string &str)
const
193 std::string
decode(
const std::string &str)
const
196 ret.reserve(str.length());
201 template <
typename V>
202 void decode(V &dest,
const std::string &str)
const
204 const char *endp = str.c_str() + str.length();
205 for (
const char *p = str.c_str(); p < endp; p += 4)
207 using vvalue_t =
typename V::value_type;
209 const unsigned int val =
token_decode(p, std::min(endp - p, ptrdiff_t(4)), marker);
210 dest.push_back(
static_cast<vvalue_t
>((val >> 16) & 0xff));
212 dest.push_back(
static_cast<vvalue_t
>((val >> 8) & 0xff));
214 dest.push_back(
static_cast<vvalue_t
>(val & 0xff));
218 template <
typename V>
219 bool is_base64(
const V &data,
const size_t expected_decoded_length)
const
221 const size_t size = data.size();
224 const size_t eq_begin = size -
num_eq(expected_decoded_length);
225 for (
size_t i = 0; i < size; ++i)
227 const char c = data[i];
245 const size_t idx = c;
246 return idx < 128 &&
dec[idx] != 0xFF;
251 const size_t idx = c;
253 throw base64_decode_error();
254 const unsigned int v =
dec[idx];
256 throw base64_decode_error();
260 unsigned int token_decode(
const char *token,
const ptrdiff_t len,
unsigned int &marker)
const
263 unsigned int val = 0;
266 throw base64_decode_error();
267 for (i = 0; i < 4; i++)
270 if (token[i] ==
equal)
273 throw base64_decode_error();
278 throw base64_decode_error();
284 return (decoded_len * 4 / 3 + 3) & ~3;
287 static size_t num_eq(
const size_t decoded_len)
289 return (-1 - decoded_len) % 3;
value_type operator[](const size_t i) const
ConstUCharWrap(const value_type *data, size_t size)
void push_back(value_type c)
UCharWrap(value_type *data, size_t size)
static size_t encode_size_max(const size_t decode_size)
bool is_base64_char(const char c) const
OPENVPN_SIMPLE_EXCEPTION(base64_bad_map)
bool is_base64(const V &data, const size_t expected_decoded_length) const
Base64(const char *altmap=nullptr)
unsigned int decode_base64_char(const char c) const
void decode(V &dest, const std::string &str) const
unsigned int token_decode(const char *token, const ptrdiff_t len, unsigned int &marker) const
static size_t num_eq(const size_t decoded_len)
std::string decode(const std::string &str) const
static size_t decode_size_max(const size_t encode_size)
static size_t encoded_len(const size_t decoded_len)
std::string encode(const void *data, size_t size) const
OPENVPN_SIMPLE_EXCEPTION(base64_decode_error)
OPENVPN_SIMPLE_EXCEPTION(base64_decode_out_of_bound_error)
std::string encode(const V &data) const
size_t decode(void *data, size_t len, const std::string &str) const
Support deferred server-side state creation when client connects.
const Base64 * base64_urlsafe
void base64_uninit_static()
void base64_init_static()