aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarry Reimann <[email protected]>2017-11-29 08:35:27 +0100
committerHarry Reimann <[email protected]>2017-12-04 10:54:14 +0100
commit805bb27dff20e491e76142db2b5fe1bd586d4788 (patch)
tree64cc4c6ea4633a86509a8b18635c802ec3c3a8e8
parentb236a8aa0803bac4fba3c1de840379fb01f54ca1 (diff)
Make support for certificate status messages optional via policy
Don't postpone the verification of a server certificate if certificate status messages are not expected in client handshake. When using an external crypto device it may be necessary to verify the certificate before using the public key for verification of the signature in the server key exchange message.
-rw-r--r--src/lib/tls/msg_client_hello.cpp3
-rw-r--r--src/lib/tls/msg_server_hello.cpp9
-rw-r--r--src/lib/tls/tls_client.cpp24
-rw-r--r--src/lib/tls/tls_policy.cpp2
-rw-r--r--src/lib/tls/tls_policy.h7
-rw-r--r--src/lib/tls/tls_text_policy.cpp5
-rw-r--r--src/tests/unit_tls.cpp3
7 files changed, 43 insertions, 10 deletions
diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp
index 3b13cf21d..bcd8397e8 100644
--- a/src/lib/tls/msg_client_hello.cpp
+++ b/src/lib/tls/msg_client_hello.cpp
@@ -105,7 +105,8 @@ Client_Hello::Client_Hello(Handshake_IO& io,
m_extensions.add(new Renegotiation_Extension(reneg_info));
m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
- m_extensions.add(new Certificate_Status_Request({}, {}));
+ if(policy.support_cert_status_message())
+ m_extensions.add(new Certificate_Status_Request({}, {}));
if(reneg_info.empty() && !next_protocols.empty())
m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
diff --git a/src/lib/tls/msg_server_hello.cpp b/src/lib/tls/msg_server_hello.cpp
index 67c3d530f..81f9e1f62 100644
--- a/src/lib/tls/msg_server_hello.cpp
+++ b/src/lib/tls/msg_server_hello.cpp
@@ -37,7 +37,7 @@ Server_Hello::Server_Hello(Handshake_IO& io,
m_extensions.add(new Extended_Master_Secret);
// Sending the extension back does not commit us to sending a stapled response
- if(client_hello.supports_cert_status_message())
+ if(client_hello.supports_cert_status_message() && policy.support_cert_status_message())
m_extensions.add(new Certificate_Status_Request);
Ciphersuite c = Ciphersuite::by_id(m_ciphersuite);
@@ -105,7 +105,7 @@ Server_Hello::Server_Hello(Handshake_IO& io,
m_extensions.add(new Extended_Master_Secret);
// Sending the extension back does not commit us to sending a stapled response
- if(client_hello.supports_cert_status_message())
+ if(client_hello.supports_cert_status_message() && policy.support_cert_status_message())
m_extensions.add(new Certificate_Status_Request);
if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac())
@@ -115,11 +115,6 @@ Server_Hello::Server_Hello(Handshake_IO& io,
m_extensions.add(new Encrypt_then_MAC);
}
- if(client_hello.supports_cert_status_message())
- {
- m_extensions.add(new Certificate_Status_Request);
- }
-
if(resumed_session.ciphersuite().ecc_ciphersuite())
{
m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp
index 0e620a279..a1b71841d 100644
--- a/src/lib/tls/tls_client.cpp
+++ b/src/lib/tls/tls_client.cpp
@@ -386,7 +386,8 @@ void Client::process_handshake_msg(const Handshake_State* active_state,
"Client: No certificates sent by server");
/*
- Certificate verification happens after we receive the server hello done,
+ If the server supports certificate status messages,
+ certificate verification happens after we receive the server hello done,
in case an OCSP response was also available
*/
@@ -412,6 +413,24 @@ void Client::process_handshake_msg(const Handshake_State* active_state,
{
state.set_expected_next(CERTIFICATE_STATUS); // optional
}
+ else
+ {
+ try
+ {
+ auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
+
+ callbacks().tls_verify_cert_chain(server_certs,
+ {},
+ trusted_CAs,
+ Usage_Type::TLS_SERVER_AUTH,
+ m_info.hostname(),
+ policy());
+ }
+ catch(std::exception& e)
+ {
+ throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what());
+ }
+ }
}
else if(type == CERTIFICATE_STATUS)
{
@@ -459,7 +478,8 @@ void Client::process_handshake_msg(const Handshake_State* active_state,
{
state.server_hello_done(new Server_Hello_Done(contents));
- if(state.server_certs() != nullptr)
+ if(state.server_certs() != nullptr &&
+ state.server_hello()->supports_certificate_status_message())
{
try
{
diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp
index 5d82eee0c..1c6be6620 100644
--- a/src/lib/tls/tls_policy.cpp
+++ b/src/lib/tls/tls_policy.cpp
@@ -341,6 +341,7 @@ bool Policy::include_time_in_hello_random() const { return true; }
bool Policy::hide_unknown_users() const { return false; }
bool Policy::server_uses_own_ciphersuite_preferences() const { return true; }
bool Policy::negotiate_encrypt_then_mac() const { return true; }
+bool Policy::support_cert_status_message() const { return true; }
// 1 second initial timeout, 60 second max - see RFC 6347 sec 4.2.4.1
size_t Policy::dtls_initial_timeout() const { return 1*1000; }
@@ -552,6 +553,7 @@ void Policy::print(std::ostream& o) const
print_bool(o, "hide_unknown_users", hide_unknown_users());
print_bool(o, "server_uses_own_ciphersuite_preferences", server_uses_own_ciphersuite_preferences());
print_bool(o, "negotiate_encrypt_then_mac", negotiate_encrypt_then_mac());
+ print_bool(o, "support_cert_status_message", support_cert_status_message());
o << "session_ticket_lifetime = " << session_ticket_lifetime() << '\n';
o << "dh_group = " << dh_group() << '\n';
o << "minimum_dh_group_size = " << minimum_dh_group_size() << '\n';
diff --git a/src/lib/tls/tls_policy.h b/src/lib/tls/tls_policy.h
index db2cbb3bb..fe7e50f8d 100644
--- a/src/lib/tls/tls_policy.h
+++ b/src/lib/tls/tls_policy.h
@@ -288,6 +288,11 @@ class BOTAN_PUBLIC_API(2,0) Policy
virtual bool negotiate_encrypt_then_mac() const;
/**
+ * Indicates whether certificate status messages should be supported
+ */
+ virtual bool support_cert_status_message() const;
+
+ /**
* Return allowed ciphersuites, in order of preference
*/
virtual std::vector<uint16_t> ciphersuite_list(Protocol_Version version,
@@ -502,6 +507,8 @@ class BOTAN_PUBLIC_API(2,0) Text_Policy : public Policy
bool negotiate_encrypt_then_mac() const override;
+ bool support_cert_status_message() const override;
+
std::string dh_group() const override;
size_t minimum_ecdh_group_size() const override;
diff --git a/src/lib/tls/tls_text_policy.cpp b/src/lib/tls/tls_text_policy.cpp
index 345e6005f..1f93b1e0f 100644
--- a/src/lib/tls/tls_text_policy.cpp
+++ b/src/lib/tls/tls_text_policy.cpp
@@ -103,6 +103,11 @@ bool Text_Policy::negotiate_encrypt_then_mac() const
return get_bool("negotiate_encrypt_then_mac", Policy::negotiate_encrypt_then_mac());
}
+bool Text_Policy::support_cert_status_message() const
+ {
+ return get_bool("support_cert_status_message", Policy::support_cert_status_message());
+ }
+
std::string Text_Policy::dh_group() const
{
return get_str("dh_group", Policy::dh_group());
diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp
index b22028a0e..026eeb62d 100644
--- a/src/tests/unit_tls.cpp
+++ b/src/tests/unit_tls.cpp
@@ -1308,6 +1308,9 @@ class TLS_Unit_Tests final : public Test
test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
{ { "signature_methods", "RSA" } });
+ test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
+ { { "support_cert_status_message", "false" } });
+
#if defined(BOTAN_HAS_DSA)
test_modern_versions(results, *client_ses, *server_ses, *creds, "DH", "AES-128/GCM", "AEAD",
{ { "signature_methods", "DSA" } });