aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-01-24 12:52:47 +0000
committerlloyd <[email protected]>2012-01-24 12:52:47 +0000
commita1b438469c23079a92b8a89e7df7e95fa0eae0ce (patch)
treebbf26c5ca726d64f80a3c0b31ef05b475227ccba
parentefcf54fcd6858932ad4336c7eba5d30c32945bad (diff)
PEM encoding. Fix BER decoding. Encode the entire cert chain in the
session.
-rw-r--r--src/tls/tls_session.cpp68
-rw-r--r--src/tls/tls_session.h23
2 files changed, 68 insertions, 23 deletions
diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp
index d9ccd6df4..2e25a8ab3 100644
--- a/src/tls/tls_session.cpp
+++ b/src/tls/tls_session.cpp
@@ -9,6 +9,7 @@
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/asn1_str.h>
+#include <botan/pem.h>
#include <botan/time.h>
namespace Botan {
@@ -35,12 +36,10 @@ Session::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();
}
Session::Session(const byte ber[], size_t ber_len)
@@ -53,31 +52,55 @@ Session::Session(const byte ber[], size_t ber_len)
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(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(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> 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))
@@ -91,13 +114,18 @@ SecureVector<byte> Session::BER_encode() const
.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");
+ }
+
}
}
diff --git a/src/tls/tls_session.h b/src/tls/tls_session.h
index 96ef6514e..297ff5f96 100644
--- a/src/tls/tls_session.h
+++ b/src/tls/tls_session.h
@@ -54,16 +54,28 @@ class BOTAN_DLL Session
const std::string& srp_identifier = "");
/**
- * Load a session from BER (created by BER_encode)
+ * Load a session from DER representation (created by DER_encode)
*/
Session(const byte ber[], size_t ber_len);
/**
+ * Load a session from PEM representation (created by PEM_encode)
+ */
+ Session(const std::string& pem);
+
+ /**
+ * Encode this session data for storage
+ * @warning if the master secret is compromised so is the
+ * session traffic
+ */
+ SecureVector<byte> DER_encode() const;
+
+ /**
* Encode this session data for storage
* @warning if the master secret is compromised so is the
* session traffic
*/
- SecureVector<byte> BER_encode() const;
+ std::string PEM_encode() const;
/**
* Get the version of the saved session
@@ -125,6 +137,11 @@ class BOTAN_DLL Session
{ return m_secure_renegotiation_supported; }
/**
+ * Return the certificate chain of the peer (possibly empty)
+ */
+ std::vector<X509_Certificate> peer_certs() const { return m_peer_certs; }
+
+ /**
* Get the time this session began (seconds since Epoch)
*/
u64bit start_time() const { return m_start_time; }
@@ -145,7 +162,7 @@ class BOTAN_DLL Session
bool m_secure_renegotiation_supported;
size_t m_fragment_size;
- MemoryVector<byte> m_peer_certificate; // optional
+ std::vector<X509_Certificate> m_peer_certs;
std::string m_sni_hostname; // optional
std::string m_srp_identifier; // optional
};