// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using Xunit; namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer { public class ConfigureSigningCredentialsTests { // We need to cast the underlying int value of the EphemeralKeySet to X509KeyStorageFlags // due to the fact that is not part of .NET Standard. This value is only used with non-windows // platforms (all .NET Core) for which the value is defined on the underlying platform. private const X509KeyStorageFlags UnsafeEphemeralKeySet = (X509KeyStorageFlags)32; private static readonly X509KeyStorageFlags DefaultFlags = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? UnsafeEphemeralKeySet : (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? X509KeyStorageFlags.PersistKeySet : X509KeyStorageFlags.DefaultKeySet); [ConditionalFact] [FrameworkSkipCondition(RuntimeFrameworks.CLR)] public void Configure_AddsDevelopmentKeyFromConfiguration() { var expectedKeyPath = Path.Combine(Directory.GetCurrentDirectory(), "./testkey.json"); try { // Arrange var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary() { ["Type"] = "Development", ["FilePath"] = "testkey.json" }).Build(); var configureSigningCredentials = new ConfigureSigningCredentials( configuration, new TestLogger()); var options = new ApiAuthorizationOptions(); // Act configureSigningCredentials.Configure(options); // Assert Assert.NotNull(options); Assert.True(File.Exists(expectedKeyPath)); Assert.NotNull(options.SigningCredential); Assert.Equal("Development", options.SigningCredential.Kid); Assert.IsType(options.SigningCredential.Key); } finally { if (File.Exists(expectedKeyPath)) { File.Delete(expectedKeyPath); } } } [Fact] public void Configure_LoadsPfxCertificateCredentialFromConfiguration() { // Arrange var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary() { ["Type"] = "File", ["FilePath"] = "test.pfx", ["Password"] = "aspnetcore" }).Build(); var configureSigningCredentials = new ConfigureSigningCredentials( configuration, new TestLogger()); var options = new ApiAuthorizationOptions(); // Act configureSigningCredentials.Configure(options); // Assert Assert.NotNull(options); Assert.NotNull(options.SigningCredential); var key = Assert.IsType(options.SigningCredential.Key); Assert.NotNull(key.Certificate); Assert.Equal("AC8FDF4BD4C10841BD24DC88D983225D10B43BB2", key.Certificate.Thumbprint); } [Fact] public void Configure_LoadsCertificateStoreCertificateCredentialFromConfiguration() { try { // Arrange var x509Certificate = new X509Certificate2("test.pfx", "aspnetcore", DefaultFlags); SetupTestCertificate(x509Certificate); var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary() { ["Type"] = "Store", ["StoreLocation"] = "CurrentUser", ["StoreName"] = "My", ["Name"] = "CN=Test" }).Build(); var configureSigningCredentials = new ConfigureSigningCredentials( configuration, new TestLogger()); var options = new ApiAuthorizationOptions(); // Act configureSigningCredentials.Configure(options); // Assert Assert.NotNull(options); Assert.NotNull(options.SigningCredential); var key = Assert.IsType(options.SigningCredential.Key); Assert.NotNull(key.Certificate); Assert.Equal("AC8FDF4BD4C10841BD24DC88D983225D10B43BB2", key.Certificate.Thumbprint); } finally { CleanupTestCertificate(); } } private static void CleanupTestCertificate() { using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); var certificates = store .Certificates .Find(X509FindType.FindByThumbprint, "1646CFBEE354788D7116DF86EFC35C0075A9C05D", validOnly: false); foreach (var certificate in certificates) { store.Certificates.Remove(certificate); } foreach (var certificate in certificates) { certificate.Dispose(); } store.Close(); } } private static void SetupTestCertificate(X509Certificate2 x509Certificate) { using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); var certificates = store .Certificates .Find(X509FindType.FindByThumbprint, "AC8FDF4BD4C10841BD24DC88D983225D10B43BB2", validOnly: false); if (certificates.Count == 0) { store.Add(x509Certificate); } foreach (var certificate in certificates) { certificate.Dispose(); } store.Close(); } } } }