Botan  1.11.15
src/lib/tls/tls_session.cpp
Go to the documentation of this file.
00001 /*
00002 * TLS Session State
00003 * (C) 2011-2012,2015 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/tls_session.h>
00009 #include <botan/der_enc.h>
00010 #include <botan/ber_dec.h>
00011 #include <botan/asn1_str.h>
00012 #include <botan/pem.h>
00013 #include <botan/aead.h>
00014 #include <botan/sha2_32.h>
00015 #include <botan/hmac.h>
00016 
00017 namespace Botan {
00018 
00019 namespace TLS {
00020 
00021 Session::Session(const std::vector<byte>& session_identifier,
00022                  const secure_vector<byte>& master_secret,
00023                  Protocol_Version version,
00024                  u16bit ciphersuite,
00025                  byte compression_method,
00026                  Connection_Side side,
00027                  size_t fragment_size,
00028                  const std::vector<X509_Certificate>& certs,
00029                  const std::vector<byte>& ticket,
00030                  const Server_Information& server_info,
00031                  const std::string& srp_identifier,
00032                  u16bit srtp_profile) :
00033    m_start_time(std::chrono::system_clock::now()),
00034    m_identifier(session_identifier),
00035    m_session_ticket(ticket),
00036    m_master_secret(master_secret),
00037    m_version(version),
00038    m_ciphersuite(ciphersuite),
00039    m_compression_method(compression_method),
00040    m_connection_side(side),
00041    m_srtp_profile(srtp_profile),
00042    m_fragment_size(fragment_size),
00043    m_peer_certs(certs),
00044    m_server_info(server_info),
00045    m_srp_identifier(srp_identifier)
00046    {
00047    }
00048 
00049 Session::Session(const std::string& pem)
00050    {
00051    secure_vector<byte> der = PEM_Code::decode_check_label(pem, "TLS SESSION");
00052 
00053    *this = Session(&der[0], der.size());
00054    }
00055 
00056 Session::Session(const byte ber[], size_t ber_len)
00057    {
00058    byte side_code = 0;
00059 
00060    ASN1_String server_hostname;
00061    ASN1_String server_service;
00062    size_t server_port;
00063 
00064    ASN1_String srp_identifier_str;
00065 
00066    byte major_version = 0, minor_version = 0;
00067    std::vector<byte> peer_cert_bits;
00068 
00069    size_t start_time = 0;
00070    size_t srtp_profile = 0;
00071 
00072    BER_Decoder(ber, ber_len)
00073       .start_cons(SEQUENCE)
00074         .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION),
00075                           "Unknown version in serialized TLS session")
00076         .decode_integer_type(start_time)
00077         .decode_integer_type(major_version)
00078         .decode_integer_type(minor_version)
00079         .decode(m_identifier, OCTET_STRING)
00080         .decode(m_session_ticket, OCTET_STRING)
00081         .decode_integer_type(m_ciphersuite)
00082         .decode_integer_type(m_compression_method)
00083         .decode_integer_type(side_code)
00084         .decode_integer_type(m_fragment_size)
00085         .decode(m_master_secret, OCTET_STRING)
00086         .decode(peer_cert_bits, OCTET_STRING)
00087         .decode(server_hostname)
00088         .decode(server_service)
00089         .decode(server_port)
00090         .decode(srp_identifier_str)
00091         .decode(srtp_profile)
00092       .end_cons()
00093       .verify_end();
00094 
00095    m_version = Protocol_Version(major_version, minor_version);
00096    m_start_time = std::chrono::system_clock::from_time_t(start_time);
00097    m_connection_side = static_cast<Connection_Side>(side_code);
00098    m_srtp_profile = srtp_profile;
00099 
00100    m_server_info = Server_Information(server_hostname.value(),
00101                                       server_service.value(),
00102                                       server_port);
00103 
00104    m_srp_identifier = srp_identifier_str.value();
00105 
00106    if(!peer_cert_bits.empty())
00107       {
00108       DataSource_Memory certs(&peer_cert_bits[0], peer_cert_bits.size());
00109 
00110       while(!certs.end_of_data())
00111          m_peer_certs.push_back(X509_Certificate(certs));
00112       }
00113    }
00114 
00115 secure_vector<byte> Session::DER_encode() const
00116    {
00117    std::vector<byte> peer_cert_bits;
00118    for(size_t i = 0; i != m_peer_certs.size(); ++i)
00119       peer_cert_bits += m_peer_certs[i].BER_encode();
00120 
00121    return DER_Encoder()
00122       .start_cons(SEQUENCE)
00123          .encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION))
00124          .encode(static_cast<size_t>(std::chrono::system_clock::to_time_t(m_start_time)))
00125          .encode(static_cast<size_t>(m_version.major_version()))
00126          .encode(static_cast<size_t>(m_version.minor_version()))
00127          .encode(m_identifier, OCTET_STRING)
00128          .encode(m_session_ticket, OCTET_STRING)
00129          .encode(static_cast<size_t>(m_ciphersuite))
00130          .encode(static_cast<size_t>(m_compression_method))
00131          .encode(static_cast<size_t>(m_connection_side))
00132          .encode(static_cast<size_t>(m_fragment_size))
00133          .encode(m_master_secret, OCTET_STRING)
00134          .encode(peer_cert_bits, OCTET_STRING)
00135          .encode(ASN1_String(m_server_info.hostname(), UTF8_STRING))
00136          .encode(ASN1_String(m_server_info.service(), UTF8_STRING))
00137          .encode(static_cast<size_t>(m_server_info.port()))
00138          .encode(ASN1_String(m_srp_identifier, UTF8_STRING))
00139          .encode(static_cast<size_t>(m_srtp_profile))
00140       .end_cons()
00141    .get_contents();
00142    }
00143 
00144 std::string Session::PEM_encode() const
00145    {
00146    return PEM_Code::encode(this->DER_encode(), "TLS SESSION");
00147    }
00148 
00149 std::chrono::seconds Session::session_age() const
00150    {
00151    return std::chrono::duration_cast<std::chrono::seconds>(
00152       std::chrono::system_clock::now() - m_start_time);
00153    }
00154 
00155 std::vector<byte>
00156 Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const
00157    {
00158    std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", ENCRYPTION));
00159    const size_t nonce_len = aead->default_nonce_length();
00160 
00161    const secure_vector<byte> nonce = rng.random_vec(nonce_len);
00162    const secure_vector<byte> bits = this->DER_encode();
00163 
00164    // Support any length key for input
00165    HMAC hmac(new SHA_256);
00166    hmac.set_key(key);
00167    hmac.update(nonce);
00168    aead->set_key(hmac.final());
00169 
00170    secure_vector<byte> buf = nonce;
00171    buf += bits;
00172    aead->start(&buf[0], nonce_len);
00173    aead->finish(buf, nonce_len);
00174    return unlock(buf);
00175    }
00176 
00177 Session Session::decrypt(const byte in[], size_t in_len, const SymmetricKey& key)
00178    {
00179    try
00180       {
00181       std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", DECRYPTION));
00182       const size_t nonce_len = aead->default_nonce_length();
00183 
00184       if(in_len < nonce_len + aead->tag_size())
00185          throw Decoding_Error("Encrypted session too short to be valid");
00186 
00187       // Support any length key for input
00188       HMAC hmac(new SHA_256);
00189       hmac.set_key(key);
00190       hmac.update(in, nonce_len); // nonce bytes
00191       aead->set_key(hmac.final());
00192 
00193       aead->start(in, nonce_len);
00194       secure_vector<byte> buf(in + nonce_len, in + in_len);
00195       aead->finish(buf, 0);
00196 
00197       return Session(&buf[0], buf.size());
00198       }
00199    catch(std::exception& e)
00200       {
00201       throw Decoding_Error("Failed to decrypt serialized TLS session: " +
00202                            std::string(e.what()));
00203       }
00204    }
00205 
00206 }
00207 
00208 }
00209