Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/codec/base64/base64.cpp
Line
Count
Source (jump to first uncovered line)
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
91
         {
22
91
         return "base64";
23
91
         }
24
25
      static inline size_t encoding_bytes_in() noexcept
26
0
         {
27
0
         return m_encoding_bytes_in;
28
0
         }
29
      static inline size_t encoding_bytes_out() noexcept
30
0
         {
31
0
         return m_encoding_bytes_out;
32
0
         }
33
34
      static inline size_t decoding_bytes_in() noexcept
35
5.93k
         {
36
5.93k
         return m_encoding_bytes_out;
37
5.93k
         }
38
      static inline size_t decoding_bytes_out() noexcept
39
5.93k
         {
40
5.93k
         return m_encoding_bytes_in;
41
5.93k
         }
42
43
      static inline size_t bits_consumed() noexcept
44
0
         {
45
0
         return m_encoding_bits;
46
0
         }
47
      static inline size_t remaining_bits_before_padding() noexcept
48
0
         {
49
0
         return m_remaining_bits_before_padding;
50
0
         }
51
52
      static inline size_t encode_max_output(size_t input_length)
53
0
         {
54
0
         return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * m_encoding_bytes_out;
55
0
         }
56
      static inline size_t decode_max_output(size_t input_length)
57
11.8k
         {
58
11.8k
         return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;
59
11.8k
         }
60
61
      static void encode(char out[8], const uint8_t in[5]) noexcept
62
0
         {
63
0
         out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2];
64
0
         out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
65
0
         out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
66
0
         out[3] = Base64::m_bin_to_base64[in[2] & 0x3F];
67
0
         }
68
69
      static inline uint8_t lookup_binary_value(char input) noexcept
70
6.46M
         {
71
6.46M
         return Base64::m_base64_to_bin[static_cast<uint8_t>(input)];
72
6.46M
         }
73
74
      static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)
75
6.45M
         {
76
6.45M
         if(bin <= 0x3F)
77
6.32M
            {
78
6.32M
            return true;
79
6.32M
            }
80
129k
         else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
81
121
            {
82
121
            std::string bad_char(1, input);
83
121
            if(bad_char == "\t")
84
0
               { bad_char = "\\t"; }
85
121
            else if(bad_char == "\n")
86
0
               { bad_char = "\\n"; }
87
121
            else if(bad_char == "\r")
88
0
               { bad_char = "\\r"; }
89
121
90
121
            throw Invalid_Argument(
91
121
               std::string("base64_decode: invalid base64 character '") +
92
121
               bad_char + "'");
93
121
            }
94
128k
         return false;
95
128k
         }
96
97
      static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4])
98
1.58M
         {
99
1.58M
         out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
100
1.58M
         out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
101
1.58M
         out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
102
1.58M
         }
103
104
      static inline size_t bytes_to_remove(size_t final_truncate)
105
5.81k
         {
106
5.81k
         return final_truncate;
107
5.81k
         }
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
0
   {
172
0
   return base_encode(Base64(), out, in, input_length, input_consumed, final_inputs);
173
0
   }
174
175
std::string base64_encode(const uint8_t input[],
176
                          size_t input_length)
177
0
   {
178
0
   return base_encode_to_string(Base64(), input, input_length);
179
0
   }
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
0
   {
188
0
   return base_decode(Base64(), out, in, input_length, input_consumed, final_inputs, ignore_ws);
189
0
   }
190
191
size_t base64_decode(uint8_t output[],
192
                     const char input[],
193
                     size_t input_length,
194
                     bool ignore_ws)
195
0
   {
196
0
   return base_decode_full(Base64(), output, input, input_length, ignore_ws);
197
0
   }
198
199
size_t base64_decode(uint8_t output[],
200
                     const std::string& input,
201
                     bool ignore_ws)
202
0
   {
203
0
   return base64_decode(output, input.data(), input.length(), ignore_ws);
204
0
   }
205
206
secure_vector<uint8_t> base64_decode(const char input[],
207
                                     size_t input_length,
208
                                     bool ignore_ws)
209
5.93k
   {
210
5.93k
   return base_decode_to_vec<secure_vector<uint8_t>>(Base64(), input, input_length, ignore_ws);
211
5.93k
   }
212
213
secure_vector<uint8_t> base64_decode(const std::string& input,
214
                                     bool ignore_ws)
215
0
   {
216
0
   return base64_decode(input.data(), input.size(), ignore_ws);
217
0
   }
218
219
size_t base64_encode_max_output(size_t input_length)
220
0
   {
221
0
   return Base64::encode_max_output(input_length);
222
0
   }
223
224
size_t base64_decode_max_output(size_t input_length)
225
0
   {
226
0
   return Base64::decode_max_output(input_length);
227
0
   }
228
229
}