Class AttestationClient

java.lang.Object
com.azure.security.attestation.AttestationClient

public final class AttestationClient extends Object
The AttestationClient implements the functionality required by the "Attest" family of APIs.

An enclave (or Trusted Execution Environment) is a chunk of code that is isolated from the host (think: "encrypted VM" or "encrypted container"). But there's one key attribute of the enclave: It is encrypted.That means that if data is sent from the enclave, there is no way of knowing that the data came from the enclave.

And even worse, there is no way of securely communicating with the enclave (since the enclave is fully isolated from the host, all information passed into the enclave has to go through its host first).

To solve the communication problem, the Attest API can be used to facilitate what is known as the "Secure Key Release" (SKR) protocol.

There are 4 parties involved in an attestation operation:

  • The host (which hosts the enclave)
  • The enclave (which is the enclave :)  encrypted, nobody can see what goes on inside it),
  • The "verifier" which verifies the evidence from the enclave (this is the attestation service) and generates a token which can be received by a relying party, and
  • The "relying party" which will interpret the token from the service. For the Secure Key Release Protocol, this is the entity which wishes to communicate with the enclave.

It's possible that all these parties are on the same computer, it's possible theyre on multiple computers.
It's possible that the host is also the relying party. It's possible that the relying party is a component like Azure Managed HSM.

There are three primary pieces of data received by the service for the Attest family of APIs. All of them are arrays of bytes, and all of them originate from code running in the enclave (thus they need to be treated as opaque arrays of bytes by the SDK):

  1. Evidence. For Intel SGX enclaves, this has two forms, either an SGX 'Quote' or an OpenEnclave 'Report'. It is required for attestation operations.
  2. InitTimeData  This is data which is specified at Initialization Time. It is optional (and not currently supported on all enclave types in Azure)
  3. RunTimeData  this is data which is specified at the time the quote is generated (at runtime). It is optional, but required for the Secure Key Release protocol.

The Evidence is cryptographically signed by a known authority (for Intel SGX Quotes or OpenEnclave reports, this is a key owned by Intel which represents that the SGX enclave is valid and can be trusted).
The core idea for all attestation operations is to take advantage of a region within the Evidence which is controlled by enclave. For SGX Enclaves, this is the 64 bytes of "user data" contained within SGX quote.

For the Secure Key Release protocol, code inside the enclave generates an asymmetric key and serializes the public key into a byte buffer. It then calculates the SHA256 hash of the serialized key and creates a quote containing that SHA256 hash. We now have a cryptographically validated indication that the contents of the byte buffer was known inside the enclave.

The enclave then hands the byte buffer and the quote to its host. The host sends the quote and byte buffer as the "RunTime Data" to the via the attestSgxEnclave(BinaryData) or attestOpenEnclave(com.azure.core.util.BinaryData) API. Assuming the byte buffer and quote are valid, and the quote contains the hash of the byte buffer, the attestation service responds with an AttestationToken signed by the attestation service, whose body is an AttestationResult.

The token generated also includes the contents of the InitTimeData and/or RunTimeData if it was provided in the Attest API call.

The host then sends the token to the relying party. The relying party verifies the token and verifies the claims within the token indicate that the enclave is the correct enclave. It then takes the key from the token and uses it to encrypt the data to be sent to the enclave and sends that back to the host, which passes it into the enclave.

That completes the secure key release protocol.


When the Attestation Token is generated by the attestation service, as mentioned, it contains the InitTime and RunTime data.

There are two possible representations for RunTime Data in the attestation token, depending on the requirements of the relying party:
The first is as JSON formatted data. That can be convenient if the relying party expects to receive its public key as a JSON Web Key
The second is as a binary blob of data. That is needed if either the data sent by the enclave isn't a JSON object - for instance, if the RunTime data contained an asymmetric key which is formatted as a PEM encoded key, it should be interpreted as a binary blob

If you ask for the RunTime data to be included in the token as binary, then it will be base64url encoded in the "x-ms-maa-enclavehelddata" claim in the output token (the AttestationResult.getEnclaveHeldData() property).
If you ask for the RunTime data to be included in the token as JSON, then it will be included in the "x-ms-maa-runtimeClaims" claim in the output token (the AttestationResult.getRuntimeClaims() property).

In addition to the Attest APIs, the AttestationClient object also contains helper APIs which can be used to retrieve the OpenId Metadata document and signing keys from the service.

The OpenId Metadata document contains properties which describe the attestation service.

The Attestation Signing Keys describe the keys which will be used to sign tokens generated by the attestation service. All tokens emitted by the attestation service will be signed by one of the certificates listed in the attestation signing keys.

