Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
Smjert committed Mar 18, 2024
1 parent b316a5d commit 94e5cf7
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 118 deletions.
2 changes: 2 additions & 0 deletions osquery/core/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ Initializer::Initializer(int& argc,
// Let gflags parse the non-help options/flags.
GFLAGS_NAMESPACE::ParseCommandLineFlags(argc_, argv_, isShell());

std::cout << "Post parsing" << std::endl;

if (isShell()) {
// Do not set these values before calling ParseCommandLineFlags.
// These values are force-set and ignore the configuration and CLI.
Expand Down
261 changes: 155 additions & 106 deletions osquery/remote/transports/tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@

#include <charconv>
#include <chrono>
#include <iostream>
#include <variant>
#include <vector>

#include <osquery/core/core.h>
#include <osquery/core/flags.h>
#include <osquery/core/init.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/logger/data_logger.h>
#include <osquery/utils/config/default_paths.h>
#include <osquery/utils/conversions/split.h>
#include <osquery/utils/info/platform_type.h>
Expand Down Expand Up @@ -89,12 +92,17 @@ DECLARE_bool(verbose);
namespace {
enum class OpenSSLMode { Default, Native };

constexpr bool isUnsafeTLSDisabled() {
#ifndef NDEBUG
return !FLAGS_tls_allow_unsafe;
#else
return true;
#endif
// This is used when parsing the certificate flags,
// to understand if the user is attempting to specify a mixed mode,
// which is not supported
static std::optional<OpenSSLMode> detectedOpenSSLMode;

std::string extractTLSParams(std::string uri, OpenSSLMode mode) {
if (mode == OpenSSLMode::Default) {
return uri.substr(kFilePrefix.size());
} else {
return uri.substr(kCertPrefix.size());
}
}

std::optional<OpenSSLMode> detectOpenSSLMode(std::string_view uri) {
Expand All @@ -109,6 +117,126 @@ std::optional<OpenSSLMode> detectOpenSSLMode(std::string_view uri) {
return std::nullopt;
}

bool validateClientCert(const char* flagname, const std::string& value) {
std::cout << "Attempting to validate tls_client_cert" << std::endl;

if (value.empty()) {
return true;
}

std::cout << "Client cert value is: " << value << std::endl;

auto opt_openssl_mode = detectOpenSSLMode(value);
if (!opt_openssl_mode.has_value()) {
osquery::systemLog(
"The tls_client_cert value should either start with cert:// or "
"file://");
std::cerr
<< "The tls_client_cert value should either start with cert:// or "
"file://"
<< std::endl;
return false;
}

std::cerr << "OpenSSL mode: " << int(*opt_openssl_mode) << std::endl;

if (detectedOpenSSLMode.has_value() &&
detectedOpenSSLMode != opt_openssl_mode) {
osquery::systemLog(
"Cannot mix filesystem and native store mode in the client/server "
"certificates and private key options");
std::cerr << "Cannot mix filesystem and native store mode in the "
"client/server certificates and private key options"
<< std::endl;
return false;
}

detectedOpenSSLMode = opt_openssl_mode;

return true;
}

bool validateClientKey(const char* flagname, const std::string& value) {
std::cout << "Attempting to validate tls_client_key" << std::endl;

if (value.empty()) {
return true;
}

std::cout << "Client cert key is: " << value << std::endl;

auto opt_openssl_mode = detectOpenSSLMode(value);
if (!opt_openssl_mode.has_value() ||
*opt_openssl_mode == OpenSSLMode::Native) {
osquery::systemLog("The tls_client_key value should start with file://");
std::cerr << "The tls_client_key value should start with file://"
<< std::endl;
return false;
}

if (detectedOpenSSLMode.has_value() &&
detectedOpenSSLMode != opt_openssl_mode) {
osquery::systemLog(
"Cannot mix filesystem and native store mode in the client/server "
"certificates and private key options");
std::cerr << "Cannot mix filesystem and native store mode in the "
"client/server certificates and private key options"
<< std::endl;
return false;
}

detectedOpenSSLMode = opt_openssl_mode;

return true;
}

bool validateServerCerts(const char* flagname, const std::string& value) {
std::cout << "Attempting to validate tls_server_certs" << std::endl;

if (value.empty()) {
return true;
}

std::cout << "Server cert value is: " << value << std::endl;

auto opt_openssl_mode = detectOpenSSLMode(value);
if (!opt_openssl_mode.has_value()) {
osquery::systemLog(
"The tls_server_certs value should either start with cert:// or "
"file://");
std::cerr
<< "The tls_server_certs value should either start with cert:// or "
"file://"
<< std::endl;
return false;
}

std::cerr << "OpenSSL mode: " << int(*opt_openssl_mode) << std::endl;

if (detectedOpenSSLMode.has_value() &&
detectedOpenSSLMode != opt_openssl_mode) {
osquery::systemLog(
"Cannot mix filesystem and native store mode in the client/server "
"certificates and private key options");
std::cerr << "Cannot mix filesystem and native store mode in the "
"client/server certificates and private key options"
<< std::endl;
return false;
}

detectedOpenSSLMode = opt_openssl_mode;

return true;
}

constexpr bool isUnsafeTLSDisabled() {
#ifndef NDEBUG
return !FLAGS_tls_allow_unsafe;
#else
return true;
#endif
}

std::optional<NativeOpenSSLParameters::CertificateSearchParameters>
parseCertParams(std::string_view cert_params_string) {
if (cert_params_string == "all") {
Expand Down Expand Up @@ -177,94 +305,11 @@ http::Client::Options createCommonOptions(bool verify_peer) {
}

std::optional<std::variant<DefaultOpenSSLParameters, NativeOpenSSLParameters>>
createOpenSSLParametersFrom(std::string client_certificate_uri,
std::string client_private_key_uri,
std::string server_certificate_uri) {
auto last_detected_openssl_mode = OpenSSLMode::Default;
std::string_view client_certificate_params;
std::string_view client_private_key_params;
std::string_view server_certificate_params;

if (!server_certificate_uri.empty()) {
auto opt_openssl_mode = detectOpenSSLMode(server_certificate_uri);

if (!opt_openssl_mode.has_value()) {
LOG(ERROR) << "Could not properly parse the tls_server_certs flag, "
"format was incorrect";
return std::nullopt;
}

last_detected_openssl_mode = *opt_openssl_mode;

if (last_detected_openssl_mode == OpenSSLMode::Default) {
server_certificate_params =
std::string_view(server_certificate_uri.data() + kFilePrefix.size(),
server_certificate_uri.size() - kFilePrefix.size());
} else {
server_certificate_params =
std::string_view(server_certificate_uri.data() + kCertPrefix.size(),
server_certificate_uri.size() - kCertPrefix.size());
}
}

if (!client_certificate_uri.empty()) {
auto opt_openssl_mode = detectOpenSSLMode(client_certificate_uri);

if (!opt_openssl_mode.has_value()) {
LOG(ERROR) << "Could not properly parse the tls_client_cert flag, "
"format was incorrect";
return std::nullopt;
}

if (*opt_openssl_mode != last_detected_openssl_mode) {
LOG(ERROR) << "Cannot mix filesystem and native store mode in the "
"client/server certificates and private key options";
return std::nullopt;
}

last_detected_openssl_mode = *opt_openssl_mode;

if (last_detected_openssl_mode == OpenSSLMode::Default) {
client_certificate_params =
std::string_view(client_certificate_uri.data() + kFilePrefix.size(),
client_certificate_uri.size() - kFilePrefix.size());
} else {
client_certificate_params =
std::string_view(client_certificate_uri.data() + kCertPrefix.size(),
client_certificate_uri.size() - kCertPrefix.size());
}
}

// TODO: Cleanup, group this with the client cert check, since they need to be
// both present
if (!client_private_key_uri.empty()) {
auto opt_openssl_mode = detectOpenSSLMode(client_certificate_uri);

if (!opt_openssl_mode.has_value()) {
LOG(ERROR) << "Could not properly parse the tls_client_cert flag, "
"format was incorrect";
return std::nullopt;
}

if (*opt_openssl_mode != last_detected_openssl_mode) {
LOG(ERROR) << "Cannot mix filesystem and native store mode in the "
"client/server certificates and private key options";
return std::nullopt;
}

if (last_detected_openssl_mode != OpenSSLMode::Default) {
LOG(WARNING)
<< "The tls_client_key option must be of the format file://<path to "
"private key on filesystem>, it cannot be in native store form. "
"Value will be ignored.";
}

client_private_key_params =
std::string_view(client_private_key_uri.data() + kFilePrefix.size(),
client_private_key_uri.size() - kFilePrefix.size());
}

if (last_detected_openssl_mode == OpenSSLMode::Default) {
createOpenSSLParametersFrom(std::string client_certificate_params,
std::string client_private_key_params,
std::string server_certificate_params,
OpenSSLMode openssl_mode) {
if (openssl_mode == OpenSSLMode::Default) {
DefaultOpenSSLParameters openssl_parameters{};

if (!server_certificate_params.empty()) {
Expand Down Expand Up @@ -334,8 +379,6 @@ createOpenSSLParametersFrom(std::string client_certificate_uri,
return openssl_parameters;
}

last_detected_openssl_mode = OpenSSLMode::Native;

openssl_parameters.server_search_parameters =
std::get<NativeOpenSSLParameters::CertificateFields>(
*opt_cert_params);
Expand All @@ -350,8 +393,6 @@ createOpenSSLParametersFrom(std::string client_certificate_uri,
return openssl_parameters;
}

last_detected_openssl_mode = OpenSSLMode::Native;

openssl_parameters.client_cert_search_parameters = *opt_cert_params;
}

Expand All @@ -362,10 +403,17 @@ createOpenSSLParametersFrom(std::string client_certificate_uri,
}
} // namespace

DEFINE_validator(tls_client_cert, &validateClientCert);
DEFINE_validator(tls_client_key, &validateClientKey);
DEFINE_validator(tls_server_certs, &validateServerCerts);

TLSTransport::TLSTransport()
: server_certificate_file_(FLAGS_tls_server_certs),
client_certificate_file_(FLAGS_tls_client_cert),
client_private_key_file_(FLAGS_tls_client_key) {}
: server_certificate_params_(extractTLSParams(FLAGS_tls_server_certs,
detectedOpenSSLMode.value())),
client_certificate_params_(
extractTLSParams(FLAGS_tls_client_cert, detectedOpenSSLMode.value())),
client_private_key_params_(extractTLSParams(
FLAGS_tls_client_key, detectedOpenSSLMode.value())) {}

void TLSTransport::decorateRequest(http::Request& r) {
r << http::Request::Header("Content-Type", serializer_->getContentType());
Expand All @@ -376,8 +424,8 @@ void TLSTransport::decorateRequest(http::Request& r) {
http::Client::Options TLSTransport::getOptions() {
http::Client::Options options = createCommonOptions(verify_peer_);

auto openssl_cert_parameters =
createOpenSSLParametersFrom({}, {}, server_certificate_file_);
auto openssl_cert_parameters = createOpenSSLParametersFrom(
{}, {}, server_certificate_params_, detectedOpenSSLMode.value());

options.openssl_set_cert_parameters(openssl_cert_parameters);

Expand All @@ -391,9 +439,10 @@ http::Client::Options TLSTransport::getInternalOptions() {
http::Client::Options options = createCommonOptions(verify_peer_);

auto openssl_cert_parameters =
createOpenSSLParametersFrom(client_certificate_file_,
client_private_key_file_,
server_certificate_file_);
createOpenSSLParametersFrom(client_certificate_params_,
client_private_key_params_,
server_certificate_params_,
detectedOpenSSLMode.value());

options.openssl_set_cert_parameters(openssl_cert_parameters);

Expand Down
24 changes: 12 additions & 12 deletions osquery/remote/transports/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,26 +105,26 @@ class TLSTransport : public Transport {
}

/// Set TLS-client authentication options.
void setClientCertificate(const std::string& certificate_file,
const std::string& private_key_file) {
client_certificate_file_ = certificate_file;
client_private_key_file_ = private_key_file;
void setClientCertificate(const std::string& certificate_params,
const std::string& private_key_params) {
client_certificate_params_ = certificate_params;
client_private_key_params_ = private_key_params;
}

/// Set TLS server/ca pinning options.
void setPeerCertificate(const std::string& server_certificate_file) {
server_certificate_file_ = server_certificate_file;
void setPeerCertificate(const std::string& server_certificate_params) {
server_certificate_params_ = server_certificate_params;
}

private:
/// Optional TLS client-auth client certificate filename.
std::string client_certificate_file_;
/// Optional TLS client-auth client certificate uri.
std::string client_certificate_params_;

/// Optional TLS client-auth client private key filename.
std::string client_private_key_file_;
/// Optional TLS client-auth client private key uri.
std::string client_private_key_params_;

/// Optional TLS server-pinning server certificate/bundle filename.
std::string server_certificate_file_;
/// Optional TLS server-pinning server certificate/bundle uri.
std::string server_certificate_params_;

/// Testing-only, disable peer verification.
bool verify_peer_{true};
Expand Down

0 comments on commit 94e5cf7

Please sign in to comment.