public void ToObjectThrowsExceptionOnIncompatibleType() { TestModel payload = new TestModel { A = "value", B = 5, C = true }; BinaryData data = BinaryData.FromObjectAsJson(payload); Assert.ThrowsAny <Exception>(() => data.ToObjectFromJson <string>()); Assert.ThrowsAny <Exception>(() => data.ToObjectFromJson <MismatchedTestModel>(jsonTypeInfo: MismatchedTestModelJsonContext.Default.MismatchedTestModel)); }
public async Task GetUnsecuredAttestationToken() { object tokenBody = new StoredAttestationPolicy { AttestationPolicy = "Foo", }; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody)); string serializedToken = token.Serialize(); await ValidateSerializedToken(serializedToken, tokenBody); }
public void Send(string methodName, string argument) { sender.SendMessageAsync(new ServiceBusMessage(BinaryData.FromObjectAsJson(new AzureInvalidationMessage { CreationDate = DateTime.UtcNow, OriginMachineName = Environment.MachineName, OriginApplicationName = Schema.Current.ApplicationName, MethodName = methodName, Argument = argument, }, EntityJsonContext.FullJsonSerializerOptions))).Wait(); }
public async Task SettingAttestationPolicy() { var endpoint = TestEnvironment.AadAttestationUrl; #region Snippet:GetPolicy var client = new AttestationAdministrationClient(new Uri(endpoint), new DefaultAzureCredential()); AttestationResponse <string> policyResult = await client.GetPolicyAsync(AttestationType.SgxEnclave); string result = policyResult.Value; #endregion #region Snippet:SetPolicy string attestationPolicy = "version=1.0; authorizationrules{=> permit();}; issuancerules{};"; //@@ X509Certificate2 policyTokenCertificate = new X509Certificate2(<Attestation Policy Signing Certificate>); //@@ AsymmetricAlgorithm policyTokenKey = <Attestation Policy Signing Key>; /*@@*/ var policyTokenCertificate = TestEnvironment.PolicyCertificate0; /*@@*/ var policyTokenKey = TestEnvironment.PolicySigningKey0; var setResult = client.SetPolicy(AttestationType.SgxEnclave, attestationPolicy, new AttestationTokenSigningKey(policyTokenKey, policyTokenCertificate)); #endregion #region Snippet:VerifySigningHash // The SetPolicyAsync API will create an AttestationToken signed with the TokenSigningKey to transmit the policy. // To verify that the policy specified by the caller was received by the service inside the enclave, we // verify that the hash of the policy document returned from the Attestation Service matches the hash // of an attestation token created locally. //@@ TokenSigningKey signingKey = new TokenSigningKey(<Customer provided signing key>, <Customer provided certificate>) /*@@*/ AttestationTokenSigningKey signingKey = new AttestationTokenSigningKey(policyTokenKey, policyTokenCertificate); var policySetToken = new AttestationToken( BinaryData.FromObjectAsJson(new StoredAttestationPolicy { AttestationPolicy = attestationPolicy }), signingKey); using var shaHasher = SHA256.Create(); byte[] attestationPolicyHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.Serialize())); Debug.Assert(attestationPolicyHash.SequenceEqual(setResult.Value.PolicyTokenHash.ToArray())); #endregion var resetResult = client.ResetPolicy(AttestationType.SgxEnclave); // When the attestation instance is in Isolated mode, the ResetPolicy API requires using a signing key/certificate to authorize the user. var resetResult2 = client.ResetPolicy( AttestationType.SgxEnclave, new AttestationTokenSigningKey(TestEnvironment.PolicySigningKey0, policyTokenCertificate)); return; }
public void ToFromCustomType() { #region Snippet:BinaryDataToFromCustomModel var model = new CustomModel { A = "some text", B = 5, C = true }; var data = BinaryData.FromObjectAsJson(model); model = data.ToObjectFromJson <CustomModel>(); #endregion }
public async Task GetSecuredAttestationToken() { X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; AsymmetricAlgorithm privateKey = TestEnvironment.PolicyManagementKey; object tokenBody = new StoredAttestationPolicy { AttestationPolicy = "Foo", }; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody), new AttestationTokenSigningKey(privateKey, fullCertificate)); string serializedToken = token.Serialize(); await ValidateSerializedToken(serializedToken, tokenBody); }
public async Task SetPolicyUnsecuredAad() { var adminclient = TestEnvironment.GetAadAdministrationClient(this); // Reset the current attestation policy to a known state. Necessary if there were previous runs that failed. await ResetAttestationPolicy(adminclient, AttestationType.OpenEnclave, false, false); string originalPolicy; { originalPolicy = await adminclient.GetPolicyAsync(AttestationType.OpenEnclave); } byte[] disallowDebuggingHash; { var policySetResult = await adminclient.SetPolicyAsync(AttestationType.OpenEnclave, disallowDebugging); // The SetPolicyAsync API will create an UnsecuredAttestationToken to transmit the policy. var shaHasher = SHA256.Create(); var policySetToken = new AttestationToken(BinaryData.FromObjectAsJson(new StoredAttestationPolicy { AttestationPolicy = disallowDebugging })); disallowDebuggingHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.Serialize())); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Updated, policySetResult.Value.PolicyResolution); CollectionAssert.AreEqual(disallowDebuggingHash, policySetResult.Value.PolicyTokenHash.ToArray()); } { string policyResult = await adminclient.GetPolicyAsync(AttestationType.OpenEnclave); Assert.AreEqual(disallowDebugging, policyResult); } { var policySetResult = await adminclient.ResetPolicyAsync(AttestationType.OpenEnclave); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Removed, policySetResult.Value.PolicyResolution); } { var policyResult = await adminclient.GetPolicyAsync(AttestationType.OpenEnclave); // And when we're done, policy should be reset to the original value. Assert.AreEqual(originalPolicy, policyResult.Value); } }
protected static GenericResourceData ConstructGenericAvailabilitySet() { var data = new GenericResourceData(AzureLocation.WestUS2); data.Sku = new ResourcesSku() { Name = "Aligned" }; var propertyBag = new Dictionary <string, object>(); propertyBag.Add("platformUpdateDomainCount", 5); propertyBag.Add("platformFaultDomainCount", 2); data.Properties = BinaryData.FromObjectAsJson(propertyBag); return(data); }
protected static ArmDeploymentProperties CreateDeploymentProperties() { ArmDeploymentProperties tmpDeploymentProperties = new ArmDeploymentProperties(ArmDeploymentMode.Incremental); tmpDeploymentProperties.TemplateLink = new ArmDeploymentTemplateLink(); tmpDeploymentProperties.TemplateLink.Uri = new Uri("https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.storage/storage-account-create/azuredeploy.json"); tmpDeploymentProperties.Parameters = BinaryData.FromObjectAsJson(new JsonObject() { { "storageAccountType", new JsonObject() { { "value", "Standard_GRS" } } } }); return(tmpDeploymentProperties); }
public WebPubSubConnectionContext(WebPubSubEventType eventType, string eventName, string hub, string connectionId, string userId, string signature, string origin, IReadOnlyDictionary <string, object> states, IReadOnlyDictionary <string, string[]> headers) : this( eventType, eventName, hub, connectionId, userId, signature, origin, states?.ToDictionary( p => p.Key, p => p.Value as BinaryData ?? BinaryData.FromObjectAsJson(p.Value)), headers) { }
public BinaryData GeneratePayload() { double currentTemperature = minTemperature + Random.Shared.NextDouble() * 15; double currentHumidity = minHumidity + Random.Shared.NextDouble() * 20; object telemetryDataPoint = new { createdAt = DateTime.UtcNow, deviceId = "EventHubDevice" + Random.Shared.Next(1, 300000), temperature = currentTemperature, humidity = currentHumidity, }; return(BinaryData.FromObjectAsJson(telemetryDataPoint)); }
public async Task TestStateChanges() { _adaptor.RegisterHub <TestHub>(); var initState = new Dictionary <string, BinaryData> { { "counter", BinaryData.FromObjectAsJson(2) } }; var context = PrepareHttpContext(httpMethod: HttpMethods.Post, type: WebPubSubEventType.User, eventName: "message", body: "1", connectionState: initState); // 1 to update counter to 10. await _adaptor.HandleRequest(context); context.Response.Headers.TryGetValue(Constants.Headers.CloudEvents.State, out var states); Assert.NotNull(states); var updated = states[0].DecodeConnectionStates(); Assert.AreEqual(1, updated.Count); Assert.AreEqual(10, updated["counter"].ToObjectFromJson <int>()); // 2 to add a new state. context = PrepareHttpContext(httpMethod: HttpMethods.Post, type: WebPubSubEventType.User, eventName: "message", body: "2", connectionState: initState); _adaptor.RegisterHub <TestHub>(); await _adaptor.HandleRequest(context); context.Response.Headers.TryGetValue(Constants.Headers.CloudEvents.State, out states); Assert.NotNull(states); updated = states[0].DecodeConnectionStates(); Assert.AreEqual(2, updated.Count); Assert.AreEqual("new", updated["new"].ToObjectFromJson <string>()); // 3 to clear states context = PrepareHttpContext(httpMethod: HttpMethods.Post, type: WebPubSubEventType.User, eventName: "message", body: "3", connectionState: initState); await _adaptor.HandleRequest(context); var exist = context.Response.Headers.TryGetValue(Constants.Headers.CloudEvents.State, out _); Assert.False(exist); // 4 clar and add context = PrepareHttpContext(httpMethod: HttpMethods.Post, type: WebPubSubEventType.User, eventName: "message", body: "4", connectionState: initState); await _adaptor.HandleRequest(context); context.Response.Headers.TryGetValue(Constants.Headers.CloudEvents.State, out states); Assert.NotNull(states); updated = states[0].DecodeConnectionStates(); Assert.AreEqual(2, updated.Count); Assert.AreEqual("new1", updated["new1"].ToObjectFromJson <string>()); }
public async Task GetSecuredAttestationTokenWithPrivateKey() { X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; fullCertificate.PrivateKey = TestEnvironment.PolicyManagementKey; // The body of attestation token MUST be a JSON object. TestBody body = new TestBody { StringField = "Foo", }; var token = new AttestationToken(BinaryData.FromObjectAsJson(body), new AttestationTokenSigningKey(fullCertificate)); string serializedToken = token.Serialize(); await ValidateSerializedToken(serializedToken, body); }
public void TestEncodeAndDecodeState() { var state = new Dictionary <string, BinaryData> { { "aaa", BinaryData.FromObjectAsJson("aaa") }, { "bbb", BinaryData.FromObjectAsJson("bbb") } }; var encoded = state.EncodeConnectionStates(); var decoded = encoded.DecodeConnectionStates(); CollectionAssert.AreEquivalent( state.Values.Select(d => d.ToObjectFromJson <string>()), decoded.Values.Select(d => d.ToObjectFromJson <string>())); }
protected static ArmApplicationData CreateApplicationData(ResourceIdentifier applicationDefinitionId, ResourceIdentifier managedResourceGroupId, string storageAccountPrefix) => new ArmApplicationData(AzureLocation.WestUS2, "ServiceCatalog") { ApplicationDefinitionId = applicationDefinitionId, ManagedResourceGroupId = managedResourceGroupId, Parameters = BinaryData.FromObjectAsJson(new JsonObject() { { "storageAccountNamePrefix", new JsonObject() { { "value", storageAccountPrefix } } }, { "storageAccountType", new JsonObject() { { "value", "Standard_LRS" } } } }) };
public void CreateVmExtension() { #region Snippet:Changelog_CreateVMExtension var vmExtension = new VirtualMachineExtensionData(AzureLocation.WestUS) { Tags = { { "extensionTag1", "1" }, { "extensionTag2", "2" } }, Publisher = "Microsoft.Compute", ExtensionType = "VMAccessAgent", TypeHandlerVersion = "2.0", AutoUpgradeMinorVersion = true, ForceUpdateTag = "RerunExtension", Settings = BinaryData.FromObjectAsJson(new { }), ProtectedSettings = BinaryData.FromObjectAsJson(new { }) }; #endregion }
public async Task ValidateJustExpiredAttestationToken() { // Create a JWT whose body has just expired. object tokenBody = new JwtTestBody { StringField = "Foo", ExpiresAt = DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(5)).ToUnixTimeSeconds(), }; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody)); string serializedToken = token.Serialize(); // This check should fail since the token expired 5 seconds ago. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken(serializedToken, tokenBody)); // This check should succeed since the token slack is greater than the 5 second expiration time. await ValidateSerializedToken(serializedToken, tokenBody, new AttestationTokenValidationOptions { TimeValidationSlack = 10 }); }
public async Task WriteToBlob( BlobContainerClient client, string blobName, object content) { var blob = client.GetBlobClient(blobName); if (_useCompression) { var serializedContent = AvroConvert.Serialize(content); await blob.UploadAsync(new BinaryData(serializedContent)); } else { await blob.UploadAsync(BinaryData.FromObjectAsJson(content)); } }
// WEIRD: second level resources cannot use GenericResourceCollection to create. // Exception thrown: System.InvalidOperationException : An invalid resource id was given /subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9c123c/resourceGroups/testRG-4544/providers/Microsoft.Network/virtualNetworks/testVNet-9796/subnets/testSubnet-1786 private async Task <GenericResource> CreateSubnet(ResourceIdentifier vnetId) { var subnetName = Recording.GenerateAssetName("testSubnet-"); ResourceIdentifier subnetId = new ResourceIdentifier($"{vnetId}/subnets/{subnetName}"); var input = new GenericResourceData(DefaultLocation) { Properties = BinaryData.FromObjectAsJson(new Dictionary <string, object>() { { "addressPrefixes", new List <string>() { "10.0.2.0/24" } } }) }; var operation = await _genericResourceCollection.CreateOrUpdateAsync(WaitUntil.Completed, subnetId, input); return(operation.Value); }
protected static ArmDeploymentProperties CreateDeploymentPropertiesAtSub() { ArmDeploymentProperties tmpDeploymentProperties = new ArmDeploymentProperties(ArmDeploymentMode.Incremental); tmpDeploymentProperties.TemplateLink = new ArmDeploymentTemplateLink(); tmpDeploymentProperties.TemplateLink.Uri = new Uri("https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/emptyrg.json"); tmpDeploymentProperties.Parameters = BinaryData.FromObjectAsJson(new JsonObject() { { "rgName", new JsonObject() { { "value", "testDeployAtSub" } } }, { "rgLocation", new JsonObject() { { "value", $"{AzureLocation.CentralUS}" } } }, }); return(tmpDeploymentProperties); }
public void SerailizeUsingDictStringObject() { var expected = File.ReadAllText(GetFileName("JsonFormattedString.json")).TrimEnd(); var payload = new ModelWithBinaryData { A = "a.value" }; var properties = new Dictionary <string, object>(); var innerProperties = new Dictionary <string, object>(); properties.Add("a", "properties.a.value"); innerProperties.Add("a", "properties.innerProperties.a.value"); properties.Add("innerProperties", innerProperties); payload.Properties = BinaryData.FromObjectAsJson(properties); string actual = GetSerializedString(payload); Assert.AreEqual(expected, actual); }
private GenericResourceData ConstructGenericVirtualNetworkData() { var properties = new JsonObject() { { "addressSpace", new JsonObject() { { "addressPrefixes", new List <string>() { "10.0.0.0/16" } } } } }; var virtualNetwork = new GenericResourceData(AzureLocation.WestUS2) { Properties = BinaryData.FromObjectAsJson(properties), }; return(virtualNetwork); }
public void TestConnectionStatesConverter_SystemText() { var jsonOption = new SystemJson.JsonSerializerOptions(); jsonOption.Converters.Add(new ConnectionStatesConverter()); IReadOnlyDictionary <string, BinaryData> input = new Dictionary <string, BinaryData> { { "aKey", BinaryData.FromString("aValue") }, { "bKey", BinaryData.FromObjectAsJson(123) }, { "cKey", BinaryData.FromObjectAsJson(new StateTestClass()) } }; var serialized = SystemJson.JsonSerializer.Serialize(input, jsonOption); var deserialized = SystemJson.JsonSerializer.Deserialize <IReadOnlyDictionary <string, BinaryData> >(serialized, jsonOption); Assert.AreEqual(3, deserialized.Count); Assert.AreEqual("aValue", deserialized["aKey"].ToString()); Assert.AreEqual(123, deserialized["bKey"].ToObjectFromJson <int>()); }
public static async Task <IActionResult> RunAsync( [HttpTrigger(AuthorizationLevel.Function, "post", Route = Constants.Routes.EventConfigs)] HttpRequest req, ILogger log, CancellationToken cancellationToken) { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var entity = JsonConvert.DeserializeObject <PseudoEvent>(requestBody); if (entity == null) { return(new BadRequestResult()); } var timestamp = entity.EventTimestamp.AddMinutes(-entity.LeadTimeInMinutes); if (timestamp < DateTimeOffset.UtcNow) { return(new NoContentResult()); } var payload = new EventDispatchTrigger { DispatchedAt = DateTimeOffset.UtcNow, Payload = entity, PayloadType = nameof(PseudoEvent), EntityId = entity.Id.ToString(), EntityTag = DateTimeOffset.UtcNow.ToString("O") // For Cosmos DB entities this could be the ETag value }; var message = new ServiceBusMessage { Subject = nameof(EventDispatchTrigger), MessageId = entity.Id.ToString(), Body = BinaryData.FromObjectAsJson(payload), ContentType = "application/json", CorrelationId = Guid.NewGuid().ToString() }; await FunctionHelper.ScheduleTrigger(message, timestamp, log, cancellationToken); return(new OkResult()); }
private static PolicyDefinitionData ConstructPolicyDefinitionData(string displayName) => new PolicyDefinitionData { DisplayName = $"Test ${displayName}", PolicyRule = BinaryData.FromObjectAsJson(new Dictionary <string, object> { { "if", new Dictionary <string, object> { { "source", "action" }, { "equals", "ResourceProviderTestHost/TestResourceType/TestResourceTypeNestedOne/write" } } }, { "then", new Dictionary <string, object> { { "effect", "deny" } } } }) };
public void CanSerializeNullData() { BinaryData data = new BinaryData(jsonSerializable: null); Assert.Null(data.ToObjectFromJson <object>()); data = BinaryData.FromObjectAsJson <object>(null); Assert.Null(data.ToObjectFromJson <object>()); data = new BinaryData(jsonSerializable: null, type: typeof(TestModel)); Assert.Null(data.ToObjectFromJson <TestModel>()); data = new BinaryData(jsonSerializable: null); Assert.Null(data.ToObjectFromJson <TestModel>()); data = new BinaryData(jsonSerializable: null, type: null); Assert.Null(data.ToObjectFromJson <TestModel>()); data = BinaryData.FromObjectAsJson <TestModel>(null); Assert.Null(data.ToObjectFromJson <TestModel>()); }
public void CanSerializeBaseType() { DerivedModel payload = new DerivedModel { A = "value", B = 5, C = true, D = null, E = "derived property" }; BinaryData data = new BinaryData(jsonSerializable: payload, type: typeof(TestModel)); Assert.Null(data.ToObjectFromJson <DerivedModel>().E); data = new BinaryData(jsonSerializable: payload, type: typeof(DerivedModel)); Assert.Equal("derived property", data.ToObjectFromJson <DerivedModel>().E); data = new BinaryData(jsonSerializable: payload); Assert.Equal("derived property", data.ToObjectFromJson <DerivedModel>().E); data = BinaryData.FromObjectAsJson <TestModel>(payload); Assert.Null(data.ToObjectFromJson <DerivedModel>().E); data = BinaryData.FromObjectAsJson <DerivedModel>(payload); Assert.Equal("derived property", data.ToObjectFromJson <DerivedModel>().E); }
public void TestConnectionStatesEncodeDecode() { var testTime = DateTime.Parse("2021-11-10 4:23:55"); var input = new Dictionary <string, object> { { "aKey", BinaryData.FromString("aValue") }, { "bKey", BinaryData.FromObjectAsJson(123) }, { "cKey", BinaryData.FromObjectAsJson(new StateTestClass()) }, { "dKey", JObject.FromObject(new StateTestClass()) }, { "eKey", BinaryData.FromObjectAsJson(testTime) } }; var encoded = input.EncodeConnectionStates(); var decoded = encoded.DecodeConnectionStates(); Assert.AreEqual(5, decoded.Count); Assert.AreEqual("aValue", decoded["aKey"].ToString()); Assert.AreEqual(123, ((BinaryData)decoded["bKey"]).ToObjectFromJson <int>()); Assert.NotNull(((BinaryData)decoded["cKey"]).ToObjectFromJson <StateTestClass>()); Assert.NotNull(((BinaryData)decoded["dKey"]).ToObjectFromJson <StateTestClass>()); Assert.AreEqual(testTime, ((BinaryData)decoded["eKey"]).ToObjectFromJson <DateTime>()); }
/// <summary> /// Sets the attesttion policy for the specified <see cref="AttestationType"/>. /// </summary> /// <param name="attestationType"><see cref="AttestationType"/> whose policy should be set.</param> /// <param name="policyToSet">Specifies the attestation policy to set.</param> /// <param name="signingKey">If provided, specifies the signing key used to sign the request to the attestation service.</param> /// <param name="cancellationToken">Cancellation token used to cancel this operation.</param> /// <returns>An <see cref="AttestationResponse{PolicyResult}"/> with the policy for the specified attestation type.</returns> /// <remarks> /// If the <paramref name="signingKey"/> parameter is not provided, then the policy document sent to the /// attestation service will be unsigned. Unsigned attestation policies are only allowed when the attestation instance is running in AAD mode - if the /// attestation instance is running in Isolated mode, then a signing key and signing certificate MUST be provided to ensure that the caller of the API is authorized to change policy. /// The <see cref="AttestationTokenSigningKey.Certificate"/> field MUST be one of the certificates returned by the <see cref="GetPolicyManagementCertificates(CancellationToken)"/> API. /// <para/> /// Clients need to be able to verify that the attestation policy document was not modified before the policy document was received by the attestation service's enclave. /// There are two properties provided in the [PolicyResult][attestation_policy_result] that can be used to verify that the service received the policy document: /// <list type="bullet"> /// <item> /// <description><see cref="PolicyModificationResult.PolicySigner"/> - if the <see cref="SetPolicy(AttestationType, string, AttestationTokenSigningKey, CancellationToken)"/> call included a signing certificate, this will be the certificate provided at the time of the `SetPolicy` call. If no policy signer was set, this will be null. </description> /// </item> /// <item> /// <description><see cref="PolicyModificationResult.PolicyTokenHash"/> - this is the hash of the [JSON Web Token][json_web_token] sent to the service</description> /// </item> /// </list> /// To verify the hash, clients can generate an attestation token and verify the hash generated from that token: /// <code snippet="Snippet:VerifySigningHash"> /// // The SetPolicyAsync API will create an AttestationToken signed with the TokenSigningKey to transmit the policy. /// // To verify that the policy specified by the caller was received by the service inside the enclave, we /// // verify that the hash of the policy document returned from the Attestation Service matches the hash /// // of an attestation token created locally. /// TokenSigningKey signingKey = new TokenSigningKey(<Customer provided signing key>, <Customer provided certificate>) /// var policySetToken = new AttestationToken( /// BinaryData.FromObjectAsJson(new StoredAttestationPolicy { AttestationPolicy = attestationPolicy }), /// signingKey); /// /// using var shaHasher = SHA256Managed.Create(); /// byte[] attestationPolicyHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.Serialize())); /// /// Debug.Assert(attestationPolicyHash.SequenceEqual(setResult.Value.PolicyTokenHash.ToArray())); /// </code> /// /// If the signing key and certificate are not provided, then the SetPolicyAsync API will create an unsecured attestation token /// wrapping the attestation policy. To validate the <see cref="PolicyModificationResult.PolicyTokenHash"/> return value, a developer /// can create their own <see cref="AttestationToken"/> and create the hash of that. /// <code> /// using var shaHasher = SHA256Managed.Create(); /// var policySetToken = new AttestationToken(new StoredAttestationPolicy { AttestationPolicy = disallowDebugging }); /// disallowDebuggingHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.ToString())); /// </code> /// </remarks> public virtual async Task <AttestationResponse <PolicyModificationResult> > SetPolicyAsync( AttestationType attestationType, string policyToSet, AttestationTokenSigningKey signingKey = default, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(policyToSet)) { throw new ArgumentException($"'{nameof(policyToSet)}' cannot be null or empty.", nameof(policyToSet)); } using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(AttestationAdministrationClient)}.{nameof(SetPolicy)}"); scope.Start(); try { AttestationToken tokenToSet = new AttestationToken(BinaryData.FromObjectAsJson(new StoredAttestationPolicy { AttestationPolicy = policyToSet, }), signingKey); var result = await _policyClient.SetAsync(attestationType, tokenToSet.Serialize(), cancellationToken).ConfigureAwait(false); var token = AttestationToken.Deserialize(result.Value.Token, _clientDiagnostics); if (_options.TokenOptions.ValidateToken) { var signers = await GetSignersAsync(true, cancellationToken).ConfigureAwait(false); if (!await token.ValidateTokenAsync(_options.TokenOptions, signers, cancellationToken).ConfigureAwait(false)) { AttestationTokenValidationFailedException.ThrowFailure(signers, token); } } return(new AttestationResponse <PolicyModificationResult>(result.GetRawResponse(), token)); } catch (Exception ex) { scope.Failed(ex); throw; } }
public async Task ValidateTooEarlyAttestationToken() { // 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(); // This check should fail since the token won't be valid for another 5 seconds. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken(serializedToken, tokenBody)); // This check should succeed since the token slack is greater than the 10 seconds before it becomes valid. await ValidateSerializedToken(serializedToken, tokenBody, new AttestationTokenValidationOptions { TimeValidationSlack = 10 }); }