Note: The Response returned by the WithResponse APIs is actually an AttestationToken object, which contains a method AttestationToken.serialize() which returns the actual JSON Web Token returned by the attestation service. If a client is going to be transmitting the attestation token from the MAA service to an external relying party, they should send the actual token from the service to the relying party.

  • Method Details

    • getOpenIdMetadata

      public AttestationOpenIdMetadata getOpenIdMetadata()
      Retrieves the open-id metadata about the attestation signing keys in use by the attestation service.

      The attestation service exposes a standard OpenID metadata Discovery Document which can be used to discover attributes of the attestation service.

      The getOpenIdMetadata API allows the client to retrieve the information contained in the metadata discovery document.

      This is required if an application is manually validating the tokens returned from the attestation service.

      Retrieve the OpenID metadata for this client.

       AttestationOpenIdMetadata openIdMetadata = client.getOpenIdMetadata();
       
      Returns:
      An AttestationOpenIdMetadata object containing the MAA provided OpenID connect information.
      Throws:
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • getOpenIdMetadataWithResponse

      public Response<AttestationOpenIdMetadata> getOpenIdMetadataWithResponse(Context context)
      Retrieves the open-id metadata about the attestation signing keys in use by the attestation service.

      The attestation service exposes a standard OpenID metadata Discovery Document which can be used to discover attributes of the attestation service.

      The getOpenIdMetadata API allows the client to retrieve the information contained in the metadata discovery document.

      This is required if an application is manually validating the tokens returned from the attestation service.

      Retrieve the OpenID metadata for this attestation instance.

       Response<AttestationOpenIdMetadata> response = client.getOpenIdMetadataWithResponse(Context.NONE);
       
      Parameters:
      context - Context for the operation.
      Returns:
      An AttestationOpenIdMetadata object containing the MAA provided OpenID connect information.
      Throws:
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • listAttestationSigners

      public AttestationSignerCollection listAttestationSigners()
      Retrieves the list of AttestationSigner objects associated with this attestation instance.

      An AttestationSigner represents an X.509 certificate chain and KeyId which can be used to validate an attestation token returned by the service.

      Retrieve Attestation Signers for this async client.

       AttestationSignerCollection signers = client.listAttestationSigners();
       signers.getAttestationSigners().forEach(cert -> {
           System.out.println("Found certificate.");
           if (cert.getKeyId() != null) {
               System.out.println("    Certificate Key ID: " + cert.getKeyId());
           } else {
               System.out.println("    Signer does not have a Key ID");
           }
           cert.getCertificates().forEach(chainElement -> {
               System.out.println("        Cert Subject: " + chainElement.getSubjectDN().getName());
               System.out.println("        Cert Issuer: " + chainElement.getIssuerDN().getName());
           });
       });
       
      Returns:
      Returns a collection of AttestationSigner objects which will be used to sign tokens returned from the attestation service.
    • listAttestationSignersWithResponse

      public Response<AttestationSignerCollection> listAttestationSignersWithResponse(Context context)
      Retrieves the list of AttestationSigner objects associated with this attestation instance. An AttestationSigner represents an X.509 certificate chain and KeyId which can be used to validate an attestation token returned by the service.
       Response<AttestationSignerCollection> responseOfSigners = client.listAttestationSignersWithResponse(Context.NONE);
       
      Parameters:
      context - Context for operation.
      Returns:
      Returns an array of AttestationSigner objects.
    • attestOpenEnclave

      public AttestationResult attestOpenEnclave(BinaryData report)
      Attest an OpenEnclave report.

      This method is a convenience method which attests evidence from an OpenEnclave enclave with no RuntimeData or InitTimeData.

      The report is generated via the oe_get_report}.

      It returns an AttestationResult containing the claims emitted by the attestation service.
       AttestationResult resultWithReport = client.attestOpenEnclave(openEnclaveReport);
       
      Parameters:
      report - - OpenEnclave generated report.
      Returns:
      the result of an attestation operation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestOpenEnclave

      public AttestationResult attestOpenEnclave(AttestationOptions options)
      Attest an OpenEnclave report, specifying RunTimeData and InitTimeData. The AttestationOptions parameter allows the caller to specify the OpenEnclave report which contains evidence from the enclave, and runtime data which allows the enclave to specify additional data from within the enclave. When calling the AttestationOptions.setRunTimeData(AttestationData) API, the caller can specify whether the attestation service should treat the runtime data as binary or as JSON when it is included in the response attestation token.

      Attest an OpenEnclave enclave with attestation options.

       AttestationResult result = client.attestOpenEnclave(new AttestationOptions(openEnclaveReport)
           .setRunTimeData(new AttestationData(runtimeData, AttestationDataInterpretation.BINARY)));
      
       
      Parameters:
      options - Attestation options for an OpenEnclave enclave.
      Returns:
      the result of an attestation operation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestOpenEnclaveWithResponse

      public AttestationResponse<AttestationResult> attestOpenEnclaveWithResponse(AttestationOptions options, Context context)
      Attest an OpenEnclave report, specifying RunTimeData and InitTimeData. The AttestationOptions parameter allows the caller to specify the OpenEnclave report which contains evidence from the enclave, and runtime data which allows the enclave to specify additional data from within the enclave. When calling the AttestationOptions.setRunTimeData(AttestationData) API, the caller can specify whether the attestation service should treat the runtime data as binary or as JSON when it is included in the response attestation token.

      Attest an OpenEnclave enclave with attestation options.

       Response<AttestationResult> openEnclaveResponse = client.attestOpenEnclaveWithResponse(
           new AttestationOptions(openEnclaveReport)
               .setRunTimeData(new AttestationData(runtimeData, AttestationDataInterpretation.JSON)), Context.NONE);
      
       
      Parameters:
      options - Attestation request for Intel SGX enclaves.
      context - Context for the operation.
      Returns:
      the result of an attestation operation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestSgxEnclave

      public AttestationResult attestSgxEnclave(BinaryData quote)
      Attest an SGX Enclave Quote.

      This method is a convenience method which attests evidence from an Intel SGX enclave with no RuntimeData or InitTimeData.

      It returns an AttestationResult containing the claims emitted by the attestation service.
       AttestationResult resultWithReport = client.attestSgxEnclave(sgxEnclaveReport);
       
      Parameters:
      quote - SGX Quote to attest.
      Returns:
      the result of an attestation operation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestSgxEnclave

      public AttestationResult attestSgxEnclave(AttestationOptions options)
      Attest an SGX enclave quote, specifying RunTimeData and InitTimeData. The AttestationOptions parameter allows the caller to specify the SGX quote which contains evidence from the enclave, and runtime data which allows the enclave to specify additional data from within the enclave. When calling the AttestationOptions.setRunTimeData(AttestationData) API, the caller can specify whether the attestation service should treat the runtime data as binary or as JSON when it is included in the response attestation token.

      Attest an OpenEnclave enclave with attestation options.

       AttestationResult result = client.attestSgxEnclave(new AttestationOptions(sgxQuote)
           .setRunTimeData(new AttestationData(runtimeData, AttestationDataInterpretation.BINARY)));
      
       
      Parameters:
      options - Attestation options for Intel SGX enclaves.
      Returns:
      the result of an attestation operation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestSgxEnclaveWithResponse

      public AttestationResponse<AttestationResult> attestSgxEnclaveWithResponse(AttestationOptions request, Context context)
      Attest an SGX enclave report, specifying RunTimeData and InitTimeData. The AttestationOptions parameter allows the caller to specify the OpenEnclave report which contains evidence from the enclave, and runtime data which allows the enclave to specify additional data from within the enclave. When calling the AttestationOptions.setRunTimeData(AttestationData) API, the caller can specify whether the attestation service should treat the runtime data as binary or as JSON when it is included in the response attestation token.

      Attest an OpenEnclave enclave with attestation options.

       Response<AttestationResult> openEnclaveResponse = client.attestSgxEnclaveWithResponse(
           new AttestationOptions(sgxQuote)
               .setRunTimeData(new AttestationData(runtimeData, AttestationDataInterpretation.JSON)), Context.NONE);
      
       
      Parameters:
      request - Attestation request for Intel SGX enclaves.
      context - Context for the operation.
      Returns:
      the result of an attestation operation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestTpm

      public String attestTpm(String request)
      Performs TPM attestation. Processes attestation evidence from a VBS enclave, producing an attestation result.

      The TPM attestation protocol is defined here.

      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 "report", whose value will be an attestation result token.

      Perform the first leg of a TPM attestation operation

       // The initial payload for TPM attestation is a JSON object with a property named "payload",
       // containing an object with a property named "type" whose value is "aikcert".
      
       String attestInitialPayload = "{\"payload\": { \"type\": \"aikcert\" } }";
       String tpmResponse = client.attestTpm(attestInitialPayload);
       
      Parameters:
      request - Attestation request for Trusted Platform Module (TPM) attestation.
      Returns:
      attestation response for Trusted Platform Module (TPM) attestation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.
    • attestTpmWithResponse

      public Response<String> attestTpmWithResponse(String request, Context context)
      Performs TPM attestation. Processes attestation evidence from a VBS enclave, producing an attestation result.

      The TPM attestation protocol is defined here.

      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 "report", whose value will be an attestation result token.

      Perform the first leg of a TPM attestation operation

       // The initial payload for TPM attestation is a JSON object with a property named "payload",
       // containing an object with a property named "type" whose value is "aikcert".
      
       String attestInitialPayload = "{\"payload\": { \"type\": \"aikcert\" } }";
       Response<String> tpmResponse = client.attestTpmWithResponse(attestInitialPayload, Context.NONE);
       
      Parameters:
      request - Attestation request for Trusted Platform Module (TPM) attestation.
      context - Context for the operation.
      Returns:
      attestation response for Trusted Platform Module (TPM) attestation.
      Throws:
      IllegalArgumentException - thrown if parameters fail the validation.
      HttpResponseException - thrown if the request is rejected by server.
      RuntimeException - all other wrapped checked exceptions if the request fails to be sent.