Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update AttestationClient::AttestTpm API to match existing AttestOpenEnclave and AttestSgxmEnclave #3928

Merged
merged 15 commits into from
Sep 19, 2022
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Thank you for your interest in contributing to Azure SDK for C++.
- **DO** submit all code changes via pull requests (PRs) rather than through a direct commit. PRs will be reviewed and potentially merged by the repo maintainers after a peer review that includes at least one maintainer.
- **DO** review your own PR to make sure there aren't any unintended changes or commits before submitting it.
- **DO NOT** submit "work in progress" PRs. A PR should only be submitted when it is considered ready for review and subsequent merging by the contributor.
- If the change is work-in-progress or an experiment, **DO** start if off as a temporary draft PR.
- If the change is work-in-progress or an experiment, **DO** start it off as a temporary draft PR.
- **DO** give PRs short-but-descriptive names (e.g. "Improve code coverage for Azure.Core by 10%", not "Fix #1234") and add a description which explains why the change is being made.
- **DO** refer to any relevant issues, and include [keywords](https://docs.github.com/articles/closing-issues-via-commit-messages/) that automatically close issues when the PR is merged.
- **DO** tag any users that should know about and/or review the change.
Expand Down Expand Up @@ -48,13 +48,13 @@ Codespaces is new technology that allows you to use a container as your developm
### GitHub Codespaces

1. From the Azure SDK GitHub repo, click on the "Code -> Open with Codespaces" button.
1. Open a Terminal. The development environment will be ready for you. Continue to [Building and Testing](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#building-and-testing).
1. Open a Terminal. The development environment will be ready for you. Continue to [Building the project](#building-the-project).

### VS Code Codespaces

1. Install the [VS Code Remote Extension Pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
1. When you open the Azure SDK for C++ repo in VS Code, it will prompt you to open the project in the Dev Container. If it does not prompt you, then hit CTRL+P, and select "Remote-Containers: Open Folder in Container..."
1. Open a Terminal. The development environment will be ready for you. Continue to [Building and Testing](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#building-and-testing).
1. Open a Terminal. The development environment will be ready for you. Continue to [Building the project](#building-the-project).

## Full Local Setup

Expand Down
5 changes: 5 additions & 0 deletions sdk/attestation/azure-security-attestation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

### Breaking Changes

- Changed `AttestationClient::AttestTpm` to match `AttestOpenEnclave` and `AttestSgxEnclave`
- Added `std::vector<uint8_t>` dataToAttest parameter.
- Removed `PayLoad` in `TpmAttestationOptions`
- Changed `TpmResult` in `TpmAttestationResult` to type `std::vector<uint8_t>`

### Bugs Fixed

### Other Changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,26 +223,20 @@ namespace Azure { namespace Security { namespace Attestation {
Azure::Core::Context const& context = Azure::Core::Context{}) const;

/**
* @brief Perform a single leg
*
* Processes attestation evidence from a VBS enclave, producing an attestation result.
*
* @brief Sends TPM-based attestation data to the service.
* The TPM attestation protocol is defined
penglimsft marked this conversation as resolved.
Show resolved Hide resolved
* [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol')
*
* Unlike OpenEnclave reports and SGX enclave quotes, TPM attestation is implemented using
* JSON encoded strings.
*
* The client formats a string serialized JSON request to the
* service, which responds with a JSON response. The serialized JSON object exchange continues
* until the service responds with a JSON string with a property named {@code "report"}, whose
* value will be an attestation result token.
* @param dataToAttest - Attestation request data.
* @param options - Options to the attestation request.
* @param context - Context for the operation.
*
* @param options sent to the service for Trusted Platform Module (TPM) attestation.
* @return attestation response for Trusted Platform Module (TPM) attestation.
* @return Response<TpmAttestationResult> - The result of the attestation operation
*/
Response<Models::TpmAttestationResult> AttestTpm(
AttestTpmOptions const& options,
std::vector<uint8_t> const& dataToAttest,
AttestTpmOptions const& options = AttestTpmOptions{},
Azure::Core::Context const& context = Azure::Core::Context{}) const;

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,13 @@ namespace Azure { namespace Security { namespace Attestation { namespace Models
*/
struct TpmAttestationResult final
{
/** @brief The JSON encoded value returned from TPM attestation.
/** @brief Attestation response data.
*
* The TPM attestation protocol is defined
* [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol')
*
*/
std::string TpmResult;
std::vector<uint8_t> TpmResult;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,6 @@ namespace Azure { namespace Security { namespace Attestation {
*/
struct AttestTpmOptions final
{
/**
* @brief JSON Data to send to the attestation service for TPM attestation.
* @details The TPM attestation protocol is defined
* [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol')
*/
std::string Payload;
};

/** @brief The AttestationSigningKey represents a tuple of asymmetric private cryptographic key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,14 @@ Azure::Response<AttestationToken<AttestationResult>> AttestationClient::AttestOp
}

Azure::Response<TpmAttestationResult> AttestationClient::AttestTpm(
AttestTpmOptions const& attestTpmOptions,
std::vector<uint8_t> const& dataToAttest,
AttestTpmOptions const&,
Azure::Core::Context const& context) const
{
auto tracingContext(m_tracingFactory.CreateTracingContext("AttestTpm", context));
try
{
std::string jsonToSend = TpmDataSerializer::Serialize(attestTpmOptions.Payload);
std::string jsonToSend = TpmDataSerializer::Serialize(dataToAttest);
auto encodedVector = std::vector<uint8_t>(jsonToSend.begin(), jsonToSend.end());
Azure::Core::IO::MemoryBodyStream stream(encodedVector);

Expand All @@ -212,7 +213,7 @@ Azure::Response<TpmAttestationResult> AttestationClient::AttestTpm(
// Send the request to the service.
auto response
= AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context);
std::string returnedBody(TpmDataSerializer::Deserialize(response));
std::vector<uint8_t> returnedBody{TpmDataSerializer::Deserialize(response)};
return Response<TpmAttestationResult>(TpmAttestationResult{returnedBody}, std::move(response));
}
catch (std::runtime_error const& ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,21 +397,21 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
returnValue.CertificateThumbprint, jsonResult, "x-ms-certificate-thumbprint");
return returnValue;
}
std::string TpmDataSerializer::Serialize(std::string const& tpmData)
std::string TpmDataSerializer::Serialize(std::vector<uint8_t> const& tpmData)
{
Azure::Core::Json::_internal::json jsonData;
jsonData["data"] = Azure::Core::_internal::Base64Url::Base64UrlEncode(
std::vector<uint8_t>(tpmData.begin(), tpmData.end()));
jsonData["data"] = Azure::Core::_internal::Base64Url::Base64UrlEncode(tpmData);
return jsonData.dump();
}
std::string TpmDataSerializer::Deserialize(Azure::Core::Json::_internal::json const& jsonData)
std::vector<uint8_t> TpmDataSerializer::Deserialize(
Azure::Core::Json::_internal::json const& jsonData)
{
std::vector<uint8_t> returnValue;
JsonOptional::SetIfExists<std::string, std::vector<uint8_t>>(
returnValue, jsonData, "data", Azure::Core::_internal::Base64Url::Base64UrlDecode);
return std::string(returnValue.begin(), returnValue.end());
return returnValue;
}
std::string TpmDataSerializer::Deserialize(
std::vector<uint8_t> TpmDataSerializer::Deserialize(
std::unique_ptr<Azure::Core::Http::RawResponse> const& response)
{
return TpmDataSerializer::Deserialize(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail

struct TpmDataSerializer
{
static std::string Serialize(std::string const& tpmData);
static std::string Deserialize(Azure::Core::Json::_internal::json const& jsonData);
static std::string Deserialize(std::unique_ptr<Azure::Core::Http::RawResponse> const& response);
static std::string Serialize(std::vector<uint8_t> const& tpmData);
static std::vector<uint8_t> Deserialize(Azure::Core::Json::_internal::json const& jsonData);
static std::vector<uint8_t> Deserialize(
std::unique_ptr<Azure::Core::Http::RawResponse> const& response);
};

}}}} // namespace Azure::Security::Attestation::_detail
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
{
auto client(CreateClient(InstanceType::AAD));

auto response(client.AttestTpm(AttestTpmOptions{R"({"payload": { "type": "aikcert" } })"}));
std::string tpmQuote = R"({"payload": { "type": "aikcert" } })";
auto response(client.AttestTpm(std::vector<uint8_t>(tpmQuote.begin(), tpmQuote.end())));

Azure::Core::Json::_internal::json parsedResponse(
Azure::Core::Json::_internal::json::parse(response.Value.TpmResult));
Expand Down