Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader, u16bit extension_size) { if(extension_size == 0) return; // empty extension const u16bit name_bytes = reader.get_u16bit(); size_t bytes_remaining = extension_size - 2; if(name_bytes != bytes_remaining) throw Decoding_Error("Bad encoding of ALPN extension, bad length field"); while(bytes_remaining) { const std::string p = reader.get_string(1, 0, 255); if(bytes_remaining < p.size() + 1) throw Decoding_Error("Bad encoding of ALPN, length field too long"); bytes_remaining -= (p.size() + 1); m_protocols.push_back(p); } }
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, u16bit extension_size) { /* * This is used by the server to confirm that it knew the name */ if(extension_size == 0) return; u16bit name_bytes = reader.get_u16bit(); if(name_bytes + 2 != extension_size) throw Decoding_Error("Bad encoding of SNI extension"); while(name_bytes) { byte name_type = reader.get_byte(); name_bytes--; if(name_type == 0) // DNS { m_sni_host_name = reader.get_string(2, 1, 65535); name_bytes -= (2 + m_sni_host_name.size()); } else // some other unknown name type { reader.discard_next(name_bytes); name_bytes = 0; } } }
Maximum_Fragment_Length::Maximum_Fragment_Length(TLS_Data_Reader& reader, u16bit extension_size) { if(extension_size != 1) throw Decoding_Error("Bad size for maximum fragment extension"); const byte val = reader.get_byte(); switch(val) { case 1: m_max_fragment = 512; break; case 2: m_max_fragment = 1024; break; case 3: m_max_fragment = 2048; break; case 4: m_max_fragment = 4096; break; default: throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Bad value " + std::to_string(val) + " for max fragment len"); } }
SRP_Identifier::SRP_Identifier(TLS_Data_Reader& reader, u16bit extension_size) { m_srp_identifier = reader.get_string(1, 1, 255); if(m_srp_identifier.size() + 1 != extension_size) throw Decoding_Error("Bad encoding for SRP identifier extension"); }
void Extensions::deserialize(TLS_Data_Reader& reader) { if(reader.has_remaining()) { const u16bit all_extn_size = reader.get_u16bit(); if(reader.remaining_bytes() != all_extn_size) throw Decoding_Error("Bad extension size"); while(reader.has_remaining()) { const u16bit extension_code = reader.get_u16bit(); const u16bit extension_size = reader.get_u16bit(); Extension* extn = make_extension(reader, extension_code, extension_size); if(extn) this->add(extn); else // unknown/unhandled extension reader.discard_next(extension_size); } } }
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, u16bit extension_size) { u16bit len = reader.get_u16bit(); if(len + 2 != extension_size) throw Decoding_Error("Bad encoding on signature algorithms extension"); while(len) { const std::string hash_code = hash_algo_name(reader.get_byte()); const std::string sig_code = sig_algo_name(reader.get_byte()); len -= 2; // If not something we know, ignore it completely if(hash_code.empty() || sig_code.empty()) continue; m_supported_algos.push_back(std::make_pair(hash_code, sig_code)); } }
Supported_Elliptic_Curves::Supported_Elliptic_Curves(TLS_Data_Reader& reader, u16bit extension_size) { u16bit len = reader.get_u16bit(); if(len + 2 != extension_size) throw Decoding_Error("Inconsistent length field in elliptic curve list"); if(len % 2 == 1) throw Decoding_Error("Elliptic curve list of strange size"); len /= 2; for(size_t i = 0; i != len; ++i) { const u16bit id = reader.get_u16bit(); const std::string name = curve_id_to_name(id); if(!name.empty()) m_curves.push_back(name); } }
Heartbeat_Support_Indicator::Heartbeat_Support_Indicator(TLS_Data_Reader& reader, u16bit extension_size) { if(extension_size != 1) throw Decoding_Error("Strange size for heartbeat extension"); const byte code = reader.get_byte(); if(code != 1 && code != 2) throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Unknown heartbeat code " + std::to_string(code)); m_peer_allowed_to_send = (code == 1); }