aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/tls_extensions.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-03-20 04:32:15 +0000
committerlloyd <[email protected]>2015-03-20 04:32:15 +0000
commitb01ce65e09e50ec624bdbf62bf2c1433f0d6f637 (patch)
tree8aa46632eb381b44de64d106b62f8efad49c173d /src/lib/tls/tls_extensions.cpp
parent181e75b66d5fbffdce04d37014c260b4fab5dec8 (diff)
Add ALPN (RFC 7301) and remove NPN
Diffstat (limited to 'src/lib/tls/tls_extensions.cpp')
-rw-r--r--src/lib/tls/tls_extensions.cpp39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp
index 2c3056d9f..b7ba4a917 100644
--- a/src/lib/tls/tls_extensions.cpp
+++ b/src/lib/tls/tls_extensions.cpp
@@ -42,8 +42,8 @@ Extension* make_extension(TLS_Data_Reader& reader,
case TLSEXT_USE_SRTP:
return new SRTP_Protection_Profiles(reader, size);
- case TLSEXT_NEXT_PROTOCOL:
- return new Next_Protocol_Notification(reader, size);
+ case TLSEXT_ALPN:
+ return new Application_Layer_Protocol_Notification(reader, size);
case TLSEXT_HEARTBEAT_SUPPORT:
return new Heartbeat_Support_Indicator(reader, size);
@@ -258,20 +258,25 @@ Maximum_Fragment_Length::Maximum_Fragment_Length(TLS_Data_Reader& reader,
}
}
-Next_Protocol_Notification::Next_Protocol_Notification(TLS_Data_Reader& reader,
- u16bit extension_size)
+Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
+ u16bit extension_size)
{
if(extension_size == 0)
return; // empty extension
- size_t bytes_remaining = extension_size;
+ 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 for next protocol extension");
+ throw Decoding_Error("Bad encoding of ALPN, length field too long");
bytes_remaining -= (p.size() + 1);
@@ -279,14 +284,23 @@ Next_Protocol_Notification::Next_Protocol_Notification(TLS_Data_Reader& reader,
}
}
-std::vector<byte> Next_Protocol_Notification::serialize() const
+const std::string& Application_Layer_Protocol_Notification::single_protocol() const
{
- std::vector<byte> buf;
+ if(m_protocols.size() != 1)
+ throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
+ "Server sent " + std::to_string(m_protocols.size()) +
+ " protocols in ALPN extension response");
+ return m_protocols[0];
+ }
- for(size_t i = 0; i != m_protocols.size(); ++i)
- {
- const std::string p = m_protocols[i];
+std::vector<byte> Application_Layer_Protocol_Notification::serialize() const
+ {
+ std::vector<byte> buf(2);
+ for(auto&& p: m_protocols)
+ {
+ if(p.length() >= 256)
+ throw TLS_Exception(Alert::INTERNAL_ERROR, "ALPN name too long");
if(p != "")
append_tls_length_value(buf,
reinterpret_cast<const byte*>(p.data()),
@@ -294,6 +308,9 @@ std::vector<byte> Next_Protocol_Notification::serialize() const
1);
}
+ buf[0] = get_byte<u16bit>(0, buf.size()-2);
+ buf[1] = get_byte<u16bit>(1, buf.size()-2);
+
return buf;
}