public static IIdentityServerBuilder AddCaffStoreIdentityServer(this IServiceCollection services, IConfiguration configuration) { var builder = services.AddIdentityServer(options => { options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; }) .AddInMemoryIdentityResources(IdentityServerConfig.IdentityResources) .AddInMemoryApiScopes(IdentityServerConfig.ApiScopes) .AddInMemoryClients(IdentityServerConfig.Clients) .AddAspNetIdentity <User>(); var identityServerOptions = new IdentityServerOptions(); configuration.Bind(nameof(IdentityServerOptions), identityServerOptions); return(identityServerOptions.SigningCredentialSourceType switch { SigningCredentialSourceType.Developer => builder.AddDeveloperSigningCredential(), SigningCredentialSourceType.KeyVault => builder.AddSigningCredential( X509Certificate2Helper.GetCertificateFromAzureKeyVaultAsync( identityServerOptions.AzureKeyVaultUri, identityServerOptions.AzureKeyVaultSigningCertificateName)), _ => builder });
public static void TestClassSetup(TestContext _) { // Create a folder to hold the DPS client certificates and X509 self-signed certificates. If a folder by the same name already exists, it will be used. s_x509CertificatesFolder = Directory.CreateDirectory($"x509Certificates-{nameof(ProvisioningE2ETests)}-{Guid.NewGuid()}"); // Extract the public certificate and private key information from the intermediate certificate pfx file. // These keys will be used to sign the test leaf device certificates. s_intermediateCertificateSubject = X509Certificate2Helper.ExtractPublicCertificateAndPrivateKeyFromPfxAndReturnSubject( TestConfiguration.Provisioning.GetGroupEnrollmentIntermediatePfxCertificateBase64(), s_certificatePassword, s_x509CertificatesFolder); }
private static void AddVaultCertificateStore(this IdentityServerOptions options, VaultCertificateStoreOptions vaultOptions, IVaultAuth vaultAuth) { // This isn't great but we need a cert at startup var client = new VaultClient(vaultAuth, vaultOptions.VaultUrl, vaultOptions.VaultCertificate); var certificateStore = new VaultCertificateStore(client, vaultOptions.RoleName, vaultOptions.CommonName); var certificateHelper = new X509Certificate2Helper(); var privateKeyHelper = new RsaCryptoServiceProviderHelper(); var vaultService = new VaultCertificateService(options, certificateStore, certificateHelper, privateKeyHelper); vaultService.GetCertificates(); // Register our dependencies options.Factory.Register(new Registration <IVaultCertificateService>(vaultService)); options.Factory.SigningKeyService = new Registration <ISigningKeyService, VaultTokenSigningKeyService>(); }
private async Task TestInvalidServiceCertificate(ProvisioningTransportHandler transport) { string certificateSubject = $"E2E_{nameof(ProvisioningCertificateValidationE2ETest)}-{Guid.NewGuid()}"; X509Certificate2Helper.GenerateSelfSignedCertificateFiles(certificateSubject, s_x509CertificatesFolder, Logger); using X509Certificate2 cert = X509Certificate2Helper.CreateX509Certificate2FromPfxFile(certificateSubject, s_x509CertificatesFolder); using var security = new SecurityProviderX509Certificate(cert); var provisioningDeviceClient = ProvisioningDeviceClient.Create( TestConfiguration.Provisioning.GlobalDeviceEndpointInvalidServiceCertificate, "0ne00000001", security, transport); await provisioningDeviceClient.RegisterAsync().ConfigureAwait(false); }
/// <summary> /// Creates a new self-signed X509 certificate /// </summary> /// <param name="issuer">The certificate issuer</param> /// <param name="friendlyName">Human readable name</param> /// <param name="password">The certificate's password</param> /// <param name="startTime">Certificate creation date & time</param> /// <param name="endTime">Certificate expiry date & time</param> /// <returns>An X509Certificate2</returns> public static X509Certificate2 CreateSelfSignedCert(string issuer, string friendlyName, string password, DateTime startTime, DateTime endTime) { string distinguishedNameString = issuer; var key = Create2048RsaKey(); var creationParams = new X509CertificateCreationParameters(new X500DistinguishedName(distinguishedNameString)) { TakeOwnershipOfKey = true, StartTime = startTime, EndTime = endTime }; // adding client authentication, -eku = 1.3.6.1.5.5.7.3.2, // This is mandatory for the upload to be successful OidCollection oidCollection = new OidCollection(); oidCollection.Add(new Oid(OIDClientAuthValue, OIDClientAuthFriendlyName)); creationParams.Extensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, false)); // Documentation of CreateSelfSignedCertificate states: // If creationParameters have TakeOwnershipOfKey set to true, the certificate // generated will own the key and the input CngKey will be disposed to ensure // that the caller doesn't accidentally use it beyond its lifetime (which is // now controlled by the certificate object). // We don't dispose it ourselves in this case. var cert = key.CreateSelfSignedCertificate(creationParams); key = null; cert.FriendlyName = friendlyName; // X509 certificate needs PersistKeySet flag set. // Reload a new X509Certificate2 instance from exported bytes in order to set the PersistKeySet flag. var bytes = cert.Export(X509ContentType.Pfx, password); // NOTE: PfxValidation is not done here because these are newly created certs and assumed valid. ICommonEventSource evtSource = null; return(X509Certificate2Helper.NewX509Certificate2(bytes, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable, evtSource, doPfxValidation: false)); }
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}'."); }