aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-01-27 11:39:38 -0500
committerJack Lloyd <[email protected]>2018-01-27 11:39:38 -0500
commitef741f408e4fd793fe75a142ac63863e906cc61a (patch)
tree3810c8fed21facccaeb05f98c176d56702e4d2ea /src/lib
parentdd960f0a5e34ec4b0319c8069fb1ccb58ef8c901 (diff)
Make it possible to test custom extensions
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/tls/tls_extensions.cpp21
-rw-r--r--src/lib/tls/tls_extensions.h41
-rw-r--r--src/lib/tls/tls_server.h10
3 files changed, 59 insertions, 13 deletions
diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp
index 6497c3c11..522cf4a4f 100644
--- a/src/lib/tls/tls_extensions.cpp
+++ b/src/lib/tls/tls_extensions.cpp
@@ -59,7 +59,8 @@ Extension* make_extension(TLS_Data_Reader& reader, uint16_t code, uint16_t size)
return new Session_Ticket(reader, size);
}
- return nullptr; // not known
+ return new Unknown_Extension(static_cast<Handshake_Extension_Type>(code),
+ reader, size);
}
}
@@ -82,10 +83,7 @@ void Extensions::deserialize(TLS_Data_Reader& reader)
extension_code,
extension_size);
- if(extn)
- this->add(extn);
- else // unknown/unhandled extension
- reader.discard_next(extension_size);
+ this->add(extn);
}
}
}
@@ -141,6 +139,19 @@ std::set<Handshake_Extension_Type> Extensions::extension_types() const
return offers;
}
+Unknown_Extension::Unknown_Extension(Handshake_Extension_Type type,
+ TLS_Data_Reader& reader,
+ uint16_t extension_size) :
+ m_type(type),
+ m_value(reader.get_fixed<uint8_t>(extension_size))
+ {
+ }
+
+std::vector<uint8_t> Unknown_Extension::serialize() const
+ {
+ throw Invalid_State("Cannot encode an unknown TLS extension");
+ }
+
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader,
uint16_t extension_size)
{
diff --git a/src/lib/tls/tls_extensions.h b/src/lib/tls/tls_extensions.h
index 7b7b645bf..114b16489 100644
--- a/src/lib/tls/tls_extensions.h
+++ b/src/lib/tls/tls_extensions.h
@@ -432,6 +432,30 @@ class Certificate_Status_Request final : public Extension
};
/**
+* Unknown extensions are deserialized as this type
+*/
+class BOTAN_UNSTABLE_API Unknown_Extension final : public Extension
+ {
+ public:
+ Unknown_Extension(Handshake_Extension_Type type,
+ TLS_Data_Reader& reader,
+ uint16_t extension_size);
+
+ std::vector<uint8_t> serialize() const override; // always fails
+
+ const std::vector<uint8_t>& value() { return m_value; }
+
+ bool empty() const { return false; }
+
+ Handshake_Extension_Type type() const { return m_type; }
+
+ private:
+ Handshake_Extension_Type m_type;
+ std::vector<uint8_t> m_value;
+
+ };
+
+/**
* Represents a block of extensions in a hello message
*/
class BOTAN_UNSTABLE_API Extensions final
@@ -442,13 +466,7 @@ class BOTAN_UNSTABLE_API Extensions final
template<typename T>
T* get() const
{
- Handshake_Extension_Type type = T::static_type();
-
- auto i = m_extensions.find(type);
-
- if(i != m_extensions.end())
- return dynamic_cast<T*>(i->second.get());
- return nullptr;
+ return dynamic_cast<T*>(get(T::static_type()));
}
template<typename T>
@@ -462,6 +480,15 @@ class BOTAN_UNSTABLE_API Extensions final
m_extensions[extn->type()].reset(extn);
}
+ Extension* get(Handshake_Extension_Type type) const
+ {
+ auto i = m_extensions.find(type);
+
+ if(i != m_extensions.end())
+ return i->second.get();
+ return nullptr;
+ }
+
std::vector<uint8_t> serialize() const;
void deserialize(TLS_Data_Reader& reader);
diff --git a/src/lib/tls/tls_server.h b/src/lib/tls/tls_server.h
index eb6e710e1..7c5d9668f 100644
--- a/src/lib/tls/tls_server.h
+++ b/src/lib/tls/tls_server.h
@@ -96,12 +96,20 @@ class BOTAN_PUBLIC_API(2,0) Server final : public Channel
/**
* Return the protocol notification set by the client (using the
- * NPN extension) for this connection, if any. This value is not
+ * ALPN extension) for this connection, if any. This value is not
* tied to the session and a later renegotiation of the same
* session can choose a new protocol.
*/
std::string next_protocol() const { return m_next_protocol; }
+ /**
+ * Return the protocol notification set by the client (using the
+ * ALPN extension) for this connection, if any. This value is not
+ * tied to the session and a later renegotiation of the same
+ * session can choose a new protocol.
+ */
+ std::string application_protocol() const { return m_next_protocol; }
+
private:
std::vector<X509_Certificate>
get_peer_cert_chain(const Handshake_State& state) const override;