Skip to content

Commit

Permalink
Moved attestation factory back to static method on attestation class … (
Browse files Browse the repository at this point in the history
#3682)

* Moved attestation factory back to static method on attestation class and return a concrete type not a pointer

* Fixed factory in readme file
  • Loading branch information
LarryOsterman authored Jun 1, 2022
1 parent 7115c05 commit 0fd0267
Show file tree
Hide file tree
Showing 106 changed files with 2,700 additions and 1,126 deletions.
12 changes: 6 additions & 6 deletions samples/integration/vcpkg-all-smoke/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ int main()
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
const std::string leaseID = "leaseID";
const std::string smokeUrl = "https://blob.com";
// Creating an attestation service instance requires contacting the attestation service (to retrieve validation collateral).
// Use the West US Shared client (which should always be available) as an anonymous service instance.
// Creating an attestation service instance requires contacting the attestation service (to
// retrieve validation collateral). Use the West US Shared client (which should always be
// available) as an anonymous service instance.
const std::string attestationUrl = "https://sharedwus.wus.attest.azure.net";

auto credential
Expand Down Expand Up @@ -75,11 +76,10 @@ int main()
// Attestation
std::cout << "Creating Attestation Clients" << std::endl;

std::unique_ptr<AttestationAdministrationClient> attestationAdminClient(
AttestationAdministrationClientFactory::Create(attestationUrl, credential));
AttestationAdministrationClient attestationAdminClient(
AttestationAdministrationClient::Create(attestationUrl, credential));

std::unique_ptr<AttestationClient> attestationClient(
AttestationClientFactory::Create(attestationUrl));
AttestationClient attestationClient(AttestationClient::Create(attestationUrl));

std::cout << "Successfully Created the Clients" << std::endl;
}
Expand Down
7 changes: 1 addition & 6 deletions sdk/attestation/azure-security-attestation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@

## 1.0.0-beta.3 (Unreleased)

### 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.
- `AttestationClient` and `AttestationAdministrationClient` creation is now done using the factory method `AttestationClient::Create()` and `AttestationAdministrationClient::Create()`.

### Bugs Fixed

Expand Down
13 changes: 6 additions & 7 deletions sdk/attestation/azure-security-attestation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,22 +210,21 @@ Isolated Mode Certificate Management APIs enable clients to add, remove or enume

#### Create an attestation client

The `AttestationClientFactory::Create` method is used to create instances of the attestation client:
The `AttestationClient::Create` method is used to create instances of the attestation client:

```cpp
std::string endpoint = std::getenv("ATTESTATION_AAD_URL");
return Azure::Security::Attestation::AttestationClientFactory::CreatePointer(m_endpoint);
Azure::Security::Attestation::AttestationClient client = Azure::Security::Attestation::AttestationClient::Create(m_endpoint);
```

If the attestation APIs require authentication, use the following (note that unlike the previous example,
which returns a pointer to the client, this returns the client by value):
If the attestation APIs require authentication, use the following:

