From 8b03735e833fd44f705eb8642dcfe104a75ec592 Mon Sep 17 00:00:00 2001 From: Victor Vazquez Date: Thu, 14 Apr 2022 00:29:47 -0700 Subject: [PATCH] use option from context --- .../src/attestation_client.cpp | 27 ++++++++++++++++ .../azure/core/http/win_http_transport.hpp | 7 ++-- .../src/http/winhttp/win_http_transport.cpp | 32 +++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/sdk/attestation/azure-security-attestation/src/attestation_client.cpp b/sdk/attestation/azure-security-attestation/src/attestation_client.cpp index 41852f5fe..8ef1f1c51 100644 --- a/sdk/attestation/azure-security-attestation/src/attestation_client.cpp +++ b/sdk/attestation/azure-security-attestation/src/attestation_client.cpp @@ -26,6 +26,28 @@ using namespace Azure::Core::Http::Policies; using namespace Azure::Core::Http::Policies::_internal; using namespace Azure::Core::Http::_internal; +#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) +// Whenever winHTTP transport is built, create a policy to make request with no client certificate for attestation requests +#include "azure/core/http/win_http_transport.hpp" + +namespace { + class SetNoClientCertificatePolicy : public Azure::Core::Http::Policies::HttpPolicy { + public: + std::unique_ptr Clone() const override + { + return std::make_unique(); + } + + std::unique_ptr Send( + Azure::Core::Http::Request& request, + Azure::Core::Http::Policies::NextHttpPolicy nextHttpPolicy, + const Azure::Core::Context& ctx) const override { + return nextHttpPolicy.Send(request, Azure::Core::Http::_internal::WinHttpTransportContextProvider::GetNoClientCertificateContext(ctx)); + } + }; +} +#endif + AttestationClient::AttestationClient( std::string const& endpoint, std::shared_ptr credential, @@ -45,6 +67,11 @@ AttestationClient::AttestationClient( } m_apiVersion = options.Version.ToString(); std::vector> perCallpolicies; + + #if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) + // This configuration will make winHTTP to disable client certificate for all attestation requests + perCallpolicies.emplace_back(std::make_unique()); + #endif m_pipeline = std::make_shared( options, diff --git a/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp b/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp index 1f21497ce..91bd10b1a 100644 --- a/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp @@ -150,10 +150,9 @@ namespace Azure { namespace Core { namespace Http { WinHttpTransportContextProvider() = delete; // Creates a set up token to make - Azure::Core::Context GetNoClientCertContext(Azure::Core::Context const& parent){ - return parent - } - } + static Azure::Core::Context GetNoClientCertificateContext(Azure::Core::Context const& parent); + static bool HasNoClientCertificateConfiguration(Azure::Core::Context const& context); + }; } // namespace _internal /** diff --git a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp index 1f7e9b947..d4cad8033 100644 --- a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp +++ b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp @@ -196,8 +196,20 @@ std::string GetHeadersAsString(Azure::Core::Http::Request const& request) return requestHeaderString; } +Azure::Core::Context::Key NoClientCertificateConfiguration; + } // namespace +Azure::Core::Context Azure::Core::Http::_internal::WinHttpTransportContextProvider::GetNoClientCertificateContext(Azure::Core::Context const& parent) { + return parent.WithValue(NoClientCertificateConfiguration, true); +} + +bool Azure::Core::Http::_internal::WinHttpTransportContextProvider::HasNoClientCertificateConfiguration(Azure::Core::Context const& context) { + bool value = false; + context.TryGetValue(NoClientCertificateConfiguration, value); + return value; +} + void GetErrorAndThrow(const std::string& exceptionMessage) { DWORD error = GetLastError(); @@ -342,6 +354,23 @@ void WinHttpTransport::CreateRequestHandle(std::unique_ptr<_detail::HandleManage GetErrorAndThrow("Error while getting a request handle."); } + // Option is set up by context settings only and is only available for SDK clients + if(m_noClientCert) { + // If the service requests TLS client certificates, we want to let the WinHTTP APIs know that + // it's ok to initiate the request without a client certificate. + // + // Note: If/When TLS client certificate support is added to the pipeline, this line may need to + // be revisited. + if (!WinHttpSetOption( + handleManager->m_requestHandle, + WINHTTP_OPTION_CLIENT_CERT_CONTEXT, + WINHTTP_NO_CLIENT_CERT_CONTEXT, + 0)) + { + GetErrorAndThrow("Error while setting client cert context to ignore.."); + } + } + if (m_options.IgnoreUnknownCertificateAuthority) { auto option = SECURITY_FLAG_IGNORE_UNKNOWN_CA; @@ -637,6 +666,9 @@ std::unique_ptr WinHttpTransport::SendRequestAndGetResponse( std::unique_ptr WinHttpTransport::Send(Request& request, Context const& context) { + using namespace Azure::Core::Http::_internal; + m_noClientCert = WinHttpTransportContextProvider::HasNoClientCertificateConfiguration(context); + auto handleManager = std::make_unique<_detail::HandleManager>(request, context); CreateSessionHandle(handleManager);