Botan  2.7.0
Crypto and TLS for C++11
b64_filt.cpp
Go to the documentation of this file.
1 /*
2 * Base64 Encoder/Decoder
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/b64_filt.h>
9 #include <botan/base64.h>
10 #include <botan/exceptn.h>
11 #include <algorithm>
12 
13 namespace Botan {
14 
15 /*
16 * Base64_Encoder Constructor
17 */
18 Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) :
19  m_line_length(breaks ? length : 0),
20  m_trailing_newline(t_n && breaks),
21  m_in(48),
22  m_out(64),
23  m_position(0),
24  m_out_position(0)
25  {
26  }
27 
28 /*
29 * Encode and send a block
30 */
31 void Base64_Encoder::encode_and_send(const uint8_t input[], size_t length,
32  bool final_inputs)
33  {
34  while(length)
35  {
36  const size_t proc = std::min(length, m_in.size());
37 
38  size_t consumed = 0;
39  size_t produced = base64_encode(cast_uint8_ptr_to_char(m_out.data()),
40  input, proc, consumed, final_inputs);
41 
42  do_output(m_out.data(), produced);
43 
44  // FIXME: s/proc/consumed/?
45  input += proc;
46  length -= proc;
47  }
48  }
49 
50 /*
51 * Handle the output
52 */
53 void Base64_Encoder::do_output(const uint8_t input[], size_t length)
54  {
55  if(m_line_length == 0)
56  send(input, length);
57  else
58  {
59  size_t remaining = length, offset = 0;
60  while(remaining)
61  {
62  size_t sent = std::min(m_line_length - m_out_position, remaining);
63  send(input + offset, sent);
64  m_out_position += sent;
65  remaining -= sent;
66  offset += sent;
67  if(m_out_position == m_line_length)
68  {
69  send('\n');
70  m_out_position = 0;
71  }
72  }
73  }
74  }
75 
76 /*
77 * Convert some data into Base64
78 */
79 void Base64_Encoder::write(const uint8_t input[], size_t length)
80  {
81  buffer_insert(m_in, m_position, input, length);
82  if(m_position + length >= m_in.size())
83  {
84  encode_and_send(m_in.data(), m_in.size());
85  input += (m_in.size() - m_position);
86  length -= (m_in.size() - m_position);
87  while(length >= m_in.size())
88  {
89  encode_and_send(input, m_in.size());
90  input += m_in.size();
91  length -= m_in.size();
92  }
93  copy_mem(m_in.data(), input, length);
94  m_position = 0;
95  }
96  m_position += length;
97  }
98 
99 /*
100 * Flush buffers
101 */
103  {
104  encode_and_send(m_in.data(), m_position, true);
105 
106  if(m_trailing_newline || (m_out_position && m_line_length))
107  send('\n');
108 
109  m_out_position = m_position = 0;
110  }
111 
112 /*
113 * Base64_Decoder Constructor
114 */
116  m_checking(c), m_in(64), m_out(48), m_position(0)
117  {
118  }
119 
120 /*
121 * Convert some data from Base64
122 */
123 void Base64_Decoder::write(const uint8_t input[], size_t length)
124  {
125  while(length)
126  {
127  size_t to_copy = std::min<size_t>(length, m_in.size() - m_position);
128  if(to_copy == 0)
129  {
130  m_in.resize(m_in.size()*2);
131  m_out.resize(m_out.size()*2);
132  }
133  copy_mem(&m_in[m_position], input, to_copy);
134  m_position += to_copy;
135 
136  size_t consumed = 0;
137  size_t written = base64_decode(m_out.data(),
138  cast_uint8_ptr_to_char(m_in.data()),
139  m_position,
140  consumed,
141  false,
142  m_checking != FULL_CHECK);
143 
144  send(m_out, written);
145 
146  if(consumed != m_position)
147  {
148  copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed);
149  m_position = m_position - consumed;
150  }
151  else
152  m_position = 0;
153 
154  length -= to_copy;
155  input += to_copy;
156  }
157  }
158 
159 /*
160 * Flush buffers
161 */
163  {
164  size_t consumed = 0;
165  size_t written = base64_decode(m_out.data(),
166  cast_uint8_ptr_to_char(m_in.data()),
167  m_position,
168  consumed,
169  true,
170  m_checking != FULL_CHECK);
171 
172  send(m_out, written);
173 
174  const bool not_full_bytes = consumed != m_position;
175 
176  m_position = 0;
177 
178  if(not_full_bytes)
179  throw Invalid_Argument("Base64_Decoder: Input not full bytes");
180  }
181 
182 }
Base64_Encoder(bool breaks=false, size_t length=72, bool t_n=false)
Definition: b64_filt.cpp:18
void end_msg() override
Definition: b64_filt.cpp:102
Base64_Decoder(Decoder_Checking checking=NONE)
Definition: b64_filt.cpp:115
virtual void send(const uint8_t in[], size_t length)
Definition: filter.cpp:27
void write(const uint8_t input[], size_t length) override
Definition: b64_filt.cpp:79
void end_msg() override
Definition: b64_filt.cpp:162
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:35
size_t base64_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base64.cpp:100
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
Definition: alg_id.cpp:13
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:136
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:103
void write(const uint8_t input[], size_t length) override
Definition: b64_filt.cpp:123
Decoder_Checking
Definition: filter.h:179