diff options
author | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
commit | 12090a7148d9ee73572cc1a7268fc489504a8173 (patch) | |
tree | 51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/tls/finished.cpp | |
parent | 9594979caf775dc4062850044715b804d1fda60c (diff) | |
parent | 65cc04445f8d40497f02a14bd8cb97081790e54b (diff) |
propagate from branch 'net.randombit.botan.x509-path-validation' (head 63b5a20eab129ca13287fda33d2d02eec329708f)
to branch 'net.randombit.botan' (head 8b8150f09c55184f028f2929c4e7f7cd0d46d96e)
Diffstat (limited to 'src/tls/finished.cpp')
-rw-r--r-- | src/tls/finished.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/tls/finished.cpp b/src/tls/finished.cpp new file mode 100644 index 000000000..c8ae4a343 --- /dev/null +++ b/src/tls/finished.cpp @@ -0,0 +1,104 @@ +/* +* Finished Message +* (C) 2004-2006,2012 Jack Lloyd +* +* Released under the terms of the Botan license +*/ + +#include <botan/internal/tls_messages.h> +#include <botan/tls_record.h> +#include <memory> + +namespace Botan { + +namespace TLS { + +namespace { + +/* +* Compute the verify_data +*/ +std::vector<byte> finished_compute_verify(Handshake_State* state, + Connection_Side side) + { + if(state->version() == Protocol_Version::SSL_V3) + { + const byte SSL_CLIENT_LABEL[] = { 0x43, 0x4C, 0x4E, 0x54 }; + const byte SSL_SERVER_LABEL[] = { 0x53, 0x52, 0x56, 0x52 }; + + Handshake_Hash hash = state->hash; // don't modify state + + std::vector<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 unlock(hash.final_ssl3(state->keys.master_secret())); + } + else + { + 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 }; + + std::unique_ptr<KDF> prf(state->protocol_specific_prf()); + + std::vector<byte> input; + if(side == CLIENT) + input += std::make_pair(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL)); + else + input += std::make_pair(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL)); + + input += state->hash.final(state->version(), state->suite.mac_algo()); + + return unlock(prf->derive_key(12, state->keys.master_secret(), input)); + } + } + +} + +/* +* Create a new Finished message +*/ +Finished::Finished(Record_Writer& writer, + Handshake_State* state, + Connection_Side side) + { + verification_data = finished_compute_verify(state, side); + state->hash.update(writer.send(*this)); + } + +/* +* Serialize a Finished message +*/ +std::vector<byte> Finished::serialize() const + { + return verification_data; + } + +/* +* Deserialize a Finished message +*/ +Finished::Finished(const std::vector<byte>& buf) + { + verification_data = buf; + } + +/* +* Verify a Finished message +*/ +bool Finished::verify(Handshake_State* state, + Connection_Side side) + { + return (verification_data == finished_compute_verify(state, side)); + } + +} + +} |