aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-03-16 17:36:40 +0000
committerlloyd <[email protected]>2012-03-16 17:36:40 +0000
commit9309bf44ca05e70100a4ef1653faf602e456cdd9 (patch)
tree158469120aba67088b153e2a81e4f8b631a42db2
parent7371f7c59ae722769fbc0dc810583a0cd0e38877 (diff)
Add missing source for DTLS hello verify
-rw-r--r--src/tls/hello_verify.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/tls/hello_verify.cpp b/src/tls/hello_verify.cpp
new file mode 100644
index 000000000..c7aae94a1
--- /dev/null
+++ b/src/tls/hello_verify.cpp
@@ -0,0 +1,61 @@
+/*
+* DTLS Hello Verify Request
+* (C) 2012 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#include <botan/internal/tls_messages.h>
+#include <botan/lookup.h>
+#include <memory>
+
+namespace Botan {
+
+namespace TLS {
+
+Hello_Verify_Request::Hello_Verify_Request(const MemoryRegion<byte>& buf)
+ {
+ if(buf.size() < 3)
+ throw Decoding_Error("Hello verify request too small");
+
+ if(buf[0] != 254 || (buf[1] != 255 && buf[1] != 253))
+ throw Decoding_Error("Unknown version from server in hello verify request");
+
+ m_cookie.resize(buf.size() - 2);
+ copy_mem(&m_cookie[0], &buf[2], buf.size() - 2);
+ }
+
+Hello_Verify_Request::Hello_Verify_Request(const MemoryVector<byte>& client_hello_bits,
+ const std::string& client_identity,
+ const SymmetricKey& secret_key)
+ {
+ std::auto_ptr<MessageAuthenticationCode> hmac(get_mac("HMAC(SHA-256)"));
+ hmac->set_key(secret_key);
+
+ hmac->update_be(client_hello_bits.size());
+ hmac->update(client_hello_bits);
+ hmac->update_be(client_identity.size());
+ hmac->update(client_identity);
+
+ m_cookie = hmac->final();
+ }
+
+MemoryVector<byte> Hello_Verify_Request::serialize() const
+ {
+ /* DTLS 1.2 server implementations SHOULD use DTLS version 1.0
+ regardless of the version of TLS that is expected to be
+ negotiated (RFC 6347, section 4.2.1)
+ */
+
+ Protocol_Version format_version(Protocol_Version::TLS_V11);
+
+ MemoryVector<byte> bits;
+ bits.push_back(format_version.major_version());
+ bits.push_back(format_version.minor_version());
+ bits += m_cookie;
+ return bits;
+ }
+
+}
+
+}