Botan 2.19.2
Crypto and TLS for C&
tls_reader.h
Go to the documentation of this file.
1/*
2* TLS Data Reader
3* (C) 2010-2011,2014 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_TLS_READER_H_
9#define BOTAN_TLS_READER_H_
10
11#include <botan/exceptn.h>
12#include <botan/secmem.h>
13#include <botan/loadstor.h>
14#include <string>
15#include <vector>
16
17namespace Botan {
18
19namespace TLS {
20
21/**
22* Helper class for decoding TLS protocol messages
23*/
25 {
26 public:
27 TLS_Data_Reader(const char* type, const std::vector<uint8_t>& buf_in) :
28 m_typename(type), m_buf(buf_in), m_offset(0) {}
29
30 void assert_done() const
31 {
32 if(has_remaining())
33 throw decode_error("Extra bytes at end of message");
34 }
35
36 size_t read_so_far() const { return m_offset; }
37
38 size_t remaining_bytes() const { return m_buf.size() - m_offset; }
39
40 bool has_remaining() const { return (remaining_bytes() > 0); }
41
42 std::vector<uint8_t> get_remaining()
43 {
44 return std::vector<uint8_t>(m_buf.begin() + m_offset, m_buf.end());
45 }
46
47 void discard_next(size_t bytes)
48 {
49 assert_at_least(bytes);
50 m_offset += bytes;
51 }
52
53 uint32_t get_uint32_t()
54 {
55 assert_at_least(4);
56 uint32_t result = make_uint32(m_buf[m_offset ], m_buf[m_offset+1],
57 m_buf[m_offset+2], m_buf[m_offset+3]);
58 m_offset += 4;
59 return result;
60 }
61
62 uint16_t get_uint16_t()
63 {
64 assert_at_least(2);
65 uint16_t result = make_uint16(m_buf[m_offset], m_buf[m_offset+1]);
66 m_offset += 2;
67 return result;
68 }
69
70 uint8_t get_byte()
71 {
72 assert_at_least(1);
73 uint8_t result = m_buf[m_offset];
74 m_offset += 1;
75 return result;
76 }
77
78 template<typename T, typename Container>
79 Container get_elem(size_t num_elems)
80 {
81 assert_at_least(num_elems * sizeof(T));
82
83 Container result(num_elems);
84
85 for(size_t i = 0; i != num_elems; ++i)
86 result[i] = load_be<T>(&m_buf[m_offset], i);
87
88 m_offset += num_elems * sizeof(T);
89
90 return result;
91 }
92
93 template<typename T>
94 std::vector<T> get_range(size_t len_bytes,
95 size_t min_elems,
96 size_t max_elems)
97 {
98 const size_t num_elems =
99 get_num_elems(len_bytes, sizeof(T), min_elems, max_elems);
100
101 return get_elem<T, std::vector<T>>(num_elems);
102 }
103
104 template<typename T>
105 std::vector<T> get_range_vector(size_t len_bytes,
106 size_t min_elems,
107 size_t max_elems)
108 {
109 const size_t num_elems =
110 get_num_elems(len_bytes, sizeof(T), min_elems, max_elems);
111
112 return get_elem<T, std::vector<T>>(num_elems);
113 }
114
115 std::string get_string(size_t len_bytes,
116 size_t min_bytes,
117 size_t max_bytes)
118 {
119 std::vector<uint8_t> v =
120 get_range_vector<uint8_t>(len_bytes, min_bytes, max_bytes);
121
122 return std::string(cast_uint8_ptr_to_char(v.data()), v.size());
123 }
124
125 template<typename T>
126 std::vector<T> get_fixed(size_t size)
127 {
128 return get_elem<T, std::vector<T>>(size);
129 }
130
131 private:
132 size_t get_length_field(size_t len_bytes)
133 {
134 assert_at_least(len_bytes);
135
136 if(len_bytes == 1)
137 return get_byte();
138 else if(len_bytes == 2)
139 return get_uint16_t();
140
141 throw decode_error("Bad length size");
142 }
143
144 size_t get_num_elems(size_t len_bytes,
145 size_t T_size,
146 size_t min_elems,
147 size_t max_elems)
148 {
149 const size_t byte_length = get_length_field(len_bytes);
150
151 if(byte_length % T_size != 0)
152 throw decode_error("Size isn't multiple of T");
153
154 const size_t num_elems = byte_length / T_size;
155
156 if(num_elems < min_elems || num_elems > max_elems)
157 throw decode_error("Length field outside parameters");
158
159 return num_elems;
160 }
161
162 void assert_at_least(size_t n) const
163 {
164 if(m_buf.size() - m_offset < n)
165 throw decode_error("Expected " + std::to_string(n) +
166 " bytes remaining, only " +
167 std::to_string(m_buf.size()-m_offset) +
168 " left");
169 }
170
171 Decoding_Error decode_error(const std::string& why) const
172 {
173 return Decoding_Error("Invalid " + std::string(m_typename) + ": " + why);
174 }
175
176 const char* m_typename;
177 const std::vector<uint8_t>& m_buf;
178 size_t m_offset;
179 };
180
181/**
182* Helper function for encoding length-tagged vectors
183*/
184template<typename T, typename Alloc>
185void append_tls_length_value(std::vector<uint8_t, Alloc>& buf,
186 const T* vals,
187 size_t vals_size,
188 size_t tag_size)
189 {
190 const size_t T_size = sizeof(T);
191 const size_t val_bytes = T_size * vals_size;
192
193 if(tag_size != 1 && tag_size != 2)
194 throw Invalid_Argument("append_tls_length_value: invalid tag size");
195
196 if((tag_size == 1 && val_bytes > 255) ||
197 (tag_size == 2 && val_bytes > 65535))
198 throw Invalid_Argument("append_tls_length_value: value too large");
199
200 for(size_t i = 0; i != tag_size; ++i)
201 buf.push_back(get_byte(sizeof(val_bytes)-tag_size+i, val_bytes));
202
203 for(size_t i = 0; i != vals_size; ++i)
204 for(size_t j = 0; j != T_size; ++j)
205 buf.push_back(get_byte(j, vals[i]));
206 }
207
208template<typename T, typename Alloc, typename Alloc2>
209void append_tls_length_value(std::vector<uint8_t, Alloc>& buf,
210 const std::vector<T, Alloc2>& vals,
211 size_t tag_size)
212 {
213 append_tls_length_value(buf, vals.data(), vals.size(), tag_size);
214 }
215
216template<typename Alloc>
217void append_tls_length_value(std::vector<uint8_t, Alloc>& buf,
218 const std::string& str,
219 size_t tag_size)
220 {
222 cast_char_ptr_to_uint8(str.data()),
223 str.size(),
224 tag_size);
225 }
226
227}
228
229}
230
231#endif
std::string get_string(size_t len_bytes, size_t min_bytes, size_t max_bytes)
Definition: tls_reader.h:115
bool has_remaining() const
Definition: tls_reader.h:40
std::vector< uint8_t > get_remaining()
Definition: tls_reader.h:42
size_t read_so_far() const
Definition: tls_reader.h:36
void discard_next(size_t bytes)
Definition: tls_reader.h:47
Container get_elem(size_t num_elems)
Definition: tls_reader.h:79
TLS_Data_Reader(const char *type, const std::vector< uint8_t > &buf_in)
Definition: tls_reader.h:27
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:94
size_t remaining_bytes() const
Definition: tls_reader.h:38
std::vector< T > get_fixed(size_t size)
Definition: tls_reader.h:126
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:105
int(* final)(unsigned char *, CTX *)
fe T
Definition: ge.cpp:37
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:185
Definition: alg_id.cpp:13
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition: loadstor.h:67
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:195
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:54
MechanismType type