```cpp
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::AttestationClientFactory::Create(m_endpoint, credential);
auto client = Azure::Security::Attestation::AttestationClient::Create(m_endpoint, credential);
```
The same pattern is used to create an `Azure::Security::Attestation::AttestationAdministrationClient`.
Expand All @@ -240,7 +239,7 @@ attestation service, however the APIs are provided for completeness and to facil
attestation results.
```cpp
auto validationCertificates = attestationClient->GetTokenValidationCertificates();
auto validationCertificates = attestationClient.GetTokenValidationCertificates();
// Enumerate the signers.
for (const auto& signer : validationCertificates.Value.Signers)
{
Expand Down Expand Up @@ -271,7 +270,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(AttestationAdministrationClientFactory::Create(m_endpoint, credential));
AttestationAdministrationClient adminClient(AttestationAdministrationClient::Create(m_endpoint, credential));
```
#### Retrieve current attestation policy for OpenEnclave
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,23 @@ namespace Azure { namespace Security { namespace Attestation {
*
*/
class AttestationAdministrationClient final {
friend class AttestationAdministrationClientFactory;

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 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 new Attestation Administration Client object from another attestation
* administration client.
Expand All @@ -56,7 +70,8 @@ namespace Azure { namespace Security { namespace Attestation {
AttestationAdministrationClient(AttestationAdministrationClient const& attestationClient)
: m_endpoint(attestationClient.m_endpoint), m_apiVersion(attestationClient.m_apiVersion),
m_pipeline(attestationClient.m_pipeline),
m_tokenValidationOptions(attestationClient.m_tokenValidationOptions){};
m_tokenValidationOptions(attestationClient.m_tokenValidationOptions),
m_attestationSigners(attestationClient.m_attestationSigners){};

/**
* @brief Destructor.
Expand Down Expand Up @@ -255,6 +270,36 @@ namespace Azure { namespace Security { namespace Attestation {

std::vector<Models::AttestationSigner> m_attestationSigners;

/**
* @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 The newly created client.
*/
static AttestationAdministrationClient CreateConcrete(
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 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 The newly created client.
*/
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{});

/**
* @brief Construct a new Attestation Administration Client object.
*
Expand Down Expand Up @@ -289,29 +334,4 @@ namespace Azure { namespace Security { namespace Attestation {
void RetrieveResponseValidationCollateral(
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
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,44 @@ 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 Construct a new Attestation Client object
*
* @details Constructs a new attestation client. Follows the
* factory pattern in [C++ Core Guidelines
* C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
*
* @param endpoint The URL address where the client will send the requests to.
* @param credential The authentication method to use (required for TPM attestation). If the
* credential parameter is not supplied, the connection will be unauthenticated.
* @param options The options to customize the client behavior.
* @return The newly created client.
*/
static AttestationClient Create(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions const& options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});

/** @brief Construct a new anonymous Attestation Client object
*
* @details Constructs a new anonymous (unauthenticated) attestation client. Follows the
* factory pattern in [C++ Core Guidelines
* C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
*
* @param endpoint The URL address where the client will send the requests to.
* @param options The options to customize the client behavior.
* @return The newly created attestation client.
*
* @note TPM attestation requires an authenticated attestation client.
*
*/
static AttestationClient Create(
std::string const& endpoint,
AttestationClientOptions options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});

/**
* @brief Destructor.
*
Expand All @@ -131,7 +165,8 @@ namespace Azure { namespace Security { namespace Attestation {
AttestationClient(AttestationClient const& attestationClient)
: m_endpoint(attestationClient.m_endpoint), m_apiVersion(attestationClient.m_apiVersion),
m_pipeline(attestationClient.m_pipeline),
m_tokenValidationOptions(attestationClient.m_tokenValidationOptions){};
m_tokenValidationOptions(attestationClient.m_tokenValidationOptions),
m_attestationSigners(attestationClient.m_attestationSigners){};

std::string const Endpoint() const { return m_endpoint.GetAbsoluteUrl(); }

Expand Down Expand Up @@ -225,38 +260,25 @@ namespace Azure { namespace Security { namespace Attestation {
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
*
* @details Constructs a new attestation client. Follows the
* factory pattern in [C++ Core Guidelines
* C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
*
* @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 credential The authentication method to use (required for TPM attestation). If the
* credential parameter is not supplied, the connection will be unauthenticated.
* @param options The options to customize the client behavior.
* @return std::unique_ptr<AttestationClient> The newly created client.
*/
AttestationClient(
static AttestationClient CreateConcrete(
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{});
};

/** @brief Construct a new AttestationClient object.
*
* The AttestationClientFactory class is a factory class for instantiating new AttestationClient
* objects.
*
*/
class AttestationClientFactory final {
public:
AttestationClientOptions const& options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});
/** @brief Construct a new Attestation Client object
*
* @details Constructs a new attestation client. Follows the
Expand All @@ -269,29 +291,31 @@ 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> Create(
static std::unique_ptr<AttestationClient> CreatePointer(
std::string const& endpoint,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
AttestationClientOptions options = AttestationClientOptions{},
AttestationClientOptions const& options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});

/** @brief Construct a new anonymous Attestation Client object
*
* @details Constructs a new anonymous (unauthenticated) attestation client. Follows the
* factory pattern in [C++ Core Guidelines
* C.50](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization)
/** @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 std::unique_ptr<AttestationClient> The newly created attestation client.
*
* @note TPM attestation requires an authenticated attestation client.
*
*/
static std::unique_ptr<AttestationClient> Create(
AttestationClient(
std::string const& endpoint,
AttestationClientOptions options = AttestationClientOptions{},
Azure::Core::Context const& constext = Azure::Core::Context{});
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{});
};

}}} // namespace Azure::Security::Attestation
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ int main()
std::string const endpoint
= "https://shared" + shortLocation + "." + shortLocation + ".attest.azure.net";

std::unique_ptr<AttestationClient> attestationClient(
AttestationClientFactory::Create(endpoint));
AttestationClient const attestationClient(AttestationClient::Create(endpoint));

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ int main()
{
std::cout << "In function: SampleAttestSgxEnclaveSimple" << std::endl;
// create client
std::unique_ptr<AttestationClient const> attestationClient(
AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
AttestationClient const attestationClient(
AttestationClient::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));

std::vector<uint8_t> const openEnclaveReport = AttestationCollateral::OpenEnclaveReport();

Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ int main()
{
std::cout << "In function: SampleAttestSgxEnclaveSimple" << std::endl;
// create client
std::unique_ptr<AttestationClient> attestationClient(
AttestationClientFactory::Create(GetEnvHelper::GetEnv("ATTESTATION_AAD_URL")));
AttestationClient attestationClient(
AttestationClient::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;
Expand Down
Loading

0 comments on commit 0fd0267

Please sign in to comment.