Split out attestation client factory into separate class (#3654)

* Split out attestation client factory into separate class

* Updated readme; clang-format

* Final set of API review changes

* Replaced () constructors with {} constructors
This commit is contained in:
Larry Osterman 2022-05-23 15:54:57 -07:00 committed by GitHub
parent 644ab3e0b7
commit 745091d01c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 218 additions and 229 deletions

View File

@ -69,9 +69,10 @@ int main()
// Attestation
std::cout << "Creating Attestation Clients" << std::endl;
AttestationClient attestationClient(AttestationClient::Create(smokeUrl));
AttestationAdministrationClient attestationAdminClient(
AttestationAdministrationClient::Create(smokeUrl, credential));
std::unique_ptr<AttestationClient> attestationClient(
AttestationClientFactory::Create(std::getenv("ATTESTATION_AAD_URL")));
std::unique_ptr<AttestationAdministrationClient> attestationAdminClient(
AttestationAdministrationClientFactory::Create(std::getenv("ATTESTATION_AAD_URL"), credential));
std::cout << "Successfully Created the Clients" << std::endl;
}

View File

@ -5,6 +5,14 @@
### Features Added
### Breaking Changes
- `ValueToSend` field in `TpmAttestationOptions` becomes `Payload`.
- `AddIsolatedModeCertificatesOptions` becomes `AddIsolatedModeCertificateOptions`
- `RemoveIsolatedModeCertificatesOptions` becomes `RemoveIsolatedModeCertificateOptions`
- Renamed `AttestEnclaveOptions` to `AttestSgxEnclaveOptions` and `AttestOpenEnclaveOptions`.
- Split out `AttestationClient::Create` into its own factory class `AttestationClientFactory`.
- Note that the `AttestationClientFactory::Create` method returns a `std::unique_ptr` to the client object.
- Split out `AttestationAdministrationClient::Create` into its own factory class `AttestationAdministrationClientFactory`.
- Note that the `AttestationAdministrationClientFactory::Create` method returns a `std::unique_ptr` to the client object.
### Bugs Fixed

View File

