private AttestationMechanism(AttestationMechanismType type, TpmAttestation tpm, X509Attestation x509, SymmetricKeyAttestation symmetricKey) { switch (type) { case AttestationMechanismType.Tpm: if (tpm == null) { throw new ProvisioningServiceClientException("Invalid TPM attestation mechanism."); } Tpm = tpm; break; case AttestationMechanismType.X509: if (x509 == null) { throw new ProvisioningServiceClientException("Invalid X509 attestation mechanism."); } X509 = x509; break; case AttestationMechanismType.None: break; case AttestationMechanismType.SymmetricKey: // In some cases symmetric keys are nulled out by the service SymmetricKey = symmetricKey ?? new SymmetricKeyAttestation(string.Empty, string.Empty); break; default: throw new ProvisioningServiceClientException("Unknown attestation mechanism."); } }
/// <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, AttestationMechanismType 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 != AttestationMechanismType.X509) //x509 enrollments are hardcoded, should never be deleted { await ProvisioningE2ETests.DeleteCreatedEnrollmentAsync(enrollmentType, provisioningServiceClient, security, groupId).ConfigureAwait(false); } }
public async Task ProvisioningServiceClient_GroupEnrollments_Create_Ok( string proxyServerAddress, AttestationMechanismType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iothubs) { string groupId = s_devicePrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); using (ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress)) { EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroupAsync( provisioningServiceClient, attestationType, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, null, Logger).ConfigureAwait(false); EnrollmentGroup enrollmentGroupResult = null; await RetryOperationHelper .RetryOperationsAsync( async() => { enrollmentGroupResult = await provisioningServiceClient.GetEnrollmentGroupAsync(enrollmentGroup.EnrollmentGroupId).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, Logger) .ConfigureAwait(false); if (enrollmentGroupResult == null) { throw new ArgumentException($"The enrollment group with group Id {enrollmentGroup.EnrollmentGroupId} could not retrieved, exiting test."); } 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 DeleteCreatedEnrollmentAsync(EnrollmentType.Group, "", enrollmentGroup.EnrollmentGroupId, Logger).ConfigureAwait(false); } }
public static async Task <EnrollmentGroup> CreateEnrollmentGroupAsync( ProvisioningServiceClient provisioningServiceClient, AttestationMechanismType attestationType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iothubs, DeviceCapabilities capabilities, MsTestLogger logger) { Attestation attestation; switch (attestationType) { case AttestationMechanismType.Tpm: throw new NotSupportedException("Group enrollments do not support tpm attestation"); case AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } var enrollmentGroup = new EnrollmentGroup(groupId, attestation) { Capabilities = capabilities, ReprovisionPolicy = reprovisionPolicy, AllocationPolicy = allocationPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iothubs, }; EnrollmentGroup createdEnrollmentGroup = null; await RetryOperationHelper .RetryOperationsAsync( async() => { createdEnrollmentGroup = await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (createdEnrollmentGroup == null) { throw new ArgumentException($"The enrollment entry with group Id {groupId} could not be created, exiting test."); } return(createdEnrollmentGroup); }
private AttestationMechanism(AttestationMechanismType type, TpmAttestation tpm, X509Attestation x509, SymmetricKeyAttestation symmetricKey) { switch (type) { case AttestationMechanismType.Tpm: if (tpm == null) { /* SRS_ATTESTATION_MECHANISM_21_013: [The constructor shall throw ProvisioningServiceClientException if the * provided AttestationMechanismType is `TPM` but the TPM attestation is null.] */ throw new ProvisioningServiceClientException("Invalid TPM attestation mechanism."); } /* SRS_ATTESTATION_MECHANISM_21_014: [If the provided AttestationMechanismType is `TPM`, the constructor * shall store the provided TPM attestation.] */ Tpm = tpm; break; case AttestationMechanismType.X509: if (x509 == null) { /* SRS_ATTESTATION_MECHANISM_21_015: [The constructor shall throw ProvisioningServiceClientException if the * provided AttestationMechanismType is `X509` but the X509 attestation is null.] */ throw new ProvisioningServiceClientException("Invalid X509 attestation mechanism."); } /* SRS_ATTESTATION_MECHANISM_21_016: [If the provided AttestationMechanismType is `X509`, the constructor * shall store the provided X509 attestation.] */ X509 = x509; break; case AttestationMechanismType.None: break; case AttestationMechanismType.SymmetricKey: // In some cases symmetric keys are nulled out by the service if (symmetricKey == null) { SymmetricKey = new SymmetricKeyAttestation(string.Empty, string.Empty); } else { SymmetricKey = symmetricKey; } break; default: /* SRS_ATTESTATION_MECHANISM_21_017: [The constructor shall throw ProvisioningServiceClientException if the * provided ProvisioningServiceClientException is not `TPM` or `X509`.] */ throw new ProvisioningServiceClientException("Unknown attestation mechanism."); } }
/// <summary> /// Returns the registrationId compliant name for the provided attestation type /// </summary> public static string AttestationTypeToString(AttestationMechanismType attestationType) { switch (attestationType) { case AttestationMechanismType.Tpm: return "tpm"; case AttestationMechanismType.SymmetricKey: return "symmetrickey"; case AttestationMechanismType.X509: return "x509"; default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } }
public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(AttestationMechanismType attestationType) { using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); string groupId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroupAsync(provisioningServiceClient, attestationType, groupId, null, AllocationPolicy.Static, null, null, null, Logger); AttestationMechanism attestationMechanism = null; await RetryOperationHelper .RetryOperationsAsync( async() => { attestationMechanism = await provisioningServiceClient.GetEnrollmentGroupAttestationAsync(enrollmentGroup.EnrollmentGroupId); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, Logger) .ConfigureAwait(false); if (attestationMechanism == null) { throw new ArgumentException($"The attestation mechanism for enrollment with group Id {enrollmentGroup.EnrollmentGroupId} could not retrieved, exiting test."); } // Note that tpm is not a supported attestation type for group enrollments if (attestationType == AttestationMechanismType.SymmetricKey) { attestationMechanism.Type.Should().Be(AttestationMechanismType.SymmetricKey); var symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation(); symmetricKeyAttestation.PrimaryKey.Should().Be(((SymmetricKeyAttestation)enrollmentGroup.Attestation).PrimaryKey); symmetricKeyAttestation.SecondaryKey.Should().Be(((SymmetricKeyAttestation)enrollmentGroup.Attestation).SecondaryKey); } else if (attestationType == AttestationMechanismType.X509) { attestationMechanism.Type.Should().Be(AttestationMechanismType.X509); var x509Attestation = (X509Attestation)attestationMechanism.GetAttestation(); x509Attestation.GetPrimaryX509CertificateInfo().SHA1Thumbprint.Should().Be(((X509Attestation)enrollmentGroup.Attestation).GetPrimaryX509CertificateInfo().SHA1Thumbprint); x509Attestation.GetSecondaryX509CertificateInfo().SHA1Thumbprint.Should().Be(((X509Attestation)enrollmentGroup.Attestation).GetSecondaryX509CertificateInfo().SHA1Thumbprint); } }
private AttestationMechanism(AttestationMechanismType type, TpmAttestation tpm, X509Attestation x509) { switch (type) { case AttestationMechanismType.Tpm: if (tpm == null) { /* SRS_ATTESTATION_MECHANISM_21_013: [The constructor shall throw ProvisioningServiceClientException if the * provided AttestationMechanismType is `TPM` but the TPM attestation is null.] */ throw new ProvisioningServiceClientException("Invalid TPM attestation mechanism."); } /* SRS_ATTESTATION_MECHANISM_21_014: [If the provided AttestationMechanismType is `TPM`, the constructor * shall store the provided TPM attestation.] */ Tpm = tpm; break; case AttestationMechanismType.X509: if (x509 == null) { /* SRS_ATTESTATION_MECHANISM_21_015: [The constructor shall throw ProvisioningServiceClientException if the * provided AttestationMechanismType is `X509` but the X509 attestation is null.] */ throw new ProvisioningServiceClientException("Invalid X509 attestation mechanism."); } /* SRS_ATTESTATION_MECHANISM_21_016: [If the provided AttestationMechanismType is `X509`, the constructor * shall store the provided X509 attestation.] */ X509 = x509; break; case AttestationMechanismType.None: break; default: /* SRS_ATTESTATION_MECHANISM_21_017: [The constructor shall throw ProvisioningServiceClientException if the * provided ProvisioningServiceClientException is not `TPM` or `X509`.] */ throw new ProvisioningServiceClientException("Unknown attestation mechanism."); } }
public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(AttestationMechanismType attestationType) { ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); string groupId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, attestationType, groupId, null, AllocationPolicy.Static, null, null, null); AttestationMechanism attestationMechanism = await provisioningServiceClient.GetEnrollmentGroupAttestationAsync(enrollmentGroup.EnrollmentGroupId); // Note that tpm is not a supported attestation type for group enrollments if (attestationType == AttestationMechanismType.SymmetricKey) { Assert.AreEqual(AttestationMechanismType.SymmetricKey, attestationMechanism.Type); SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation(); Assert.AreEqual(((SymmetricKeyAttestation)enrollmentGroup.Attestation).PrimaryKey, symmetricKeyAttestation.PrimaryKey); Assert.AreEqual(((SymmetricKeyAttestation)enrollmentGroup.Attestation).SecondaryKey, symmetricKeyAttestation.SecondaryKey); } else if (attestationType == AttestationMechanismType.X509) { Assert.AreEqual(AttestationMechanismType.X509, attestationMechanism.Type); X509Attestation x509Attestation = (X509Attestation)attestationMechanism.GetAttestation(); Assert.AreEqual(((X509Attestation)enrollmentGroup.Attestation).GetPrimaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetPrimaryX509CertificateInfo().SHA1Thumbprint); Assert.AreEqual(((X509Attestation)enrollmentGroup.Attestation).GetSecondaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetSecondaryX509CertificateInfo().SHA1Thumbprint); } }
/// <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, AttestationMechanismType attestationType, EnrollmentType? enrollmentType, bool setCustomProxy, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection<string> iotHubsToStartAt, ICollection<string> iotHubsToReprovisionTo, string proxyServerAddress = null) { using ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress); string groupId = null; if (enrollmentType == EnrollmentType.Group) { if (attestationType == AttestationMechanismType.X509) { groupId = TestConfiguration.Provisioning.X509GroupEnrollmentName; } else { groupId = _idPrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); } } bool transportProtocolSupportsTwinOperations = transportProtocol != Client.TransportType.Http1; using ProvisioningTransportHandler transport = CreateTransportHandlerFromName(transportProtocol); using SecurityProvider security = await CreateSecurityProviderFromNameAsync( attestationType, enrollmentType, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iotHubsToStartAt) .ConfigureAwait(false); //Check basic provisioning if (ImplementsWebProxy(transportProtocol) && setCustomProxy) { transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null; } var provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, TestConfiguration.Provisioning.IdScope, security, transport); using var cts = new CancellationTokenSource(PassingTimeoutMiliseconds); DeviceRegistrationResult result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false); ValidateDeviceRegistrationResult(result); #pragma warning disable CA2000 // Dispose objects before losing scope // The certificate instance referenced in the DeviceAuthenticationWithX509Certificate instance is common for all tests in this class. It is disposed during class cleanup. Client.IAuthenticationMethod auth = CreateAuthenticationMethodFromSecurityProvider(security, result.DeviceId); #pragma warning restore CA2000 // Dispose objects before losing scope await ConfirmRegisteredDeviceWorks(result, auth, transportProtocol, transportProtocolSupportsTwinOperations).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, transportProtocolSupportsTwinOperations).ConfigureAwait(false); if (attestationType == AttestationMechanismType.X509 && enrollmentType == EnrollmentType.Group) { Logger.Trace($"The test enrollment type {attestationType}-{enrollmentType} with group Id {groupId} is currently hardcoded - do not delete."); } else { Logger.Trace($"Deleting test enrollment type {attestationType}-{enrollmentType} with registration Id {security.GetRegistrationID()}."); await DeleteCreatedEnrollmentAsync(enrollmentType, security, groupId, Logger).ConfigureAwait(false); } if (security is SecurityProviderX509 x509Security) { X509Certificate2 deviceCertificate = x509Security.GetAuthenticationCertificate(); deviceCertificate?.Dispose(); } if (auth != null && auth is IDisposable disposableAuth) { disposableAuth?.Dispose(); } }
public static async Task<EnrollmentGroup> CreateEnrollmentGroup(ProvisioningServiceClient provisioningServiceClient, AttestationMechanismType attestationType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection<string> iothubs, DeviceCapabilities capabilities) { Attestation attestation; switch (attestationType) { case AttestationMechanismType.Tpm: throw new NotSupportedException("Group enrollments do not support tpm attestation"); case AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } var enrollmentGroup = new EnrollmentGroup(groupId, attestation) { Capabilities = capabilities, ReprovisionPolicy = reprovisionPolicy, AllocationPolicy = allocationPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iothubs, }; return await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false); }
public static async Task<IndividualEnrollment> CreateIndividualEnrollment(ProvisioningServiceClient provisioningServiceClient, AttestationMechanismType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection<string> iotHubsToProvisionTo, DeviceCapabilities capabilities) { string registrationId = AttestationTypeToString(attestationType) + "-registration-id-" + Guid.NewGuid(); Attestation attestation; IndividualEnrollment individualEnrollment; switch (attestationType) { case AttestationMechanismType.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)) { Capabilities = capabilities, AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, CustomAllocationDefinition = customAllocationDefinition, 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 AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } individualEnrollment = new IndividualEnrollment(registrationId, attestation); individualEnrollment.Capabilities = capabilities; 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, AttestationMechanismType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection<string> iothubs) { string groupId = s_devicePrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); using (ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress)) { EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, attestationType, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, null).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); try { await provisioningServiceClient.DeleteEnrollmentGroupAsync(enrollmentGroup.EnrollmentGroupId).ConfigureAwait(false); } catch (Exception ex) { Console.WriteLine($"Cleanup of enrollment group failed due to {ex}"); } } }
public static async Task ProvisioningServiceClient_GroupEnrollments_Create_Ok(string proxyServerAddress, AttestationMechanismType 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, AttestationMechanismType 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, null).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); } }
public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(AttestationMechanismType attestationType) { ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); IndividualEnrollment individualEnrollment = await CreateIndividualEnrollment(provisioningServiceClient, attestationType, null, AllocationPolicy.Static, null, null, null); AttestationMechanism attestationMechanism = await provisioningServiceClient.GetIndividualEnrollmentAttestationAsync(individualEnrollment.RegistrationId); if (attestationType == AttestationMechanismType.SymmetricKey) { Assert.AreEqual(AttestationMechanismType.SymmetricKey, attestationMechanism.Type); SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation(); Assert.AreEqual(((SymmetricKeyAttestation)individualEnrollment.Attestation).PrimaryKey, symmetricKeyAttestation.PrimaryKey); Assert.AreEqual(((SymmetricKeyAttestation)individualEnrollment.Attestation).SecondaryKey, symmetricKeyAttestation.SecondaryKey); } else if (attestationType == AttestationMechanismType.X509) { Assert.AreEqual(AttestationMechanismType.X509, attestationMechanism.Type); X509Attestation x509Attestation = (X509Attestation)attestationMechanism.GetAttestation(); Assert.AreEqual(((X509Attestation)individualEnrollment.Attestation).GetPrimaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetPrimaryX509CertificateInfo().SHA1Thumbprint); Assert.AreEqual(((X509Attestation)individualEnrollment.Attestation).GetSecondaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetSecondaryX509CertificateInfo().SHA1Thumbprint); } else { Assert.AreEqual(AttestationMechanismType.Tpm, attestationMechanism.Type); TpmAttestation tpmAttestation = (TpmAttestation)attestationMechanism.GetAttestation(); Assert.AreEqual(((TpmAttestation)individualEnrollment.Attestation).EndorsementKey, tpmAttestation.EndorsementKey); Assert.AreEqual(((TpmAttestation)individualEnrollment.Attestation).StorageRootKey, tpmAttestation.StorageRootKey); } }
private async Task <SecurityProvider> CreateSecurityProviderFromName(AttestationMechanismType 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 AttestationMechanismType.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); Logger.Trace($"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; Logger.Trace($"Updating enrollment: RegistrationID = {registrationId} EK = '{base64Ek}'"); await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false); return(tpmSim); case AttestationMechanismType.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 AttestationMechanismType.SymmetricKey: switch (enrollmentType) { case EnrollmentType.Group: EnrollmentGroup symmetricKeyEnrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, AttestationMechanismType.SymmetricKey, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities).ConfigureAwait(false); Assert.IsTrue(symmetricKeyEnrollmentGroup.Attestation is SymmetricKeyAttestation); SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation; string registrationIdSymmetricKey = _devicePrefix + 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, AttestationMechanismType.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}'."); }
private async Task<SecurityProvider> CreateSecurityProviderFromNameAsync( AttestationMechanismType attestationType, EnrollmentType? enrollmentType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection<string> iothubs, DeviceCapabilities capabilities = null) { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromNameAsync)}({attestationType})"); string registrationId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); switch (attestationType) { case AttestationMechanismType.Tpm: IndividualEnrollment tpmEnrollment = await CreateIndividualEnrollmentAsync( provisioningServiceClient, registrationId, AttestationMechanismType.Tpm, null, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities, Logger).ConfigureAwait(false); return new SecurityProviderTpmSimulator(tpmEnrollment.RegistrationId); case AttestationMechanismType.X509: X509Certificate2 certificate = null; X509Certificate2Collection collection = null; switch (enrollmentType) { case EnrollmentType.Individual: X509Certificate2Helper.GenerateSelfSignedCertificateFiles(registrationId, s_x509CertificatesFolder, Logger); #pragma warning disable CA2000 // Dispose objects before losing scope // This certificate is used for authentication with IoT hub and is returned to the caller of this method. // It is disposed when the caller to this method is disposed, at the end of the test method. certificate = X509Certificate2Helper.CreateX509Certificate2FromPfxFile(registrationId, s_x509CertificatesFolder); #pragma warning restore CA2000 // Dispose objects before losing scope using (X509Certificate2 publicCertificate = X509Certificate2Helper.CreateX509Certificate2FromCerFile(registrationId, s_x509CertificatesFolder)) { IndividualEnrollment x509IndividualEnrollment = await CreateIndividualEnrollmentAsync( provisioningServiceClient, registrationId, AttestationMechanismType.X509, publicCertificate, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities, Logger).ConfigureAwait(false); x509IndividualEnrollment.Attestation.Should().BeAssignableTo<X509Attestation>(); } break; case EnrollmentType.Group: // The X509 enrollment group has been hardcoded for the purpose of E2E tests and the root certificate has been verified on DPS. // Each device identity provisioning through the above enrollment group is created on-demand. X509Certificate2Helper.GenerateIntermediateCertificateSignedCertificateFiles( registrationId, s_intermediateCertificateSubject, s_x509CertificatesFolder, Logger); #pragma warning disable CA2000 // Dispose objects before losing scope // This certificate is used for authentication with IoT hub and is returned to the caller of this method. // It is disposed when the caller to this method is disposed, at the end of the test method. certificate = X509Certificate2Helper.CreateX509Certificate2FromPfxFile(registrationId, s_x509CertificatesFolder); #pragma warning restore CA2000 // Dispose objects before losing scope collection = new X509Certificate2Collection { TestConfiguration.CommonCertificates.GetRootCaCertificate(), TestConfiguration.CommonCertificates.GetIntermediate1Certificate(), TestConfiguration.CommonCertificates.GetIntermediate2Certificate(), X509Certificate2Helper.CreateX509Certificate2FromCerFile(registrationId, s_x509CertificatesFolder) }; break; default: throw new NotSupportedException($"Unknown X509 type: '{enrollmentType}'"); } return new SecurityProviderX509Certificate(certificate, collection); case AttestationMechanismType.SymmetricKey: switch (enrollmentType) { case EnrollmentType.Group: EnrollmentGroup symmetricKeyEnrollmentGroup = await CreateEnrollmentGroupAsync( provisioningServiceClient, AttestationMechanismType.SymmetricKey, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities, Logger) .ConfigureAwait(false); Assert.IsTrue(symmetricKeyEnrollmentGroup.Attestation is SymmetricKeyAttestation); var symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation; string registrationIdSymmetricKey = _idPrefix + Guid.NewGuid(); string primaryKeyEnrollmentGroup = symmetricKeyAttestation.PrimaryKey; string secondaryKeyEnrollmentGroup = symmetricKeyAttestation.SecondaryKey; string primaryKeyIndividual = ComputeDerivedSymmetricKey(Convert.FromBase64String(primaryKeyEnrollmentGroup), registrationIdSymmetricKey); string secondaryKeyIndividual = ComputeDerivedSymmetricKey(Convert.FromBase64String(secondaryKeyEnrollmentGroup), registrationIdSymmetricKey); return new SecurityProviderSymmetricKey(registrationIdSymmetricKey, primaryKeyIndividual, secondaryKeyIndividual); case EnrollmentType.Individual: IndividualEnrollment symmetricKeyEnrollment = await CreateIndividualEnrollmentAsync( provisioningServiceClient, registrationId, AttestationMechanismType.SymmetricKey, null, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities, Logger).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, AttestationMechanismType 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 async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(AttestationMechanismType attestationType) { using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); string registrationId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); IndividualEnrollment individualEnrollment = await CreateIndividualEnrollmentAsync( provisioningServiceClient, registrationId, attestationType, null, null, AllocationPolicy.Static, null, null, null, Logger) .ConfigureAwait(false); AttestationMechanism attestationMechanism = null; await RetryOperationHelper .RetryOperationsAsync( async() => { attestationMechanism = await provisioningServiceClient.GetIndividualEnrollmentAttestationAsync(individualEnrollment.RegistrationId); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, Logger) .ConfigureAwait(false); if (attestationMechanism == null) { throw new ArgumentException($"The attestation mechanism for enrollment with registration Id {individualEnrollment.RegistrationId} could not retrieved, exiting test."); } if (attestationType == AttestationMechanismType.SymmetricKey) { attestationMechanism.Type.Should().Be(AttestationMechanismType.SymmetricKey); var symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation(); symmetricKeyAttestation.PrimaryKey.Should().Be(((SymmetricKeyAttestation)individualEnrollment.Attestation).PrimaryKey); symmetricKeyAttestation.SecondaryKey.Should().Be(((SymmetricKeyAttestation)individualEnrollment.Attestation).SecondaryKey); } else if (attestationType == AttestationMechanismType.X509) { attestationMechanism.Type.Should().Be(AttestationMechanismType.X509); var x509Attestation = (X509Attestation)attestationMechanism.GetAttestation(); x509Attestation.GetPrimaryX509CertificateInfo().SHA1Thumbprint.Should().Be(((X509Attestation)individualEnrollment.Attestation).GetPrimaryX509CertificateInfo().SHA1Thumbprint); x509Attestation.GetSecondaryX509CertificateInfo().SHA1Thumbprint.Should().Be(((X509Attestation)individualEnrollment.Attestation).GetSecondaryX509CertificateInfo().SHA1Thumbprint); } else { attestationMechanism.Type.Should().Be(AttestationMechanismType.Tpm); var tpmAttestation = (TpmAttestation)attestationMechanism.GetAttestation(); tpmAttestation.EndorsementKey.Should().Be(((TpmAttestation)individualEnrollment.Attestation).EndorsementKey); tpmAttestation.StorageRootKey.Should().Be(((TpmAttestation)individualEnrollment.Attestation).StorageRootKey); } }
public async Task ProvisioningServiceClient_IndividualEnrollments_Create_Ok( string proxyServerAddress, AttestationMechanismType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToProvisionTo) { using (ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress)) { string registrationId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); IndividualEnrollment individualEnrollment = await CreateIndividualEnrollmentAsync( provisioningServiceClient, registrationId, attestationType, null, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iotHubsToProvisionTo, null, Logger).ConfigureAwait(false); IndividualEnrollment individualEnrollmentResult = null; await RetryOperationHelper .RetryOperationsAsync( async() => { individualEnrollmentResult = await provisioningServiceClient.GetIndividualEnrollmentAsync(individualEnrollment.RegistrationId).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, Logger) .ConfigureAwait(false); if (individualEnrollmentResult == null) { throw new ArgumentException($"The individual enrollment with registration Id {individualEnrollment.RegistrationId} could not retrieved, exiting test."); } 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 DeleteCreatedEnrollmentAsync(EnrollmentType.Individual, individualEnrollment.RegistrationId, null, Logger); } }
public static async Task <IndividualEnrollment> CreateIndividualEnrollmentAsync( ProvisioningServiceClient provisioningServiceClient, string registrationId, AttestationMechanismType attestationType, X509Certificate2 authenticationCertificate, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToProvisionTo, DeviceCapabilities capabilities, MsTestLogger logger) { Attestation attestation; IndividualEnrollment individualEnrollment; IndividualEnrollment createdEnrollment = null; switch (attestationType) { case AttestationMechanismType.Tpm: using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { Capabilities = capabilities, AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iotHubsToProvisionTo }; IndividualEnrollment temporaryCreatedEnrollment = null; await RetryOperationHelper .RetryOperationsAsync( async() => { temporaryCreatedEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (temporaryCreatedEnrollment == null) { throw new ArgumentException($"The enrollment entry with registration Id {registrationId} could not be created, exiting test."); } attestation = new TpmAttestation(base64Ek); temporaryCreatedEnrollment.Attestation = attestation; await RetryOperationHelper .RetryOperationsAsync( async() => { createdEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(temporaryCreatedEnrollment).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (createdEnrollment == null) { throw new ArgumentException($"The enrollment entry with registration Id {registrationId} could not be updated, exiting test."); } return(createdEnrollment); } case AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: attestation = X509Attestation.CreateFromClientCertificates(authenticationCertificate); break; default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } individualEnrollment = new IndividualEnrollment(registrationId, attestation) { Capabilities = capabilities, AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iotHubsToProvisionTo, }; await RetryOperationHelper .RetryOperationsAsync( async() => { createdEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (createdEnrollment == null) { throw new ArgumentException($"The enrollment entry with registration Id {registrationId} could not be created, exiting test."); } return(createdEnrollment); }