Created Attestation Administration client (#3355)
* Created Attestation Administration client * Integrated with main
This commit is contained in:
parent
9f58947056
commit
cd9ae61a8e
@ -83,6 +83,7 @@ jobs:
|
||||
Pool: azsdk-pool-mms-win-2019-general
|
||||
OSVmImage: MMS2019
|
||||
VCPKG_DEFAULT_TRIPLET: 'x86-windows-static'
|
||||
VcpkgInstall: 'openssl'
|
||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
||||
CMAKE_GENERATOR_PLATFORM: Win32
|
||||
CmakeArgs: ' -DBUILD_TESTING=ON -DRUN_LONG_UNIT_TESTS=ON -DBUILD_PERFORMANCE_TESTS=ON '
|
||||
@ -91,7 +92,7 @@ jobs:
|
||||
Win_x86_no_rtti_whit_unit_test:
|
||||
Pool: azsdk-pool-mms-win-2019-general
|
||||
OSVmImage: MMS2019
|
||||
VcpkgInstall: 'libxml2'
|
||||
VcpkgInstall: 'libxml2 openssl'
|
||||
VCPKG_DEFAULT_TRIPLET: 'x86-windows-static'
|
||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
||||
CMAKE_GENERATOR_PLATFORM: Win32
|
||||
@ -99,6 +100,7 @@ jobs:
|
||||
BuildArgs: '-v --parallel 8'
|
||||
Win_x64_with_unit_test_winHttp:
|
||||
Pool: azsdk-pool-mms-win-2019-general
|
||||
VcpkgInstall: 'openssl'
|
||||
OSVmImage: MMS2019
|
||||
VCPKG_DEFAULT_TRIPLET: 'x64-windows-static'
|
||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
||||
|
||||
@ -32,6 +32,7 @@ set(
|
||||
AZURE_ATTESTATION_HEADER
|
||||
inc/azure/attestation/dll_import_export.hpp
|
||||
inc/azure/attestation/attestation_client.hpp
|
||||
inc/azure/attestation/attestation_administration_client.hpp
|
||||
inc/azure/attestation.hpp
|
||||
inc/azure/attestation/attestation_client_models.hpp
|
||||
inc/azure/attestation/attestation_client_options.hpp
|
||||
@ -48,6 +49,7 @@ set(
|
||||
set(
|
||||
AZURE_ATTESTATION_SOURCE
|
||||
src/attestation_client.cpp
|
||||
src/attestation_administration_client.cpp
|
||||
src/attestation_client_options.cpp
|
||||
src/attestation_common_request.cpp
|
||||
src/private/attestation_deserializers_private.cpp
|
||||
|
||||
@ -1,51 +1,370 @@
|
||||
# Azure Attestation Package client library for C++
|
||||
|
||||
Azure Template Package client library for C++ (`azure-security-attestation`) matches necessary patterns that the development team has established to create a unified SDK written in the C++ programming language. These libraries follow the Azure SDK Design Guidelines for C++.
|
||||
Microsoft Azure Attestation is a unified solution for remotely verifying the trustworthiness of a platform and integrity of the binaries running inside it. The service supports attestation of the platforms backed by Trusted Platform Modules (TPMs) alongside the ability to attest to the state of Trusted Execution Environments (TEEs) such as Intel(tm) Software Guard Extensions (SGX) enclaves and Virtualization-based Security (VBS) enclaves.
|
||||
|
||||
The library allows client libraries to expose common functionality in a consistent fashion. Once you learn how to use these APIs in one client library, you will know how to use them in other client libraries.
|
||||
Attestation is a process for demonstrating that software binaries were properly instantiated on a trusted platform. Remote
|
||||
relying parties can then gain confidence that only such intended software is running on trusted hardware.
|
||||
|
||||
Azure Attestation enables cutting-edge security paradigms such as Azure Confidential computing and Intelligent Edge protection. Customers have been requesting the ability to independently verify the location of a machine, the posture of a virtual machine (VM) on that machine, and the environment within which enclaves are running on that VM. Azure Attestation will empower these and many additional customer requests.
|
||||
|
||||
Azure Attestation receives evidence from compute entities, turns them into a set of claims, validates them against configurable policies, and produces cryptographic proofs for claims-based applications (for example, relying parties and auditing authorities).
|
||||
|
||||
## Getting started
|
||||
|
||||
For a rich example of a well formatted readme, please check [here.](https://github.com/Azure/azure-sdk/blob/main/docs/policies/README-TEMPLATE.md) In addition, this is an [example readme](https://github.com/Azure/azure-sdk/blob/main/docs/policies/README-EXAMPLE.md) that should be emulated. Note that the top-level sections in this template align with that of the [template.](https://github.com/Azure/azure-sdk/blob/main/docs/policies/README-TEMPLATE.md)
|
||||
For the best development experience, we recommend that developers use the [CMake projects in Visual Studio](https://docs.microsoft.com/cpp/build/cmake-projects-in-visual-studio?view=vs-2019) to view and build the source code together with its dependencies.
|
||||
|
||||
# Key concepts
|
||||
### Prerequisites
|
||||
|
||||
Bullet point list of your library's main concepts.
|
||||
- [Azure Subscription][azure_subscription]. Sign up for a [free trial](https://azure.microsoft.com/pricing/free-trial/) or use your [MSDN subscriber benefits](https://azure.microsoft.com/pricing/member-offers/msdn-benefits-details/).
|
||||
- An existing [Azure Attestation instance][azure_attestation]. If you need to create an attestation instance, you can use the [Azure Cloud Shell][azure_cloud_shell] to create one with this Azure CLI command. Replace `<your-resource-group-name>` and `<your-instance-name>` with your own, unique names:
|
||||
|
||||
# Examples
|
||||
```bash
|
||||
az attestation create --resource-group <your-resource-group-name> --name <your-service instance name>
|
||||
```
|
||||
|
||||
Examples of some of the key concepts for your library.
|
||||
### Download & Install
|
||||
|
||||
# Troubleshooting
|
||||
### Install Dependencies
|
||||
|
||||
Running into issues? This section should contain details as to what to do there.
|
||||
#### Windows
|
||||
|
||||
# Next steps
|
||||
On Windows, dependencies are managed by [vcpkg](https://github.com/microsoft/vcpkg). You can reference the [Quick Start](https://github.com/microsoft/vcpkg#quick-start-windows) to quickly set yourself up.
|
||||
After Vcpkg is initialized and bootstrapped, you can install the dependencies:
|
||||
|
||||
More sample code should go here, along with links out to the appropriate example tests.
|
||||
```BatchFile
|
||||
vcpkg.exe install curl:x64-windows-static
|
||||
vcpkg.exe install openssl:x64-windows-static
|
||||
```
|
||||
|
||||
#### POSIX Platforms
|
||||
|
||||
You can use the package manager on different POSIX platforms to install the dependencies. The dependencies to be installed are:
|
||||
|
||||
- CMake 3.13.0 or higher.
|
||||
- OpenSSL.
|
||||
- libcurl.
|
||||
|
||||
### Build from Source
|
||||
|
||||
First, download the repository to your local folder:
|
||||
|
||||
```BatchFile
|
||||
git clone https://github.com/Azure/azure-sdk-for-cpp.git
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
##### Use CMake to generate the solution file
|
||||
|
||||
In a new folder you created under the root directory:
|
||||
|
||||
```BatchFile
|
||||
cmake .. -A x64 -DCMAKE_TOOLCHAIN_FILE=<YOUR_VCPKG_INSTALL_DIR>/scripts/buildsystems/vcpkg.cmake
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
The built library will be in `.\sdk\<ProjectDir>\<Configuration>\` respectively for Azure Core and Azure Attestation. e.g. `azure_core.lib` will be in `.\sdk\core\azure-core\Debug` for debug configuration.
|
||||
|
||||
##### Use Visual Studio's Open by folder feature
|
||||
|
||||
Open the root folder of the library with Visual Studio's Open folder feature.
|
||||
|
||||
If Vcpkg is not globally integrated, then you need to open CMakeSettings.json and change the `Make toolchain file to be <YOUR_VCPKG_INSTALL_DIR>/scripts/buildsystems/vcpkg.cmake` and save.
|
||||
Then you can build Azure Storage libraries by selecting the target in Visual Studio, or simply build all.
|
||||
The libraries will be in `<ProjectRoot>\out\build\<Configuration>\sdk\<LibraryName>` respectively.
|
||||
|
||||
#### POSIX Platforms
|
||||
|
||||
You can run the following command in a new folder created under the downloaded code's root folder to build the code.
|
||||
|
||||
```bash
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
Then you can consume the built library with the header files.
|
||||
make/ninja install is work in progress.
|
||||
|
||||
### Via vcpkg
|
||||
|
||||
The easiest way to acquire the C++ SDK is leveraging vcpkg package manager. See the corresponding [Azure SDK for C++ readme section][azsdk_vcpkg_install].
|
||||
|
||||
To install Azure Storage packages via vcpkg:
|
||||
|
||||
```cmd
|
||||
> vcpkg install azure-security-attestation-cpp
|
||||
```
|
||||
|
||||
Then, use in your CMake file:
|
||||
|
||||
```CMake
|
||||
find_package(azure-security-attestation-cpp CONFIG REQUIRED)
|
||||
target_link_libraries(<your project name> PRIVATE Azure::azure-security-attestation)
|
||||
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [Azure Core SDK](https://github.com/Azure/azure-sdk-for-cpp/blob/main/README.md)
|
||||
- OpenSSL
|
||||
|
||||
### Authenticate the client
|
||||
|
||||
Many of the APIs supported by the Azure Attestation service require authentication (some do not, if an API does not require
|
||||
authentication, the documentation for that API will reflect that the attestation service instance does not require authentication).
|
||||
|
||||
To interact with the authenticated APIs supported by the Azure Attestation service, your client must present an Azure Active Directory bearer token to the service.
|
||||
|
||||
The simplest way of providing a bearer token is to use the `DefaultAzureCredential` authentication method by providing client secret credentials is being used in this getting started section, but you can find more ways to authenticate with [azure-identity][azure_identity].
|
||||
|
||||
## Key concepts
|
||||
|
||||
The Microsoft Azure Attestation service runs in two separate modes: "Isolated" and "AAD". When the service is running in "Isolated" mode, the customer needs to
|
||||
provide additional information beyond their authentication credentials to verify that they are authorized to modify the state of an attestation instance.
|
||||
|
||||
There are four major client types provided in this SDK:
|
||||
|
||||
- [SGX and TPM enclave attestation.](#attestation)
|
||||
- [MAA Attestation Token signing certificate discovery and validation.](#attestation-token-signing-certificate-discovery-and-validation)
|
||||
- [Attestation Policy management.](#policy-management)
|
||||
- [Attestation policy management certificate management](#policy-management-certificate-management) (yes, policy management management).
|
||||
|
||||
Each attestation instance operates in one of three separate modes of operation:
|
||||
|
||||
- Isolated mode.
|
||||
- AAD mode.
|
||||
- Shared mode.
|
||||
|
||||
### Isolated Mode Attestation Instances
|
||||
|
||||
In "Isolated" mode, the customer indicates that they want to ensure that Microsoft administrators cannot influence the inputs or outputs of an attestation service instance. When the attestation service instance is running in Isolated mode, the customer is expected to provide additional proof that they are authorized to make changes to the attestation service instance.
|
||||
|
||||
### AAD Mode Attestation Instances
|
||||
|
||||
In "AAD" mode, access to the service is controlled solely by Azure Role Based Access Control. When the
|
||||
|
||||
### Shared Mode Attestation Instances
|
||||
|
||||
Each region in which the Microsoft Azure Attestation service is available supports a "shared" instance, which
|
||||
can be used to attest SGX enclaves which only need verification against the azure baseline (there are no policies applied to the
|
||||
shared instance).
|
||||
|
||||
The following APIs are available in the shared instance:
|
||||
|
||||
- AttestSgxEnclave
|
||||
- AttestOpenEnclave
|
||||
- GetAttestationPolicy
|
||||
- GetPolicyManagementCertificates (always returns an empty set)
|
||||
|
||||
The following APIs are not available in the shared instance:
|
||||
|
||||
- AttestTPMEnclave
|
||||
- SetAttestationPolicy
|
||||
- ResetAttestationPolicy
|
||||
- AddPolicyManagementCertificate
|
||||
- RemovePolicyManagementCertificate
|
||||
|
||||
The APIs available in the shared instance do not require AAD authentication.
|
||||
|
||||
### Attestation
|
||||
|
||||
SGX or TPM attestation is the process of validating evidence collected from a trusted execution environment to ensure that it
|
||||
meets both the Azure baseline for that environment and customer defined policies applied to that environment.
|
||||
|
||||
#### Attestation token signing certificate discovery and validation
|
||||
|
||||
Most responses from the MAA service are expressed in the form of a JSON Web Token. This token will be signed by a signing certificate
|
||||
issued by the MAA service for the specified instance. If the MAA service instance is running in a region where the service runs in an SGX enclave, then
|
||||
the certificate issued by the server can be verified using the [oe_verify_attestation_certificate() API](https://openenclave.github.io/openenclave/api/enclave_8h_a3b75c5638360adca181a0d945b45ad86.html).
|
||||
|
||||
### Policy Management
|
||||
|
||||
Each attestation service instance has a policy applied to it which defines additional criteria which the customer has defined.
|
||||
|
||||
For more information on attestation policies, see [Attestation Policy](https://docs.microsoft.com/azure/attestation/author-sign-policy)
|
||||
|
||||
### Policy Management certificate management
|
||||
|
||||
When an attestation instance is running in "Isolated" mode, the customer who created the instance will have provided
|
||||
a policy management certificate at the time the instance is created. All policy modification operations require that the customer sign
|
||||
the policy data with one of the existing policy management certificates. The Policy Management Certificate Management APIs enable
|
||||
clients to add, remove or enumerate the policy management certificates.
|
||||
|
||||
### Examples
|
||||
|
||||
- [Instantiate a synchronous attestation client](#create-a-synchronous-attestation-client)
|
||||
- [Retrieve token validation certificates](#retrieve-token-certificates)
|
||||
- [Attest an SGX enclave](#attest-an-sgx-enclave)
|
||||
- [Instantiate a synchronous administrative client](#create-a-synchronous-administrative-client)
|
||||
- [Get attestation policy](#retrieve-current-attestation-policy-for-openenclave)
|
||||
- [Set unsigned attestation policy](#set-unsigned-attestation-policy-aad-clients-only)
|
||||
- [Set signed attestation policy](#set-signed-attestation-policy)
|
||||
- [List policy management certificates](#list-attestation-signing-certificates)
|
||||
- [Add policy management certificate](#add-attestation-signing-certificate)
|
||||
|
||||
#### Create a synchronous attestation client
|
||||
|
||||
The `AttestationClientBuilder` class is used to create instances of the attestation client:
|
||||
|
||||
```cpp readme-sample-create-synchronous-client
|
||||
```
|
||||
|
||||
#### Retrieve Token Certificates
|
||||
|
||||
Use `listAttestationSigners` to retrieve the set of certificates, which can be used to validate the token returned from the attestation service.
|
||||
Normally, this information is not required as the attestation SDK will perform the validation as a part of the interaction with the
|
||||
attestation service, however the APIs are provided for completeness and to facilitate customer's independently validating
|
||||
attestation results.
|
||||
|
||||
```cpp readme-sample-getSigningCertificates
|
||||
```
|
||||
|
||||
#### Attest an SGX Enclave
|
||||
|
||||
Use the `AttestSgxEnclave` method to attest an SGX enclave.
|
||||
|
||||
```cpp readme-sample-attest-sgx-enclave
|
||||
```
|
||||
|
||||
#### Create a synchronous administrative client
|
||||
|
||||
All administrative clients are authenticated.
|
||||
|
||||
```cpp readme-sample-create-admin-client
|
||||
AttestationAdministrationClientBuilder attestationBuilder = new AttestationAdministrationClientBuilder();
|
||||
// Note that the "policy" calls require authentication.
|
||||
AttestationAdministrationClient client = attestationBuilder
|
||||
.endpoint(endpoint)
|
||||
.credential(new DefaultAzureCredentialBuilder().build())
|
||||
.buildClient();
|
||||
```
|
||||
|
||||
#### Retrieve current attestation policy for OpenEnclave
|
||||
|
||||
Use the `GetAttestationPolicy` API to retrieve the current attestation policy for a given TEE.
|
||||
|
||||
```java readme-sample-getCurrentPolicy
|
||||
String currentPolicy = client.getAttestationPolicy(AttestationType.OPEN_ENCLAVE);
|
||||
System.out.printf("Current policy for OpenEnclave is: %s\n", currentPolicy);
|
||||
```
|
||||
|
||||
#### Set unsigned attestation policy (AAD clients only)
|
||||
|
||||
When an attestation instance is in AAD mode, the caller can use a convenience method to set an unsigned attestation
|
||||
policy on the instance.
|
||||
|
||||
```java readme-sample-set-unsigned-policy
|
||||
// Set the listed policy on an attestation instance. Please note that this particular policy will deny all
|
||||
// attestation requests and should not be used in production.
|
||||
PolicyResult policyResult = client.setAttestationPolicy(AttestationType.OPEN_ENCLAVE,
|
||||
"version=1.0; authorizationrules{=> deny();}; issuancerules{};");
|
||||
System.out.printf("Policy set for OpenEnclave result: %s\n", policyResult.getPolicyResolution());
|
||||
```
|
||||
|
||||
#### Set signed attestation policy
|
||||
|
||||
For isolated mode attestation instances, the set or reset policy request must be signed using the key that is associated
|
||||
with the attestation signing certificates configured on the attestation instance.
|
||||
|
||||
```java readme-sample-set-signed-policy
|
||||
// Set the listed policy on an attestation instance using a signed policy token.
|
||||
PolicyResult policyResult = client.setAttestationPolicy(AttestationType.SGX_ENCLAVE,
|
||||
new AttestationPolicySetOptions()
|
||||
.setAttestationPolicy("version=1.0; authorizationrules{=> permit();}; issuancerules{};")
|
||||
.setAttestationSigner(new AttestationSigningKey(certificate, privateKey)));
|
||||
System.out.printf("Policy set for Sgx result: %s\n", policyResult.getPolicyResolution());
|
||||
```
|
||||
|
||||
#### List attestation signing certificates
|
||||
|
||||
When an attestation instance is in `Isolated` mode, the policy APIs need additional proof of authorization. This proof is
|
||||
provided via the `AttestationSigningKey` parameter passed into the set and reset policy APIs.
|
||||
|
||||
Each `Isolated` mode instance has a set of certificates, which determine whether a caller has the authority to set an
|
||||
attestation policy. When an attestation policy is set, the client presents a signed "token" to the service, which is signed
|
||||
by the key in the `AttestationSigningKey`. The signed token, including the certificate in the `AttestationSigningKey` is
|
||||
sent to the attestation service, which verifies that the token was signed with the private key corresponding to the
|
||||
public key in the token. The set or reset policy operation will only succeed if the certificate in the token is one of
|
||||
the policy management tokens. This interaction ensures that the client is in possession of the private key associated with
|
||||
one of the policy management certificates and is thus authorized to perform the operation.
|
||||
|
||||
```java readme-sample-listPolicyCertificates
|
||||
AttestationSignerCollection signers = client.listPolicyManagementCertificates();
|
||||
System.out.printf("Instance %s contains %d signers.\n", endpoint, signers.getAttestationSigners().size());
|
||||
for (AttestationSigner signer : signers.getAttestationSigners()) {
|
||||
System.out.printf("Certificate Subject: %s", signer.getCertificates().get(0).getSubjectDN().toString());
|
||||
}
|
||||
```
|
||||
|
||||
#### Add attestation signing certificate
|
||||
|
||||
Adds a new certificate to the set of policy management certificates. The request to add the policy management certificate
|
||||
must be signed with the private key associated with one of the existing policy management certificates (this ensures that
|
||||
the caller is authorized to update the set of policy certificates).
|
||||
|
||||
Note: Adding the same certificate twice is not considered an error - if the certificate is already present, the addition is
|
||||
ignored (this possibly surprising behavior is there because retries could cause the addition to be executed multiple times)
|
||||
|
||||
```java readme-sample-addPolicyManagementCertificate
|
||||
System.out.printf("Adding new certificate %s\n", certificateToAdd.getSubjectDN().toString());
|
||||
PolicyCertificatesModificationResult modificationResult = client.addPolicyManagementCertificate(
|
||||
new PolicyManagementCertificateOptions(certificateToAdd,
|
||||
new AttestationSigningKey(isolatedCertificate, isolatedKey)));
|
||||
System.out.printf("Updated policy certificate, certificate add result: %s\n",
|
||||
modificationResult.getCertificateResolution());
|
||||
System.out.printf("Added certificate thumbprint: %s\n", modificationResult.getCertificateThumbprint());
|
||||
```
|
||||
|
||||
#### Remove attestation signing certificate
|
||||
|
||||
Removes a certificate from the set of policy management certificates. The request to remove the policy management certificate
|
||||
must be signed with the private key associated with one of the existing policy management certificates (this ensures that
|
||||
the caller is authorized to update the set of policy certificates).
|
||||
|
||||
Note: Removing a non-existent certificate is not considered an error - if the certificate is not present, the removal is
|
||||
ignored (this possibly surprising behavior is there because retries could cause the removal to be executed multiple times)
|
||||
|
||||
```java readme-sample-removePolicyManagementCertificate
|
||||
System.out.printf("Removing existing certificate %s\n", certificateToRemove.getSubjectDN().toString());
|
||||
PolicyCertificatesModificationResult modificationResult = client.deletePolicyManagementCertificate(
|
||||
new PolicyManagementCertificateOptions(certificateToRemove,
|
||||
new AttestationSigningKey(isolatedCertificate, isolatedKey)));
|
||||
System.out.printf("Updated policy certificate, certificate remove result: %s\n",
|
||||
modificationResult.getCertificateResolution());
|
||||
System.out.printf("Removed certificate thumbprint: %s\n", modificationResult.getCertificateThumbprint());
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Troubleshooting information for the MAA service can be found [here](https://docs.microsoft.com/azure/attestation/troubleshoot-guide)
|
||||
|
||||
## Next steps
|
||||
|
||||
For more information about the Microsoft Azure Attestation service, please see our [documentation page](https://docs.microsoft.com/azure/attestation/).
|
||||
|
||||
## Contributing
|
||||
|
||||
For details on contributing to this repository, see the [contributing guide][azure_sdk_for_cpp_contributing].
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor
|
||||
License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your
|
||||
contribution. For details, visit <https://cla.microsoft.com>.
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate
|
||||
the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to
|
||||
do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
### Additional Helpful Links for Contributors
|
||||
|
||||
Many people all over the world have helped make this project better. You'll want to check out:
|
||||
|
||||
* [What are some good first issues for new contributors to the repo?](https://github.com/azure/azure-sdk-for-cpp/issues?q=is%3Aopen+is%3Aissue+label%3A%22up+for+grabs%22)
|
||||
* [How to build and test your change][azure_sdk_for_cpp_contributing_developer_guide]
|
||||
* [How you can make a change happen!][azure_sdk_for_cpp_contributing_pull_requests]
|
||||
* Frequently Asked Questions (FAQ) and Conceptual Topics in the detailed [Azure SDK for C++ wiki](https://github.com/azure/azure-sdk-for-cpp/wiki).
|
||||
- [What are some good first issues for new contributors to the repo?](https://github.com/azure/azure-sdk-for-cpp/issues?q=is%3Aopen+is%3Aissue+label%3A%22up+for+grabs%22)
|
||||
- [How to build and test your change][azure_sdk_for_cpp_contributing_developer_guide]
|
||||
- [How you can make a change happen!][azure_sdk_for_cpp_contributing_pull_requests]
|
||||
- Frequently Asked Questions (FAQ) and Conceptual Topics in the detailed [Azure SDK for C++ wiki](https://github.com/azure/azure-sdk-for-cpp/wiki).
|
||||
|
||||
<!-- ### Community-->
|
||||
### Reporting security issues and security bugs
|
||||
@ -55,8 +374,16 @@ Security issues and bugs should be reported privately, via email, to the Microso
|
||||
### License
|
||||
|
||||
Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk-for-cpp/blob/main/LICENSE.txt) license.
|
||||
|
||||
<!-- LINKS -->
|
||||
[style-guide-msft]: https://docs.microsoft.com/style-guide/capitalization
|
||||
[azure_attestation]: https://docs.microsoft.com/azure/attestation
|
||||
[azure_identity]: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/identity/azure-identity
|
||||
[azure_subscription]: https://azure.microsoft.com/
|
||||
[azure_cli]: https://docs.microsoft.com/cli/azure
|
||||
[rest_api]: https://docs.microsoft.com/rest/api/attestation/
|
||||
[azure_create_application_in_portal]: https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal
|
||||
[azure_cloud_shell]: https://shell.azure.com/bash
|
||||
[microsoft_code_of_conduct]: https://opensource.microsoft.com/codeofconduct/
|
||||
[azure_sdk_for_cpp_contributing]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md
|
||||
[azure_sdk_for_cpp_contributing_developer_guide]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#developer-guide
|
||||
[azure_sdk_for_cpp_contributing_pull_requests]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#pull-requests
|
||||
@ -68,3 +395,5 @@ Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk
|
||||
[c_compiler]: https://visualstudio.microsoft.com/vs/features/cplusplus/
|
||||
[cloud_shell]: https://docs.microsoft.com/azure/cloud-shell/overview
|
||||
[cloud_shell_bash]: https://shell.azure.com/bash
|
||||
|
||||

|
||||
|
||||
@ -8,5 +8,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "attestation/attestation_administration_client.hpp"
|
||||
#include "attestation/attestation_client.hpp"
|
||||
#include "attestation/dll_import_export.hpp"
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "azure/attestation/attestation_client_models.hpp"
|
||||
#include "azure/attestation/attestation_client_options.hpp"
|
||||
#include <azure/core/context.hpp>
|
||||
#include <azure/core/url.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace Azure { namespace Core { namespace Http { namespace _internal {
|
||||
class HttpPipeline;
|
||||
}}}} // namespace Azure::Core::Http::_internal
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation {
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief The AttestationAdministrationClient implements the functionality required by the
|
||||
* "Administration" family of attestation service APIs.
|
||||
*
|
||||
* @note: Attestation administration APIs cannot be used on shared attestation service instances.
|
||||
*
|
||||
* @details
|
||||
* The Administration family of APIs provide APIs to manage:
|
||||
*
|
||||
* - Attestation policies.
|
||||
* - Attestation policy management certificates (Isolated attestation service instances only).
|
||||
*
|
||||
* There are three flavors of attestation service instances:
|
||||
* -# Shared Mode
|
||||
* -# AAD Mode
|
||||
* -# Isolated Mode
|
||||
*
|
||||
* Shared mode attestation service instances do not allow any administration actions at all. They
|
||||
* exist to allow customers to perform attestation operations without requiring any
|
||||
* customizations.
|
||||
*
|
||||
* AAD Mode instances allow customers to modify attestation policies. When the attestation
|
||||
* instance is in AAD mode, the creator of the instance indicates that they trust ARM RBAC and
|
||||
* Microsoft AAD to validate client connections to the service. As such, additional proof of
|
||||
* authorization is not required for administrative operations.
|
||||
*
|
||||
*/
|
||||
class AttestationAdministrationClient final {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*
|
||||
*/
|
||||
virtual ~AttestationAdministrationClient() = default;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
explicit AttestationAdministrationClient(
|
||||
std::string const& endpoint,
|
||||
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
|
||||
AttestationAdministrationClientOptions const& options
|
||||
= AttestationAdministrationClientOptions());
|
||||
|
||||
/**
|
||||
* @brief Returns the API version the client was configured with.
|
||||
*
|
||||
* @returns The API version used when communicating with the attestation service.
|
||||
*/
|
||||
std::string const& ClientVersion() const { return m_apiVersion; }
|
||||
|
||||
/**
|
||||
* @brief Construct a new Attestation Administration Client object from another attestation
|
||||
* administration client.
|
||||
*
|
||||
* @param attestationClient An existing attestation client.
|
||||
*/
|
||||
explicit AttestationAdministrationClient(
|
||||
AttestationAdministrationClient const& attestationClient)
|
||||
: m_endpoint(attestationClient.m_endpoint), m_apiVersion(attestationClient.m_apiVersion),
|
||||
m_pipeline(attestationClient.m_pipeline),
|
||||
m_tokenValidationOptions(attestationClient.m_tokenValidationOptions){};
|
||||
|
||||
/** @brief Retrieves the attestation policy for the specified attestation type.
|
||||
*/
|
||||
Response<Models::AttestationToken<std::string>> GetAttestationPolicy(
|
||||
Models::AttestationType const& attestationType,
|
||||
GetPolicyOptions const& options = GetPolicyOptions(),
|
||||
Azure::Core::Context const& context = Azure::Core::Context::ApplicationContext) 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;
|
||||
|
||||
mutable std::vector<Models::AttestationSigner> m_attestationSigners;
|
||||
|
||||
std::vector<Models::AttestationSigner> const& GetAttestationSigners(
|
||||
Azure::Core::Context const& context) const;
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Security::Attestation
|
||||
@ -15,102 +15,6 @@ namespace Azure { namespace Core { namespace Http { namespace _internal {
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation {
|
||||
|
||||
/** An AttestationToken represents an RFC 7519 JSON Web Token returned from the attestation
|
||||
* service with the specialized body type.
|
||||
* <typeparam name="T"></typeparam> The type which represents the body of the attestation token.
|
||||
*/
|
||||
template <typename T> class AttestationToken final {
|
||||
public:
|
||||
/**
|
||||
* @brief The full RFC 7515 JWS/JWT token returned by the attestation service.
|
||||
*/
|
||||
std::string RawToken;
|
||||
|
||||
/**
|
||||
* @brief The elements of the raw token which will be signed by the Signature.
|
||||
*/
|
||||
std::string SignedElements;
|
||||
|
||||
/**
|
||||
* @brief Signature (if present) for the attestation token.
|
||||
*/
|
||||
std::vector<uint8_t> Signature;
|
||||
|
||||
/**
|
||||
* @brief RFC 7515 header properties.
|
||||
*/
|
||||
Models::AttestationTokenHeader Header;
|
||||
|
||||
// RFC 7519 properties.
|
||||
|
||||
/**
|
||||
* The Expiration time for this attestation token.
|
||||
*
|
||||
* After this time, the token cannot be considered valid.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4'>RFC 7519
|
||||
* Section 4.1.4</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<Azure::DateTime> ExpiresOn;
|
||||
|
||||
/**
|
||||
* The time at which this token was issued.
|
||||
*
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6'>RFC 7519
|
||||
* Section 4.1.6</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<Azure::DateTime> IssuedOn;
|
||||
|
||||
/**
|
||||
* The time before which this token cannot be considered valid.
|
||||
*
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5'>RFC 7519
|
||||
* Section 4.1.5</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<Azure::DateTime> NotBefore;
|
||||
|
||||
/**
|
||||
* The issuer of this attestation token
|
||||
*
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1'>RFC 7519
|
||||
* Section 4.1.1</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> Issuer;
|
||||
|
||||
/**
|
||||
* An identifier which uniquely identifies this token.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7'>RFC 7519
|
||||
* Section 4.1.7</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> UniqueIdentifier;
|
||||
|
||||
/**
|
||||
* The subject for this attestation token.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2'>RFC 7519
|
||||
* Section 4.1.2</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> Subject;
|
||||
|
||||
/**
|
||||
* The audience for this attestation token.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3'>RFC 7519
|
||||
* Section 4.1.3</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> Audience;
|
||||
|
||||
/**
|
||||
* @brief The deserialized body of the attestation token.
|
||||
*
|
||||
*/
|
||||
T Body;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* The AttestationAsyncClient implements the functionality required by the "Attest" family of
|
||||
@ -214,17 +118,6 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
*/
|
||||
|
||||
class AttestationClient final {
|
||||
private:
|
||||
Azure::Core::Url m_endpoint;
|
||||
std::string m_apiVersion;
|
||||
std::shared_ptr<Azure::Core::Http::_internal::HttpPipeline> m_pipeline;
|
||||
AttestationTokenValidationOptions m_tokenValidationOptions;
|
||||
|
||||
mutable std::vector<Models::AttestationSigner> m_attestationSigners;
|
||||
|
||||
std::vector<Models::AttestationSigner> const& GetAttestationSigners(
|
||||
Azure::Core::Context const& context) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
@ -298,7 +191,7 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
* @returns Response<{@link AttestationToken}<{@link AttestationResult}>> - The result of the
|
||||
* attestation operation.
|
||||
*/
|
||||
Response<AttestationToken<Models::AttestationResult>> AttestSgxEnclave(
|
||||
Response<Models::AttestationToken<Models::AttestationResult>> AttestSgxEnclave(
|
||||
std::vector<uint8_t> const& sgxQuoteToAttest,
|
||||
AttestOptions options = AttestOptions(),
|
||||
Azure::Core::Context const& context = Azure::Core::Context::ApplicationContext) const;
|
||||
@ -315,10 +208,22 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
* @returns Response<AttestationToken<AttestationResult>> - The result of the attestation
|
||||
* operation
|
||||
*/
|
||||
Response<AttestationToken<Models::AttestationResult>> AttestOpenEnclave(
|
||||
Response<Models::AttestationToken<Models::AttestationResult>> AttestOpenEnclave(
|
||||
std::vector<uint8_t> const& openEnclaveReportToAttest,
|
||||
AttestOptions options = AttestOptions(),
|
||||
Azure::Core::Context const& context = Azure::Core::Context::ApplicationContext) 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;
|
||||
|
||||
mutable std::vector<Models::AttestationSigner> m_attestationSigners;
|
||||
|
||||
std::vector<Models::AttestationSigner> const& GetAttestationSigners(
|
||||
Azure::Core::Context const& context) const;
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Security::Attestation
|
||||
|
||||
@ -24,6 +24,58 @@
|
||||
// cspell: words MRSIGNER MRENCLAVE
|
||||
namespace Azure { namespace Security { namespace Attestation { namespace Models {
|
||||
|
||||
/**
|
||||
* @brief The AttestationType type represent a Trusted Execution Environment supported by
|
||||
* the attestation service.
|
||||
*
|
||||
*/
|
||||
class AttestationType final {
|
||||
private:
|
||||
std::string m_attestationType;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new AttestationType object
|
||||
*
|
||||
* @param attestationType The string attestationType used for the attestation policy operation.
|
||||
*/
|
||||
AttestationType(std::string attestationType) : m_attestationType(std::move(attestationType)) {}
|
||||
|
||||
/**
|
||||
* @brief Enable comparing the ext enum.
|
||||
*
|
||||
* @param other Another #AttestationType to be compared.
|
||||
*/
|
||||
bool operator==(AttestationType const& other) const
|
||||
{
|
||||
return m_attestationType == other.m_attestationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the #AttestationType string representation.
|
||||
*
|
||||
*/
|
||||
std::string const& ToString() const { return m_attestationType; }
|
||||
|
||||
/**
|
||||
* @brief Specifies that this should apply to SGX enclaves.
|
||||
*
|
||||
*/
|
||||
AZ_ATTESTATION_DLLEXPORT static const AttestationType SgxEnclave;
|
||||
|
||||
/**
|
||||
* @brief Specifies that this should apply to SGX enclaves using the OpenEnclave APIs.
|
||||
*
|
||||
*/
|
||||
AZ_ATTESTATION_DLLEXPORT static const AttestationType OpenEnclave;
|
||||
|
||||
/**
|
||||
* @brief Specifies that this should apply to TPM enclaves.
|
||||
*
|
||||
*/
|
||||
AZ_ATTESTATION_DLLEXPORT static const AttestationType Tpm;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Contains information about this instance of the attestation service, which can be
|
||||
* used to validate attestation service responses.
|
||||
@ -187,6 +239,102 @@ namespace Azure { namespace Security { namespace Attestation { namespace Models
|
||||
std::vector<AttestationSigner> Signers;
|
||||
};
|
||||
|
||||
/** An AttestationToken represents an RFC 7519 JSON Web Token returned from the attestation
|
||||
* service with the specialized body type.
|
||||
* <typeparam name="T"></typeparam> The type which represents the body of the attestation token.
|
||||
*/
|
||||
template <typename T> class AttestationToken final {
|
||||
public:
|
||||
/**
|
||||
* @brief The full RFC 7515 JWS/JWT token returned by the attestation service.
|
||||
*/
|
||||
std::string RawToken;
|
||||
|
||||
/**
|
||||
* @brief The elements of the raw token which will be signed by the Signature.
|
||||
*/
|
||||
std::string SignedElements;
|
||||
|
||||
/**
|
||||
* @brief Signature (if present) for the attestation token.
|
||||
*/
|
||||
std::vector<uint8_t> Signature;
|
||||
|
||||
/**
|
||||
* @brief RFC 7515 header properties.
|
||||
*/
|
||||
Models::AttestationTokenHeader Header;
|
||||
|
||||
// RFC 7519 properties.
|
||||
|
||||
/**
|
||||
* The Expiration time for this attestation token.
|
||||
*
|
||||
* After this time, the token cannot be considered valid.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4'>RFC 7519
|
||||
* Section 4.1.4</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<Azure::DateTime> ExpiresOn;
|
||||
|
||||
/**
|
||||
* The time at which this token was issued.
|
||||
*
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6'>RFC 7519
|
||||
* Section 4.1.6</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<Azure::DateTime> IssuedOn;
|
||||
|
||||
/**
|
||||
* The time before which this token cannot be considered valid.
|
||||
*
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5'>RFC 7519
|
||||
* Section 4.1.5</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<Azure::DateTime> NotBefore;
|
||||
|
||||
/**
|
||||
* The issuer of this attestation token
|
||||
*
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1'>RFC 7519
|
||||
* Section 4.1.1</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> Issuer;
|
||||
|
||||
/**
|
||||
* An identifier which uniquely identifies this token.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7'>RFC 7519
|
||||
* Section 4.1.7</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> UniqueIdentifier;
|
||||
|
||||
/**
|
||||
* The subject for this attestation token.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2'>RFC 7519
|
||||
* Section 4.1.2</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> Subject;
|
||||
|
||||
/**
|
||||
* The audience for this attestation token.
|
||||
*
|
||||
* See <a href='https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3'>RFC 7519
|
||||
* Section 4.1.3</a> for more information.
|
||||
*/
|
||||
Azure::Nullable<std::string> Audience;
|
||||
|
||||
/**
|
||||
* @brief The deserialized body of the attestation token.
|
||||
*
|
||||
*/
|
||||
T Body;
|
||||
};
|
||||
|
||||
/** @brief An AttestationResult reflects the result of an Attestation operation.
|
||||
*
|
||||
* The fields in the AttestationResult represent the claims in the AttestationToken returned
|
||||
@ -274,4 +422,73 @@ namespace Azure { namespace Security { namespace Attestation { namespace Models
|
||||
Azure::Nullable<std::string> SgxCollateral;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The PolicyModification enumeration represents the result of an attestation
|
||||
* policy modification.
|
||||
*
|
||||
*/
|
||||
class PolicyModification final {
|
||||
private:
|
||||
std::string m_policyModification;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new PolicyResolution object
|
||||
*
|
||||
* @param modification The string resolution used for the result of an attestation policy
|
||||
* operation.
|
||||
*/
|
||||
PolicyModification(std::string modification) : m_policyModification(std::move(modification)) {}
|
||||
|
||||
/**
|
||||
* @brief Enable comparing the ext enum.
|
||||
*
|
||||
* @param other Another #PolicyModification to be compared.
|
||||
*/
|
||||
bool operator==(PolicyModification const& other) const
|
||||
{
|
||||
return m_policyModification == other.m_policyModification;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the #PolicyModification string representation.
|
||||
*
|
||||
*/
|
||||
std::string const& ToString() const { return m_policyModification; }
|
||||
|
||||
/**
|
||||
* @brief Specifies that the policy object was updated.
|
||||
*
|
||||
*/
|
||||
AZ_ATTESTATION_DLLEXPORT static const PolicyModification Updated;
|
||||
|
||||
/**
|
||||
* @brief Specifies that the policy object was removed.
|
||||
*
|
||||
*/
|
||||
AZ_ATTESTATION_DLLEXPORT static const PolicyModification Removed;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Result of a SetPolicy or ResetPolicy operation.
|
||||
*/
|
||||
struct PolicyResult
|
||||
{
|
||||
/**
|
||||
* @brief Result of a modification.
|
||||
*/
|
||||
Azure::Nullable<PolicyModification> PolicyResolution;
|
||||
|
||||
/**
|
||||
* @brief The SHA256 hash of the policy object which was received by the service.
|
||||
*/
|
||||
Azure::Nullable<std::vector<uint8_t>> PolicyTokenHash;
|
||||
|
||||
/**
|
||||
* @brief A JSON Web Key containing the signer of the policy token. If not present, the token
|
||||
* was unsecured.
|
||||
*/
|
||||
Azure::Nullable<AttestationSigner> PolicySigner;
|
||||
};
|
||||
|
||||
}}}} // namespace Azure::Security::Attestation::Models
|
||||
|
||||
@ -28,7 +28,7 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
ServiceVersion(std::string version) : m_version(std::move(version)) {}
|
||||
|
||||
/**
|
||||
* @brief Enable comparing the ext enum.
|
||||
* @brief Enable comparing the extensible enum.
|
||||
*
|
||||
* @param other Another #ServiceVersion to be compared.
|
||||
*/
|
||||
@ -107,7 +107,7 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Define the options to create an SDK Keys client.
|
||||
* @brief Define the options to create an Attestation client.
|
||||
*/
|
||||
struct AttestationClientOptions final : public Azure::Core::_internal::ClientOptions
|
||||
{
|
||||
@ -129,6 +129,29 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Define the options to create an Attestation Administration client.
|
||||
*/
|
||||
struct AttestationAdministrationClientOptions final : public Azure::Core::_internal::ClientOptions
|
||||
{
|
||||
ServiceVersion Version;
|
||||
AttestationTokenValidationOptions TokenValidationOptions;
|
||||
/**
|
||||
* @brief Construct a new Attestation Client Options object.
|
||||
*
|
||||
* @param version Optional version for the client.
|
||||
* @param tokenValidationOptions Options applied when validating attestation tokens returned by
|
||||
* the service.
|
||||
*/
|
||||
AttestationAdministrationClientOptions(
|
||||
ServiceVersion version = ServiceVersion::V2020_10_01,
|
||||
AttestationTokenValidationOptions const& tokenValidationOptions = {})
|
||||
: Azure::Core::_internal::ClientOptions(), Version(version),
|
||||
TokenValidationOptions(tokenValidationOptions)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief The AttestationDataType represents how the attestation service should interpret the
|
||||
* {@link AttestOptions::RuntimeData} and {@link AttestOptions::InittimeData} fields.
|
||||
*/
|
||||
@ -145,7 +168,7 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
AttestationDataType(std::string dataType) : m_dataType(std::move(dataType)) {}
|
||||
AttestationDataType() {}
|
||||
/**
|
||||
* @brief Enable comparing the ext enum.
|
||||
* @brief Enable comparing the extensible enum.
|
||||
*
|
||||
* @param other Another AttestationDataType to be compared.
|
||||
*/
|
||||
@ -249,4 +272,16 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
std::string PemEncodedX509Certificate;
|
||||
};
|
||||
|
||||
/** @brief Parameters sent to the attestation service when retrieving an attestation policy.
|
||||
*/
|
||||
struct GetPolicyOptions final
|
||||
{
|
||||
/** @brief Specifies the options which should be used to validate the attestation token returned
|
||||
* by the attestation service.
|
||||
* @details If not provided by the caller, the token validation options
|
||||
* specified when the @{link AttestationAdministrationClient} was created will be used.
|
||||
*/
|
||||
Azure::Nullable<AttestationTokenValidationOptions> TokenValidationOptions{};
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Security::Attestation
|
||||
|
||||
@ -0,0 +1,160 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/attestation/attestation_administration_client.hpp"
|
||||
#include "azure/attestation/attestation_client.hpp"
|
||||
#include "private/attestation_client_models_private.hpp"
|
||||
#include "private/attestation_client_private.hpp"
|
||||
#include "private/attestation_common_request.hpp"
|
||||
#include "private/attestation_deserializers_private.hpp"
|
||||
#include "private/package_version.hpp"
|
||||
#include <azure/core/base64.hpp>
|
||||
#include <azure/core/http/policies/policy.hpp>
|
||||
#include <azure/core/internal/diagnostics/log.hpp>
|
||||
#include <azure/core/internal/http/pipeline.hpp>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace Azure::Security::Attestation;
|
||||
using namespace Azure::Security::Attestation::Models;
|
||||
using namespace Azure::Security::Attestation::_detail;
|
||||
using namespace Azure::Security::Attestation::Models::_detail;
|
||||
using namespace Azure::Core::Http;
|
||||
using namespace Azure::Core::Http::Policies;
|
||||
using namespace Azure::Core::Http::Policies::_internal;
|
||||
using namespace Azure::Core::Http::_internal;
|
||||
using namespace Azure::Core::Diagnostics::_internal;
|
||||
using namespace Azure::Core::Diagnostics;
|
||||
|
||||
const Models::AttestationType AttestationType::SgxEnclave("SgxEnclave");
|
||||
const Models::AttestationType AttestationType::OpenEnclave("OpenEnclave");
|
||||
const Models::AttestationType AttestationType::Tpm("Tpm");
|
||||
const Models::PolicyModification PolicyModification::Removed("Removed");
|
||||
const Models::PolicyModification PolicyModification::Updated("Updated");
|
||||
|
||||
AttestationAdministrationClient::AttestationAdministrationClient(
|
||||
std::string const& endpoint,
|
||||
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
|
||||
AttestationAdministrationClientOptions const& options)
|
||||
: m_endpoint(endpoint), m_apiVersion(options.Version.ToString()),
|
||||
m_tokenValidationOptions(options.TokenValidationOptions)
|
||||
{
|
||||
std::vector<std::unique_ptr<HttpPolicy>> perRetrypolicies;
|
||||
if (credential)
|
||||
{
|
||||
m_credentials = credential;
|
||||
Azure::Core::Credentials::TokenRequestContext const tokenContext
|
||||
= {{"https://attest.azure.net/.default"}};
|
||||
|
||||
perRetrypolicies.emplace_back(
|
||||
std::make_unique<BearerTokenAuthenticationPolicy>(credential, tokenContext));
|
||||
}
|
||||
m_apiVersion = options.Version.ToString();
|
||||
std::vector<std::unique_ptr<HttpPolicy>> perCallpolicies;
|
||||
|
||||
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
|
||||
options,
|
||||
"Attestation",
|
||||
PackageVersion::ToString(),
|
||||
std::move(perRetrypolicies),
|
||||
std::move(perCallpolicies));
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::shared_timed_mutex SharedStateLock;
|
||||
}
|
||||
|
||||
Azure::Response<Models::AttestationToken<std::string>>
|
||||
AttestationAdministrationClient::GetAttestationPolicy(
|
||||
AttestationType const& attestationType,
|
||||
GetPolicyOptions const& options,
|
||||
Azure::Core::Context const& context) const
|
||||
{
|
||||
Log::Write(
|
||||
Logger::Level::Informational,
|
||||
std::string("Get Policy for AttestationType:") + attestationType.ToString());
|
||||
|
||||
auto request = AttestationCommonRequest::CreateRequest(
|
||||
m_endpoint,
|
||||
m_apiVersion,
|
||||
HttpMethod::Get,
|
||||
{"policies/" + attestationType.ToString()},
|
||||
nullptr);
|
||||
|
||||
// Send the request to the service.
|
||||
auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
|
||||
|
||||
// Deserialize the Service response token and return the JSON web token returned by the
|
||||
// service.
|
||||
std::string responseToken = AttestationServiceTokenResponseSerializer::Deserialize(response);
|
||||
|
||||
// Parse the JWT returned by the attestation service.
|
||||
auto resultToken
|
||||
= AttestationTokenInternal<Models::_detail::PolicyResult, PolicyResultSerializer>(
|
||||
responseToken);
|
||||
|
||||
// Validate the token returned by the service. Use the cached attestation signers in the
|
||||
// validation.
|
||||
std::vector<AttestationSigner> const& signers = GetAttestationSigners(context);
|
||||
resultToken.ValidateToken(
|
||||
options.TokenValidationOptions ? options.TokenValidationOptions.Value()
|
||||
: this->m_tokenValidationOptions,
|
||||
signers);
|
||||
|
||||
// Extract the underlying policy token from the response.
|
||||
std::string policyTokenValue
|
||||
= static_cast<AttestationToken<Models::_detail::PolicyResult>>(resultToken)
|
||||
.Body.PolicyToken.Value();
|
||||
|
||||
// TPM policies are empty by default, at least in our test instances, so handle the empty policy
|
||||
// token case.
|
||||
auto policyTokenI
|
||||
= AttestationTokenInternal<StoredAttestationPolicy, StoredAttestationPolicySerializer>(
|
||||
policyTokenValue);
|
||||
AttestationToken<StoredAttestationPolicy> policyToken(policyTokenI);
|
||||
std::string returnPolicy;
|
||||
if (policyToken.Body.AttestationPolicy)
|
||||
{
|
||||
std::vector<uint8_t> policyUtf8 = policyToken.Body.AttestationPolicy.Value();
|
||||
returnPolicy = std::string(policyUtf8.begin(), policyUtf8.end());
|
||||
}
|
||||
|
||||
// Construct a token whose body is the policy, but whose token is the response from the
|
||||
// service.
|
||||
auto returnedToken = AttestationTokenInternal<std::string>(responseToken, returnPolicy);
|
||||
return Response<AttestationToken<std::string>>(returnedToken, std::move(response));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the attestation signers to validate the attestation token returned from the
|
||||
* service.
|
||||
*
|
||||
* @details Validating attestation tokens returned by the attestation service requires a set of
|
||||
* possible signers for the attestation token. Retrieving this can take a significant amount of time
|
||||
* (tens or hundreds of milliseconds), so we cache the results for the lifetime of this client.
|
||||
*
|
||||
* @param context Client context for the request to the service.
|
||||
* @return std::vector<AttestationSigner> const& Returns a reference to the private member filled in
|
||||
* with the signers returned by the service.
|
||||
*/
|
||||
std::vector<AttestationSigner> const& AttestationAdministrationClient::GetAttestationSigners(
|
||||
Azure::Core::Context const& context) const
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> stateLock(SharedStateLock);
|
||||
|
||||
if (m_attestationSigners.size() == 0)
|
||||
{
|
||||
auto request
|
||||
= AttestationCommonRequest::CreateRequest(m_endpoint, HttpMethod::Get, {"certs"}, nullptr);
|
||||
auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, context);
|
||||
auto jsonWebKeySet(JsonWebKeySetSerializer::Deserialize(response));
|
||||
AttestationSigningCertificateResult returnValue;
|
||||
for (const auto& jwk : jsonWebKeySet.Keys)
|
||||
{
|
||||
AttestationSignerInternal internalSigner(jwk);
|
||||
m_attestationSigners.push_back(internalSigner);
|
||||
}
|
||||
}
|
||||
return m_attestationSigners;
|
||||
}
|
||||
@ -2,12 +2,14 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/attestation/attestation_client.hpp"
|
||||
#include "azure/attestation/attestation_administration_client.hpp"
|
||||
#include "private/attestation_client_models_private.hpp"
|
||||
#include "private/attestation_client_private.hpp"
|
||||
#include "private/attestation_common_request.hpp"
|
||||
#include "private/attestation_deserializers_private.hpp"
|
||||
#include "private/package_version.hpp"
|
||||
#include <azure/core/base64.hpp>
|
||||
#include <azure/core/credentials/credentials.hpp>
|
||||
#include <azure/core/http/policies/policy.hpp>
|
||||
#include <azure/core/internal/diagnostics/log.hpp>
|
||||
#include <azure/core/internal/http/pipeline.hpp>
|
||||
@ -21,23 +23,25 @@ using namespace Azure::Security::Attestation::_detail;
|
||||
using namespace Azure::Security::Attestation::Models::_detail;
|
||||
using namespace Azure::Core::Http;
|
||||
using namespace Azure::Core::Http::Policies;
|
||||
using namespace Azure::Core::Http::Policies::_internal;
|
||||
using namespace Azure::Core::Http::_internal;
|
||||
|
||||
AttestationClient::AttestationClient(
|
||||
std::string const& endpoint,
|
||||
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
|
||||
AttestationClientOptions options)
|
||||
: m_endpoint(endpoint), m_tokenValidationOptions(options.TokenValidationOptions)
|
||||
: m_endpoint(endpoint), m_credentials(credential),
|
||||
m_tokenValidationOptions(options.TokenValidationOptions)
|
||||
{
|
||||
std::vector<std::unique_ptr<HttpPolicy>> perRetrypolicies;
|
||||
if (credential)
|
||||
{
|
||||
// Azure::Core::Credentials::TokenRequestContext const tokenContext
|
||||
// = {{_internal::UrlScope::GetScopeFromUrl(m_vaultUrl)}};
|
||||
m_credentials = credential;
|
||||
Azure::Core::Credentials::TokenRequestContext const tokenContext
|
||||
= {{"https://attest.azure.net/.default"}};
|
||||
|
||||
// perRetrypolicies.emplace_back(
|
||||
// std::make_unique<BearerTokenAuthenticationPolicy>(credential,
|
||||
// std::move(tokenContext)));
|
||||
perRetrypolicies.emplace_back(
|
||||
std::make_unique<BearerTokenAuthenticationPolicy>(credential, tokenContext));
|
||||
}
|
||||
m_apiVersion = options.Version.ToString();
|
||||
std::vector<std::unique_ptr<HttpPolicy>> perCallpolicies;
|
||||
|
||||
@ -8,4 +8,5 @@ namespace Azure { namespace Security { namespace Attestation {
|
||||
|
||||
const AttestationDataType AttestationDataType ::Binary("Binary");
|
||||
const AttestationDataType AttestationDataType::Json("Json");
|
||||
|
||||
}}} // namespace Azure::Security::Attestation
|
||||
|
||||
@ -241,4 +241,39 @@ namespace Azure {
|
||||
Azure::Nullable<std::string> Nonce;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Result of a GetPolicy, SetPolicy, or ResetPolicy operation.
|
||||
*/
|
||||
struct PolicyResult
|
||||
{
|
||||
/**
|
||||
* @brief Result of a modification.
|
||||
*/
|
||||
Azure::Nullable<std::string> PolicyResolution;
|
||||
|
||||
/**
|
||||
* @brief The SHA256 hash of the policy object which was received by the service.
|
||||
*/
|
||||
Azure::Nullable<std::string> PolicyTokenHash;
|
||||
/**
|
||||
* @brief A JSON Web Key containing the signer of the policy token.
|
||||
*/
|
||||
Azure::Nullable<JsonWebKey> PolicySigner;
|
||||
/**
|
||||
* @brief The policy token returned by the service.
|
||||
*/
|
||||
Azure::Nullable<std::string> PolicyToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A StoredAttestationPolicy is a JWS object which represents a (possibly signed)
|
||||
* attestation policy received by the attestation service.
|
||||
*/
|
||||
struct StoredAttestationPolicy
|
||||
{
|
||||
/** @brief UTF-8 encoded representation of the attestation policy.
|
||||
*/
|
||||
Azure::Nullable<std::vector<uint8_t>> AttestationPolicy;
|
||||
};
|
||||
|
||||
}}}}} // namespace Azure::Security::Attestation::Models::_detail
|
||||
|
||||
@ -28,9 +28,17 @@
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation { namespace _detail {
|
||||
|
||||
template <class T, typename TDeserializer> class AttestationTokenInternal {
|
||||
template <class T> class EmptyDeserializer {
|
||||
public:
|
||||
static std::string Deserialize(Azure::Core::Json::_internal::json const&)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class TDeserializer = EmptyDeserializer<T>> class AttestationTokenInternal {
|
||||
private:
|
||||
AttestationToken<T> m_token;
|
||||
Models::AttestationToken<T> m_token;
|
||||
|
||||
/**
|
||||
* @brief Validate the time elements in a JSON Web token as controlled by the provided
|
||||
@ -211,7 +219,9 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
|
||||
*
|
||||
* @param jwt - the JSON Web Token/JSON Web Signature to be parsed.
|
||||
*/
|
||||
AttestationTokenInternal(std::string const& jwt)
|
||||
AttestationTokenInternal(
|
||||
std::string const& jwt,
|
||||
Azure::Nullable<T> preferredBody = Azure::Nullable<T>())
|
||||
{
|
||||
m_token.RawToken = jwt;
|
||||
|
||||
@ -259,35 +269,44 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
|
||||
|
||||
// Now add the encoded body to the signed elements.
|
||||
m_token.SignedElements += body;
|
||||
if (!body.empty())
|
||||
{
|
||||
auto jsonBody(Azure::Core::Json::_internal::json::parse(
|
||||
Azure::Core::_internal::Base64Url::Base64UrlDecode(body)));
|
||||
|
||||
auto jsonBody(Azure::Core::Json::_internal::json::parse(
|
||||
Azure::Core::_internal::Base64Url::Base64UrlDecode(body)));
|
||||
|
||||
// Parse the RFC 7519 JSON Web Token body properties.
|
||||
// Note that if this is a JWS, these properties will NOT be present.
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
|
||||
m_token.ExpiresOn,
|
||||
jsonBody,
|
||||
"exp",
|
||||
Azure::Core::_internal::PosixTimeConverter::PosixTimeToDateTime);
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
|
||||
m_token.IssuedOn,
|
||||
jsonBody,
|
||||
"iat",
|
||||
Azure::Core::_internal::PosixTimeConverter::PosixTimeToDateTime);
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
|
||||
m_token.NotBefore,
|
||||
jsonBody,
|
||||
"nbf",
|
||||
Azure::Core::_internal::PosixTimeConverter::PosixTimeToDateTime);
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(m_token.Issuer, jsonBody, "iss");
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(m_token.Subject, jsonBody, "sub");
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(m_token.Audience, jsonBody, "aud");
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(
|
||||
m_token.UniqueIdentifier, jsonBody, "jti");
|
||||
|
||||
m_token.Body = TDeserializer::Deserialize(jsonBody);
|
||||
// Parse the RFC 7519 JSON Web Token body properties.
|
||||
// Note that if this is a JWS, these properties will NOT be present.
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
|
||||
m_token.ExpiresOn,
|
||||
jsonBody,
|
||||
"exp",
|
||||
Azure::Core::_internal::PosixTimeConverter::PosixTimeToDateTime);
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
|
||||
m_token.IssuedOn,
|
||||
jsonBody,
|
||||
"iat",
|
||||
Azure::Core::_internal::PosixTimeConverter::PosixTimeToDateTime);
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
|
||||
m_token.NotBefore,
|
||||
jsonBody,
|
||||
"nbf",
|
||||
Azure::Core::_internal::PosixTimeConverter::PosixTimeToDateTime);
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(m_token.Issuer, jsonBody, "iss");
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(m_token.Subject, jsonBody, "sub");
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(
|
||||
m_token.Audience, jsonBody, "aud");
|
||||
Azure::Core::Json::_internal::JsonOptional::SetIfExists(
|
||||
m_token.UniqueIdentifier, jsonBody, "jti");
|
||||
|
||||
if (preferredBody)
|
||||
{
|
||||
m_token.Body = preferredBody.Value();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_token.Body = TDeserializer::Deserialize(jsonBody);
|
||||
}
|
||||
}
|
||||
// Remove the body from the token, we've remembered its contents.
|
||||
token.erase(0, bodyIndex + 1);
|
||||
}
|
||||
@ -406,6 +425,6 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
|
||||
ValidateTokenIssuer(validationOptions);
|
||||
}
|
||||
|
||||
operator AttestationToken<T>&&() { return std::move(m_token); }
|
||||
operator Models::AttestationToken<T>&&() { return std::move(m_token); }
|
||||
};
|
||||
}}}} // namespace Azure::Security::Attestation::_detail
|
||||
|
||||
@ -273,4 +273,31 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
Models::_detail::PolicyResult PolicyResultSerializer::Deserialize(
|
||||
Azure::Core::Json::_internal::json const& parsedResult)
|
||||
{
|
||||
Models::_detail::PolicyResult returnValue;
|
||||
JsonOptional::SetIfExists(returnValue.PolicyResolution, parsedResult, "x-ms-policy-result");
|
||||
JsonOptional::SetIfExists(returnValue.PolicyTokenHash, parsedResult, "x-ms-policy-token-hash");
|
||||
if (parsedResult.contains("x-ms-policy-signer"))
|
||||
{
|
||||
returnValue.PolicySigner
|
||||
= JsonWebKeySerializer::Deserialize(parsedResult["x-ms-policy-signer"]);
|
||||
}
|
||||
JsonOptional::SetIfExists(returnValue.PolicyToken, parsedResult, "x-ms-policy");
|
||||
return returnValue;
|
||||
}
|
||||
Models::_detail::StoredAttestationPolicy StoredAttestationPolicySerializer::Deserialize(
|
||||
Azure::Core::Json::_internal::json const& parsedResult)
|
||||
{
|
||||
Models::_detail::StoredAttestationPolicy returnValue;
|
||||
JsonOptional::SetIfExists<std::string, std::vector<uint8_t>>(
|
||||
returnValue.AttestationPolicy,
|
||||
parsedResult,
|
||||
"AttestationPolicy",
|
||||
Azure::Core::_internal::Base64Url::Base64UrlDecode);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
}}}} // namespace Azure::Security::Attestation::_detail
|
||||
|
||||
@ -94,4 +94,23 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail
|
||||
static std::string Serialize(Models::AttestationTokenHeader const& tokenHeader);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Serializer/Deserializer for internal PolicyResult objects.
|
||||
*/
|
||||
struct PolicyResultSerializer final
|
||||
{
|
||||
static Models::_detail::PolicyResult Deserialize(
|
||||
Azure::Core::Json::_internal::json const& json);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Serializer/Deserializer for internal PolicyResult objects.
|
||||
*/
|
||||
struct StoredAttestationPolicySerializer final
|
||||
{
|
||||
static Models::_detail::StoredAttestationPolicy Deserialize(
|
||||
Azure::Core::Json::_internal::json const& json);
|
||||
static std::string Serialize(Models::_detail::StoredAttestationPolicy const& policy);
|
||||
};
|
||||
|
||||
}}}} // namespace Azure::Security::Attestation::_detail
|
||||
|
||||
@ -19,7 +19,8 @@ add_executable (
|
||||
macro_guard.cpp
|
||||
crypto_test.cpp
|
||||
attestation_test.cpp
|
||||
token_test.cpp)
|
||||
token_test.cpp administration_test.cpp
|
||||
attestation_collateral.cpp)
|
||||
|
||||
create_per_service_target_build(azure-security-attestation-test attestation)
|
||||
|
||||
|
||||
@ -0,0 +1,112 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/attestation/attestation_administration_client.hpp"
|
||||
#include "azure/identity/client_secret_credential.hpp"
|
||||
#include <azure/attestation/attestation_client_models.hpp>
|
||||
#include <azure/core/test/test_base.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
using namespace Azure::Security::Attestation;
|
||||
using namespace Azure::Security::Attestation::Models;
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation { namespace Test {
|
||||
|
||||
class AdministrationTests
|
||||
: public Azure::Core::Test::TestBase,
|
||||
public testing::WithParamInterface<std::tuple<std::string, AttestationType>> {
|
||||
private:
|
||||
protected:
|
||||
std::shared_ptr<Azure::Core::Credentials::TokenCredential> m_credential;
|
||||
std::string m_endpoint;
|
||||
|
||||
// Create
|
||||
virtual void SetUp() override
|
||||
{
|
||||
Azure::Core::Test::TestBase::SetUpTestBase(AZURE_TEST_RECORDING_DIR);
|
||||
|
||||
std::string const mode(std::get<0>(GetParam()));
|
||||
if (mode == "Shared")
|
||||
{
|
||||
std::string const shortLocation(GetEnv("LOCATION_SHORT_NAME"));
|
||||
m_endpoint = "https://shared" + shortLocation + "." + shortLocation + ".attest.azure.net";
|
||||
}
|
||||
else if (mode == "Aad")
|
||||
{
|
||||
m_endpoint = GetEnv("ATTESTATION_AAD_URL");
|
||||
}
|
||||
else if (mode == "Isolated")
|
||||
{
|
||||
m_endpoint = GetEnv("ATTESTATION_ISOLATED_URL");
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AttestationAdministrationClient> CreateClient()
|
||||
{
|
||||
// `InitTestClient` takes care of setting up Record&Playback.
|
||||
Azure::Security::Attestation::AttestationAdministrationClientOptions options;
|
||||
if (m_testContext.IsPlaybackMode())
|
||||
{
|
||||
// Skip validating time stamps if using recordings.
|
||||
options.TokenValidationOptions.ValidateNotBeforeTime = false;
|
||||
options.TokenValidationOptions.ValidateExpirationTime = false;
|
||||
}
|
||||
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential
|
||||
= std::make_shared<Azure::Identity::ClientSecretCredential>(
|
||||
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
|
||||
|
||||
return InitTestClient<
|
||||
Azure::Security::Attestation::AttestationAdministrationClient,
|
||||
Azure::Security::Attestation::AttestationAdministrationClientOptions>(
|
||||
m_endpoint, credential, options);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(AdministrationTests, GetPolicy)
|
||||
{
|
||||
auto adminClient(CreateClient());
|
||||
|
||||
EXPECT_FALSE(adminClient->ClientVersion().empty());
|
||||
|
||||
AttestationType attestationType(std::get<1>(GetParam()));
|
||||
{
|
||||
auto policy = adminClient->GetAttestationPolicy(attestationType);
|
||||
|
||||
// The policy should have a value, and the token should have been issued by the service.
|
||||
if (policy.Value.Body.empty())
|
||||
{
|
||||
EXPECT_EQ(AttestationType::Tpm, attestationType);
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(0UL, policy.Value.Body.find("version"));
|
||||
}
|
||||
if (!m_testContext.IsPlaybackMode())
|
||||
{
|
||||
EXPECT_EQ(m_endpoint, policy.Value.Issuer.Value());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
GetPolicyOptions gpOptions;
|
||||
EXPECT_FALSE(gpOptions.TokenValidationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Attestation,
|
||||
AdministrationTests,
|
||||
testing::Combine(
|
||||
::testing::Values("Shared", "Aad", "Isolated"),
|
||||
::testing::Values(
|
||||
AttestationType::SgxEnclave,
|
||||
AttestationType::OpenEnclave,
|
||||
AttestationType::Tpm)),
|
||||
[](testing::TestParamInfo<AdministrationTests::ParamType> const& info) -> std::string {
|
||||
std::string instanceType = std::get<0>(info.param);
|
||||
return instanceType + "_" + std::get<1>(info.param).ToString();
|
||||
});
|
||||
|
||||
}}}} // namespace Azure::Security::Attestation::Test
|
||||
@ -0,0 +1,355 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "attestation_collateral.hpp"
|
||||
#include <azure/core/base64.hpp>
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation { namespace Test {
|
||||
// cspell:disable
|
||||
const std::string OpenEnclaveQuote(
|
||||
"AQAAAAIAAADoEQAAAAAAAAMAAgAAAAAABQAKAJOacjP3nEyplAoNs5V_Bgfl_"
|
||||
"L18zrEJejtqk6RDB0IzAAAAABERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAABwAAAAAAAAApKh9LUZ5GYn6yR4o9mFFAVlPFtLCmkl3"
|
||||
"oQ4N"
|
||||
"NkhaFDgAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAASupfmg7QSxH4iarf5qHTdiE6Kalahc5zN65vf-"
|
||||
"zmYQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAA"
|
||||
"AAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKFQuRP5-c_ZhD2sxrnV2kl8JzNu0xWRlg-"
|
||||
"zBVhM3qP8AAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAADQQAACJx8e27oQ0pijs3lXQ9HfKWP9NMqVHQFL9SOjC_KGDcbv-I2fCafTHJ__"
|
||||
"AmNqVXy7XTXnzmLp1HhUCy1_9AORSAT"
|
||||
"qGZ1PtvBf4Q2NfNxqVkNrGJAjYuqMPStdg0MuM21nN-Qc9BWNycRMMsU7YfHSzmw7eGjBb_"
|
||||
"Ewfb3k6N4ZYRhERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAAAAAAABwAAAAAAAAA_sKzghp0uMPKOhtcMdmQDpU-"
|
||||
"7zWWO7ODhuUipFVkXQAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAjE9XddeWUD6WE393xoqCmgBWrI3tcBQLCBsJRJDFe_"
|
||||
"8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAUAAAA"
|
||||
"AAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH_"
|
||||
"mzVQFF8XbJCRGdNkA3SPx9ZUPgtx3874VyDYQnFRIAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAEUP2-pxe7LoyevtN5BdE4KKikxKK6-"
|
||||
"hwG0xCDmxmfLphcnrVskSbKmiKUfzkWUBehrF8gHCGNGIPX3QQDwmtZ4gAAABAgME"
|
||||
"BQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fBQDMDQAALS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVn"
|
||||
"VEND"
|
||||
"QkNhZ0F3SUJBZ0lVU3I5VmR"
|
||||
"iSnFWbzVyZzRadUpCRWo2SjNoak9jd0NnWUlLb1pJemowRUF3SXcKY1RFak1DRUdBMVVFQXd3YVNXNTBaV3dnVTB"
|
||||
"kWUl"
|
||||
"GQkRTeUJRY205alpYTnpiM0"
|
||||
"lnUTBFeEdqQVlCZ05WQkFvTQpFVWx1ZEdWc0lFTnZjbkJ2Y21GMGFXOXVNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQk"
|
||||
"RiR0"
|
||||
"Z5WVRFTE1Ba0dBMVVFCkNBd"
|
||||
"0NRMEV4Q3pBSkJnTlZCQVlUQWxWVE1CNFhEVEl4TURNeE9UQTBOVEl3T0ZvWERUSTRNRE14T1RBME5USXcKT0Zvd"
|
||||
"2NER"
|
||||
"WlNQ0FHQTFVRUF3d1pTVzUw"
|
||||
"Wld3Z1UwZFlJRkJEU3lCRFpYSjBhV1pwWTJGMFpURWFNQmdHQTFVRQpDZ3dSU1c1MFpXd2dRMjl5Y0c5eVlYUnBi"
|
||||
"MjR4"
|
||||
"RkRBU0JnTlZCQWNNQzFOaGJ"
|
||||
"uUmhJRU5zWVhKaE1Rc3dDUVlEClZRUUlEQUpEUVRFTE1Ba0dBMVVFQmhNQ1ZWTXdXVEFUQmdjcWhrak9QUUlCQmd"
|
||||
"ncWh"
|
||||
"rak9QUU1CQndOQ0FBUlQKVG"
|
||||
"RNNVhTMGFiRTA2ZUdVTVU3S1JOQXJlRGRtTWJHK25KVHlucDZXankyeXJ6NmlEa3h1R1F3WGZ1b25uUVBuZApjdH"
|
||||
"gwbH"
|
||||
"IyR3I0WjF1YXNsQjM2Vm80S"
|
||||
"UNtekNDQXBjd0h3WURWUjBqQkJnd0ZvQVUwT2lxMm5YWCtTNUpGNWc4CmV4UmwwTlh5V1Uwd1h3WURWUjBmQkZnd"
|
||||
"1ZqQ"
|
||||
"lVvRktnVUlaT2FIUjBjSE02"
|
||||
"THk5aGNHa3VkSEoxYzNSbFpITmwKY25acFkyVnpMbWx1ZEdWc0xtTnZiUzl6WjNndlkyVnlkR2xtYVdOaGRHbHZi"
|
||||
"aTky"
|
||||
"TWk5d1kydGpjbXcvWTJFOQp"
|
||||
"jSEp2WTJWemMyOXlNQjBHQTFVZERnUVdCQlRMejZNQ3VHcVZobFYrR2Q0ZGtacmx4YndCV2pBT0JnTlZIUThCCkF"
|
||||
"mOEV"
|
||||
"CQU1DQnNBd0RBWURWUjBUQV"
|
||||
"FIL0JBSXdBRENDQWRRR0NTcUdTSWI0VFFFTkFRU0NBY1V3Z2dIQk1CNEcKQ2lxR1NJYjRUUUVOQVFFRUVMOEhhRE"
|
||||
"xXWW"
|
||||
"dVUFUzU3c3Tm1Ibkhrd2dnR"
|
||||
"mtCZ29xaGtpRytFMEJEUUVDTUlJQgpWREFRQmdzcWhraUcrRTBCRFFFQ0FRSUJFVEFRQmdzcWhraUcrRTBCRFFFQ"
|
||||
"0FnS"
|
||||
"UJFVEFRQmdzcWhraUcrRTBC"
|
||||
"CkRRRUNBd0lCQWpBUUJnc3Foa2lHK0UwQkRRRUNCQUlCQkRBUUJnc3Foa2lHK0UwQkRRRUNCUUlCQVRBUkJnc3EK"
|
||||
"aGtp"
|
||||
"RytFMEJEUUVDQmdJQ0FJQXd"
|
||||
"FQVlMS29aSWh2aE5BUTBCQWdjQ0FRWXdFQVlMS29aSWh2aE5BUTBCQWdnQwpBUUF3RUFZTEtvWklodmhOQVEwQkF"
|
||||
"na0N"
|
||||
"BUUF3RUFZTEtvWklodmhOQV"
|
||||
"EwQkFnb0NBUUF3RUFZTEtvWklodmhOCkFRMEJBZ3NDQVFBd0VBWUxLb1pJaHZoTkFRMEJBZ3dDQVFBd0VBWUxLb1"
|
||||
"pJaH"
|
||||
"ZoTkFRMEJBZzBDQVFBd0VBW"
|
||||
"UwKS29aSWh2aE5BUTBCQWc0Q0FRQXdFQVlMS29aSWh2aE5BUTBCQWc4Q0FRQXdFQVlMS29aSWh2aE5BUTBCQWhBQ"
|
||||
"wpBU"
|
||||
"UF3RUFZTEtvWklodmhOQVEw"
|
||||
"QkFoRUNBUW93SHdZTEtvWklodmhOQVEwQkFoSUVFQkVSQWdRQmdBWUFBQUFBCkFBQUFBQUF3RUFZS0tvWklodmhO"
|
||||
"QVEw"
|
||||
"QkF3UUNBQUF3RkFZS0tvWkl"
|
||||
"odmhOQVEwQkJBUUdBSkJ1MVFBQU1BOEcKQ2lxR1NJYjRUUUVOQVFVS0FRQXdDZ1lJS29aSXpqMEVBd0lEU1FBd1J"
|
||||
"nSWh"
|
||||
"BSzZPMS9GNy80NFprcWhUN2"
|
||||
"FhNgp5QVh6QlltRWxUVHRvL25rVUd4N1BtUktBaUVBMXliSWt6SjVwcXR1L21jOW5DUWNwRUJOdk5KZFNIcW1jc0"
|
||||
"4rCk"
|
||||
"V2dWJ3WlU9Ci0tLS0tRU5EI"
|
||||
"ENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNsekNDQWo2Z0F3SUJBZ0lWQ"
|
||||
"U5Eb"
|
||||
"3F0cDExL2t1U1JlWVBIc1Va"
|
||||
"ZERWOGxsTk1Bb0dDQ3FHU000OUJBTUMKTUdneEdqQVlCZ05WQkFNTUVVbHVkR1ZzSUZOSFdDQlNiMjkwSUVOQk1S"
|
||||
"b3dH"
|
||||
"QVlEVlFRS0RCRkpiblJsYkN"
|
||||
"CRApiM0p3YjNKaGRHbHZiakVVTUJJR0ExVUVCd3dMVTJGdWRHRWdRMnhoY21FeEN6QUpCZ05WQkFnTUFrTkJNUXN"
|
||||
"3CkN"
|
||||
"RWURWUVFHRXdKVlV6QWVGdz"
|
||||
"B4T0RBMU1qRXhNRFExTURoYUZ3MHpNekExTWpFeE1EUTFNRGhhTUhFeEl6QWgKQmdOVkJBTU1Ha2x1ZEdWc0lGTk"
|
||||
"hXQ0"
|
||||
"JRUTBzZ1VISnZZMlZ6YzI5e"
|
||||
"UlFTkJNUm93R0FZRFZRUUtEQkZKYm5SbApiQ0JEYjNKd2IzSmhkR2x2YmpFVU1CSUdBMVVFQnd3TFUyRnVkR0VnU"
|
||||
"TJ4a"
|
||||
"GNtRXhDekFKQmdOVkJBZ01B"
|
||||
"a05CCk1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCTDlxK05NcDJJ"
|
||||
"T2cK"
|
||||
"dGRsMWJrL3VXWjUrVEdRbTh"
|
||||
"hQ2k4ejc4ZnMrZktDUTNkK3VEelhuVlRBVDJaaERDaWZ5SXVKd3ZOM3dOQnA5aQpIQlNTTUpNSnJCT2pnYnN3Z2J"
|
||||
"nd0h"
|
||||
"3WURWUjBqQkJnd0ZvQVVJbV"
|
||||
"VNMWxxZE5JbnpnN1NWVXI5UUd6a25CcXd3ClVnWURWUjBmQkVzd1NUQkhvRVdnUTRaQmFIUjBjSE02THk5alpYSj"
|
||||
"BhV1"
|
||||
"pwWTJGMFpYTXVkSEoxYzNSb"
|
||||
"FpITmwKY25acFkyVnpMbWx1ZEdWc0xtTnZiUzlKYm5SbGJGTkhXRkp2YjNSRFFTNWpjbXd3SFFZRFZSME9CQllFR"
|
||||
"k5Eb"
|
||||
"wpxdHAxMS9rdVNSZVlQSHNV"
|
||||
"WmREVjhsbE5NQTRHQTFVZER3RUIvd1FFQXdJQkJqQVNCZ05WSFJNQkFmOEVDREFHCkFRSC9BZ0VBTUFvR0NDcUdT"
|
||||
"TTQ5"
|
||||
"QkFNQ0EwY0FNRVFDSUMvOWo"
|
||||
"rODRUK0h6dFZPL3NPUUJXSmJTZCsvMnVleEsKNCthQTBqY0ZCTGNwQWlBM2RoTXJGNWNENTJ0NkZxTXZBSXBqOFh"
|
||||
"kR21"
|
||||
"5MmJlZWxqTEpLK3B6cGNSQT"
|
||||
"09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNqakNDQW"
|
||||
"pTZ0"
|
||||
"F3SUJBZ0lVSW1VTTFscWROS"
|
||||
"W56ZzdTVlVyOVFHemtuQnF3d0NnWUlLb1pJemowRUF3SXcKYURFYU1CZ0dBMVVFQXd3UlNXNTBaV3dnVTBkWUlGS"
|
||||
"nZiM"
|
||||
"1FnUTBFeEdqQVlCZ05WQkFv"
|
||||
"TUVVbHVkR1ZzSUVOdgpjbkJ2Y21GMGFXOXVNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQkRiR0Z5WVRFTE1Ba0dBMVVF"
|
||||
"Q0F3"
|
||||
"Q1EwRXhDekFKCkJnTlZCQVl"
|
||||
"UQWxWVE1CNFhEVEU0TURVeU1URXdOREV4TVZvWERUTXpNRFV5TVRFd05ERXhNRm93YURFYU1CZ0cKQTFVRUF3d1J"
|
||||
"TVzU"
|
||||
"wWld3Z1UwZFlJRkp2YjNRZ1"
|
||||
"EwRXhHakFZQmdOVkJBb01FVWx1ZEdWc0lFTnZjbkJ2Y21GMAphVzl1TVJRd0VnWURWUVFIREF0VFlXNTBZU0JEYk"
|
||||
"dGeV"
|
||||
"lURUxNQWtHQTFVRUNBd0NRM"
|
||||
"EV4Q3pBSkJnTlZCQVlUCkFsVlRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVDNm5Fd01ESVlaT"
|
||||
"2ova"
|
||||
"VBXc0N6YUVLaTcKMU9pT1NM"
|
||||
"UkZoV0dqYm5CVkpmVm5rWTR1M0lqa0RZWUwwTXhPNG1xc3lZamxCYWxUVll4RlAyc0pCSzV6bEtPQgp1ekNCdURB"
|
||||
"ZkJn"
|
||||
"TlZIU01FR0RBV2dCUWlaUXp"
|
||||
"XV3AwMGlmT0R0SlZTdjFBYk9TY0dyREJTQmdOVkhSOEVTekJKCk1FZWdSYUJEaGtGb2RIUndjem92TDJObGNuUnB"
|
||||
"abWx"
|
||||
"qWVhSbGN5NTBjblZ6ZEdWa2"
|
||||
"MyVnlkbWxqWlhNdWFXNTAKWld3dVkyOXRMMGx1ZEdWc1UwZFlVbTl2ZEVOQkxtTnliREFkQmdOVkhRNEVGZ1FVSW"
|
||||
"1VTT"
|
||||
"FscWROSW56ZzdTVgpVcjlRR"
|
||||
"3prbkJxd3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRRXdDZ1lJCktvWkl6a"
|
||||
"jBFQ"
|
||||
"XdJRFNBQXdSUUlnUVFzLzA4"
|
||||
"cnljZFBhdUNGazhVUFFYQ01BbHNsb0JlN053YVFHVGNkcGEwRUMKSVFDVXQ4U0d2eEttanBjTS96MFdQOUR2bzho"
|
||||
"Mms1"
|
||||
"ZHUxaVdEZEJrQW4rMGlpQT0"
|
||||
"9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KAA");
|
||||
|
||||
const std::string OpenEnclaveNonDebugQuote(
|
||||
"AQAAAAIAAADoEQAAAAAAAAMAAgAAAAAABQAKAJOacjP3nEyplAoNs5V_"
|
||||
"BgfDYELtjmo1LWZEqF8xasaZAAAAABERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAABwAAAAAAAAC3eSAmGL7LY2do5dkC8o1SQiJzX6-"
|
||||
"1OeqboHw_wXGhwgAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAALBpElSroIHE1xsKbdbjAKTcu6UtnfhXCC9QjQPENQaoAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAAAAAAAAAAAAAA"
|
||||
"AAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKFQuRP5-c_ZhD2sxrnV2kl8JzNu0xWRlg-"
|
||||
"zBVhM3qP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQQAA"
|
||||
"Ck3Zl7b4XERNDrAJfKbmzU0NSTIzY5rsFeyW_6deDzOyjXAnxA3b1WfBwrFrU9JKpfI9SDlpwms3YSQtJArmrD-"
|
||||
"8i_"
|
||||
"meLNk8sQSwSkR7TdIadTEAZdb7S-7qMt"
|
||||
"Yt3kWMfQ7H3g338R0kcF9wcy0jZmeBrRLDXyEUDcPI63Fwvp_BERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAAAAA"
|
||||
"AABwAAAAAAAAA_sKzghp0uMPKOhtcMdmQDpU-"
|
||||
"7zWWO7ODhuUipFVkXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjE9XddeWUD6WE393xoqCmgBW"
|
||||
"rI3tcBQLCBsJRJDFe_"
|
||||
"8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAA"
|
||||
"AAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAABAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAA"
|
||||
"AAAAAAAAAAAAAAAAAAmm22hOMEcuVw"
|
||||
"P_d08cVnQ2JF3uT3Q5as4s-"
|
||||
"D4yNshB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgCuq8kIluOwzRvIHV3J7G-"
|
||||
"62qz2UxkrKQ2aJHVWlzGwveCOd"
|
||||
"GIgpSJVM7GNcJW12FOveof_7m_"
|
||||
"nA78uk3D3C4gAAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fBQDMDQAALS0tLS1CRUdJTiBDRVJUSUZJ"
|
||||
"Q0FU"
|
||||
"RS0t"
|
||||
"LS0tCk1JSUVnVENDQkNlZ0F3SUJBZ0lWQU9jMDJHVHYvUTRvOUhHS1Bndk8yeUpPMElWTk1Bb0dDQ3FHU000OUJB"
|
||||
"TUMK"
|
||||
"TUhFeEl6QWhCZ05WQkFNTUdrbHVkR1"
|
||||
"ZzSUZOSFdDQlFRMHNnVUhKdlkyVnpjMjl5SUVOQk1Sb3dHQVlEVlFRSwpEQkZKYm5SbGJDQkRiM0p3YjNKaGRHbH"
|
||||
"Ziak"
|
||||
"VVTUJJR0ExVUVCd3dMVTJGdWRHRWdR"
|
||||
"MnhoY21FeEN6QUpCZ05WCkJBZ01Ba05CTVFzd0NRWURWUVFHRXdKVlV6QWVGdzB5TVRBME1Ea3hNalU1TWpoYUZ3"
|
||||
"MHlP"
|
||||
"REEwTURreE1qVTUKTWpoYU1IQXhJak"
|
||||
"FnQmdOVkJBTU1HVWx1ZEdWc0lGTkhXQ0JRUTBzZ1EyVnlkR2xtYVdOaGRHVXhHakFZQmdOVgpCQW9NRVVsdWRHVn"
|
||||
"NJRU"
|
||||
"52Y25CdmNtRjBhVzl1TVJRd0VnWURW"
|
||||
"UVFIREF0VFlXNTBZU0JEYkdGeVlURUxNQWtHCkExVUVDQXdDUTBFeEN6QUpCZ05WQkFZVEFsVlRNRmt3RXdZSEtv"
|
||||
"Wkl6"
|
||||
"ajBDQVFZSUtvWkl6ajBEQVFjRFFnQU"
|
||||
"UKYzZ1TjVuZGlFY25mWUp1OFU1MUgzc3lzWm5kQ05JamlwRVdEZjJuaXp6VU9XdlZjdjIxWUUwakxMdmxpL2s3NA"
|
||||
"p2bj"
|
||||
"FtUzYvbkNYV3MxOFVZeE1PMFM2T0NB"
|
||||
"cHN3Z2dLWE1COEdBMVVkSXdRWU1CYUFGTkRvcXRwMTEva3VTUmVZClBIc1VaZERWOGxsTk1GOEdBMVVkSHdSWU1G"
|
||||
"WXdW"
|
||||
"S0JTb0ZDR1RtaDBkSEJ6T2k4dllYQn"
|
||||
"BMblJ5ZFhOMFpXUnoKWlhKMmFXTmxjeTVwYm5SbGJDNWpiMjB2YzJkNEwyTmxjblJwWm1sallYUnBiMjR2ZGpJdm"
|
||||
"NHTn"
|
||||
"JZM0pzUDJOaApQWEJ5YjJObGMzTnZj"
|
||||
"akFkQmdOVkhRNEVGZ1FVRzBZaHd5VEh2bFFUNFlQVU1lRGplMmFUUWNjd0RnWURWUjBQCkFRSC9CQVFEQWdiQU1B"
|
||||
"d0dB"
|
||||
"MVVkRXdFQi93UUNNQUF3Z2dIVUJna3"
|
||||
"Foa2lHK0UwQkRRRUVnZ0hGTUlJQndUQWUKQmdvcWhraUcrRTBCRFFFQkJCRDBRZ2lrT3FkRWxVQnJYSWFPdCtVYU"
|
||||
"1JSU"
|
||||
"JaQVlLS29aSWh2aE5BUTBCQWpDQwpB"
|
||||
"VlF3RUFZTEtvWklodmhOQVEwQkFnRUNBUkV3RUFZTEtvWklodmhOQVEwQkFnSUNBUkV3RUFZTEtvWklodmhOCkFR"
|
||||
"MEJB"
|
||||
"Z01DQVFJd0VBWUxLb1pJaHZoTkFRME"
|
||||
"JBZ1FDQVFRd0VBWUxLb1pJaHZoTkFRMEJBZ1VDQVFFd0VRWUwKS29aSWh2aE5BUTBCQWdZQ0FnQ0FNQkFHQ3lxR1"
|
||||
"NJYj"
|
||||
"RUUUVOQVFJSEFnRUdNQkFHQ3lxR1NJ"
|
||||
"YjRUUUVOQVFJSQpBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSUpBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSUtBZ0VBTUJB"
|
||||
"R0N5"
|
||||
"cUdTSWI0ClRRRU5BUUlMQWdFQU1CQU"
|
||||
"dDeXFHU0liNFRRRU5BUUlNQWdFQU1CQUdDeXFHU0liNFRRRU5BUUlOQWdFQU1CQUcKQ3lxR1NJYjRUUUVOQVFJT0"
|
||||
"FnRU"
|
||||
"FNQkFHQ3lxR1NJYjRUUUVOQVFJUEFn"
|
||||
"RUFNQkFHQ3lxR1NJYjRUUUVOQVFJUQpBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSVJBZ0VLTUI4R0N5cUdTSWI0VFFF"
|
||||
"TkFR"
|
||||
"SVNCQkFSRVFJRUFZQUdBQUFBCkFBQU"
|
||||
"FBQUFBTUJBR0NpcUdTSWI0VFFFTkFRTUVBZ0FBTUJRR0NpcUdTSWI0VFFFTkFRUUVCZ0NRYnRVQUFEQVAKQmdvcW"
|
||||
"hraU"
|
||||
"crRTBCRFFFRkNnRUFNQW9HQ0NxR1NN"
|
||||
"NDlCQU1DQTBnQU1FVUNJUUNiNVBlMkd6ZkJTeWh2VDB4MgpXWEQ4MWlHYm8vMUs2cU9zRm1XNjg4R0FPZ0lnUzRi"
|
||||
"ZjUr"
|
||||
"R0R6VExPUXpNMitESVJEc0VPelpUR1"
|
||||
"Jzc3pTOHFECm1lSVBKKzA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS"
|
||||
"0tLS"
|
||||
"0tCk1JSUNsekNDQWo2Z0F3SUJBZ0lW"
|
||||
"QU5Eb3F0cDExL2t1U1JlWVBIc1VaZERWOGxsTk1Bb0dDQ3FHU000OUJBTUMKTUdneEdqQVlCZ05WQkFNTUVVbHVk"
|
||||
"R1Zz"
|
||||
"SUZOSFdDQlNiMjkwSUVOQk1Sb3dHQV"
|
||||
"lEVlFRS0RCRkpiblJsYkNCRApiM0p3YjNKaGRHbHZiakVVTUJJR0ExVUVCd3dMVTJGdWRHRWdRMnhoY21FeEN6QU"
|
||||
"pCZ0"
|
||||
"5WQkFnTUFrTkJNUXN3CkNRWURWUVFH"
|
||||
"RXdKVlV6QWVGdzB4T0RBMU1qRXhNRFExTURoYUZ3MHpNekExTWpFeE1EUTFNRGhhTUhFeEl6QWgKQmdOVkJBTU1H"
|
||||
"a2x1"
|
||||
"ZEdWc0lGTkhXQ0JRUTBzZ1VISnZZMl"
|
||||
"Z6YzI5eUlFTkJNUm93R0FZRFZRUUtEQkZKYm5SbApiQ0JEYjNKd2IzSmhkR2x2YmpFVU1CSUdBMVVFQnd3TFUyRn"
|
||||
"VkR0"
|
||||
"VnUTJ4aGNtRXhDekFKQmdOVkJBZ01B"
|
||||
"a05CCk1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCTDlxK05NcDJJ"
|
||||
"T2cK"
|
||||
"dGRsMWJrL3VXWjUrVEdRbThhQ2k4ej"
|
||||
"c4ZnMrZktDUTNkK3VEelhuVlRBVDJaaERDaWZ5SXVKd3ZOM3dOQnA5aQpIQlNTTUpNSnJCT2pnYnN3Z2Jnd0h3WU"
|
||||
"RWUj"
|
||||
"BqQkJnd0ZvQVVJbVVNMWxxZE5Jbnpn"
|
||||
"N1NWVXI5UUd6a25CcXd3ClVnWURWUjBmQkVzd1NUQkhvRVdnUTRaQmFIUjBjSE02THk5alpYSjBhV1pwWTJGMFpY"
|
||||
"TXVk"
|
||||
"SEoxYzNSbFpITmwKY25acFkyVnpMbW"
|
||||
"x1ZEdWc0xtTnZiUzlKYm5SbGJGTkhXRkp2YjNSRFFTNWpjbXd3SFFZRFZSME9CQllFRk5EbwpxdHAxMS9rdVNSZV"
|
||||
"lQSH"
|
||||
"NVWmREVjhsbE5NQTRHQTFVZER3RUIv"
|
||||
"d1FFQXdJQkJqQVNCZ05WSFJNQkFmOEVDREFHCkFRSC9BZ0VBTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUMvOWor"
|
||||
"ODRU"
|
||||
"K0h6dFZPL3NPUUJXSmJTZCsvMnVleE"
|
||||
"sKNCthQTBqY0ZCTGNwQWlBM2RoTXJGNWNENTJ0NkZxTXZBSXBqOFhkR215MmJlZWxqTEpLK3B6cGNSQT09Ci0tLS"
|
||||
"0tRU"
|
||||
"5EIENFUlRJRklDQVRFLS0tLS0KLS0t"
|
||||
"LS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNqakNDQWpTZ0F3SUJBZ0lVSW1VTTFscWROSW56ZzdTVlVyOVFH"
|
||||
"emtu"
|
||||
"QnF3d0NnWUlLb1pJemowRUF3SXcKYU"
|
||||
"RFYU1CZ0dBMVVFQXd3UlNXNTBaV3dnVTBkWUlGSnZiM1FnUTBFeEdqQVlCZ05WQkFvTUVVbHVkR1ZzSUVOdgpjbk"
|
||||
"J2Y2"
|
||||
"1GMGFXOXVNUlF3RWdZRFZRUUhEQXRU"
|
||||
"WVc1MFlTQkRiR0Z5WVRFTE1Ba0dBMVVFQ0F3Q1EwRXhDekFKCkJnTlZCQVlUQWxWVE1CNFhEVEU0TURVeU1URXdO"
|
||||
"REV4"
|
||||
"TVZvWERUTXpNRFV5TVRFd05ERXhNRm"
|
||||
"93YURFYU1CZ0cKQTFVRUF3d1JTVzUwWld3Z1UwZFlJRkp2YjNRZ1EwRXhHakFZQmdOVkJBb01FVWx1ZEdWc0lFTn"
|
||||
"Zjbk"
|
||||
"J2Y21GMAphVzl1TVJRd0VnWURWUVFI"
|
||||
"REF0VFlXNTBZU0JEYkdGeVlURUxNQWtHQTFVRUNBd0NRMEV4Q3pBSkJnTlZCQVlUCkFsVlRNRmt3RXdZSEtvWkl6"
|
||||
"ajBD"
|
||||
"QVFZSUtvWkl6ajBEQVFjRFFnQUVDNm"
|
||||
"5Fd01ESVlaT2ovaVBXc0N6YUVLaTcKMU9pT1NMUkZoV0dqYm5CVkpmVm5rWTR1M0lqa0RZWUwwTXhPNG1xc3lZam"
|
||||
"xCYW"
|
||||
"xUVll4RlAyc0pCSzV6bEtPQgp1ekNC"
|
||||
"dURBZkJnTlZIU01FR0RBV2dCUWlaUXpXV3AwMGlmT0R0SlZTdjFBYk9TY0dyREJTQmdOVkhSOEVTekJKCk1FZWdS"
|
||||
"YUJE"
|
||||
"aGtGb2RIUndjem92TDJObGNuUnBabW"
|
||||
"xqWVhSbGN5NTBjblZ6ZEdWa2MyVnlkbWxqWlhNdWFXNTAKWld3dVkyOXRMMGx1ZEdWc1UwZFlVbTl2ZEVOQkxtTn"
|
||||
"liRE"
|
||||
"FkQmdOVkhRNEVGZ1FVSW1VTTFscWRO"
|
||||
"SW56ZzdTVgpVcjlRR3prbkJxd3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FR"
|
||||
"RXdD"
|
||||
"Z1lJCktvWkl6ajBFQXdJRFNBQXdSUU"
|
||||
"lnUVFzLzA4cnljZFBhdUNGazhVUFFYQ01BbHNsb0JlN053YVFHVGNkcGEwRUMKSVFDVXQ4U0d2eEttanBjTS96MF"
|
||||
"dQOU"
|
||||
"R2bzhoMms1ZHUxaVdEZEJrQW4rMGlp"
|
||||
"QT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KAA");
|
||||
|
||||
std::string RuntimeJWKClaim = R"(
|
||||
{
|
||||
"jwk" : {
|
||||
"kty":"EC",
|
||||
"use":"sig",
|
||||
"crv":"P-256",
|
||||
"x":"18wHLeIgW9wVN6VD1Txgpqy2LszYkMf6J8njVAibvhM",
|
||||
"y":"cV4dS4UaLMgP_4fY4j8ir7cl1TXlFdAgcx55o7TkcSA"
|
||||
}
|
||||
}
|
||||
)";
|
||||
std::string SgxEnclaveHeldData
|
||||
= "CiAgICAgICAgewogICAgICAgICAgICAiandrIiA6IHsKICAgICAgICAgICAgICAgICJrdHkiOiJFQyI"
|
||||
"sCiAgICAgICAgICAgICAgICAidXNlIjoic2lnIiwKICAgICAgICAgICAgICAgICJjcnYiOiJQLTI1Ni"
|
||||
"IsCiAgICAgICAgICAgICAgICAieCI6IjE4d0hMZUlnVzl3Vk42VkQxVHhncHF5MkxzellrTWY2Sjhua"
|
||||
"lZBaWJ2aE0iLAogICAgICAgICAgICAgICAgInkiOiJjVjRkUzRVYUxNZ1BfNGZZNGo4aXI3Y2wxVFhs"
|
||||
"RmRBZ2N4NTVvN1RrY1NBIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAA";
|
||||
// cspell:enable
|
||||
|
||||
std::vector<uint8_t> AttestationCollateral::OpenEnclaveReport()
|
||||
{
|
||||
return Azure::Core::_internal::Base64Url::Base64UrlDecode(OpenEnclaveQuote);
|
||||
}
|
||||
std::vector<uint8_t> AttestationCollateral::SgxQuote()
|
||||
{
|
||||
// An OpenEnclave report is a wrapper around an SGX quote - there are
|
||||
// 16 bytes of OpenEnclave header at the start of the report and what remains is
|
||||
// an SGX quote, so to convert from an OE report to an SGX quote simply strip
|
||||
// the first 16 bytes of the report.
|
||||
auto openEnclaveReport = AttestationCollateral::OpenEnclaveReport();
|
||||
openEnclaveReport.erase(openEnclaveReport.begin(), openEnclaveReport.begin() + 16);
|
||||
return openEnclaveReport;
|
||||
// return std::vector<uint8_t>(openEnclaveReport.begin() + 0x10,
|
||||
// openEnclaveReport.end());
|
||||
}
|
||||
std::vector<uint8_t> AttestationCollateral::RuntimeData()
|
||||
{
|
||||
return Azure::Core::_internal::Base64Url::Base64UrlDecode(SgxEnclaveHeldData);
|
||||
// return std::vector<uint8_t>(RuntimeJWKClaim.begin(), RuntimeJWKClaim.end());
|
||||
}
|
||||
}}}} // namespace Azure::Security::Attestation::Test
|
||||
@ -6,262 +6,10 @@
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation { namespace Test {
|
||||
|
||||
// cspell:disable
|
||||
const std::string OpenEnclaveQuote(
|
||||
"AQAAAAIAAADoEQAAAAAAAAMAAgAAAAAABQAKAJOacjP3nEyplAoNs5V_Bgfl_L18zrEJejtqk6RDB0IzAAAAABERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAABwAAAAAAAAApKh9LUZ5GYn6yR4o9mFFAVlPFtLCmkl3oQ4N"
|
||||
"NkhaFDgAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAASupfmg7QSxH4iarf5qHTdiE6Kalahc5zN65vf-"
|
||||
"zmYQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKFQuRP5-c_ZhD2sxrnV2kl8JzNu0xWRlg-"
|
||||
"zBVhM3qP8AAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAADQQAACJx8e27oQ0pijs3lXQ9HfKWP9NMqVHQFL9SOjC_KGDcbv-I2fCafTHJ__"
|
||||
"AmNqVXy7XTXnzmLp1HhUCy1_9AORSAT"
|
||||
"qGZ1PtvBf4Q2NfNxqVkNrGJAjYuqMPStdg0MuM21nN-Qc9BWNycRMMsU7YfHSzmw7eGjBb_Ewfb3k6N4ZYRhERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAAAAAAABwAAAAAAAAA_sKzghp0uMPKOhtcMdmQDpU-"
|
||||
"7zWWO7ODhuUipFVkXQAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAjE9XddeWUD6WE393xoqCmgBWrI3tcBQLCBsJRJDFe_"
|
||||
"8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAUAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH_"
|
||||
"mzVQFF8XbJCRGdNkA3SPx9ZUPgtx3874VyDYQnFRIAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAEUP2-pxe7LoyevtN5BdE4KKikxKK6-"
|
||||
"hwG0xCDmxmfLphcnrVskSbKmiKUfzkWUBehrF8gHCGNGIPX3QQDwmtZ4gAAABAgME"
|
||||
"BQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fBQDMDQAALS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVnVEND"
|
||||
"QkNhZ0F3SUJBZ0lVU3I5VmR"
|
||||
"iSnFWbzVyZzRadUpCRWo2SjNoak9jd0NnWUlLb1pJemowRUF3SXcKY1RFak1DRUdBMVVFQXd3YVNXNTBaV3dnVTBkWUl"
|
||||
"GQkRTeUJRY205alpYTnpiM0"
|
||||
"lnUTBFeEdqQVlCZ05WQkFvTQpFVWx1ZEdWc0lFTnZjbkJ2Y21GMGFXOXVNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQkRiR0"
|
||||
"Z5WVRFTE1Ba0dBMVVFCkNBd"
|
||||
"0NRMEV4Q3pBSkJnTlZCQVlUQWxWVE1CNFhEVEl4TURNeE9UQTBOVEl3T0ZvWERUSTRNRE14T1RBME5USXcKT0Zvd2NER"
|
||||
"WlNQ0FHQTFVRUF3d1pTVzUw"
|
||||
"Wld3Z1UwZFlJRkJEU3lCRFpYSjBhV1pwWTJGMFpURWFNQmdHQTFVRQpDZ3dSU1c1MFpXd2dRMjl5Y0c5eVlYUnBiMjR4"
|
||||
"RkRBU0JnTlZCQWNNQzFOaGJ"
|
||||
"uUmhJRU5zWVhKaE1Rc3dDUVlEClZRUUlEQUpEUVRFTE1Ba0dBMVVFQmhNQ1ZWTXdXVEFUQmdjcWhrak9QUUlCQmdncWh"
|
||||
"rak9QUU1CQndOQ0FBUlQKVG"
|
||||
"RNNVhTMGFiRTA2ZUdVTVU3S1JOQXJlRGRtTWJHK25KVHlucDZXankyeXJ6NmlEa3h1R1F3WGZ1b25uUVBuZApjdHgwbH"
|
||||
"IyR3I0WjF1YXNsQjM2Vm80S"
|
||||
"UNtekNDQXBjd0h3WURWUjBqQkJnd0ZvQVUwT2lxMm5YWCtTNUpGNWc4CmV4UmwwTlh5V1Uwd1h3WURWUjBmQkZnd1ZqQ"
|
||||
"lVvRktnVUlaT2FIUjBjSE02"
|
||||
"THk5aGNHa3VkSEoxYzNSbFpITmwKY25acFkyVnpMbWx1ZEdWc0xtTnZiUzl6WjNndlkyVnlkR2xtYVdOaGRHbHZiaTky"
|
||||
"TWk5d1kydGpjbXcvWTJFOQp"
|
||||
"jSEp2WTJWemMyOXlNQjBHQTFVZERnUVdCQlRMejZNQ3VHcVZobFYrR2Q0ZGtacmx4YndCV2pBT0JnTlZIUThCCkFmOEV"
|
||||
"CQU1DQnNBd0RBWURWUjBUQV"
|
||||
"FIL0JBSXdBRENDQWRRR0NTcUdTSWI0VFFFTkFRU0NBY1V3Z2dIQk1CNEcKQ2lxR1NJYjRUUUVOQVFFRUVMOEhhRExXWW"
|
||||
"dVUFUzU3c3Tm1Ibkhrd2dnR"
|
||||
"mtCZ29xaGtpRytFMEJEUUVDTUlJQgpWREFRQmdzcWhraUcrRTBCRFFFQ0FRSUJFVEFRQmdzcWhraUcrRTBCRFFFQ0FnS"
|
||||
"UJFVEFRQmdzcWhraUcrRTBC"
|
||||
"CkRRRUNBd0lCQWpBUUJnc3Foa2lHK0UwQkRRRUNCQUlCQkRBUUJnc3Foa2lHK0UwQkRRRUNCUUlCQVRBUkJnc3EKaGtp"
|
||||
"RytFMEJEUUVDQmdJQ0FJQXd"
|
||||
"FQVlMS29aSWh2aE5BUTBCQWdjQ0FRWXdFQVlMS29aSWh2aE5BUTBCQWdnQwpBUUF3RUFZTEtvWklodmhOQVEwQkFna0N"
|
||||
"BUUF3RUFZTEtvWklodmhOQV"
|
||||
"EwQkFnb0NBUUF3RUFZTEtvWklodmhOCkFRMEJBZ3NDQVFBd0VBWUxLb1pJaHZoTkFRMEJBZ3dDQVFBd0VBWUxLb1pJaH"
|
||||
"ZoTkFRMEJBZzBDQVFBd0VBW"
|
||||
"UwKS29aSWh2aE5BUTBCQWc0Q0FRQXdFQVlMS29aSWh2aE5BUTBCQWc4Q0FRQXdFQVlMS29aSWh2aE5BUTBCQWhBQwpBU"
|
||||
"UF3RUFZTEtvWklodmhOQVEw"
|
||||
"QkFoRUNBUW93SHdZTEtvWklodmhOQVEwQkFoSUVFQkVSQWdRQmdBWUFBQUFBCkFBQUFBQUF3RUFZS0tvWklodmhOQVEw"
|
||||
"QkF3UUNBQUF3RkFZS0tvWkl"
|
||||
"odmhOQVEwQkJBUUdBSkJ1MVFBQU1BOEcKQ2lxR1NJYjRUUUVOQVFVS0FRQXdDZ1lJS29aSXpqMEVBd0lEU1FBd1JnSWh"
|
||||
"BSzZPMS9GNy80NFprcWhUN2"
|
||||
"FhNgp5QVh6QlltRWxUVHRvL25rVUd4N1BtUktBaUVBMXliSWt6SjVwcXR1L21jOW5DUWNwRUJOdk5KZFNIcW1jc04rCk"
|
||||
"V2dWJ3WlU9Ci0tLS0tRU5EI"
|
||||
"ENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNsekNDQWo2Z0F3SUJBZ0lWQU5Eb"
|
||||
"3F0cDExL2t1U1JlWVBIc1Va"
|
||||
"ZERWOGxsTk1Bb0dDQ3FHU000OUJBTUMKTUdneEdqQVlCZ05WQkFNTUVVbHVkR1ZzSUZOSFdDQlNiMjkwSUVOQk1Sb3dH"
|
||||
"QVlEVlFRS0RCRkpiblJsYkN"
|
||||
"CRApiM0p3YjNKaGRHbHZiakVVTUJJR0ExVUVCd3dMVTJGdWRHRWdRMnhoY21FeEN6QUpCZ05WQkFnTUFrTkJNUXN3CkN"
|
||||
"RWURWUVFHRXdKVlV6QWVGdz"
|
||||
"B4T0RBMU1qRXhNRFExTURoYUZ3MHpNekExTWpFeE1EUTFNRGhhTUhFeEl6QWgKQmdOVkJBTU1Ha2x1ZEdWc0lGTkhXQ0"
|
||||
"JRUTBzZ1VISnZZMlZ6YzI5e"
|
||||
"UlFTkJNUm93R0FZRFZRUUtEQkZKYm5SbApiQ0JEYjNKd2IzSmhkR2x2YmpFVU1CSUdBMVVFQnd3TFUyRnVkR0VnUTJ4a"
|
||||
"GNtRXhDekFKQmdOVkJBZ01B"
|
||||
"a05CCk1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCTDlxK05NcDJJT2cK"
|
||||
"dGRsMWJrL3VXWjUrVEdRbTh"
|
||||
"hQ2k4ejc4ZnMrZktDUTNkK3VEelhuVlRBVDJaaERDaWZ5SXVKd3ZOM3dOQnA5aQpIQlNTTUpNSnJCT2pnYnN3Z2Jnd0h"
|
||||
"3WURWUjBqQkJnd0ZvQVVJbV"
|
||||
"VNMWxxZE5JbnpnN1NWVXI5UUd6a25CcXd3ClVnWURWUjBmQkVzd1NUQkhvRVdnUTRaQmFIUjBjSE02THk5alpYSjBhV1"
|
||||
"pwWTJGMFpYTXVkSEoxYzNSb"
|
||||
"FpITmwKY25acFkyVnpMbWx1ZEdWc0xtTnZiUzlKYm5SbGJGTkhXRkp2YjNSRFFTNWpjbXd3SFFZRFZSME9CQllFRk5Eb"
|
||||
"wpxdHAxMS9rdVNSZVlQSHNV"
|
||||
"WmREVjhsbE5NQTRHQTFVZER3RUIvd1FFQXdJQkJqQVNCZ05WSFJNQkFmOEVDREFHCkFRSC9BZ0VBTUFvR0NDcUdTTTQ5"
|
||||
"QkFNQ0EwY0FNRVFDSUMvOWo"
|
||||
"rODRUK0h6dFZPL3NPUUJXSmJTZCsvMnVleEsKNCthQTBqY0ZCTGNwQWlBM2RoTXJGNWNENTJ0NkZxTXZBSXBqOFhkR21"
|
||||
"5MmJlZWxqTEpLK3B6cGNSQT"
|
||||
"09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNqakNDQWpTZ0"
|
||||
"F3SUJBZ0lVSW1VTTFscWROS"
|
||||
"W56ZzdTVlVyOVFHemtuQnF3d0NnWUlLb1pJemowRUF3SXcKYURFYU1CZ0dBMVVFQXd3UlNXNTBaV3dnVTBkWUlGSnZiM"
|
||||
"1FnUTBFeEdqQVlCZ05WQkFv"
|
||||
"TUVVbHVkR1ZzSUVOdgpjbkJ2Y21GMGFXOXVNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQkRiR0Z5WVRFTE1Ba0dBMVVFQ0F3"
|
||||
"Q1EwRXhDekFKCkJnTlZCQVl"
|
||||
"UQWxWVE1CNFhEVEU0TURVeU1URXdOREV4TVZvWERUTXpNRFV5TVRFd05ERXhNRm93YURFYU1CZ0cKQTFVRUF3d1JTVzU"
|
||||
"wWld3Z1UwZFlJRkp2YjNRZ1"
|
||||
"EwRXhHakFZQmdOVkJBb01FVWx1ZEdWc0lFTnZjbkJ2Y21GMAphVzl1TVJRd0VnWURWUVFIREF0VFlXNTBZU0JEYkdGeV"
|
||||
"lURUxNQWtHQTFVRUNBd0NRM"
|
||||
"EV4Q3pBSkJnTlZCQVlUCkFsVlRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVDNm5Fd01ESVlaT2ova"
|
||||
"VBXc0N6YUVLaTcKMU9pT1NM"
|
||||
"UkZoV0dqYm5CVkpmVm5rWTR1M0lqa0RZWUwwTXhPNG1xc3lZamxCYWxUVll4RlAyc0pCSzV6bEtPQgp1ekNCdURBZkJn"
|
||||
"TlZIU01FR0RBV2dCUWlaUXp"
|
||||
"XV3AwMGlmT0R0SlZTdjFBYk9TY0dyREJTQmdOVkhSOEVTekJKCk1FZWdSYUJEaGtGb2RIUndjem92TDJObGNuUnBabWx"
|
||||
"qWVhSbGN5NTBjblZ6ZEdWa2"
|
||||
"MyVnlkbWxqWlhNdWFXNTAKWld3dVkyOXRMMGx1ZEdWc1UwZFlVbTl2ZEVOQkxtTnliREFkQmdOVkhRNEVGZ1FVSW1VTT"
|
||||
"FscWROSW56ZzdTVgpVcjlRR"
|
||||
"3prbkJxd3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRRXdDZ1lJCktvWkl6ajBFQ"
|
||||
"XdJRFNBQXdSUUlnUVFzLzA4"
|
||||
"cnljZFBhdUNGazhVUFFYQ01BbHNsb0JlN053YVFHVGNkcGEwRUMKSVFDVXQ4U0d2eEttanBjTS96MFdQOUR2bzhoMms1"
|
||||
"ZHUxaVdEZEJrQW4rMGlpQT0"
|
||||
"9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KAA");
|
||||
|
||||
const std::string OpenEnclaveNonDebugQuote(
|
||||
"AQAAAAIAAADoEQAAAAAAAAMAAgAAAAAABQAKAJOacjP3nEyplAoNs5V_BgfDYELtjmo1LWZEqF8xasaZAAAAABERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAABwAAAAAAAAC3eSAmGL7LY2do5dkC8o1SQiJzX6-"
|
||||
"1OeqboHw_wXGhwgAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAALBpElSroIHE1xsKbdbjAKTcu6UtnfhXCC9QjQPENQaoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKFQuRP5-c_ZhD2sxrnV2kl8JzNu0xWRlg-"
|
||||
"zBVhM3qP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQQAA"
|
||||
"Ck3Zl7b4XERNDrAJfKbmzU0NSTIzY5rsFeyW_6deDzOyjXAnxA3b1WfBwrFrU9JKpfI9SDlpwms3YSQtJArmrD-8i_"
|
||||
"meLNk8sQSwSkR7TdIadTEAZdb7S-7qMt"
|
||||
"Yt3kWMfQ7H3g338R0kcF9wcy0jZmeBrRLDXyEUDcPI63Fwvp_BERAwX_"
|
||||
"gAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAAAAA"
|
||||
"AABwAAAAAAAAA_sKzghp0uMPKOhtcMdmQDpU-"
|
||||
"7zWWO7ODhuUipFVkXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjE9XddeWUD6WE393xoqCmgBW"
|
||||
"rI3tcBQLCBsJRJDFe_"
|
||||
"8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAABAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AAAAAAAAAAAAAAAAAAmm22hOMEcuVw"
|
||||
"P_d08cVnQ2JF3uT3Q5as4s-"
|
||||
"D4yNshB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgCuq8kIluOwzRvIHV3J7G-"
|
||||
"62qz2UxkrKQ2aJHVWlzGwveCOd"
|
||||
"GIgpSJVM7GNcJW12FOveof_7m_"
|
||||
"nA78uk3D3C4gAAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fBQDMDQAALS0tLS1CRUdJTiBDRVJUSUZJQ0FU"
|
||||
"RS0t"
|
||||
"LS0tCk1JSUVnVENDQkNlZ0F3SUJBZ0lWQU9jMDJHVHYvUTRvOUhHS1Bndk8yeUpPMElWTk1Bb0dDQ3FHU000OUJBTUMK"
|
||||
"TUhFeEl6QWhCZ05WQkFNTUdrbHVkR1"
|
||||
"ZzSUZOSFdDQlFRMHNnVUhKdlkyVnpjMjl5SUVOQk1Sb3dHQVlEVlFRSwpEQkZKYm5SbGJDQkRiM0p3YjNKaGRHbHZiak"
|
||||
"VVTUJJR0ExVUVCd3dMVTJGdWRHRWdR"
|
||||
"MnhoY21FeEN6QUpCZ05WCkJBZ01Ba05CTVFzd0NRWURWUVFHRXdKVlV6QWVGdzB5TVRBME1Ea3hNalU1TWpoYUZ3MHlP"
|
||||
"REEwTURreE1qVTUKTWpoYU1IQXhJak"
|
||||
"FnQmdOVkJBTU1HVWx1ZEdWc0lGTkhXQ0JRUTBzZ1EyVnlkR2xtYVdOaGRHVXhHakFZQmdOVgpCQW9NRVVsdWRHVnNJRU"
|
||||
"52Y25CdmNtRjBhVzl1TVJRd0VnWURW"
|
||||
"UVFIREF0VFlXNTBZU0JEYkdGeVlURUxNQWtHCkExVUVDQXdDUTBFeEN6QUpCZ05WQkFZVEFsVlRNRmt3RXdZSEtvWkl6"
|
||||
"ajBDQVFZSUtvWkl6ajBEQVFjRFFnQU"
|
||||
"UKYzZ1TjVuZGlFY25mWUp1OFU1MUgzc3lzWm5kQ05JamlwRVdEZjJuaXp6VU9XdlZjdjIxWUUwakxMdmxpL2s3NAp2bj"
|
||||
"FtUzYvbkNYV3MxOFVZeE1PMFM2T0NB"
|
||||
"cHN3Z2dLWE1COEdBMVVkSXdRWU1CYUFGTkRvcXRwMTEva3VTUmVZClBIc1VaZERWOGxsTk1GOEdBMVVkSHdSWU1GWXdW"
|
||||
"S0JTb0ZDR1RtaDBkSEJ6T2k4dllYQn"
|
||||
"BMblJ5ZFhOMFpXUnoKWlhKMmFXTmxjeTVwYm5SbGJDNWpiMjB2YzJkNEwyTmxjblJwWm1sallYUnBiMjR2ZGpJdmNHTn"
|
||||
"JZM0pzUDJOaApQWEJ5YjJObGMzTnZj"
|
||||
"akFkQmdOVkhRNEVGZ1FVRzBZaHd5VEh2bFFUNFlQVU1lRGplMmFUUWNjd0RnWURWUjBQCkFRSC9CQVFEQWdiQU1Bd0dB"
|
||||
"MVVkRXdFQi93UUNNQUF3Z2dIVUJna3"
|
||||
"Foa2lHK0UwQkRRRUVnZ0hGTUlJQndUQWUKQmdvcWhraUcrRTBCRFFFQkJCRDBRZ2lrT3FkRWxVQnJYSWFPdCtVYU1JSU"
|
||||
"JaQVlLS29aSWh2aE5BUTBCQWpDQwpB"
|
||||
"VlF3RUFZTEtvWklodmhOQVEwQkFnRUNBUkV3RUFZTEtvWklodmhOQVEwQkFnSUNBUkV3RUFZTEtvWklodmhOCkFRMEJB"
|
||||
"Z01DQVFJd0VBWUxLb1pJaHZoTkFRME"
|
||||
"JBZ1FDQVFRd0VBWUxLb1pJaHZoTkFRMEJBZ1VDQVFFd0VRWUwKS29aSWh2aE5BUTBCQWdZQ0FnQ0FNQkFHQ3lxR1NJYj"
|
||||
"RUUUVOQVFJSEFnRUdNQkFHQ3lxR1NJ"
|
||||
"YjRUUUVOQVFJSQpBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSUpBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSUtBZ0VBTUJBR0N5"
|
||||
"cUdTSWI0ClRRRU5BUUlMQWdFQU1CQU"
|
||||
"dDeXFHU0liNFRRRU5BUUlNQWdFQU1CQUdDeXFHU0liNFRRRU5BUUlOQWdFQU1CQUcKQ3lxR1NJYjRUUUVOQVFJT0FnRU"
|
||||
"FNQkFHQ3lxR1NJYjRUUUVOQVFJUEFn"
|
||||
"RUFNQkFHQ3lxR1NJYjRUUUVOQVFJUQpBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSVJBZ0VLTUI4R0N5cUdTSWI0VFFFTkFR"
|
||||
"SVNCQkFSRVFJRUFZQUdBQUFBCkFBQU"
|
||||
"FBQUFBTUJBR0NpcUdTSWI0VFFFTkFRTUVBZ0FBTUJRR0NpcUdTSWI0VFFFTkFRUUVCZ0NRYnRVQUFEQVAKQmdvcWhraU"
|
||||
"crRTBCRFFFRkNnRUFNQW9HQ0NxR1NN"
|
||||
"NDlCQU1DQTBnQU1FVUNJUUNiNVBlMkd6ZkJTeWh2VDB4MgpXWEQ4MWlHYm8vMUs2cU9zRm1XNjg4R0FPZ0lnUzRiZjUr"
|
||||
"R0R6VExPUXpNMitESVJEc0VPelpUR1"
|
||||
"Jzc3pTOHFECm1lSVBKKzA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS"
|
||||
"0tCk1JSUNsekNDQWo2Z0F3SUJBZ0lW"
|
||||
"QU5Eb3F0cDExL2t1U1JlWVBIc1VaZERWOGxsTk1Bb0dDQ3FHU000OUJBTUMKTUdneEdqQVlCZ05WQkFNTUVVbHVkR1Zz"
|
||||
"SUZOSFdDQlNiMjkwSUVOQk1Sb3dHQV"
|
||||
"lEVlFRS0RCRkpiblJsYkNCRApiM0p3YjNKaGRHbHZiakVVTUJJR0ExVUVCd3dMVTJGdWRHRWdRMnhoY21FeEN6QUpCZ0"
|
||||
"5WQkFnTUFrTkJNUXN3CkNRWURWUVFH"
|
||||
"RXdKVlV6QWVGdzB4T0RBMU1qRXhNRFExTURoYUZ3MHpNekExTWpFeE1EUTFNRGhhTUhFeEl6QWgKQmdOVkJBTU1Ha2x1"
|
||||
"ZEdWc0lGTkhXQ0JRUTBzZ1VISnZZMl"
|
||||
"Z6YzI5eUlFTkJNUm93R0FZRFZRUUtEQkZKYm5SbApiQ0JEYjNKd2IzSmhkR2x2YmpFVU1CSUdBMVVFQnd3TFUyRnVkR0"
|
||||
"VnUTJ4aGNtRXhDekFKQmdOVkJBZ01B"
|
||||
"a05CCk1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCTDlxK05NcDJJT2cK"
|
||||
"dGRsMWJrL3VXWjUrVEdRbThhQ2k4ej"
|
||||
"c4ZnMrZktDUTNkK3VEelhuVlRBVDJaaERDaWZ5SXVKd3ZOM3dOQnA5aQpIQlNTTUpNSnJCT2pnYnN3Z2Jnd0h3WURWUj"
|
||||
"BqQkJnd0ZvQVVJbVVNMWxxZE5Jbnpn"
|
||||
"N1NWVXI5UUd6a25CcXd3ClVnWURWUjBmQkVzd1NUQkhvRVdnUTRaQmFIUjBjSE02THk5alpYSjBhV1pwWTJGMFpYTXVk"
|
||||
"SEoxYzNSbFpITmwKY25acFkyVnpMbW"
|
||||
"x1ZEdWc0xtTnZiUzlKYm5SbGJGTkhXRkp2YjNSRFFTNWpjbXd3SFFZRFZSME9CQllFRk5EbwpxdHAxMS9rdVNSZVlQSH"
|
||||
"NVWmREVjhsbE5NQTRHQTFVZER3RUIv"
|
||||
"d1FFQXdJQkJqQVNCZ05WSFJNQkFmOEVDREFHCkFRSC9BZ0VBTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUMvOWorODRU"
|
||||
"K0h6dFZPL3NPUUJXSmJTZCsvMnVleE"
|
||||
"sKNCthQTBqY0ZCTGNwQWlBM2RoTXJGNWNENTJ0NkZxTXZBSXBqOFhkR215MmJlZWxqTEpLK3B6cGNSQT09Ci0tLS0tRU"
|
||||
"5EIENFUlRJRklDQVRFLS0tLS0KLS0t"
|
||||
"LS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNqakNDQWpTZ0F3SUJBZ0lVSW1VTTFscWROSW56ZzdTVlVyOVFHemtu"
|
||||
"QnF3d0NnWUlLb1pJemowRUF3SXcKYU"
|
||||
"RFYU1CZ0dBMVVFQXd3UlNXNTBaV3dnVTBkWUlGSnZiM1FnUTBFeEdqQVlCZ05WQkFvTUVVbHVkR1ZzSUVOdgpjbkJ2Y2"
|
||||
"1GMGFXOXVNUlF3RWdZRFZRUUhEQXRU"
|
||||
"WVc1MFlTQkRiR0Z5WVRFTE1Ba0dBMVVFQ0F3Q1EwRXhDekFKCkJnTlZCQVlUQWxWVE1CNFhEVEU0TURVeU1URXdOREV4"
|
||||
"TVZvWERUTXpNRFV5TVRFd05ERXhNRm"
|
||||
"93YURFYU1CZ0cKQTFVRUF3d1JTVzUwWld3Z1UwZFlJRkp2YjNRZ1EwRXhHakFZQmdOVkJBb01FVWx1ZEdWc0lFTnZjbk"
|
||||
"J2Y21GMAphVzl1TVJRd0VnWURWUVFI"
|
||||
"REF0VFlXNTBZU0JEYkdGeVlURUxNQWtHQTFVRUNBd0NRMEV4Q3pBSkJnTlZCQVlUCkFsVlRNRmt3RXdZSEtvWkl6ajBD"
|
||||
"QVFZSUtvWkl6ajBEQVFjRFFnQUVDNm"
|
||||
"5Fd01ESVlaT2ovaVBXc0N6YUVLaTcKMU9pT1NMUkZoV0dqYm5CVkpmVm5rWTR1M0lqa0RZWUwwTXhPNG1xc3lZamxCYW"
|
||||
"xUVll4RlAyc0pCSzV6bEtPQgp1ekNC"
|
||||
"dURBZkJnTlZIU01FR0RBV2dCUWlaUXpXV3AwMGlmT0R0SlZTdjFBYk9TY0dyREJTQmdOVkhSOEVTekJKCk1FZWdSYUJE"
|
||||
"aGtGb2RIUndjem92TDJObGNuUnBabW"
|
||||
"xqWVhSbGN5NTBjblZ6ZEdWa2MyVnlkbWxqWlhNdWFXNTAKWld3dVkyOXRMMGx1ZEdWc1UwZFlVbTl2ZEVOQkxtTnliRE"
|
||||
"FkQmdOVkhRNEVGZ1FVSW1VTTFscWRO"
|
||||
"SW56ZzdTVgpVcjlRR3prbkJxd3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRRXdD"
|
||||
"Z1lJCktvWkl6ajBFQXdJRFNBQXdSUU"
|
||||
"lnUVFzLzA4cnljZFBhdUNGazhVUFFYQ01BbHNsb0JlN053YVFHVGNkcGEwRUMKSVFDVXQ4U0d2eEttanBjTS96MFdQOU"
|
||||
"R2bzhoMms1ZHUxaVdEZEJrQW4rMGlp"
|
||||
"QT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KAA");
|
||||
|
||||
std::string RuntimeJWKClaim = R"(
|
||||
{
|
||||
"jwk" : {
|
||||
"kty":"EC",
|
||||
"use":"sig",
|
||||
"crv":"P-256",
|
||||
"x":"18wHLeIgW9wVN6VD1Txgpqy2LszYkMf6J8njVAibvhM",
|
||||
"y":"cV4dS4UaLMgP_4fY4j8ir7cl1TXlFdAgcx55o7TkcSA"
|
||||
}
|
||||
}
|
||||
)";
|
||||
std::string SgxEnclaveHeldData
|
||||
= "CiAgICAgICAgewogICAgICAgICAgICAiandrIiA6IHsKICAgICAgICAgICAgICAgICJrdHkiOiJFQyI"
|
||||
"sCiAgICAgICAgICAgICAgICAidXNlIjoic2lnIiwKICAgICAgICAgICAgICAgICJjcnYiOiJQLTI1Ni"
|
||||
"IsCiAgICAgICAgICAgICAgICAieCI6IjE4d0hMZUlnVzl3Vk42VkQxVHhncHF5MkxzellrTWY2Sjhua"
|
||||
"lZBaWJ2aE0iLAogICAgICAgICAgICAgICAgInkiOiJjVjRkUzRVYUxNZ1BfNGZZNGo4aXI3Y2wxVFhs"
|
||||
"RmRBZ2N4NTVvN1RrY1NBIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAA";
|
||||
// cspell:enable
|
||||
|
||||
class AttestationCollateral {
|
||||
public:
|
||||
static std::vector<uint8_t> OpenEnclaveReport()
|
||||
{
|
||||
return Azure::Core::_internal::Base64Url::Base64UrlDecode(OpenEnclaveQuote);
|
||||
}
|
||||
static std::vector<uint8_t> SgxQuote()
|
||||
{
|
||||
// An OpenEnclave report is a wrapper around an SGX quote - there are
|
||||
// 16 bytes of OpenEnclave header at the start of the report and what remains is
|
||||
// an SGX quote, so to convert from an OE report to an SGX quote simply strip
|
||||
// the first 16 bytes of the report.
|
||||
auto openEnclaveReport = OpenEnclaveReport();
|
||||
openEnclaveReport.erase(openEnclaveReport.begin(), openEnclaveReport.begin() + 16);
|
||||
return openEnclaveReport;
|
||||
// return std::vector<uint8_t>(openEnclaveReport.begin() + 0x10, openEnclaveReport.end());
|
||||
}
|
||||
static std::vector<uint8_t> RuntimeData()
|
||||
{
|
||||
return Azure::Core::_internal::Base64Url::Base64UrlDecode(SgxEnclaveHeldData);
|
||||
// return std::vector<uint8_t>(RuntimeJWKClaim.begin(), RuntimeJWKClaim.end());
|
||||
}
|
||||
static std::vector<uint8_t> OpenEnclaveReport();
|
||||
static std::vector<uint8_t> SgxQuote();
|
||||
static std::vector<uint8_t> RuntimeData();
|
||||
};
|
||||
}}}} // namespace Azure::Security::Attestation::Test
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace Azure::Security::Attestation;
|
||||
using namespace Azure::Core;
|
||||
|
||||
namespace Azure { namespace Security { namespace Attestation { namespace Test {
|
||||
|
||||
@ -54,11 +55,19 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test {
|
||||
std::unique_ptr<AttestationClient> CreateAuthenticatedClient()
|
||||
{
|
||||
// `InitClientOptions` takes care of setting up Record&Playback.
|
||||
auto options = InitClientOptions<Azure::Security::Attestation::AttestationClientOptions>();
|
||||
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(
|
||||
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
|
||||
AttestationClientOptions options;
|
||||
if (m_testContext.IsPlaybackMode())
|
||||
{
|
||||
// Skip validating time stamps if using recordings.
|
||||
options.TokenValidationOptions.ValidateNotBeforeTime = false;
|
||||
options.TokenValidationOptions.ValidateExpirationTime = false;
|
||||
}
|
||||
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential
|
||||
= std::make_shared<Azure::Identity::ClientSecretCredential>(
|
||||
GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET"));
|
||||
|
||||
return std::make_unique<AttestationClient>(m_endpoint, credential, options);
|
||||
return InitTestClient<AttestationClient, AttestationClientOptions>(
|
||||
m_endpoint, credential, options);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@
|
||||
"Headers": {
|
||||
"content-type": "application/json",
|
||||
"user-agent": "azsdk-cpp-Attestation/1.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)",
|
||||
"x-ms-client-request-id": "e046efa1-c976-4b55-72dd-aa397b095785"
|
||||
"x-ms-client-request-id": "2b846afd-db33-4a76-4c53-62ad37784ac7"
|
||||
},
|
||||
"Method": "GET",
|
||||
"Response": {
|
||||
@ -13,10 +13,10 @@
|
||||
"STATUS_CODE": "200",
|
||||
"content-length": "612",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"date": "Tue, 15 Feb 2022 23:42:32 GMT",
|
||||
"date": "Fri, 18 Feb 2022 22:54:35 GMT",
|
||||
"server": "Kestrel",
|
||||
"x-ms-maa-service-version": "1.10.01847.0002",
|
||||
"x-ms-request-id": "00-5743d231cf8c458d2f1697e995e29ea0-0000000000000000-00"
|
||||
"x-ms-request-id": "00-8681f02e670159945fc7e2739e960153-0000000000000000-00"
|
||||
},
|
||||
"Url": "https://REDACTED.wus.attest.azure.net/.well-known/openid-configuration"
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"Headers": {
|
||||
"content-type": "application/json",
|
||||
"user-agent": "azsdk-cpp-Attestation/1.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)",
|
||||
"x-ms-client-request-id": "77922c07-6bda-41fc-7400-2f5db58dee20"
|
||||
"x-ms-client-request-id": "0f497567-f183-4d46-5d1c-9d29b13ba646"
|
||||
},
|
||||
"Method": "GET",
|
||||
"Response": {
|
||||
@ -13,10 +13,10 @@
|
||||
"STATUS_CODE": "200",
|
||||
"content-length": "612",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"date": "Tue, 15 Feb 2022 23:42:32 GMT",
|
||||
"date": "Fri, 18 Feb 2022 22:54:35 GMT",
|
||||
"server": "Kestrel",
|
||||
"x-ms-maa-service-version": "1.10.01847.0002",
|
||||
"x-ms-request-id": "00-d1489f7996238011361c19ab5d2320e3-0000000000000000-00"
|
||||
"x-ms-request-id": "00-37a7b30eb34898490aaee465889da23f-0000000000000000-00"
|
||||
},
|
||||
"Url": "https://REDACTED.wus.attest.azure.net/.well-known/openid-configuration"
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"Headers": {
|
||||
"content-type": "application/json",
|
||||
"user-agent": "azsdk-cpp-Attestation/1.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)",
|
||||
"x-ms-client-request-id": "f8a13526-14a5-4cf1-6426-4ac61aa2eaca"
|
||||
"x-ms-client-request-id": "d5ce1416-62ce-4254-53f4-4e41106486c2"
|
||||
},
|
||||
"Method": "GET",
|
||||
"Response": {
|
||||
@ -13,10 +13,10 @@
|
||||
"STATUS_CODE": "200",
|
||||
"content-length": "573",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"date": "Tue, 15 Feb 2022 23:42:31 GMT",
|
||||
"date": "Fri, 18 Feb 2022 22:54:35 GMT",
|
||||
"server": "Kestrel",
|
||||
"x-ms-maa-service-version": "1.10.01847.0002",
|
||||
"x-ms-request-id": "00-dc235c9a32f5f0088db57b1bcdf25057-0000000000000000-00"
|
||||
"x-ms-request-id": "00-eb432378564692a729b975fcd4491565-0000000000000000-00"
|
||||
},
|
||||
"Url": "https://REDACTED.wus.attest.azure.net/.well-known/openid-configuration"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -26,7 +26,9 @@ stages:
|
||||
- template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml
|
||||
parameters:
|
||||
ServiceDirectory: attestation
|
||||
Location: WestUS
|
||||
CtestRegex: azure-security-attestation.*
|
||||
LiveTestCtestRegex: azure-security-attestation.*
|
||||
LineCoverageTarget: 90
|
||||
BranchCoverageTarget: 45
|
||||
Artifacts:
|
||||
@ -47,5 +49,6 @@ stages:
|
||||
Value: "non-real-client"
|
||||
- Name: AZURE_CLIENT_SECRET
|
||||
Value: "non-real-secret"
|
||||
# NOTE: The LOCATION_SHORT_NAME *must* match the region in which the tests were created.
|
||||
- Name: LOCATION_SHORT_NAME
|
||||
Value: "wus"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user