@ -206,11 +206,11 @@ Isolated Mode Certificate Management APIs enable clients to add, remove or enume
#### Create an attestation client
The `AttestationClient::Create` method is used to create instances of the attestation client:
The `AttestationClientFactory::Create` method is used to create instances of the attestation client:
```cpp
std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
return Azure::Security::Attestation::AttestationClient::CreatePointer(m_endpoint);
return Azure::Security::Attestation::AttestationClientFactory::CreatePointer(m_endpoint);
```
If the attestation APIs require authentication, use the following (note that unlike the previous example,
@ -221,7 +221,7 @@ std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(
std::getenv("AZURE_TENANT_ID"), std::getenv("AZURE_CLIENT_ID"), std::getenv("AZURE_CLIENT_SECRET"));
return Azure::Security::Attestation::AttestationClient::Create(m_endpoint, credential);
return Azure::Security::Attestation::AttestationClientFactory::Create(m_endpoint, credential);
```
The same pattern is used to create an `Azure::Security::Attestation::AttestationAdministrationClient`.
@ -267,7 +267,7 @@ std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(
std::getenv("AZURE_TENANT_ID"), std::getenv("AZURE_CLIENT_ID"), std::getenv("AZURE_CLIENT_SECRET"));
AttestationAdministrationClient adminClient(m_endpoint, credential);
AttestationAdministrationClient adminClient(AttestationAdministrationClientFactory::Create(m_endpoint, credential));
```
#### Retrieve current attestation policy for OpenEnclave
@ -275,9 +275,6 @@ AttestationAdministrationClient adminClient(m_endpoint, credential);
Use the `GetAttestationPolicy` API to retrieve the current attestation policy for a given TEE.
```cpp
// Retrieve attestation response validation collateral before calling into the service.
adminClient.RetrieveResponseValidationCollateral();
// Retrieve the SGX Attestation Policy from this attestation service instance.
Azure::Response<AttestationToken<std::string>> const sgxPolicy
= adminClient.GetAttestationPolicy(AttestationType::SgxEnclave);
@ -291,9 +288,6 @@ When an attestation instance is in AAD mode, the caller can use a convenience me
policy on the instance.
```cpp
// Retrieve attestation response validation collateral before calling into the service.
adminClient.RetrieveResponseValidationCollateral();
// Set the attestation policy on this attestation instance.
// Note that because this is an AAD mode instance, the caller does not need to sign the policy
// being set.
@ -368,9 +362,6 @@ the policy management tokens. This interaction ensures that the client is in pos
one of the policy management certificates and is thus authorized to perform the operation.
```cpp
// Retrieve attestation response validation collateral before calling into the service.
adminClient.RetrieveResponseValidationCollateral();
// Retrieve the SGX Attestation Policy from this attestation service instance.
Azure::Response<AttestationToken<IsolatedModeCertificateListResult>> const policyCertificates
= adminClient.GetIsolatedModeCertificates();
@ -396,9 +387,6 @@ ignored (this possibly surprising behavior is there because retries could cause
AttestationSigningKey const requestSigner{pemSigningKey, pemSigningCert};
// Retrieve attestation response validation collateral before calling into the service.
adminClient.RetrieveResponseValidationCollateral();
// We start this sample by adding a new certificate to the set of policy management
// certificates.
{

View File

@ -44,6 +44,8 @@ namespace Azure { namespace Security { namespace Attestation {
*
*/
class AttestationAdministrationClient final {
friend class AttestationAdministrationClientFactory;
public:
/**
* @brief Construct a new Attestation Administration Client object from another attestation
@ -84,7 +86,7 @@ namespace Azure { namespace Security { namespace Attestation {
*/
Response<Models::AttestationToken<std::string>> GetAttestationPolicy(
Models::AttestationType const& attestationType,
GetPolicyOptions const& options = GetPolicyOptions(),
GetPolicyOptions const& options = GetPolicyOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
@ -121,7 +123,7 @@ namespace Azure { namespace Security { namespace Attestation {
Response<Models::AttestationToken<Models::PolicyResult>> SetAttestationPolicy(
Models::AttestationType const& attestationType,
std::string const& policyToSet,
SetPolicyOptions const& options = SetPolicyOptions(),
SetPolicyOptions const& options = SetPolicyOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
@ -139,7 +141,7 @@ namespace Azure { namespace Security { namespace Attestation {
*/
Response<Models::AttestationToken<Models::PolicyResult>> ResetAttestationPolicy(
Models::AttestationType const& attestationType,
SetPolicyOptions const& options = SetPolicyOptions(),
SetPolicyOptions const& options = SetPolicyOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
@ -213,7 +215,7 @@ namespace Azure { namespace Security { namespace Attestation {
AddIsolatedModeCertificate(
std::string const& pemEncodedCertificateToAdd,
AttestationSigningKey const& signerForRequest,
AddIsolatedModeCertificatesOptions const& options = AddIsolatedModeCertificatesOptions{},
AddIsolatedModeCertificateOptions const& options = AddIsolatedModeCertificateOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
@ -240,41 +242,10 @@ namespace Azure { namespace Security { namespace Attestation {
RemoveIsolatedModeCertificate(
std::string const& pemEncodedCertificateToAdd,
AttestationSigningKey const& signerForRequest,
AddIsolatedModeCertificatesOptions const& options = AddIsolatedModeCertificatesOptions{},
RemoveIsolatedModeCertificateOptions const& options
= RemoveIsolatedModeCertificateOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
* @brief Construct a new Attestation Administration Client object.
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication token to use.
* @param options The options to customize the client behavior.
* @return std::unique_ptr<AttestationAdministrationClient> The newly created client.
*/
static AttestationAdministrationClient Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationAdministrationClientOptions const& options
= AttestationAdministrationClientOptions(),
Azure::Core::Context const& context = Azure::Core::Context{});
/**
* @brief Construct a pointer to a new Attestation Administration Client object.
*
* @note It is the responsibility of the caller to manage the lifetime of the returned
* AttestationAdministrationClient object, typically by constructing a std::unique_ptr or
* std::shared_ptr from this pointer.
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication token to use.
* @param options The options to customize the client behavior.
*/
static std::unique_ptr<AttestationAdministrationClient> CreatePointer(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationAdministrationClientOptions const& options
= AttestationAdministrationClientOptions(),
Azure::Core::Context const& context = Azure::Core::Context{});
private:
Azure::Core::Url m_endpoint;
std::string m_apiVersion;
@ -282,7 +253,7 @@ namespace Azure { namespace Security { namespace Attestation {
std::shared_ptr<Azure::Core::Http::_internal::HttpPipeline> m_pipeline;
AttestationTokenValidationOptions m_tokenValidationOptions;
mutable std::vector<Models::AttestationSigner> m_attestationSigners;
std::vector<Models::AttestationSigner> m_attestationSigners;
/**
* @brief Construct a new Attestation Administration Client object.
@ -295,7 +266,7 @@ namespace Azure { namespace Security { namespace Attestation {
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationAdministrationClientOptions const& options
= AttestationAdministrationClientOptions());
= AttestationAdministrationClientOptions{});
std::string CreateIsolatedModeModificationToken(
std::string const& pemEncodedX509CertificateToAdd,
@ -316,7 +287,31 @@ namespace Azure { namespace Security { namespace Attestation {
* @param context Client context for the request to the service.
*/
void RetrieveResponseValidationCollateral(
Azure::Core::Context const& context = Azure::Core::Context{}) const;
Azure::Core::Context const& context = Azure::Core::Context{});
};
/** @brief Construct a new AttestationAdministrationClient object.
*
* The AttestationAdministrationClientFactory class is a factory class for instantiating new
* AttestationAdministrationClient objects.
*
*/
class AttestationAdministrationClientFactory final {
public:
/**
* @brief Construct a new Attestation Administration Client object.
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication token to use.
* @param options The options to customize the client behavior.
* @return std::unique_ptr<AttestationAdministrationClient> The newly created client.
*/
static std::unique_ptr<AttestationAdministrationClient> Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationAdministrationClientOptions const& options
= AttestationAdministrationClientOptions{},
Azure::Core::Context const& context = Azure::Core::Context{});
};
}}} // namespace Azure::Security::Attestation

View File

@ -114,6 +114,9 @@ namespace Azure { namespace Security { namespace Attestation {
*/
class AttestationClient final {
// Allow client factory to access private methods in the AttestationClient object.
friend class AttestationClientFactory;
public:
/**
* @brief Destructor.
@ -169,7 +172,7 @@ namespace Azure { namespace Security { namespace Attestation {
*/
Response<Models::AttestationToken<Models::AttestationResult>> AttestSgxEnclave(
std::vector<uint8_t> const& sgxQuoteToAttest,
AttestEnclaveOptions options = AttestEnclaveOptions(),
AttestSgxEnclaveOptions options = AttestSgxEnclaveOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
@ -190,7 +193,7 @@ namespace Azure { namespace Security { namespace Attestation {
*/
Response<Models::AttestationToken<Models::AttestationResult>> AttestOpenEnclave(
std::vector<uint8_t> const& openEnclaveReportToAttest,
AttestEnclaveOptions options = AttestEnclaveOptions(),
AttestOpenEnclaveOptions options = AttestOpenEnclaveOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;
/**
@ -214,34 +217,46 @@ namespace Azure { namespace Security { namespace Attestation {
*/
Response<Models::TpmAttestationResult> AttestTpm(
AttestTpmOptions const& options,
Azure::Core::Context const& context = Azure::Core::Context::ApplicationContext) const;
Azure::Core::Context const& context = Azure::Core::Context{}) const;
private:
Azure::Core::Url m_endpoint;
std::string m_apiVersion;
std::shared_ptr<Azure::Core::Credentials::TokenCredential const> m_credentials;
std::shared_ptr<Azure::Core::Http::_internal::HttpPipeline> m_pipeline;
AttestationTokenValidationOptions m_tokenValidationOptions;
std::vector<Models::AttestationSigner> m_attestationSigners;
/** @brief Construct a new Attestation Client object
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication method to use (required for TPM attestation).
* @param options The options to customize the client behavior.
* @return AttestationClient The newly created client.
*/
static AttestationClient Create(
AttestationClient(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions options = AttestationClientOptions(),
Azure::Core::Context const& constext = Azure::Core::Context{});
AttestationClientOptions options = AttestationClientOptions{});
/** @brief Construct a new anonymous Attestation Client object
/**
* @brief Retrieves the information needed to validate a response from the attestation service.
*
* @param endpoint The URL address where the client will send the requests to.
* @param options The options to customize the client behavior.
* @return AttestationClient The newly created client.
*
* @note TPM attestation requires an authenticated attestation client.
* @note: This method MUST be called before any calls to the attestation service which must be
* validated.
*/
static AttestationClient Create(
std::string const& endpoint,
AttestationClientOptions options = AttestationClientOptions(),
Azure::Core::Context const& constext = Azure::Core::Context{});
void RetrieveResponseValidationCollateral(
Azure::Core::Context const& context = Azure::Core::Context{});
};
/** @brief Construct a new AttestationClient object.
*
* The AttestationClientFactory class is a factory class for instantiating new AttestationClient
* objects.
*
*/
class AttestationClientFactory final {
public:
/** @brief Construct a new Attestation Client object
*
* @details Constructs a new attestation client. Follows the
@ -254,10 +269,10 @@ namespace Azure { namespace Security { namespace Attestation {
* @param options The options to customize the client behavior.
* @return std::unique_ptr<AttestationClient> The newly created client.
*/
static std::unique_ptr<AttestationClient> CreatePointer(
static std::unique_ptr<AttestationClient> Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions options = AttestationClientOptions(),
AttestationClientOptions options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});
/** @brief Construct a new anonymous Attestation Client object
@ -273,38 +288,10 @@ namespace Azure { namespace Security { namespace Attestation {
* @note TPM attestation requires an authenticated attestation client.
*
*/
static std::unique_ptr<AttestationClient> CreatePointer(
static std::unique_ptr<AttestationClient> Create(
std::string const& endpoint,
AttestationClientOptions options = AttestationClientOptions(),
AttestationClientOptions options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});
private:
Azure::Core::Url m_endpoint;
std::string m_apiVersion;
std::shared_ptr<Azure::Core::Credentials::TokenCredential const> m_credentials;
std::shared_ptr<Azure::Core::Http::_internal::HttpPipeline> m_pipeline;
AttestationTokenValidationOptions m_tokenValidationOptions;
mutable std::vector<Models::AttestationSigner> m_attestationSigners;
/** @brief Construct a new Attestation Client object
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication method to use (required for TPM attestation).
* @param options The options to customize the client behavior.
*/
AttestationClient(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions options = AttestationClientOptions());
/**
* @brief Retrieves the information needed to validate a response from the attestation service.
*
* @note: This method MUST be called before any calls to the attestation service which must be
* validated.
*/
void RetrieveResponseValidationCollateral(
Azure::Core::Context const& context = Azure::Core::Context{}) const;
};
}}} // namespace Azure::Security::Attestation

View File

@ -265,7 +265,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Models
* SHA256 hash of the policy document sent to the attestation service.
*
* In order to verify that the attestation service correctly received the attestation policy sent
* by the client, the AttestationAdministrationClient::CreateSetAttestationPolicyToken API can be
* by the client, the AttestationAdministrationClient::CreateAttestationPolicyToken API can be
* used to create an AttestationToken object which is not specialized on any type
* (`AttestationToken<>`). The RawToken field in that can be used to calculate the hash which was
* sent to the service.

View File

@ -216,9 +216,45 @@ namespace Azure { namespace Security { namespace Attestation {
AttestationDataType DataType;
};
/** @brief Parameters sent to the attestation service to be consumed in an attestation operation.
/** @brief Parameters sent to the attestation service for the AttestationClient::AttestSgxEnclave
* API.
*/
struct AttestEnclaveOptions final
struct AttestSgxEnclaveOptions final
{
/**
* @brief Data created dynamically within the enclave
*/
Azure::Nullable<AttestationData> RunTimeData{};
/**
* @brief Data created when the enclave was created. Not supported on Coffeelake processors.
*/
Azure::Nullable<AttestationData> InitTimeData{};
/**
* @brief Nonce which is sent to the attestation service to allow a caller to prevent replay
* attacks.
*/
Azure::Nullable<std::string> Nonce{};
/**
* @brief A test hook which allows developers to test attestation policies before they commit
* them to the service.
*/
Azure::Nullable<std::string> DraftPolicyForAttestation{};
/** @brief Specifies the options which should be used to validate the attestation token returned
* by the attestation service. Overrides the value specified in the AttestationClient.
* @details If not provided by the caller, the token validation options
* specified when the @{link AttestationClient} was created will be used.
*/
Azure::Nullable<AttestationTokenValidationOptions> TokenValidationOptionsOverride{};
};
/** @brief Parameters sent to the attestation service for the AttestationClient::AttestOpenEnclave
* API.
*/
struct AttestOpenEnclaveOptions final
{
/**
* @brief Data created dynamically within the enclave
@ -259,7 +295,7 @@ namespace Azure { namespace Security { namespace Attestation {
* @details The TPM attestation protocol is defined
* [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol')
*/
std::string ValueToSend;
std::string Payload;
};
/** @brief The AttestationSigningKey represents a tuple of asymmetric private cryptographic key
@ -327,7 +363,7 @@ namespace Azure { namespace Security { namespace Attestation {
/** @brief Parameters sent to the attestation service when adding a new policy
* management certificate.
*/
struct AddIsolatedModeCertificatesOptions final
struct AddIsolatedModeCertificateOptions final
{
/** @brief Specifies the options which should be used to validate the attestation token returned
* by the attestation service. Overrides the value specified in the AttestationClient.
@ -340,7 +376,7 @@ namespace Azure { namespace Security { namespace Attestation {
/** @brief Parameters sent to the attestation service when removing a policy
* management certificate.
*/
struct RemoveIsolatedModeCertificatesOptions final
struct RemoveIsolatedModeCertificateOptions final
{
/** @brief Specifies the options which should be used to validate the attestation token returned
* by the attestation service. Overrides the value specified in the AttestationClient.

View File

@ -48,7 +48,7 @@ int main()
= "https://shared" + shortLocation + "." + shortLocation + ".attest.azure.net";
std::unique_ptr<AttestationClient> attestationClient(
AttestationClient::CreatePointer(endpoint));
AttestationClientFactory::Create(endpoint));
std::vector<uint8_t> const sgxEnclaveQuote = AttestationCollateral::SgxQuote();

View File

@ -42,12 +42,12 @@ int main()
{
std::cout << "In function: SampleAttestSgxEnclaveSimple" << std::endl;
// create client
AttestationClient const attestationClient(
AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::unique_ptr<AttestationClient const> attestationClient(
AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::vector<uint8_t> const openEnclaveReport = AttestationCollateral::OpenEnclaveReport();
AttestEnclaveOptions options;
AttestOpenEnclaveOptions options;
options.DraftPolicyForAttestation = R"(version= 1.0;
authorizationrules
{
@ -61,7 +61,7 @@ issuancerules {
c:[type=="x-ms-sgx-mrsigner"] => issue(type="custom-name", value=c.value);
};)";
Azure::Response<AttestationToken<AttestationResult>> const sgxResult(
attestationClient.AttestOpenEnclave(openEnclaveReport, options));
attestationClient->AttestOpenEnclave(openEnclaveReport, options));
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;

View File

@ -42,13 +42,13 @@ int main()
{
std::cout << "In function: SampleAttestSgxEnclaveSimple" << std::endl;
// create client
AttestationClient attestationClient(
AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::unique_ptr<AttestationClient> attestationClient(
AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::vector<uint8_t> const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
Azure::Response<AttestationToken<AttestationResult>> const sgxResult
= attestationClient.AttestSgxEnclave(sgxEnclaveQuote);
= attestationClient->AttestSgxEnclave(sgxEnclaveQuote);
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;

View File

@ -45,13 +45,13 @@ int main()
// create client
std::string endpoint(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"));
std::shared_ptr<AttestationClient> attestationClient(
AttestationClient::CreatePointer(endpoint));
AttestationClientFactory::Create(endpoint));
std::vector<uint8_t> const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
// Set the RunTimeData in the request to the service. Ask the service to interpret the
// RunTimeData as a JSON object when it is returned in the resulting token.
AttestEnclaveOptions attestOptions;
AttestSgxEnclaveOptions attestOptions;
attestOptions.RunTimeData
= AttestationData{AttestationCollateral::RunTimeData(), AttestationDataType::Binary};

View File

@ -44,19 +44,20 @@ int main()
// create client
std::string const endpoint(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"));
AttestationClient const attestationClient(AttestationClient::Create(endpoint));
std::unique_ptr<AttestationClient const> attestationClient(
AttestationClientFactory::Create(endpoint));
std::vector<uint8_t> const sgxEnclaveQuote = AttestationCollateral::SgxQuote();
// Set the RunTimeData in the request to the service. Ask the service to interpret the
// RunTimeData as a JSON object when it is returned in the resulting token.
AttestEnclaveOptions attestOptions;
AttestSgxEnclaveOptions attestOptions;
attestOptions.RunTimeData
= AttestationData{AttestationCollateral::RunTimeData(), AttestationDataType::Json};
Azure::Response<AttestationToken<AttestationResult>> const sgxResult
= attestationClient.AttestSgxEnclave(sgxEnclaveQuote, attestOptions);
= attestationClient->AttestSgxEnclave(sgxEnclaveQuote, attestOptions);
std::cout << "SGX Quote MRSIGNER is: "
<< Convert::Base64Encode(*sgxResult.Value.Body.SgxMrSigner) << std::endl;

View File

@ -39,10 +39,11 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
AttestationAdministrationClient const adminClient(AttestationAdministrationClient::Create(
GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
std::unique_ptr<AttestationAdministrationClient const> adminClient(
AttestationAdministrationClientFactory::Create(
GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
std::cout << "Admin client is Communicating with " << adminClient.Endpoint() << std::endl;
std::cout << "Admin client is Communicating with " << adminClient->Endpoint() << std::endl;
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{

View File

@ -35,10 +35,10 @@ int main()
clientOptions.TokenValidationOptions.TimeValidationSlack = 10s;
// create client
AttestationClient const attestationClient(
AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), clientOptions));
std::unique_ptr<AttestationClient> attestationClient(AttestationClientFactory::Create(
GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), clientOptions));
attestationClient.GetOpenIdMetadata();
attestationClient->GetOpenIdMetadata();
}
catch (Azure::Core::Credentials::AuthenticationException const& e)
{

View File

@ -32,11 +32,11 @@ int main()
try
{
// create client
AttestationClient const attestationClient(
AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::unique_ptr<AttestationClient const> attestationClient(
AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
// Retrieve the OpenId metadata from this attestation service instance.
Azure::Response<OpenIdMetadata> const openIdMetadata = attestationClient.GetOpenIdMetadata();
Azure::Response<OpenIdMetadata> const openIdMetadata = attestationClient->GetOpenIdMetadata();
std::cout << "Attestation Certificate Endpoint is: " << *openIdMetadata.Value.JsonWebKeySetUrl
<< std::endl;
}

View File

@ -32,12 +32,12 @@ int main()
try
{
// create client
AttestationClient const attestationClient(
AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
std::unique_ptr<AttestationClient const> attestationClient(
AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
// Retrieve the OpenId metadata from this attestation service instance.
Azure::Response<TokenValidationCertificateResult> const signingCertificates
= attestationClient.GetTokenValidationCertificates();
= attestationClient->GetTokenValidationCertificates();
std::cout << "There are " << signingCertificates.Value.Signers.size() << "signing certificates."
<< std::endl;

View File

@ -51,7 +51,7 @@ int main()
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
std::shared_ptr<AttestationAdministrationClient> adminClient(
AttestationAdministrationClient::CreatePointer(
AttestationAdministrationClientFactory::Create(
GetEnvHelper::GetEnv("ATTESTATION_ISOLATED_URL"), credential));
std::string const signingKey(GetEnvHelper::GetEnv("ISOLATED_SIGNING_KEY"));

View File

@ -46,7 +46,7 @@ int main()
auto const credential = std::make_shared<Azure::Identity::ClientSecretCredential>(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
std::unique_ptr<AttestationAdministrationClient> adminClient(
AttestationAdministrationClient::CreatePointer(
AttestationAdministrationClientFactory::Create(
GetEnv("ATTESTATION_ISOLATED_URL"), credential));
// Retrieve the SGX Attestation Policy from this attestation service instance.

View File

@ -40,12 +40,13 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
AttestationAdministrationClient adminClient(AttestationAdministrationClient::Create(
GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
std::unique_ptr<AttestationAdministrationClient> adminClient(
AttestationAdministrationClientFactory::Create(
GetEnvHelper::GetEnv("ATTESTATION_AAD_URL"), credential));
// Retrieve the SGX Attestation Policy from this attestation service instance.
Azure::Response<AttestationToken<std::string>> const sgxPolicy
= adminClient.GetAttestationPolicy(AttestationType::SgxEnclave);
= adminClient->GetAttestationPolicy(AttestationType::SgxEnclave);
std::cout << "SGX Attestation Policy is: " << sgxPolicy.Value.Body << std::endl;
}
catch (Azure::Core::Credentials::AuthenticationException const& e)

View File

@ -59,11 +59,11 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
AttestationAdministrationClient const adminClient(
AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
std::unique_ptr<AttestationAdministrationClient const> adminClient(
AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
Azure::Response<AttestationToken<PolicyResult>> const resetResult
= adminClient.ResetAttestationPolicy(AttestationType::SgxEnclave);
= adminClient->ResetAttestationPolicy(AttestationType::SgxEnclave);
if (resetResult.Value.Body.PolicyResolution == PolicyModification::Removed)
{

View File

@ -60,8 +60,8 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
AttestationAdministrationClient const adminClient(
AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
std::shared_ptr<AttestationAdministrationClient const> adminClient(
AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
std::string const signingKey(GetEnvHelper::GetEnv("ISOLATED_SIGNING_KEY"));
std::string const signingCert(GetEnvHelper::GetEnv("ISOLATED_SIGNING_CERTIFICATE"));
@ -76,7 +76,7 @@ int main()
resetOptions.SigningKey = AttestationSigningKey{pemSigningKey, pemSigningCert};
Azure::Response<AttestationToken<PolicyResult>> const resetResult
= adminClient.ResetAttestationPolicy(AttestationType::SgxEnclave, resetOptions);
= adminClient->ResetAttestationPolicy(AttestationType::SgxEnclave, resetOptions);
if (resetResult.Value.Body.PolicyResolution == PolicyModification::Updated)
{

View File

@ -59,7 +59,7 @@ int main()
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
std::unique_ptr<AttestationAdministrationClient const> adminClient(
AttestationAdministrationClient::CreatePointer(endpoint, credential, clientOptions));
AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
// Set the attestation policy on this attestation instance.
// Note that because this is an AAD mode instance, the caller does not need to sign the policy

View File

@ -62,8 +62,8 @@ int main()
GetEnvHelper::GetEnv("AZURE_TENANT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_ID"),
GetEnvHelper::GetEnv("AZURE_CLIENT_SECRET"));
AttestationAdministrationClient const adminClient(
AttestationAdministrationClient::Create(endpoint, credential, clientOptions));
std::shared_ptr<AttestationAdministrationClient const> adminClient(
AttestationAdministrationClientFactory::Create(endpoint, credential, clientOptions));
std::string const signingKey(GetEnvHelper::GetEnv("ISOLATED_SIGNING_KEY"));
std::string const signingCert(GetEnvHelper::GetEnv("ISOLATED_SIGNING_CERTIFICATE"));
@ -87,7 +87,7 @@ authorizationrules
setOptions.SigningKey = AttestationSigningKey{pemSigningKey, pemSigningCert};
Azure::Response<AttestationToken<PolicyResult>> const setResult
= adminClient.SetAttestationPolicy(AttestationType::SgxEnclave, policyToSet, setOptions);
= adminClient->SetAttestationPolicy(AttestationType::SgxEnclave, policyToSet, setOptions);
if (setResult.Value.Body.PolicyResolution == PolicyModification::Updated)
{
@ -104,7 +104,7 @@ authorizationrules
// generate the SHA256 of that token and compare it with the value returned by the service - the
// two hash values should be identical.
auto const setPolicyToken
= adminClient.CreateAttestationPolicyToken(policyToSet, setOptions.SigningKey);
= adminClient->CreateAttestationPolicyToken(policyToSet, setOptions.SigningKey);
Sha256Hash shaHasher;
std::vector<uint8_t> const policyTokenHash = shaHasher.Final(
reinterpret_cast<uint8_t const*>(setPolicyToken.RawToken.data()),

View File

@ -65,18 +65,7 @@ AttestationAdministrationClient::AttestationAdministrationClient(
std::move(perCallpolicies));
}
AttestationAdministrationClient AttestationAdministrationClient::Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationAdministrationClientOptions const& options,
Azure::Core::Context const& context)
{
AttestationAdministrationClient returnValue(endpoint, credential, options);
returnValue.RetrieveResponseValidationCollateral(context);
return returnValue;
}
std::unique_ptr<AttestationAdministrationClient> AttestationAdministrationClient::CreatePointer(
std::unique_ptr<AttestationAdministrationClient> AttestationAdministrationClientFactory::Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationAdministrationClientOptions const& options,
@ -421,7 +410,7 @@ Azure::Response<Models::AttestationToken<Models::IsolatedModeCertificateModifica
AttestationAdministrationClient::AddIsolatedModeCertificate(
std::string const& pemEncodedX509CertificateToAdd,
AttestationSigningKey const& existingSigningKey,
AddIsolatedModeCertificatesOptions const& options,
AddIsolatedModeCertificateOptions const& options,
Azure::Core::Context const& context) const
{
auto const policyCertToken(
@ -447,7 +436,7 @@ Azure::Response<Models::AttestationToken<Models::IsolatedModeCertificateModifica
AttestationAdministrationClient::RemoveIsolatedModeCertificate(
std::string const& pemEncodedX509CertificateToRemove,
AttestationSigningKey const& existingSigningKey,
AddIsolatedModeCertificatesOptions const& options,
RemoveIsolatedModeCertificateOptions const& options,
Azure::Core::Context const& context) const
{
// Calculate a signed (or unsigned) attestation policy token to send to the service.
@ -482,7 +471,7 @@ AttestationAdministrationClient::RemoveIsolatedModeCertificate(
* @param context Client context for the request to the service.
*/
void AttestationAdministrationClient::RetrieveResponseValidationCollateral(
Azure::Core::Context const& context) const
Azure::Core::Context const& context)
{
std::unique_lock<std::shared_timed_mutex> stateLock(SharedStateLock);

View File

@ -84,7 +84,7 @@ Azure::Response<TokenValidationCertificateResult> AttestationClient::GetTokenVal
Azure::Response<AttestationToken<AttestationResult>> AttestationClient::AttestSgxEnclave(
std::vector<uint8_t> const& sgxQuote,
AttestEnclaveOptions options,
AttestSgxEnclaveOptions options,
Azure::Core::Context const& context) const
{
AttestSgxEnclaveRequest attestRequest{
@ -126,7 +126,7 @@ Azure::Response<AttestationToken<AttestationResult>> AttestationClient::AttestSg
Azure::Response<AttestationToken<AttestationResult>> AttestationClient::AttestOpenEnclave(
std::vector<uint8_t> const& openEnclaveReport,
AttestEnclaveOptions options,
AttestOpenEnclaveOptions options,
Azure::Core::Context const& context) const
{
AttestOpenEnclaveRequest attestRequest{
@ -158,7 +158,7 @@ Azure::Response<TpmAttestationResult> AttestationClient::AttestTpm(
AttestTpmOptions const& attestTpmOptions,
Azure::Core::Context const& context) const
{
std::string jsonToSend = TpmDataSerializer::Serialize(attestTpmOptions.ValueToSend);
std::string jsonToSend = TpmDataSerializer::Serialize(attestTpmOptions.Payload);
auto encodedVector = std::vector<uint8_t>(jsonToSend.begin(), jsonToSend.end());
Azure::Core::IO::MemoryBodyStream stream(encodedVector);
@ -184,8 +184,7 @@ std::shared_timed_mutex SharedStateLock;
*
* @param context Client context for the request to the service.
*/
void AttestationClient::RetrieveResponseValidationCollateral(
Azure::Core::Context const& context) const
void AttestationClient::RetrieveResponseValidationCollateral(Azure::Core::Context const& context)
{
std::unique_lock<std::shared_timed_mutex> stateLock(SharedStateLock);
@ -217,39 +216,7 @@ void AttestationClient::RetrieveResponseValidationCollateral(
* @param credential The authentication method to use (required for TPM attestation).
* @param options The options to customize the client behavior.
*/
AttestationClient AttestationClient::Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions options,
Azure::Core::Context const& context)
{
AttestationClient returnValue(endpoint, credential, options);
returnValue.RetrieveResponseValidationCollateral(context);
return returnValue;
}
/** @brief Construct a new anonymous Attestation Client object
*
* @param endpoint The URL address where the client will send the requests to.
* @param options The options to customize the client behavior.
*
* @note TPM attestation requires an authenticated attestation client.
*/
AttestationClient AttestationClient::Create(
std::string const& endpoint,
AttestationClientOptions options,
Azure::Core::Context const& context)
{
return Create(endpoint, nullptr, options, context);
}
/** @brief Construct a new Attestation Client object
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication method to use (required for TPM attestation).
* @param options The options to customize the client behavior.
*/
std::unique_ptr<AttestationClient> AttestationClient::CreatePointer(
std::unique_ptr<AttestationClient> AttestationClientFactory::Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions options,
@ -269,10 +236,10 @@ std::unique_ptr<AttestationClient> AttestationClient::CreatePointer(
*
* @note TPM attestation requires an authenticated attestation client.
*/
std::unique_ptr<AttestationClient> AttestationClient::CreatePointer(
std::unique_ptr<AttestationClient> AttestationClientFactory::Create(
std::string const& endpoint,
AttestationClientOptions options,
Azure::Core::Context const& context)
{
return CreatePointer(endpoint, nullptr, options, context);
return Create(endpoint, nullptr, options, context);
}

View File

@ -32,7 +32,7 @@ namespace Azure {
m_signer.KeyId = jwk.Kid;
if (jwk.X5c)
{
m_signer.CertificateChain = std::vector<std::string>();
m_signer.CertificateChain = std::vector<std::string>{};
for (const auto& X5c : *jwk.X5c)
{
m_signer.CertificateChain->push_back(Cryptography::PemFromBase64(X5c, "CERTIFICATE"));

View File

@ -30,7 +30,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
template <class T> class EmptyDeserializer {
public:
static T Deserialize(Azure::Core::Json::_internal::json const&) { return T(); }
static T Deserialize(Azure::Core::Json::_internal::json const&) { return T{}; }
};
template <class T, class TDeserializer = EmptyDeserializer<T>> class AttestationTokenInternal {
@ -170,7 +170,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
pemEncodedChain.push_back(_detail::Cryptography::PemFromBase64(X5c, "CERTIFICATE"));
}
returnValue.push_back(
Models::AttestationSigner{Azure::Nullable<std::string>(), pemEncodedChain});
Models::AttestationSigner{Azure::Nullable<std::string>{}, pemEncodedChain});
}
}
return returnValue;
@ -201,7 +201,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
return signer;
}
}
return Azure::Nullable<Models::AttestationSigner>();
return Azure::Nullable<Models::AttestationSigner>{};
}
// Set the token body based on the bodyToSet parameter provided.

View File

@ -54,7 +54,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
{
// `InitTestClient` takes care of setting up Record&Playback.
auto options = InitClientOptions<Azure::Security::Attestation::AttestationClientOptions>();
return AttestationClient::CreatePointer(m_endpoint, options);
return AttestationClientFactory::Create(m_endpoint, options);
}
std::unique_ptr<AttestationClient> CreateAuthenticatedClient()
@ -65,7 +65,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
= std::make_shared<Azure::Identity::ClientSecretCredential>(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
return AttestationClient::CreatePointer(m_endpoint, credential, options);
return AttestationClientFactory::Create(m_endpoint, credential, options);
}
};

View File

@ -73,7 +73,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
// `InitTestClient` takes care of setting up Record&Playback.
auto options = InitClientOptions<Azure::Security::Attestation::AttestationClientOptions>();
options.TokenValidationOptions = GetTokenValidationOptions();
return AttestationClient::CreatePointer(m_endpoint, options);
return AttestationClientFactory::Create(m_endpoint, options);
}
std::unique_ptr<AttestationClient> CreateAuthenticatedClient()
{
@ -84,7 +84,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
= CreateClientSecretCredential(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
return AttestationClient::CreatePointer(m_endpoint, credential, options);
return AttestationClientFactory::Create(m_endpoint, credential, options);
}
void ValidateAttestResponse(
@ -159,17 +159,19 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
auto runtimeData = AttestationCollateral::RunTimeData();
AttestationType type = std::get<1>(GetParam());
AttestEnclaveOptions options;
AttestationData data{runtimeData, AttestationDataType::Binary};
options.RunTimeData = data;
if (type == AttestationType::OpenEnclave)
{
AttestOpenEnclaveOptions options;
options.RunTimeData = data;
auto report = AttestationCollateral::OpenEnclaveReport();
auto attestResponse = client->AttestOpenEnclave(report, options);
ValidateAttestResponse(attestResponse, data);
}
else if (type == AttestationType::SgxEnclave)
{
AttestSgxEnclaveOptions options;
options.RunTimeData = data;
auto quote = AttestationCollateral::SgxQuote();
auto attestResponse = client->AttestSgxEnclave(quote, options);
ValidateAttestResponse(attestResponse, data);
@ -184,8 +186,10 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
AttestationType type = std::get<1>(GetParam());
AttestEnclaveOptions options;
options.DraftPolicyForAttestation = R"(version= 1.0;
if (type == AttestationType::OpenEnclave)
{
AttestOpenEnclaveOptions options;
options.DraftPolicyForAttestation = R"(version= 1.0;
authorizationrules
{
[ type=="x-ms-sgx-is-debuggable", value==true] &&
@ -197,8 +201,6 @@ authorizationrules
issuancerules {
c:[type=="x-ms-sgx-mrsigner"] => issue(type="custom-name", value=c.value);
};)";
if (type == AttestationType::OpenEnclave)
{
auto report = AttestationCollateral::OpenEnclaveReport();
auto attestResponse = client->AttestOpenEnclave(report, options);
@ -221,6 +223,19 @@ issuancerules {
}
else if (type == AttestationType::SgxEnclave)
{
AttestSgxEnclaveOptions options;
options.DraftPolicyForAttestation = R"(version= 1.0;
authorizationrules
{
[ type=="x-ms-sgx-is-debuggable", value==true] &&
[ type=="x-ms-sgx-product-id", value!=0 ] &&
[ type=="x-ms-sgx-svn", value>= 0 ] &&
[ type=="x-ms-sgx-mrsigner", value == "4aea5f9a0ed04b11f889aadfe6a1d376213a29a95a85ce7337ae6f7fece6610c"]
=> permit();
};
issuancerules {
c:[type=="x-ms-sgx-mrsigner"] => issue(type="custom-name", value=c.value);
};)";
auto quote = AttestationCollateral::SgxQuote();
auto attestResponse = client->AttestSgxEnclave(quote, options);
ValidateAttestResponse(
@ -251,7 +266,7 @@ issuancerules {
if (type == AttestationType::OpenEnclave)
{
auto report = AttestationCollateral::OpenEnclaveReport();
AttestEnclaveOptions options;
AttestOpenEnclaveOptions options;
options.RunTimeData = data;
options.TokenValidationOptionsOverride = GetTokenValidationOptions();
(*options.TokenValidationOptionsOverride).ValidationCallback

View File

@ -83,7 +83,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
= CreateClientSecretCredential(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
return AttestationAdministrationClient::CreatePointer(
return AttestationAdministrationClientFactory::Create(
GetServiceEndpoint(instanceType), credential, options);
}

View File

@ -96,7 +96,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
= CreateClientSecretCredential(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
return AttestationAdministrationClient::CreatePointer(m_endpoint, credential, options);
return AttestationAdministrationClientFactory::Create(m_endpoint, credential, options);
}
bool ValidateSetPolicyResponse(

View File

@ -98,7 +98,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential
= CreateClientSecretCredential(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
return AttestationClient::CreatePointer(GetInstanceUri(instanceType), credential, options);
return AttestationClientFactory::Create(GetInstanceUri(instanceType), credential, options);
}
std::unique_ptr<AttestationAdministrationClient> CreateAdminClient(InstanceType instanceType)
@ -110,7 +110,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential
= CreateClientSecretCredential(
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
return AttestationAdministrationClient::CreatePointer(
return AttestationAdministrationClientFactory::Create(
GetInstanceUri(instanceType), credential, options);
}
};