aboutsummaryrefslogtreecommitdiffstats
path: root/src/ssl/finished.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl/finished.cpp')
-rw-r--r--src/ssl/finished.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/ssl/finished.cpp b/src/ssl/finished.cpp
new file mode 100644
index 000000000..91193c6be
--- /dev/null
+++ b/src/ssl/finished.cpp
@@ -0,0 +1,100 @@
+/**
+* Finished Message Source File
+* (C) 2004-2006 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#include <botan/tls_messages.h>
+#include <botan/prf_tls.h>
+
+namespace Botan {
+
+/**
+* Create a new Finished message
+*/
+Finished::Finished(Record_Writer& writer,
+ Version_Code version, Connection_Side side,
+ const MemoryRegion<byte>& master_secret,
+ HandshakeHash& hash)
+ {
+ verification_data = compute_verify(master_secret, hash, side, version);
+ send(writer, hash);
+ }
+
+/**
+* Serialize a Finished message
+*/
+SecureVector<byte> Finished::serialize() const
+ {
+ return verification_data;
+ }
+
+/**
+* Deserialize a Finished message
+*/
+void Finished::deserialize(const MemoryRegion<byte>& buf)
+ {
+ verification_data = buf;
+ }
+
+/**
+* Verify a Finished message
+*/
+bool Finished::verify(const MemoryRegion<byte>& secret, Version_Code version,
+ const HandshakeHash& hash, Connection_Side side)
+ {
+ SecureVector<byte> computed = compute_verify(secret, hash, side, version);
+ if(computed == verification_data)
+ return true;
+ return false;
+ }
+
+/**
+* Compute the verify_data
+*/
+SecureVector<byte> Finished::compute_verify(const MemoryRegion<byte>& secret,
+ HandshakeHash hash,
+ Connection_Side side,
+ Version_Code version)
+ {
+ if(version == SSL_V3)
+ {
+ const byte SSL_CLIENT_LABEL[] = { 0x43, 0x4C, 0x4E, 0x54 };
+ const byte SSL_SERVER_LABEL[] = { 0x53, 0x52, 0x56, 0x52 };
+
+ SecureVector<byte> ssl3_finished;
+
+ if(side == CLIENT)
+ hash.update(SSL_CLIENT_LABEL, sizeof(SSL_CLIENT_LABEL));
+ else
+ hash.update(SSL_SERVER_LABEL, sizeof(SSL_SERVER_LABEL));
+
+ return hash.final_ssl3(secret);
+ }
+ else if(version == TLS_V10)
+ {
+ const byte TLS_CLIENT_LABEL[] = {
+ 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69,
+ 0x73, 0x68, 0x65, 0x64 };
+
+ const byte TLS_SERVER_LABEL[] = {
+ 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69,
+ 0x73, 0x68, 0x65, 0x64 };
+
+ TLS_PRF prf;
+
+ SecureVector<byte> input;
+ if(side == CLIENT)
+ input.append(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL));
+ else
+ input.append(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL));
+ input.append(hash.final());
+
+ return prf.derive_key(12, secret, input);
+ }
+ else
+ throw Invalid_Argument("Finished message: Unknown protocol version");
+ }
+
+}