Skip to content

Commit 6527358

Browse files
Significant update to samples (Azure#25545)
* Significant update to samples
1 parent 7849438 commit 6527358

36 files changed

+2920
-484
lines changed

sdk/attestation/azure-security-attestation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ on the `AttestationClientBuilder` class and implemented a new `AttestationAdmini
4949
with the `listPolicyManagementCertificates`, `addPolicyManagementCertificate` and `removePolicyManagementCertificate` APIs on the `AttestationAdministrationClient` object.
5050
* Removed `JsonWebKey`, `JsonWebKeySet`, `PolicyCertificatesModificationResult`, `PolicyCertificatesModifyResponse`, and `CertificatesResponse` objects
5151
because they are no longer a part of the public API surface.
52+
* Refactored `AttestationSigningKey` class to require certificate and signing key parameters in constructor.
5253

5354
### Bugs Fixed
5455
* Attestation tests now all pass when run in Live mode.

sdk/attestation/azure-security-attestation/README.md

Lines changed: 140 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -83,88 +83,173 @@ For more information on attestation policies, see [Attestation Policy](https://d
8383
When an attestation instance is running in "Isolated" mode, the customer who created the instance will have provided
8484
a policy management certificate at the time the instance is created. All policy modification operations require that the customer sign
8585
the policy data with one of the existing policy management certificates. The Policy Management Certificate Management APIs enable
86-
clients to "roll" the policy management certificates.
86+
clients to add, remove or enumerate the policy management certificates.
8787

8888

8989
## Examples
9090

91-
* [Attest an SGX enclave](#attest-sgx-enclave)
92-
* [Get attestation policy](#get-attestation-policy)
91+
* [Instantiate a synchronous attestation client](#create-a-synchronous-attestation-client)
9392
* [Retrieve token validation certificates](#retrieve-token-certificates)
93+
* [Attest an SGX enclave](#attest-an-sgx-enclave)
94+
* [Instantiate a synchronous administrative client](#create-a-synchronous-administrative-client)
95+
* [Get attestation policy](#retrieve-current-attestation-policy-for-openenclave)
96+
* [Set unsigned attestation policy](#set-unsigned-attestation-policy-aad-clients-only)
97+
* [Set signed attestation policy](#set-signed-attestation-policy)
98+
* [List policy management certificates](#list-attestation-signing-certificates)
99+
* [Add policy management certificate](#add-attestation-signing-certificate)
100+
101+
### Create a synchronous attestation client
102+
The `AttestationClientBuilder` class is used to create instances of the attestation client:
103+
104+
```java readme-sample-create-synchronous-client
105+
AttestationClientBuilder attestationBuilder = new AttestationClientBuilder();
106+
// Note that the "attest" calls do not require authentication.
107+
AttestationClient client = attestationBuilder
108+
.endpoint(endpoint)
109+
.buildClient();
110+
```
94111

95-
### Attest SGX Enclave
112+
### Retrieve Token Certificates
96113

97-
Use the `attestSgxEnclave` method to attest an SGX enclave.
98-
<!-- embedme src\samples\com\azure\security\attestation\ReadmeSamples.java#L36-L44 -->
99-
```java
100-
AttestSgxEnclaveRequest request = new AttestSgxEnclaveRequest();
101-
request.setQuote(decodedSgxQuote);
102-
RuntimeData runtimeData = new RuntimeData();
103-
runtimeData.setDataType(DataType.BINARY);
104-
runtimeData.setData(decodedRuntimeData);
105-
request.setRuntimeData(runtimeData);
106-
AttestationResponse response = client.attestSgxEnclave(request);
107-
108-
JWTClaimsSet claims = null;
114+
Use `listAttestationSigners` to retrieve the set of certificates which can be used to validate the token returned from the attestation service.
115+
Normally, this information is not required as the attestation SDK will perform the validation as a part of the interaction with the
116+
attestation service, however the APIs are provided for completeness and to facilitate customer's independently validating
117+
attestation results.
118+
119+
```java readme-sample-getSigningCertificates
120+
List<AttestationSigner> certs = client.listAttestationSigners();
121+
122+
certs.forEach(cert -> {
123+
System.out.println("Found certificate.");
124+
if (cert.getKeyId() != null) {
125+
System.out.println(" Certificate Key ID: " + cert.getKeyId());
126+
} else {
127+
System.out.println(" Signer does not have a Key ID");
128+
}
129+
cert.getCertificates().forEach(chainElement -> {
130+
System.out.println(" Cert Subject: " + chainElement.getSubjectDN().getName());
131+
System.out.println(" Cert Issuer: " + chainElement.getIssuerDN().getName());
132+
});
133+
});
109134
```
135+
### Attest an SGX Enclave
110136

111-
### Get attestation policy
137+
Use the `attestSgxEnclave` method to attest an SGX enclave.
138+
```java readme-sample-attest-sgx-enclave
139+
BinaryData decodedRuntimeData = BinaryData.fromBytes(SampleCollateral.getRunTimeData());
140+
BinaryData sgxQuote = BinaryData.fromBytes(SampleCollateral.getSgxEnclaveQuote());
112141

113-
The `attestationPolicyClient.get` method retrieves the attestation policy from the service.
114-
Attestation Policies are instanced on a per-attestation type basis, the `AttestationType` parameter defines the type to retrieve.
115-
The response to an attestation policy get is a JSON Web Token signed by the attestation service.
116-
The token contains an `x-ms-policy` claim, which in turn contains the secured (or unsecured) attestation policy document which was
117-
set by the customer.
142+
// Attest evidence from an OpenEnclave enclave specifying runtime data which should be
143+
// interpreted as binary data.
144+
AttestationResult result = client.attestSgxEnclave(new AttestationOptions(sgxQuote)
145+
.setRunTimeData(
146+
new AttestationData(decodedRuntimeData, AttestationDataInterpretation.BINARY)));
118147

119-
The attestation policy document is a JSON Web Signature object, with a single field named `AttestationPolicy`, whose value is the actual policy document encoded in Base64Url.
148+
String issuer = result.getIssuer();
120149

121-
<!-- embedme src\samples\com\azure\security\attestation\ReadmeSamples.java#L59-L84 -->
122-
```java
150+
System.out.println("Attest Sgx Enclave completed. Issuer: " + issuer);
151+
System.out.printf("Runtime Data Length: %d\n", result.getEnclaveHeldData().getLength());
152+
```
123153

124-
sponse policyResponse = client.get(AttestationType.SGX_ENCLAVE);
125-
testationToken(httpClient, clientUri, policyResponse.getToken())
126-
scribe(claims -> {
127-
if (claims != null) {
154+
### Create a synchronous administrative client
155+
All administrative clients are authenticated.
156+
```java readme-sample-create-admin-client
157+
AttestationAdministrationClientBuilder attestationBuilder = new AttestationAdministrationClientBuilder();
158+
// Note that the "policy" calls require authentication.
159+
AttestationAdministrationClient client = attestationBuilder
160+
.endpoint(endpoint)
161+
.credential(new DefaultAzureCredentialBuilder().build())
162+
.buildClient();
163+
```
128164

129-
String policyDocument = claims.getClaims().get("x-ms-policy").toString();
165+
### Retrieve current attestation policy for OpenEnclave
166+
Use the `getAttestationPolicy` API to retrieve the current attestation policy for a given TEE.
167+
```java readme-sample-getCurrentPolicy
168+
String currentPolicy = client.getAttestationPolicy(AttestationType.OPEN_ENCLAVE);
169+
System.out.printf("Current policy for OpenEnclave is: %s\n", currentPolicy);
170+
```
130171

131-
JOSEObject policyJose = null;
132-
try {
133-
policyJose = JOSEObject.parse(policyDocument);
134-
} catch (ParseException e) {
135-
throw logger.logExceptionAsError(new RuntimeException(e.toString()));
136-
}
137-
assert policyJose != null;
138-
Map<String, Object> jsonObject = policyJose.getPayload().toJSONObject();
139-
if (jsonObject != null) {
140-
assertTrue(jsonObject.containsKey("AttestationPolicy"));
141-
String base64urlPolicy = jsonObject.get("AttestationPolicy").toString();
142-
143-
byte[] attestationPolicyUtf8 = Base64.getUrlDecoder().decode(base64urlPolicy);
144-
String attestationPolicy;
145-
attestationPolicy = new String(attestationPolicyUtf8, StandardCharsets.UTF_8);
146-
// Inspect the retrieved policy.
147-
}
172+
### Set unsigned attestation policy (AAD clients only)
173+
When an attestation instance is in AAD mode, the caller can use a convenience method to set an unsigned attestation
174+
policy on the instance.
175+
176+
```java readme-sample-set-unsigned-policy
177+
// Set the listed policy on an attestation instance. Please note that this particular policy will deny all
178+
// attestation requests and should not be used in production.
179+
PolicyResult policyResult = client.setAttestationPolicy(AttestationType.OPEN_ENCLAVE, "version=1.0; authorizationrules{=> deny();}; issuancerules{};");
180+
System.out.printf("Policy set for OpenEnclave result: %s\n", policyResult.getPolicyResolution());
181+
```
182+
183+
### Set signed attestation policy
184+
For isolated mode attestation instances, the set or reset policy request must be signed using the key which is associated
185+
with the attestation signing certificates which are configured on the attestation instance.
186+
```java readme-sample-set-signed-policy
187+
// Set the listed policy on an attestation instance using a signed policy token.
188+
PolicyResult policyResult = client.setAttestationPolicy(AttestationType.SGX_ENCLAVE,
189+
new AttestationPolicySetOptions()
190+
.setAttestationPolicy("version=1.0; authorizationrules{=> permit();}; issuancerules{};")
191+
.setAttestationSigner(new AttestationSigningKey(certificate, privateKey)));
192+
System.out.printf("Policy set for Sgx result: %s\n", policyResult.getPolicyResolution());
193+
```
194+
195+
### List attestation signing certificates
196+
When an attestation instance is in `Isolated` mode, the policy APIs need additional proof of authorization. This proof is
197+
provided via the `AttestationSigningKey` parameter passed into the set and reset policy APIs.
198+
199+
Each `Isolated` mode instance has a set of certificates, which determine whether a caller has the authority to set an
200+
attestation policy. When an attestation policy is set, the client presents a signed "token" to the service which is signed
201+
by the key in the `AttestationSigningKey`. The signed token, including the certificate in the `AttestationSigningKey` is
202+
sent to the attestation service, which verifies that the token was signed with the private key corresponding to the
203+
public key in the token. The set or reset policy operation will only succeed if the certificate in the token is one of
204+
the policy management tokens. This interaction ensures that the client is in possession of the private key associated with
205+
one of the policy management certificates and is thus authorized to perform the operation.
206+
207+
```java readme-sample-listPolicyCertificates
208+
List<AttestationSigner> signers = client.listPolicyManagementCertificates();
209+
System.out.printf("Instance %s contains %d signers.\n", endpoint, signers.size());
210+
for (AttestationSigner signer : signers) {
211+
System.out.printf("Certificate Subject: %s", signer.getCertificates().get(0).getSubjectDN().toString());
148212
}
149213
```
150214

151-
### Retrieve Token Certificates
215+
### Add attestation signing certificate
216+
Adds a new certificate to the set of policy management certificates. The request to add the policy management certificate
217+
must be signed with the private key associated with one of the existing policy management certificates (this ensures that
218+
the caller is authorized to update the set of policy certificates).
152219

153-
Use `SigningCertificatesClient.get` to retrieve the certificates which can be used to validate the token returned from the attestation service.
220+
Note: Adding the same certificate twice is not considered an error - if the certificate is already present, the addition is
221+
ignored (this possibly surprising behavior is there because retries could cause the addition to be executed multiple times)
154222

155-
<!-- embedme src\samples\com\azure\security\attestation\ReadmeSamples.java#L89-L92 -->
156-
```java
223+
```java readme-sample-addPolicyManagementCertificate
224+
System.out.printf("Adding new certificate %s\n", certificateToAdd.getSubjectDN().toString());
225+
PolicyCertificatesModificationResult modificationResult = client.addPolicyManagementCertificate(
226+
new PolicyManagementCertificateOptions(certificateToAdd, new AttestationSigningKey(isolatedCertificate, isolatedKey)));
227+
System.out.printf("Updated policy certificate, certificate add result: %s\n", modificationResult.getCertificateResolution());
228+
System.out.printf("Added certificate thumbprint: %s\n", modificationResult.getCertificateThumbprint());
229+
```
230+
231+
### Remove attestation signing certificate
232+
Removes a certificate from the set of policy management certificates. The request to remove the policy management certificate
233+
must be signed with the private key associated with one of the existing policy management certificates (this ensures that
234+
the caller is authorized to update the set of policy certificates).
157235

158-
AttestationClientBuilder attestationBuilder = getBuilder(httpClient, clientUri);
236+
Note: Removing a non-existent certificate is not considered an error - if the certificate is not present, the removal is
237+
ignored (this possibly surprising behavior is there because retries could cause the removal to be executed multiple times)
159238

160-
JsonWebKeySet certs = attestationBuilder.buildSigningCertificatesClient().get();
239+
```java readme-sample-removePolicyManagementCertificate
240+
System.out.printf("Removing existing certificate %s\n", certificateToRemove.getSubjectDN().toString());
241+
PolicyCertificatesModificationResult modificationResult = client.removePolicyManagementCertificate(
242+
new PolicyManagementCertificateOptions(certificateToRemove, new AttestationSigningKey(isolatedCertificate, isolatedKey)));
243+
System.out.printf("Updated policy certificate, certificate remove result: %s\n", modificationResult.getCertificateResolution());
244+
System.out.printf("Removed certificate thumbprint: %s\n", modificationResult.getCertificateThumbprint());
161245
```
162246

163-
## Troubleshooting
164247

248+
## Troubleshooting
165249
Troubleshooting information for the MAA service can be found [here](https://docs.microsoft.com/azure/attestation/troubleshoot-guide)
250+
166251
## Next steps
167-
For more information about the Microsoft Azure Attestation service, please see our [documentation page](https://docs.microsoft.com/azure/attestation/).
252+
For more information about the Microsoft Azure Attestation service, please see our [documentation page](https://docs.microsoft.com/azure/attestation/).
168253

169254
## Contributing
170255
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.
@@ -173,7 +258,6 @@ When you submit a pull request, a CLA-bot will automatically determine whether y
173258

174259
This project has adopted the [Microsoft Open Source Code of Conduct][microsoft_code_of_conduct]. For more information see the Code of Conduct FAQ or contact <opencode@microsoft.com> with any additional questions or comments.
175260

176-
177261
<!-- LINKS -->
178262
[style-guide-msft]: https://docs.microsoft.com/style-guide/capitalization
179263

0 commit comments

Comments
 (0)