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

Updated TPM attestation APIs to remove BinaryData parameters. #20843

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/attestation/Azure.Security.Attestation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ to reduce the number of parameters passed into the API.
- The return value of `GetPolicyManagementCertificates` has been changed from `AttestationResult<PolicyCertificatesResult>` to `AttestationResult<IReadOnlyList<X509Certificate2>>` to simplify the experience of retrieving the certificate list. As a consequence of this change, the `PolicyCertificatesResult` type has been removed.
- The unused `TpmAttestationRequest` and `TpmAttestationResponse` types have been removed.
- The `AttestationTokenSigningKey` will now ensure that the public key in the provided certificate is the public key corresponding to the private key.
- `AttestTpm` and `AttestTpmAsync` are changed to accept a new `TpmAttestationRequest` and return a `TpmAttestationResponse` instead of accepting and returning a `BinaryData`. The semantics of the API do not change, just the encapsulation of the BinaryData.

## 1.0.0-beta.2 (2021-04-06)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public AttestationClient(System.Uri endpoint, Azure.Core.TokenCredential credent
public virtual System.Threading.Tasks.Task<Azure.Security.Attestation.AttestationResponse<Azure.Security.Attestation.AttestationResult>> AttestOpenEnclaveAsync(Azure.Security.Attestation.AttestationRequest request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Security.Attestation.AttestationResponse<Azure.Security.Attestation.AttestationResult> AttestSgxEnclave(Azure.Security.Attestation.AttestationRequest request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Security.Attestation.AttestationResponse<Azure.Security.Attestation.AttestationResult>> AttestSgxEnclaveAsync(Azure.Security.Attestation.AttestationRequest request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<System.BinaryData> AttestTpm(System.BinaryData request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<System.BinaryData>> AttestTpmAsync(System.BinaryData request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Security.Attestation.TpmAttestationResponse> AttestTpm(Azure.Security.Attestation.TpmAttestationRequest request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Security.Attestation.TpmAttestationResponse>> AttestTpmAsync(Azure.Security.Attestation.TpmAttestationRequest request, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<System.Collections.Generic.IReadOnlyList<Azure.Security.Attestation.AttestationSigner>> GetSigningCertificates(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<System.Collections.Generic.IReadOnlyList<Azure.Security.Attestation.AttestationSigner>>> GetSigningCertificatesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
Expand Down Expand Up @@ -277,4 +277,14 @@ public partial class StoredAttestationPolicy
public StoredAttestationPolicy() { }
public string AttestationPolicy { get { throw null; } set { } }
}
public partial class TpmAttestationRequest
{
public TpmAttestationRequest() { }
public System.BinaryData Data { get { throw null; } set { } }
}
public partial class TpmAttestationResponse
{
internal TpmAttestationResponse() { }
public System.BinaryData Data { get { throw null; } }
}
}
28 changes: 10 additions & 18 deletions sdk/attestation/Azure.Security.Attestation/src/AttestationClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,23 +273,19 @@ private async Task<AttestationResponse<AttestationResult>> AttestOpenEnclaveInte

/// <summary>
/// Attest a TPM based enclave.
/// See https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol for more information.
/// See <seealso href="https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol"/> for more information.
/// </summary>
/// <param name="request"></param>
/// <param name="request">TPM Attestation request.</param>
/// <param name="cancellationToken">Cancellation token used to cancel this operation.</param>
/// <returns>A <see cref="TpmAttestationResponse"/>.</returns>
public virtual Response<BinaryData> AttestTpm(BinaryData request, CancellationToken cancellationToken = default)
/// <returns>A <see cref="TpmAttestationResponse"/> containing the TPM attestation response.</returns>
public virtual Response<TpmAttestationResponse> AttestTpm(TpmAttestationRequest request, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(request, nameof(request));
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(AttestationClient)}.{nameof(AttestTpm)}");
scope.Start();
try
{
var response = _restClient.AttestTpm(new TpmAttestationRequest { Data = request.ToArray() }, cancellationToken);

BinaryData responseData = new BinaryData(response.Value);

return Response.FromValue(responseData, response.GetRawResponse());
return _restClient.AttestTpm(request, cancellationToken);
}
catch (Exception ex)
{
Expand All @@ -300,23 +296,19 @@ public virtual Response<BinaryData> AttestTpm(BinaryData request, CancellationTo

/// <summary>
/// Attest a TPM based enclave.
/// See https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol for more information.
/// See <seealso href="https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol"/> for more information.
/// </summary>
/// <param name="request">Incoming request to send to the TPM attestation service.</param>
/// <param name="request">TPM Attestation request.</param>
/// <param name="cancellationToken">Cancellation token used to cancel this operation.</param>
/// <returns>A <see cref="BinaryData"/> structure containing the value of <see cref="TpmAttestationResponse.Data"/>.</returns>
public virtual async Task<Response<BinaryData>> AttestTpmAsync(BinaryData request, CancellationToken cancellationToken = default)
/// <returns>A <see cref="TpmAttestationResponse"/> containing the TPM attestation response.</returns>
public virtual async Task<Response<TpmAttestationResponse>> AttestTpmAsync(TpmAttestationRequest request, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(request, nameof(request));
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(AttestationClient)}.{nameof(AttestTpm)}");
scope.Start();
try
{
var response = await _restClient.AttestTpmAsync(new TpmAttestationRequest { Data = request.ToArray() }, cancellationToken).ConfigureAwait(false);

BinaryData responseData = new BinaryData(response.Value.Data);

return Response.FromValue(responseData, response.GetRawResponse());
return await _restClient.AttestTpmAsync(request, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
namespace Azure.Security.Attestation
{
/// <summary>
/// Represents a response for a TPM attestation call. See https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol for more information.
/// Represents a request for a TPM attestation call. See <seealso href="https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol"/> for more information.
/// </summary>
[CodeGenModel("TpmAttestationRequest")]
internal partial class TpmAttestationRequest
public partial class TpmAttestationRequest
{
/// <summary>
/// Attestation Response data. See https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol for more details
/// Attestation Request data. See <seealso href="https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol"/> for more details
/// </summary>
public ReadOnlyMemory<byte> Data { get => Base64Url.Decode(InternalData); set => InternalData = Base64Url.Encode(value.ToArray()); }
public BinaryData Data { get => BinaryData.FromBytes(Base64Url.Decode(InternalData)); set => InternalData = Base64Url.Encode(value.ToArray()); }

[CodeGenMember("Data")]
internal string InternalData { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
namespace Azure.Security.Attestation
{
/// <summary>
/// Represents a response for a TPM attestation call. See https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol for more information.
/// Represents a response for a TPM attestation call. See <seealso href="https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol"/> for more information.
/// </summary>
[CodeGenModel("TpmAttestationResponse")]
internal partial class TpmAttestationResponse
public partial class TpmAttestationResponse
{
/// <summary>
/// Attestation Response data. See https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol for more details
/// Attestation Response data. See <seealso href="https://docs.microsoft.com/en-us/azure/attestation/virtualization-based-security-protocol"/> for more details.
/// </summary>
public ReadOnlyMemory<byte> Data { get => Base64Url.Decode(InternalData); }
public BinaryData Data { get => BinaryData.FromBytes(Base64Url.Decode(InternalData)); }

[CodeGenMember("Data")]
internal string InternalData { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using Azure.Core;
using Azure.Core.TestFramework;
using NUnit.Framework;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Azure.Security.Attestation.Tests
{
Expand Down Expand Up @@ -241,7 +243,7 @@ public async Task AttestOpenEnclaveShared()
});

// Confirm that the attestation token contains the enclave held data we specified.
CollectionAssert.AreEqual(binaryRuntimeData, attestationResult.Value.EnclaveHeldData.ToArray());
CollectionAssert.AreEqual(binaryRuntimeData, attestationResult.Value.EnclaveHeldData.ToArray());
// VERIFY ATTESTATIONRESULT.
// Encrypt Data using DeprecatedEnclaveHeldData
// Send to enclave.
Expand Down Expand Up @@ -338,5 +340,47 @@ public async Task AttestOpenEnclaveSharedCallbackRejects()
Assert.IsTrue(callbackInvoked);
}
}

private class TpmInit
{
[JsonPropertyName("type")]
public string Type { get; set; }
}

// TpmAttest requires a TpmPayload object.
private class TpmPayload
{
[JsonPropertyName("payload")]
public object Payload { get; set; }
}

[RecordedTest]
public async Task AttestTpmMinimalAad()
{
// TPM attestation requires that there be an attestation policy applied before it can succeed.
string attestationPolicy = "version=1.0; authorizationrules{=> permit();}; issuancerules{};";
var adminClient = TestEnvironment.GetAadAdministrationClient(this);

var setResult = await adminClient.SetPolicyAsync(AttestationType.Tpm, attestationPolicy);

var tpmPayload = new TpmPayload
{
Payload = new TpmInit
{
Type = "aikcert"
},
};

var client = TestEnvironment.GetAadAttestationClient(this);
Response<TpmAttestationResponse> tpmResponse = null;
tpmResponse = await client.AttestTpmAsync(new TpmAttestationRequest { Data = BinaryData.FromObjectAsJson(tpmPayload) });

// Make sure that the response from the service looks like it's supposed to look.
var parsedValue = JsonDocument.Parse(tpmResponse.Value.Data);
Assert.IsNotNull(parsedValue.RootElement.GetProperty("payload"));
var payload = parsedValue.RootElement.GetProperty("payload");
Assert.IsNotNull(payload.GetProperty("challenge"));
Assert.IsNotNull(payload.GetProperty("service_context"));
}
}
}
Loading