public void ValidateTokenCallback() { // Create a JWT whose body will become valid 5 seconds from now. object tokenBody = new JwtTestBody { StringField = "Foo", NotBefore = DateTimeOffset.Now.AddSeconds(5).ToUnixTimeSeconds(), ExpiresAt = DateTimeOffset.Now.AddSeconds(60).ToUnixTimeSeconds(), }; X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; AsymmetricAlgorithm privateKey = TestEnvironment.PolicyManagementKey; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody), new AttestationTokenSigningKey(privateKey, fullCertificate)); string serializedToken = token.Serialize(); var validationOptions = new AttestationTokenValidationOptions(); validationOptions.TokenValidated += (args) => { Assert.AreEqual(1, args.Signer.SigningCertificates.Count); Assert.IsNotNull(args.Signer.SigningCertificates[0]); CollectionAssert.AreEqual(fullCertificate.Export(X509ContentType.Cert), args.Signer.SigningCertificates[0].Export(X509ContentType.Cert)); Assert.AreEqual(fullCertificate, args.Signer.SigningCertificates[0]); return(Task.CompletedTask); }; // ValidateTokenAsync will throw an exception if a callback is specified outside of an attestation client. // Note that validation callbacks are tested elsewhere in the AttestationClient codebase. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken( serializedToken, tokenBody, validationOptions)); }
public async Task AttestOpenEnclaveSharedCallbackRejects() { byte[] binaryReport = Base64Url.Decode(_openEnclaveReport); byte[] binaryRuntimeData = Base64Url.Decode(_runtimeData); bool callbackInvoked = false; AttestationTokenValidationOptions tokenValidationOptions = new AttestationTokenValidationOptions { ValidateExpirationTime = TestEnvironment.IsTalkingToLiveServer, }; tokenValidationOptions.TokenValidated += (args) => { callbackInvoked = true; args.IsValid = false; return(Task.CompletedTask); }; var client = TestEnvironment.GetSharedAttestationClient(this, tokenValidationOptions); IReadOnlyList <AttestationSigner> signingCertificates = (await client.GetSigningCertificatesAsync()).Value; { // Collect quote and enclave held data from an SGX enclave. Assert.ThrowsAsync(typeof(AttestationTokenValidationFailedException), async() => await client.AttestOpenEnclaveAsync( new AttestationRequest { Evidence = BinaryData.FromBytes(binaryReport), RuntimeData = new AttestationData(BinaryData.FromBytes(binaryRuntimeData), false), })); Assert.IsTrue(callbackInvoked); } }
public async Task AttestOpenEnclaveSharedValidateCallback() { byte[] binaryReport = Base64Url.Decode(_openEnclaveReport); byte[] binaryRuntimeData = Base64Url.Decode(_runtimeData); bool callbackInvoked = false; AttestationTokenValidationOptions tokenValidationOptions = new AttestationTokenValidationOptions { ValidateExpirationTime = TestEnvironment.IsTalkingToLiveServer, }; tokenValidationOptions.TokenValidated += (args) => { // Verify that the callback can access the enclave held data field. CollectionAssert.AreEqual(binaryRuntimeData, args.Token.GetBody <AttestationResult>().EnclaveHeldData.ToArray()); // The MAA service always sends a Key ID for the signer. args.IsValid = null != args.Signer.CertificateKeyId && 1 == args.Signer.SigningCertificates.Count && null != args.Signer.SigningCertificates[0] && TestEnvironment.SharedAttestationUrl == args.Token.Issuer; callbackInvoked = true; return(Task.CompletedTask); }; var client = TestEnvironment.GetSharedAttestationClient(this, tokenValidationOptions); IReadOnlyList <AttestationSigner> signingCertificates = (await client.GetSigningCertificatesAsync()).Value; { // Collect quote and enclave held data from an SGX enclave. var attestationResult = await client.AttestOpenEnclaveAsync( new AttestationRequest { Evidence = BinaryData.FromBytes(binaryReport), RuntimeData = new AttestationData(BinaryData.FromBytes(binaryRuntimeData), false), }); // Confirm that the attestation token contains the enclave held data we specified. CollectionAssert.AreEqual(binaryRuntimeData, attestationResult.Value.EnclaveHeldData.ToArray()); #pragma warning disable CS0618 // Type or member is obsolete Assert.IsNotNull(attestationResult.Value.DeprecatedEnclaveHeldData); CollectionAssert.AreEqual(binaryRuntimeData, attestationResult.Value.DeprecatedEnclaveHeldData.ToArray()); Assert.IsNotNull(attestationResult.Value.DeprecatedEnclaveHeldData2); CollectionAssert.AreEqual(binaryRuntimeData, attestationResult.Value.DeprecatedEnclaveHeldData2.ToArray()); #pragma warning restore CS0618 // Type or member is obsolete // VERIFY ATTESTATIONRESULT. // Encrypt Data using DeprecatedEnclaveHeldData // Send to enclave. Assert.IsTrue(callbackInvoked); } }
public async Task AttestSgxEnclaveSharedValidateCallback() { // An SGX Quote is an OpenEnclave report with the first 16 bytes stripped from it. var report = Base64Url.Decode(_openEnclaveReport); var quoteList = report.ToList(); quoteList.RemoveRange(0, 0x10); byte[] binaryQuote = quoteList.ToArray(); byte[] binaryRuntimeData = Base64Url.Decode(_runtimeData); bool callbackInvoked = false; var tokenValidationOptions = new AttestationTokenValidationOptions { ValidateExpirationTime = TestEnvironment.IsTalkingToLiveServer, }; tokenValidationOptions.TokenValidated += (AttestationTokenValidationEventArgs args) => { // Verify that the callback can access the enclave held data field. CollectionAssert.AreEqual(binaryRuntimeData, args.Token.GetBody <AttestationResult>().EnclaveHeldData.ToArray()); // The MAA service always sends a Key ID for the signer. Assert.IsNotNull(args.Signer.CertificateKeyId); Assert.AreEqual(TestEnvironment.SharedAttestationUrl, args.Token.Issuer); callbackInvoked = true; return(Task.CompletedTask); }; var client = TestEnvironment.GetSharedAttestationClient(this, tokenValidationOptions); IReadOnlyList <AttestationSigner> signingCertificates = (await client.GetSigningCertificatesAsync()).Value; { // Collect quote and enclave held data from an SGX enclave. var attestationResult = await client.AttestSgxEnclaveAsync( new AttestationRequest { Evidence = BinaryData.FromBytes(binaryQuote), RuntimeData = new AttestationData(BinaryData.FromBytes(binaryRuntimeData), false), }); // Confirm that the attestation token contains the enclave held data we specified. CollectionAssert.AreEqual(binaryRuntimeData, attestationResult.Value.EnclaveHeldData.ToArray()); // VERIFY ATTESTATIONRESULT. // Encrypt Data using DeprecatedEnclaveHeldData // Send to enclave. Assert.IsTrue(callbackInvoked); } }
public async Task GetAttestationPolicy() { var tokenOptions = new AttestationTokenValidationOptions(); tokenOptions.TokenValidated += (AttestationTokenValidationEventArgs args) => { args.IsValid = true; return(Task.CompletedTask); }; var client = new AttestationAdministrationClient(new Uri(TestEnvironment.AadAttestationUrl), new DefaultAzureCredential()); var attestClient = new AttestationClient(new Uri(TestEnvironment.AadAttestationUrl), new DefaultAzureCredential(), new AttestationClientOptions(tokenOptions: tokenOptions)); ; IReadOnlyList <AttestationSigner> signingCertificates = attestClient.GetSigningCertificates().Value; var policyResult = await client.GetPolicyAsync(AttestationType.SgxEnclave); var result = policyResult.Value; }
/// <summary> /// Ensure that the serialized token validates correctly. /// </summary> /// <param name="serializedToken"></param> public async Task ValidateSerializedToken(string serializedToken, object expectedBody, AttestationTokenValidationOptions tokenOptions = default) { var parsedToken = AttestationToken.Deserialize(serializedToken); await Task.Yield(); Assert.IsTrue(await parsedToken.ValidateTokenAsync(tokenOptions ?? new AttestationTokenValidationOptions { ValidateExpirationTime = true }, null)); // The body of the token should match the expected body. Assert.AreEqual(JsonSerializer.Serialize(expectedBody), Encoding.UTF8.GetString(parsedToken.TokenBodyBytes.ToArray())); }