/// <summary> /// Provisions a device to a starting hub, tries to open a connection, send telemetry, /// and (if supported by the protocol) send a twin update. Then, this method updates the enrollment /// to provision the device to a different hub. Based on the provided reprovisioning settings, this /// method then checks that the device was/was not reprovisioned as expected, and that the device /// did/did not migrate twin data as expected. /// </summary> public async Task ProvisioningDeviceClient_ReprovisioningFlow( Client.TransportType transportProtocol, AttestationType attestationType, EnrollmentType?enrollmentType, bool setCustomProxy, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToStartAt, ICollection <string> iotHubsToReprovisionTo, string proxyServerAddress = null) { ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress); string groupId = _devicePrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); bool twinOperationsAllowed = transportProtocol != Client.TransportType.Http1; using ProvisioningTransportHandler transport = ProvisioningE2ETests.CreateTransportHandlerFromName(transportProtocol); using SecurityProvider security = await CreateSecurityProviderFromName( attestationType, enrollmentType, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iotHubsToStartAt) .ConfigureAwait(false); //Check basic provisioning if (ProvisioningE2ETests.ImplementsWebProxy(transportProtocol) && setCustomProxy) { transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null; } ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, Configuration.Provisioning.IdScope, security, transport); using var cts = new CancellationTokenSource(PassingTimeoutMiliseconds); DeviceRegistrationResult result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false); ValidateDeviceRegistrationResult(result); Client.IAuthenticationMethod auth = CreateAuthenticationMethodFromSecurityProvider(security, result.DeviceId); await ConfirmRegisteredDeviceWorks(result, auth, transportProtocol, twinOperationsAllowed).ConfigureAwait(false); //Check reprovisioning await UpdateEnrollmentToForceReprovision(enrollmentType, provisioningServiceClient, iotHubsToReprovisionTo, security, groupId).ConfigureAwait(false); result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false); ConfirmDeviceInExpectedHub(result, reprovisionPolicy, iotHubsToStartAt, iotHubsToReprovisionTo, allocationPolicy); await ConfirmDeviceWorksAfterReprovisioning(result, auth, transportProtocol, reprovisionPolicy, twinOperationsAllowed).ConfigureAwait(false); if (attestationType != AttestationType.x509) //x509 enrollments are hardcoded, should never be deleted { await ProvisioningE2ETests.DeleteCreatedEnrollment(enrollmentType, provisioningServiceClient, security, groupId).ConfigureAwait(false); } }
/// <summary> /// Returns the registrationId compliant name for the provided attestation type /// </summary> public static string AttestationTypeToString(AttestationType attestationType) { switch (attestationType) { case AttestationType.Tpm: return("tpm"); case AttestationType.SymmetricKey: return("symmetrickey"); case AttestationType.x509: return("x509"); default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } }
private async Task <SecurityProvider> CreateSecurityProviderFromName(AttestationType attestationType, EnrollmentType?enrollmentType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iothubs, DeviceCapabilities capabilities = null) { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromName)}({attestationType})"); var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); switch (attestationType) { case AttestationType.Tpm: string registrationId = AttestationTypeToString(attestationType) + "-registration-id-" + Guid.NewGuid(); var tpmSim = new SecurityProviderTpmSimulator(registrationId); string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); _log.WriteLine($"Getting enrollment: RegistrationID = {registrationId}"); IndividualEnrollment individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; IndividualEnrollment enrollment = await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); var attestation = new TpmAttestation(base64Ek); enrollment.Attestation = attestation; _log.WriteLine($"Updating enrollment: RegistrationID = {registrationId} EK = '{base64Ek}'"); await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false); return(tpmSim); case AttestationType.x509: X509Certificate2 certificate = null; X509Certificate2Collection collection = null; switch (enrollmentType) { case EnrollmentType.Individual: certificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); break; case EnrollmentType.Group: certificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); collection = Configuration.Provisioning.GetGroupEnrollmentChain(); break; default: throw new NotSupportedException($"Unknown X509 type: '{enrollmentType}'"); } return(new SecurityProviderX509Certificate(certificate, collection)); case AttestationType.SymmetricKey: switch (enrollmentType) { case EnrollmentType.Group: EnrollmentGroup symmetricKeyEnrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, AttestationType.SymmetricKey, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities).ConfigureAwait(false); Assert.IsTrue(symmetricKeyEnrollmentGroup.Attestation is SymmetricKeyAttestation); SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation; string registrationIdSymmetricKey = IdPrefix + Guid.NewGuid(); string primaryKeyEnrollmentGroup = symmetricKeyAttestation.PrimaryKey; string secondaryKeyEnrollmentGroup = symmetricKeyAttestation.SecondaryKey; string primaryKeyIndividual = ProvisioningE2ETests.ComputeDerivedSymmetricKey(Convert.FromBase64String(primaryKeyEnrollmentGroup), registrationIdSymmetricKey); string secondaryKeyIndividual = ProvisioningE2ETests.ComputeDerivedSymmetricKey(Convert.FromBase64String(secondaryKeyEnrollmentGroup), registrationIdSymmetricKey); return(new SecurityProviderSymmetricKey(registrationIdSymmetricKey, primaryKeyIndividual, secondaryKeyIndividual)); case EnrollmentType.Individual: IndividualEnrollment symmetricKeyEnrollment = await CreateIndividualEnrollment(provisioningServiceClient, AttestationType.SymmetricKey, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities).ConfigureAwait(false); Assert.IsTrue(symmetricKeyEnrollment.Attestation is SymmetricKeyAttestation); symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollment.Attestation; registrationIdSymmetricKey = symmetricKeyEnrollment.RegistrationId; string primaryKey = symmetricKeyAttestation.PrimaryKey; string secondaryKey = symmetricKeyAttestation.SecondaryKey; return(new SecurityProviderSymmetricKey(registrationIdSymmetricKey, primaryKey, secondaryKey)); default: throw new NotSupportedException("Unrecognized enrollment type"); } default: throw new NotSupportedException("Unrecognized attestation type"); } throw new NotSupportedException($"Unknown security type: '{attestationType}'."); }
/// <summary> /// The expected behaviour is that, with ReprovisionPolicy set to never update hub, the a device is not reprovisioned, even when other settings would suggest it should /// </summary> private async Task ProvisioningDeviceClient_ReprovisioningFlow_DoNotReprovision(Client.TransportType transportProtocol, AttestationType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); ICollection <string> iotHubsToStartAt = new List <string>() { Configuration.Provisioning.FarAwayIotHubHostName }; ICollection <string> iotHubsToReprovisionTo = new List <string>() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = false, UpdateHubAssignment = false }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); }
public static async Task <EnrollmentGroup> CreateEnrollmentGroup(ProvisioningServiceClient provisioningServiceClient, AttestationType attestationType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iothubs) { Attestation attestation; switch (attestationType) { case AttestationType.Tpm: throw new NotSupportedException("Group enrollments do not support tpm attestation"); case AttestationType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationType.x509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } EnrollmentGroup enrollmentGroup = new EnrollmentGroup(groupId, attestation); enrollmentGroup.ReprovisionPolicy = reprovisionPolicy; enrollmentGroup.AllocationPolicy = allocationPolicy; enrollmentGroup.CustomAllocationDefinition = customAllocationDefinition; enrollmentGroup.IotHubs = iothubs; return(await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false)); }
public static async Task <IndividualEnrollment> CreateIndividualEnrollment(ProvisioningServiceClient provisioningServiceClient, AttestationType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToProvisionTo) { string registrationId = AttestationTypeToString(attestationType) + "-registration-id-" + Guid.NewGuid(); Attestation attestation; IndividualEnrollment individualEnrollment; switch (attestationType) { case AttestationType.Tpm: using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)); individualEnrollment.AllocationPolicy = allocationPolicy; individualEnrollment.ReprovisionPolicy = reprovisionPolicy; individualEnrollment.CustomAllocationDefinition = customAllocationDefinition; individualEnrollment.IotHubs = iotHubsToProvisionTo; IndividualEnrollment enrollment = await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); attestation = new TpmAttestation(base64Ek); enrollment.Attestation = attestation; return(await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false)); } case AttestationType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationType.x509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } individualEnrollment = new IndividualEnrollment(registrationId, attestation); individualEnrollment.CustomAllocationDefinition = customAllocationDefinition; individualEnrollment.ReprovisionPolicy = reprovisionPolicy; individualEnrollment.IotHubs = iotHubsToProvisionTo; individualEnrollment.AllocationPolicy = allocationPolicy; return(await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false)); }
public static async Task ProvisioningServiceClient_GroupEnrollments_Create_Ok(string proxyServerAddress, AttestationType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iothubs) { string groupId = IdPrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); using (ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress)) { EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, attestationType, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs).ConfigureAwait(false); EnrollmentGroup enrollmentGroupResult = await provisioningServiceClient.GetEnrollmentGroupAsync(enrollmentGroup.EnrollmentGroupId).ConfigureAwait(false); Assert.AreEqual(enrollmentGroupResult.ProvisioningStatus, ProvisioningStatus.Enabled); if (reprovisionPolicy != null) { Assert.AreEqual(reprovisionPolicy.MigrateDeviceData, enrollmentGroupResult.ReprovisionPolicy.MigrateDeviceData); Assert.AreEqual(reprovisionPolicy.UpdateHubAssignment, enrollmentGroupResult.ReprovisionPolicy.UpdateHubAssignment); } if (customAllocationDefinition != null) { Assert.AreEqual(customAllocationDefinition.WebhookUrl, enrollmentGroupResult.CustomAllocationDefinition.WebhookUrl); Assert.AreEqual(customAllocationDefinition.ApiVersion, enrollmentGroupResult.CustomAllocationDefinition.ApiVersion); } Assert.AreEqual(allocationPolicy, enrollmentGroup.AllocationPolicy); await provisioningServiceClient.DeleteEnrollmentGroupAsync(enrollmentGroup.EnrollmentGroupId).ConfigureAwait(false); } }
public static async Task ProvisioningServiceClient_GroupEnrollments_Create_Ok(string proxyServerAddress, AttestationType attestationType) { await ProvisioningServiceClient_GroupEnrollments_Create_Ok(proxyServerAddress, attestationType, null, AllocationPolicy.Hashed, null, null).ConfigureAwait(false); }
public static async Task ProvisioningServiceClient_IndividualEnrollments_Create_Ok(string proxyServerAddress, AttestationType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToProvisionTo) { using (ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress)) { IndividualEnrollment individualEnrollment = await CreateIndividualEnrollment(provisioningServiceClient, attestationType, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iotHubsToProvisionTo).ConfigureAwait(false); IndividualEnrollment individualEnrollmentResult = await provisioningServiceClient.GetIndividualEnrollmentAsync(individualEnrollment.RegistrationId).ConfigureAwait(false); Assert.AreEqual(individualEnrollmentResult.ProvisioningStatus, ProvisioningStatus.Enabled); if (reprovisionPolicy != null) { Assert.AreEqual(reprovisionPolicy.UpdateHubAssignment, individualEnrollmentResult.ReprovisionPolicy.UpdateHubAssignment); Assert.AreEqual(reprovisionPolicy.MigrateDeviceData, individualEnrollmentResult.ReprovisionPolicy.MigrateDeviceData); } if (customAllocationDefinition != null) { Assert.AreEqual(customAllocationDefinition.WebhookUrl, individualEnrollmentResult.CustomAllocationDefinition.WebhookUrl); Assert.AreEqual(customAllocationDefinition.ApiVersion, individualEnrollmentResult.CustomAllocationDefinition.ApiVersion); } //allocation policy is never null Assert.AreEqual(allocationPolicy, individualEnrollmentResult.AllocationPolicy); await provisioningServiceClient.DeleteIndividualEnrollmentAsync(individualEnrollment.RegistrationId).ConfigureAwait(false); } }
private async Task ResetAttestationPolicy(AttestationAdministrationClient adminClient, AttestationType attestationType, bool isSecuredToken, bool isIsolated) { X509Certificate2 x509Certificate = null; RSA rsaKey = null; if (isSecuredToken) { if (isIsolated) { x509Certificate = TestEnvironment.PolicyManagementCertificate; rsaKey = TestEnvironment.PolicyManagementKey; } else { x509Certificate = TestEnvironment.PolicyCertificate0; rsaKey = TestEnvironment.PolicySigningKey0; } } else { } var policySetResult = await adminClient.ResetPolicyAsync(AttestationType.OpenEnclave, (rsaKey != null ? new TokenSigningKey(rsaKey, x509Certificate) : null)); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Removed, policySetResult.Value.PolicyResolution); }