diff options
Diffstat (limited to 'src/lib/tls/msg_cert_verify.cpp')
-rw-r--r-- | src/lib/tls/msg_cert_verify.cpp | 117 |
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); + } + +} + +} |