Skip to content

Commit

Permalink
Merge pull request microsoft#2 from xqp/feature/use_tls_cert_check_ca…
Browse files Browse the repository at this point in the history
…llback_once

linux: invoke the certificate chain callback only once
  • Loading branch information
chogorma authored Apr 6, 2018
2 parents 39c26e0 + 79c74d2 commit 5d5dca0
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 15 deletions.
8 changes: 4 additions & 4 deletions Release/include/cpprest/certificate_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ namespace web { namespace http { namespace client {

struct certificate_info
{
CertificateChain certificate_chain;
std::string host_name;
CertificateChain certificate_chain;
long certificate_error{ 0 };
bool verified{ false };

certificate_info(const std::string host) : host_name(host) {};
certificate_info(const std::string host, CertificateChain chain, long error = 0) : host_name(host), certificate_chain(chain), certificate_error(error) {};
certificate_info(const std::string host) : host_name(host) {}
certificate_info(const std::string host, CertificateChain chain, long error = 0) : host_name(host), certificate_chain(chain), certificate_error(error) {}
};

using CertificateChainFunction = std::function<bool(const std::shared_ptr<certificate_info> certificate_Info)>;

}}}
}}}
3 changes: 1 addition & 2 deletions Release/include/cpprest/details/x509_cert_utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ namespace web { namespace http { namespace client { namespace details {

using namespace utility;

#if !defined(__linux__)

bool is_end_certificate_in_chain(boost::asio::ssl::verify_context &verifyCtx);

#if !defined(__linux__)
/// <summary>
/// Using platform specific APIs verifies server certificate.
/// Currently implemented to work on iOS, Android, and OS X.
Expand Down
4 changes: 2 additions & 2 deletions Release/include/cpprest/ws_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,13 @@ class websocket_client_config
}

private:
http::client::CertificateChainFunction m_certificate_chain_callback;
web::web_proxy m_proxy;
web::credentials m_credentials;
web::http::http_headers m_headers;
bool m_sni_enabled;
utf8string m_sni_hostname;
bool m_validate_certificates;
http::client::CertificateChainFunction m_certificate_chain_callback;
};

/// <summary>
Expand Down Expand Up @@ -663,4 +663,4 @@ class websocket_callback_client

#endif

#endif
#endif
14 changes: 10 additions & 4 deletions Release/src/http/client/http_client_asio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
, m_needChunked(false)
, m_timer(client->client_config().timeout<std::chrono::microseconds>())
, m_connection(connection)
#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__))
#if defined(__APPLE__) || defined(ANDROID) || defined(__ANDROID__)
, m_openssl_failed(false)
#endif
{}
Expand Down Expand Up @@ -980,7 +980,7 @@ class asio_context : public request_context, public std::enable_shared_from_this

using namespace web::http::client::details;

#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__))
#if defined(__APPLE__) || defined(ANDROID) || defined(__ANDROID__)
// On OS X, iOS, and Android, OpenSSL doesn't have access to where the OS
// stores keychains. If OpenSSL fails we will doing verification at the
// end using the whole certificate chain so wait until the 'leaf' cert.
Expand All @@ -1003,7 +1003,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
};

return http::client::details::verify_cert_chain_platform_specific(verifyCtx, utility::conversions::to_utf8string(host), chainFunc);
}
}
#endif

boost::asio::ssl::rfc2818_verification rfc2818(host);
Expand All @@ -1015,6 +1015,12 @@ class asio_context : public request_context, public std::enable_shared_from_this
auto info = std::make_shared<certificate_info>(host, get_X509_cert_chain_encoded_data(verifyCtx));
info->verified = true;

if (!is_end_certificate_in_chain(verifyCtx))
{
// Continue until we get the end certificate.
return true;
}

return m_http_client->client_config().invoke_certificate_chain_callback(info);
}

Expand Down Expand Up @@ -1687,7 +1693,7 @@ class asio_context : public request_context, public std::enable_shared_from_this

std::unique_ptr<web::http::details::compression::stream_decompressor> m_decompressor;

#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__))
#if defined(__APPLE__) || defined(ANDROID) || defined(__ANDROID__)
bool m_openssl_failed;
#endif
};
Expand Down
6 changes: 3 additions & 3 deletions Release/src/http/client/x509_cert_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@

namespace web { namespace http { namespace client { namespace details {

#if !defined(__linux__)

bool is_end_certificate_in_chain(boost::asio::ssl::verify_context &verifyCtx)
{
X509_STORE_CTX *storeContext = verifyCtx.native_handle();
Expand All @@ -53,6 +51,8 @@ bool is_end_certificate_in_chain(boost::asio::ssl::verify_context &verifyCtx)
return true;
}

#if !defined(__linux__)

bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verifyCtx, const std::string &hostName, const CertificateChainFunction& func)
{
if (!is_end_certificate_in_chain(verifyCtx))
Expand Down Expand Up @@ -616,4 +616,4 @@ bool verify_X509_cert_chain(const std::vector<std::string> &certChain, const std

}}}}

#endif
#endif

0 comments on commit 5d5dca0

Please sign in to comment.