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));
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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()));
        }