Botan  2.9.0
Crypto and TLS for C++11
base64.cpp
Go to the documentation of this file.
1 /*
2 * Base64 Encoding and Decoding
3 * (C) 2010,2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/base64.h>
9 #include <botan/internal/codec_base.h>
10 #include <botan/exceptn.h>
11 #include <botan/internal/rounding.h>
12 
13 namespace Botan {
14 
15 namespace {
16 
17 class Base64 final
18  {
19  public:
20  static inline std::string name() noexcept
21  {
22  return "base64";
23  }
24 
25  static inline size_t encoding_bytes_in() noexcept
26  {
27  return m_encoding_bytes_in;
28  }
29  static inline size_t encoding_bytes_out() noexcept
30  {
31  return m_encoding_bytes_out;
32  }
33 
34  static inline size_t decoding_bytes_in() noexcept
35  {
36  return m_encoding_bytes_out;
37  }
38  static inline size_t decoding_bytes_out() noexcept
39  {
40  return m_encoding_bytes_in;
41  }
42 
43  static inline size_t bits_consumed() noexcept
44  {
45  return m_encoding_bits;
46  }
47  static inline size_t remaining_bits_before_padding() noexcept
48  {
49  return m_remaining_bits_before_padding;
50  }
51 
52  static inline size_t encode_max_output(size_t input_length)
53  {
54  return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * m_encoding_bytes_out;
55  }
56  static inline size_t decode_max_output(size_t input_length)
57  {
58  return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;
59  }
60 
61  static void encode(char out[8], const uint8_t in[5]) noexcept
62  {
63  out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2];
64  out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
65  out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
66  out[3] = Base64::m_bin_to_base64[in[2] & 0x3F];
67  }
68 
69  static inline uint8_t lookup_binary_value(char input) noexcept
70  {
71  return Base64::m_base64_to_bin[static_cast<uint8_t>(input)];
72  }
73 
74  static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)
75  {
76  if(bin <= 0x3F)
77  {
78  return true;
79  }
80  else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
81  {
82  std::string bad_char(1, input);
83  if(bad_char == "\t")
84  { bad_char = "\\t"; }
85  else if(bad_char == "\n")
86  { bad_char = "\\n"; }
87  else if(bad_char == "\r")
88  { bad_char = "\\r"; }
89 
90  throw Invalid_Argument(
91  std::string("base64_decode: invalid base64 character '") +
92  bad_char + "'");
93  }
94  return false;
95  }
96 
97  static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4])
98  {
99  out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
100  out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
101  out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
102  }
103 
104  static inline size_t bytes_to_remove(size_t final_truncate)
105  {
106  return final_truncate;
107  }
108 
109  private:
110  static const size_t m_encoding_bits = 6;
111  static const size_t m_remaining_bits_before_padding = 8;
112 
113 
114  static const size_t m_encoding_bytes_in = 3;
115  static const size_t m_encoding_bytes_out = 4;
116 
117 
118  static const uint8_t m_bin_to_base64[64];
119  static const uint8_t m_base64_to_bin[256];
120  };
121 
122 const uint8_t Base64::m_bin_to_base64[64] =
123  {
124  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
125  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
126  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
127  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
128  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
129  };
130 
131 /*
132 * base64 Decoder Lookup Table
133 * Warning: assumes ASCII encodings
134 */
135 const uint8_t Base64::m_base64_to_bin[256] =
136  {
137  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
138  0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
139  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
140  0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
141  0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
142  0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
143  0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
144  0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
145  0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
146  0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
147  0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
148  0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
149  0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
150  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
151  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
152  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
153  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
154  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
155  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
156  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
157  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
161  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
162  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
163  };
164 }
165 
166 size_t base64_encode(char out[],
167  const uint8_t in[],
168  size_t input_length,
169  size_t& input_consumed,
170  bool final_inputs)
171  {
172  return base_encode(Base64(), out, in, input_length, input_consumed, final_inputs);
173  }
174 
175 std::string base64_encode(const uint8_t input[],
176  size_t input_length)
177  {
178  return base_encode_to_string(Base64(), input, input_length);
179  }
180 
181 size_t base64_decode(uint8_t out[],
182  const char in[],
183  size_t input_length,
184  size_t& input_consumed,
185  bool final_inputs,
186  bool ignore_ws)
187  {
188  return base_decode(Base64(), out, in, input_length, input_consumed, final_inputs, ignore_ws);
189  }
190 
191 size_t base64_decode(uint8_t output[],
192  const char input[],
193  size_t input_length,
194  bool ignore_ws)
195  {
196  return base_decode_full(Base64(), output, input, input_length, ignore_ws);
197  }
198 
199 size_t base64_decode(uint8_t output[],
200  const std::string& input,
201  bool ignore_ws)
202  {
203  return base64_decode(output, input.data(), input.length(), ignore_ws);
204  }
205 
207  size_t input_length,
208  bool ignore_ws)
209  {
210  return base_decode_to_vec<secure_vector<uint8_t>>(Base64(), input, input_length, ignore_ws);
211  }
212 
213 secure_vector<uint8_t> base64_decode(const std::string& input,
214  bool ignore_ws)
215  {
216  return base64_decode(input.data(), input.size(), ignore_ws);
217  }
218 
219 size_t base64_encode_max_output(size_t input_length)
220  {
221  return Base64::encode_max_output(input_length);
222  }
223 
224 size_t base64_decode_max_output(size_t input_length)
225  {
226  return Base64::decode_max_output(input_length);
227  }
228 
229 }
size_t base_decode(Base &&base, uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws=true)
Definition: codec_base.h:124
size_t base64_decode_max_output(size_t input_length)
Definition: base64.cpp:224
size_t base64_encode_max_output(size_t input_length)
Definition: base64.cpp:219
int(* final)(unsigned char *, CTX *)
std::string base_encode_to_string(Base &&base, const uint8_t input[], size_t input_length)
Definition: codec_base.h:86
std::string name
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:166
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
Definition: alg_id.cpp:13
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base64.cpp:181
size_t base_decode_full(Base &&base, uint8_t output[], const char input[], size_t input_length, bool ignore_ws)
Definition: codec_base.h:189
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:21
size_t base_encode(Base &&base, char output[], const uint8_t input[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: codec_base.h:34