Botan  1.11.15
src/lib/tls/tls_reader.h
Go to the documentation of this file.
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