aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/msg_cert_verify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/tls/msg_cert_verify.cpp')
-rw-r--r--src/lib/tls/msg_cert_verify.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/lib/tls/msg_cert_verify.cpp b/src/lib/tls/msg_cert_verify.cpp
new file mode 100644
index 000000000..436b84c24
--- /dev/null
+++ b/src/lib/tls/msg_cert_verify.cpp
@@ -0,0 +1,117 @@
+/*
+* Certificate Verify Message
+* (C) 2004,2006,2011,2012 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#include <botan/internal/tls_messages.h>
+#include <botan/internal/tls_reader.h>
+#include <botan/internal/tls_extensions.h>
+#include <botan/internal/tls_handshake_io.h>
+#include <memory>
+
+namespace Botan {
+
+namespace TLS {
+
+/*
+* Create a new Certificate Verify message
+*/
+Certificate_Verify::Certificate_Verify(Handshake_IO& io,
+ Handshake_State& state,
+ const Policy& policy,
+ RandomNumberGenerator& rng,
+ const Private_Key* priv_key)
+ {
+ BOTAN_ASSERT_NONNULL(priv_key);
+
+ std::pair<std::string, Signature_Format> format =
+ state.choose_sig_format(*priv_key, m_hash_algo, m_sig_algo, true, policy);
+
+ PK_Signer signer(*priv_key, format.first, format.second);
+
+ if(state.version() == Protocol_Version::SSL_V3)
+ {
+ secure_vector<byte> md5_sha = state.hash().final_ssl3(
+ state.session_keys().master_secret());
+
+ if(priv_key->algo_name() == "DSA")
+ m_signature = signer.sign_message(&md5_sha[16], md5_sha.size()-16, rng);
+ else
+ m_signature = signer.sign_message(md5_sha, rng);
+ }
+ else
+ {
+ m_signature = signer.sign_message(state.hash().get_contents(), rng);
+ }
+
+ state.hash().update(io.send(*this));
+ }
+
+/*
+* Deserialize a Certificate Verify message
+*/
+Certificate_Verify::Certificate_Verify(const std::vector<byte>& buf,
+ Protocol_Version version)
+ {
+ TLS_Data_Reader reader(buf);
+
+ if(version.supports_negotiable_signature_algorithms())
+ {
+ m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte());
+ m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte());
+ }
+
+ m_signature = reader.get_range<byte>(2, 0, 65535);
+ }
+
+/*
+* Serialize a Certificate Verify message
+*/
+std::vector<byte> Certificate_Verify::serialize() const
+ {
+ std::vector<byte> buf;
+
+ if(m_hash_algo != "" && m_sig_algo != "")
+ {
+ buf.push_back(Signature_Algorithms::hash_algo_code(m_hash_algo));
+ buf.push_back(Signature_Algorithms::sig_algo_code(m_sig_algo));
+ }
+
+ const u16bit sig_len = m_signature.size();
+ buf.push_back(get_byte(0, sig_len));
+ buf.push_back(get_byte(1, sig_len));
+ buf += m_signature;
+
+ return buf;
+ }
+
+/*
+* Verify a Certificate Verify message
+*/
+bool Certificate_Verify::verify(const X509_Certificate& cert,
+ const Handshake_State& state) const
+ {
+ std::unique_ptr<Public_Key> key(cert.subject_public_key());
+
+ std::pair<std::string, Signature_Format> format =
+ state.understand_sig_format(*key.get(), m_hash_algo, m_sig_algo, true);
+
+ PK_Verifier verifier(*key, format.first, format.second);
+
+ if(state.version() == Protocol_Version::SSL_V3)
+ {
+ secure_vector<byte> md5_sha = state.hash().final_ssl3(
+ state.session_keys().master_secret());
+
+ return verifier.verify_message(&md5_sha[16], md5_sha.size()-16,
+ &m_signature[0], m_signature.size());
+ }
+
+ return verifier.verify_message(state.hash().get_contents(), m_signature);
+ }
+
+}
+
+}