/// <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);
            }
        }
Beispiel #2
0
        /// <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");
            }
        }
Beispiel #3
0
        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}'.");
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
 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);
 }
Beispiel #9
0
        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);
        }