Botan
1.11.15
|
00001 /* 00002 * TLS Data Reader 00003 * (C) 2010-2011,2014 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #ifndef BOTAN_TLS_READER_H__ 00009 #define BOTAN_TLS_READER_H__ 00010 00011 #include <botan/exceptn.h> 00012 #include <botan/secmem.h> 00013 #include <botan/loadstor.h> 00014 #include <string> 00015 #include <vector> 00016 #include <stdexcept> 00017 00018 namespace Botan { 00019 00020 namespace TLS { 00021 00022 /** 00023 * Helper class for decoding TLS protocol messages 00024 */ 00025 class TLS_Data_Reader 00026 { 00027 public: 00028 TLS_Data_Reader(const char* type, const std::vector<byte>& buf_in) : 00029 m_typename(type), m_buf(buf_in), m_offset(0) {} 00030 00031 void assert_done() const 00032 { 00033 if(has_remaining()) 00034 throw decode_error("Extra bytes at end of message"); 00035 } 00036 00037 size_t remaining_bytes() const { return m_buf.size() - m_offset; } 00038 00039 bool has_remaining() const { return (remaining_bytes() > 0); } 00040 00041 std::vector<byte> get_remaining() 00042 { 00043 return std::vector<byte>(m_buf.begin() + m_offset, m_buf.end()); 00044 } 00045 00046 void discard_next(size_t bytes) 00047 { 00048 assert_at_least(bytes); 00049 m_offset += bytes; 00050 } 00051 00052 u16bit get_u32bit() 00053 { 00054 assert_at_least(4); 00055 u16bit result = make_u32bit(m_buf[m_offset ], m_buf[m_offset+1], 00056 m_buf[m_offset+2], m_buf[m_offset+3]); 00057 m_offset += 4; 00058 return result; 00059 } 00060 00061 u16bit get_u16bit() 00062 { 00063 assert_at_least(2); 00064 u16bit result = make_u16bit(m_buf[m_offset], m_buf[m_offset+1]); 00065 m_offset += 2; 00066 return result; 00067 } 00068 00069 byte get_byte() 00070 { 00071 assert_at_least(1); 00072 byte result = m_buf[m_offset]; 00073 m_offset += 1; 00074 return result; 00075 } 00076 00077 template<typename T, typename Container> 00078 Container get_elem(size_t num_elems) 00079 { 00080 assert_at_least(num_elems * sizeof(T)); 00081 00082 Container result(num_elems); 00083 00084 for(size_t i = 0; i != num_elems; ++i) 00085 result[i] = load_be<T>(&m_buf[m_offset], i); 00086 00087 m_offset += num_elems * sizeof(T); 00088 00089 return result; 00090 } 00091 00092 template<typename T> 00093 std::vector<T> get_range(size_t len_bytes, 00094 size_t min_elems, 00095 size_t max_elems) 00096 { 00097 const size_t num_elems = 00098 get_num_elems(len_bytes, sizeof(T), min_elems, max_elems); 00099 00100 return get_elem<T, std::vector<T> >(num_elems); 00101 } 00102 00103 template<typename T> 00104 std::vector<T> get_range_vector(size_t len_bytes, 00105 size_t min_elems, 00106 size_t max_elems) 00107 { 00108 const size_t num_elems = 00109 get_num_elems(len_bytes, sizeof(T), min_elems, max_elems); 00110 00111 return get_elem<T, std::vector<T> >(num_elems); 00112 } 00113 00114 std::string get_string(size_t len_bytes, 00115 size_t min_bytes, 00116 size_t max_bytes) 00117 { 00118 std::vector<byte> v = 00119 get_range_vector<byte>(len_bytes, min_bytes, max_bytes); 00120 00121 return std::string(reinterpret_cast<char*>(&v[0]), v.size()); 00122 } 00123 00124 template<typename T> 00125 std::vector<T> get_fixed(size_t size) 00126 { 00127 return get_elem<T, std::vector<T> >(size); 00128 } 00129 00130 private: 00131 size_t get_length_field(size_t len_bytes) 00132 { 00133 assert_at_least(len_bytes); 00134 00135 if(len_bytes == 1) 00136 return get_byte(); 00137 else if(len_bytes == 2) 00138 return get_u16bit(); 00139 00140 throw decode_error("Bad length size"); 00141 } 00142 00143 size_t get_num_elems(size_t len_bytes, 00144 size_t T_size, 00145 size_t min_elems, 00146 size_t max_elems) 00147 { 00148 const size_t byte_length = get_length_field(len_bytes); 00149 00150 if(byte_length % T_size != 0) 00151 throw decode_error("Size isn't multiple of T"); 00152 00153 const size_t num_elems = byte_length / T_size; 00154 00155 if(num_elems < min_elems || num_elems > max_elems) 00156 throw decode_error("Length field outside parameters"); 00157 00158 return num_elems; 00159 } 00160 00161 void assert_at_least(size_t n) const 00162 { 00163 if(m_buf.size() - m_offset < n) 00164 throw decode_error("Expected " + std::to_string(n) + 00165 " bytes remaining, only " + 00166 std::to_string(m_buf.size()-m_offset) + 00167 " left"); 00168 } 00169 00170 Decoding_Error decode_error(const std::string& why) const 00171 { 00172 return Decoding_Error("Invalid " + std::string(m_typename) + ": " + why); 00173 } 00174 00175 const char* m_typename; 00176 const std::vector<byte>& m_buf; 00177 size_t m_offset; 00178 }; 00179 00180 /** 00181 * Helper function for encoding length-tagged vectors 00182 */ 00183 template<typename T, typename Alloc> 00184 void append_tls_length_value(std::vector<byte, Alloc>& buf, 00185 const T* vals, 00186 size_t vals_size, 00187 size_t tag_size) 00188 { 00189 const size_t T_size = sizeof(T); 00190 const size_t val_bytes = T_size * vals_size; 00191 00192 if(tag_size != 1 && tag_size != 2) 00193 throw std::invalid_argument("append_tls_length_value: invalid tag size"); 00194 00195 if((tag_size == 1 && val_bytes > 255) || 00196 (tag_size == 2 && val_bytes > 65535)) 00197 throw std::invalid_argument("append_tls_length_value: value too large"); 00198 00199 for(size_t i = 0; i != tag_size; ++i) 00200 buf.push_back(get_byte(sizeof(val_bytes)-tag_size+i, val_bytes)); 00201 00202 for(size_t i = 0; i != vals_size; ++i) 00203 for(size_t j = 0; j != T_size; ++j) 00204 buf.push_back(get_byte(j, vals[i])); 00205 } 00206 00207 template<typename T, typename Alloc, typename Alloc2> 00208 void append_tls_length_value(std::vector<byte, Alloc>& buf, 00209 const std::vector<T, Alloc2>& vals, 00210 size_t tag_size) 00211 { 00212 append_tls_length_value(buf, &vals[0], vals.size(), tag_size); 00213 } 00214 00215 template<typename Alloc> 00216 void append_tls_length_value(std::vector<byte, Alloc>& buf, 00217 const std::string& str, 00218 size_t tag_size) 00219 { 00220 append_tls_length_value(buf, 00221 reinterpret_cast<const byte*>(&str[0]), 00222 str.size(), 00223 tag_size); 00224 } 00225 00226 } 00227 00228 } 00229 00230 #endif