diff options
Diffstat (limited to 'src/tls/tls_session.cpp')
-rw-r--r-- | src/tls/tls_session.cpp | 102 |
1 files changed, 69 insertions, 33 deletions
diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp index c40e9d79e..f8e686a4a 100644 --- a/src/tls/tls_session.cpp +++ b/src/tls/tls_session.cpp @@ -9,23 +9,26 @@ #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/asn1_str.h> +#include <botan/pem.h> #include <botan/time.h> #include <botan/lookup.h> #include <memory> namespace Botan { -TLS_Session::TLS_Session(const MemoryRegion<byte>& session_identifier, - const MemoryRegion<byte>& master_secret, - Version_Code version, - u16bit ciphersuite, - byte compression_method, - Connection_Side side, - bool secure_renegotiation_supported, - size_t fragment_size, - const std::vector<X509_Certificate>& certs, - const std::string& sni_hostname, - const std::string& srp_identifier) : +namespace TLS { + +Session::Session(const MemoryRegion<byte>& session_identifier, + const MemoryRegion<byte>& master_secret, + Protocol_Version version, + u16bit ciphersuite, + byte compression_method, + Connection_Side side, + bool secure_renegotiation_supported, + size_t fragment_size, + const std::vector<X509_Certificate>& certs, + const std::string& sni_hostname, + const std::string& srp_identifier) : m_start_time(system_time()), m_identifier(session_identifier), m_master_secret(master_secret), @@ -35,15 +38,13 @@ TLS_Session::TLS_Session(const MemoryRegion<byte>& session_identifier, m_connection_side(side), m_secure_renegotiation_supported(secure_renegotiation_supported), m_fragment_size(fragment_size), + m_peer_certs(certs), m_sni_hostname(sni_hostname), m_srp_identifier(srp_identifier) { - // FIXME: encode all of them? - if(certs.size()) - m_peer_certificate = certs[0].BER_encode(); } -TLS_Session::TLS_Session(const byte ber[], size_t ber_len) +Session::Session(const byte ber[], size_t ber_len) { BER_Decoder decoder(ber, ber_len); @@ -51,48 +52,84 @@ TLS_Session::TLS_Session(const byte ber[], size_t ber_len) ASN1_String sni_hostname_str; ASN1_String srp_identifier_str; + byte major_version = 0, minor_version = 0; + + MemoryVector<byte> peer_cert_bits; + BER_Decoder(ber, ber_len) - .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION), - "Unknown version in session structure") - .decode(m_identifier, OCTET_STRING) - .decode_integer_type(m_start_time) - .decode_integer_type(m_version) - .decode_integer_type(m_ciphersuite) - .decode_integer_type(m_compression_method) - .decode_integer_type(side_code) - .decode_integer_type(m_fragment_size) - .decode(m_secure_renegotiation_supported) - .decode(m_master_secret, OCTET_STRING) - .decode(m_peer_certificate, OCTET_STRING) - .decode(sni_hostname_str) - .decode(srp_identifier_str); + .start_cons(SEQUENCE) + .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION), + "Unknown version in session structure") + .decode(m_identifier, OCTET_STRING) + .decode_integer_type(m_start_time) + .decode_integer_type(major_version) + .decode_integer_type(minor_version) + .decode_integer_type(m_ciphersuite) + .decode_integer_type(m_compression_method) + .decode_integer_type(side_code) + .decode_integer_type(m_fragment_size) + .decode(m_secure_renegotiation_supported) + .decode(m_master_secret, OCTET_STRING) + .decode(peer_cert_bits, OCTET_STRING) + .decode(sni_hostname_str) + .decode(srp_identifier_str) + .end_cons() + .verify_end(); + m_version = Protocol_Version(major_version, minor_version); m_sni_hostname = sni_hostname_str.value(); m_srp_identifier = srp_identifier_str.value(); m_connection_side = static_cast<Connection_Side>(side_code); + + if(!peer_cert_bits.empty()) + { + DataSource_Memory certs(peer_cert_bits); + + while(!certs.end_of_data()) + m_peer_certs.push_back(X509_Certificate(certs)); + } } -SecureVector<byte> TLS_Session::BER_encode() const +Session::Session(const std::string& pem) { + SecureVector<byte> der = PEM_Code::decode_check_label(pem, "SSL SESSION"); + + *this = Session(&der[0], der.size()); + } + +SecureVector<byte> Session::DER_encode() const + { + MemoryVector<byte> peer_cert_bits; + for(size_t i = 0; i != m_peer_certs.size(); ++i) + peer_cert_bits += m_peer_certs[i].BER_encode(); + return DER_Encoder() .start_cons(SEQUENCE) .encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION)) .encode(m_identifier, OCTET_STRING) .encode(static_cast<size_t>(m_start_time)) - .encode(static_cast<size_t>(m_version)) + .encode(static_cast<size_t>(m_version.major_version())) + .encode(static_cast<size_t>(m_version.minor_version())) .encode(static_cast<size_t>(m_ciphersuite)) .encode(static_cast<size_t>(m_compression_method)) .encode(static_cast<size_t>(m_connection_side)) .encode(static_cast<size_t>(m_fragment_size)) .encode(m_secure_renegotiation_supported) .encode(m_master_secret, OCTET_STRING) - .encode(m_peer_certificate, OCTET_STRING) + .encode(peer_cert_bits, OCTET_STRING) .encode(ASN1_String(m_sni_hostname, UTF8_STRING)) .encode(ASN1_String(m_srp_identifier, UTF8_STRING)) .end_cons() .get_contents(); } +std::string Session::PEM_encode() const + { + return PEM_Code::encode(this->DER_encode(), "SSL SESSION"); + } + +} + MemoryVector<byte> TLS_Session::encrypt(const SymmetricKey& master_key, const MemoryRegion<byte>& key_name, @@ -180,5 +217,4 @@ TLS_Session TLS_Session::decrypt(const MemoryRegion<byte>& buf, } } - } |