[HTTPS] Adds PEM support for Kestrel (#23584)
* Adds support for loading PEM certificates and keys in Kestrel. * You can load PEM Certificate + PKCS8 encoded PEM Keys. * Certificates in DER format + PKCS8 encoded PEM Keys. * Supported key types are: * RSA * ECSA * DSA
This commit is contained in:
parent
dc477ed2f4
commit
9d3bf572b3
|
|
@ -614,4 +614,10 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l
|
|||
<data name="ArgumentTimeSpanGreaterOrEqual" xml:space="preserve">
|
||||
<value>A TimeSpan value greater than or equal to {value} is required.</value>
|
||||
</data>
|
||||
<data name="InvalidPemKey" xml:space="preserve">
|
||||
<value>The provided key file is missing or invalid.</value>
|
||||
</data>
|
||||
<data name="UnrecognizedCertificateKeyOid" xml:space="preserve">
|
||||
<value>Unknown algorithm for certificate with public key type '{0}'.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -205,6 +205,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string KeyPath { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
// Cert store
|
||||
|
|
|
|||
|
|
@ -46,6 +46,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
new EventId(5, "DeveloperCertificateFirstRun"),
|
||||
"{Message}");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _failedToLoadCertificate =
|
||||
LoggerMessage.Define<string>(
|
||||
LogLevel.Error,
|
||||
new EventId(6, "MissingOrInvalidCertificateFile"),
|
||||
"The certificate file at '{CertificateFilePath}' can not be found, contains malformed data or does not contain a certificate.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _failedToLoadCertificateKey =
|
||||
LoggerMessage.Define<string>(
|
||||
LogLevel.Error,
|
||||
new EventId(7, "MissingOrInvalidCertificateKeyFile"),
|
||||
"The certificate key file at '{CertificateKeyFilePath}' can not be found, contains malformed data or does not contain a PEM encoded key in PKCS8 format.");
|
||||
|
||||
public static void LocatedDevelopmentCertificate(this ILogger logger, X509Certificate2 certificate) => _locatedDevelopmentCertificate(logger, certificate.Subject, certificate.Thumbprint, null);
|
||||
|
||||
public static void UnableToLocateDevelopmentCertificate(this ILogger logger) => _unableToLocateDevelopmentCertificate(logger, null);
|
||||
|
|
@ -57,5 +69,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
public static void BadDeveloperCertificateState(this ILogger logger) => _badDeveloperCertificateState(logger, null);
|
||||
|
||||
public static void DeveloperCertificateFirstRun(this ILogger logger, string message) => _developerCertificateFirstRun(logger, message, null);
|
||||
|
||||
public static void FailedToLoadCertificate(this ILogger logger, string certificatePath) => _failedToLoadCertificate(logger, certificatePath, null);
|
||||
public static void FailedToLoadCertificateKey(this ILogger logger, string certificateKeyPath) => _failedToLoadCertificateKey(logger, certificateKeyPath, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
|
@ -429,20 +430,133 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
|
||||
private X509Certificate2 LoadCertificate(CertificateConfig certInfo, string endpointName)
|
||||
{
|
||||
var logger = Options.ApplicationServices.GetRequiredService<ILogger<KestrelConfigurationLoader>>();
|
||||
if (certInfo.IsFileCert && certInfo.IsStoreCert)
|
||||
{
|
||||
throw new InvalidOperationException(CoreStrings.FormatMultipleCertificateSources(endpointName));
|
||||
}
|
||||
else if (certInfo.IsFileCert)
|
||||
{
|
||||
var env = Options.ApplicationServices.GetRequiredService<IHostEnvironment>();
|
||||
return new X509Certificate2(Path.Combine(env.ContentRootPath, certInfo.Path), certInfo.Password);
|
||||
var environment = Options.ApplicationServices.GetRequiredService<IHostEnvironment>();
|
||||
var certificatePath = Path.Combine(environment.ContentRootPath, certInfo.Path);
|
||||
if (certInfo.KeyPath != null)
|
||||
{
|
||||
var certificateKeyPath = Path.Combine(environment.ContentRootPath, certInfo.KeyPath);
|
||||
var certificate = GetCertificate(certificatePath);
|
||||
|
||||
if (certificate != null)
|
||||
{
|
||||
certificate = LoadCertificateKey(certificate, certificateKeyPath, certInfo.Password);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.FailedToLoadCertificate(certificateKeyPath);
|
||||
}
|
||||
|
||||
if (certificate != null)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return PersistKey(certificate);
|
||||
}
|
||||
|
||||
return certificate;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.FailedToLoadCertificateKey(certificateKeyPath);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(CoreStrings.InvalidPemKey);
|
||||
}
|
||||
|
||||
return new X509Certificate2(Path.Combine(environment.ContentRootPath, certInfo.Path), certInfo.Password);
|
||||
}
|
||||
else if (certInfo.IsStoreCert)
|
||||
{
|
||||
return LoadFromStoreCert(certInfo);
|
||||
}
|
||||
return null;
|
||||
|
||||
static X509Certificate2 PersistKey(X509Certificate2 fullCertificate)
|
||||
{
|
||||
// We need to force the key to be persisted.
|
||||
// See https://github.com/dotnet/runtime/issues/23749
|
||||
var certificateBytes = fullCertificate.Export(X509ContentType.Pkcs12, "");
|
||||
return new X509Certificate2(certificateBytes, "", X509KeyStorageFlags.DefaultKeySet);
|
||||
}
|
||||
|
||||
static X509Certificate2 LoadCertificateKey(X509Certificate2 certificate, string keyPath, string password)
|
||||
{
|
||||
// OIDs for the certificate key types.
|
||||
const string RSAOid = "1.2.840.113549.1.1.1";
|
||||
const string DSAOid = "1.2.840.10040.4.1";
|
||||
const string ECDsaOid = "1.2.840.10045.2.1";
|
||||
|
||||
var keyText = File.ReadAllText(keyPath);
|
||||
return certificate.PublicKey.Oid.Value switch
|
||||
{
|
||||
RSAOid => AttachPemRSAKey(certificate, keyText, password),
|
||||
ECDsaOid => AttachPemECDSAKey(certificate, keyText, password),
|
||||
DSAOid => AttachPemDSAKey(certificate, keyText, password),
|
||||
_ => throw new InvalidOperationException(string.Format(CoreStrings.UnrecognizedCertificateKeyOid, certificate.PublicKey.Oid.Value))
|
||||
};
|
||||
}
|
||||
|
||||
static X509Certificate2 GetCertificate(string certificatePath)
|
||||
{
|
||||
if (X509Certificate2.GetCertContentType(certificatePath) == X509ContentType.Cert)
|
||||
{
|
||||
return new X509Certificate2(certificatePath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static X509Certificate2 AttachPemRSAKey(X509Certificate2 certificate, string keyText, string password)
|
||||
{
|
||||
using var rsa = RSA.Create();
|
||||
if (password == null)
|
||||
{
|
||||
rsa.ImportFromPem(keyText);
|
||||
}
|
||||
else
|
||||
{
|
||||
rsa.ImportFromEncryptedPem(keyText, password);
|
||||
}
|
||||
|
||||
return certificate.CopyWithPrivateKey(rsa);
|
||||
}
|
||||
|
||||
private static X509Certificate2 AttachPemDSAKey(X509Certificate2 certificate, string keyText, string password)
|
||||
{
|
||||
using var dsa = DSA.Create();
|
||||
if (password == null)
|
||||
{
|
||||
dsa.ImportFromPem(keyText);
|
||||
}
|
||||
else
|
||||
{
|
||||
dsa.ImportFromEncryptedPem(keyText, password);
|
||||
}
|
||||
|
||||
return certificate.CopyWithPrivateKey(dsa);
|
||||
}
|
||||
|
||||
private static X509Certificate2 AttachPemECDSAKey(X509Certificate2 certificate, string keyText, string password)
|
||||
{
|
||||
using var ecdsa = ECDsa.Create();
|
||||
if (password == null)
|
||||
{
|
||||
ecdsa.ImportFromPem(keyText);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportFromEncryptedPem(keyText, password);
|
||||
}
|
||||
|
||||
return certificate.CopyWithPrivateKey(ecdsa);
|
||||
}
|
||||
|
||||
private static X509Certificate2 LoadFromStoreCert(CertificateConfig certInfo)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
<Compile Include="$(KestrelSharedSourceRoot)test\*.cs" LinkBase="shared" />
|
||||
<Compile Include="$(KestrelSharedSourceRoot)KnownHeaders.cs" LinkBase="shared" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.crt" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.key" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" />
|
||||
<Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" />
|
||||
<Compile Include="$(SharedSourceRoot)test\Shared.Tests\runtime\**\*.cs" Link="Shared\runtime\%(Filename)%(Extension)" />
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
|
@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests
|
|||
private KestrelServerOptions CreateServerOptions()
|
||||
{
|
||||
var serverOptions = new KestrelServerOptions();
|
||||
var env = new MockHostingEnvironment { ApplicationName = "TestApplication" };
|
||||
var env = new MockHostingEnvironment { ApplicationName = "TestApplication", ContentRootPath = Directory.GetCurrentDirectory() };
|
||||
serverOptions.ApplicationServices = new ServiceCollection()
|
||||
.AddLogging()
|
||||
.AddSingleton<IHostEnvironment>(env)
|
||||
|
|
@ -254,6 +255,121 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureEndpoint_ThrowsWhen_The_PasswordIsMissing()
|
||||
{
|
||||
var serverOptions = CreateServerOptions();
|
||||
var certificate = new X509Certificate2(TestResources.GetCertPath("https-aspnet.crt"));
|
||||
|
||||
var config = new ConfigurationBuilder().AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("Endpoints:End1:Url", "https://*:5001"),
|
||||
new KeyValuePair<string, string>("Certificates:Default:Path", Path.Combine("shared", "TestCertificates", "https-aspnet.crt")),
|
||||
new KeyValuePair<string, string>("Certificates:Default:KeyPath", Path.Combine("shared", "TestCertificates", "https-aspnet.key"))
|
||||
}).Build();
|
||||
|
||||
var ex = Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
serverOptions
|
||||
.Configure(config)
|
||||
.Endpoint("End1", opt =>
|
||||
{
|
||||
Assert.True(opt.IsHttps);
|
||||
}).Load();
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureEndpoint_ThrowsWhen_TheKeyDoesntMatchTheCertificateKey()
|
||||
{
|
||||
var serverOptions = CreateServerOptions();
|
||||
var certificate = new X509Certificate2(TestResources.GetCertPath("https-aspnet.crt"));
|
||||
|
||||
var config = new ConfigurationBuilder().AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("Endpoints:End1:Url", "https://*:5001"),
|
||||
new KeyValuePair<string, string>("Certificates:Default:Path", Path.Combine("shared", "TestCertificates", "https-aspnet.crt")),
|
||||
new KeyValuePair<string, string>("Certificates:Default:KeyPath", Path.Combine("shared", "TestCertificates", "https-ecdsa.key")),
|
||||
new KeyValuePair<string, string>("Certificates:Default:Password", "aspnetcore")
|
||||
}).Build();
|
||||
|
||||
var ex = Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
serverOptions
|
||||
.Configure(config)
|
||||
.Endpoint("End1", opt =>
|
||||
{
|
||||
Assert.True(opt.IsHttps);
|
||||
}).Load();
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureEndpoint_ThrowsWhen_The_PasswordIsIncorrect()
|
||||
{
|
||||
var serverOptions = CreateServerOptions();
|
||||
var certificate = new X509Certificate2(TestResources.GetCertPath("https-aspnet.crt"));
|
||||
|
||||
var config = new ConfigurationBuilder().AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("Endpoints:End1:Url", "https://*:5001"),
|
||||
new KeyValuePair<string, string>("Certificates:Default:Path", Path.Combine("shared", "TestCertificates", "https-aspnet.crt")),
|
||||
new KeyValuePair<string, string>("Certificates:Default:KeyPath", Path.Combine("shared", "TestCertificates", "https-aspnet.key")),
|
||||
new KeyValuePair<string, string>("Certificates:Default:Password", "abcde"),
|
||||
}).Build();
|
||||
|
||||
var ex = Assert.Throws<CryptographicException>(() =>
|
||||
{
|
||||
serverOptions
|
||||
.Configure(config)
|
||||
.Endpoint("End1", opt =>
|
||||
{
|
||||
Assert.True(opt.IsHttps);
|
||||
}).Load();
|
||||
});
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https-rsa.pem", "https-rsa.key", null)]
|
||||
[InlineData("https-rsa.pem", "https-rsa-protected.key", "aspnetcore")]
|
||||
[InlineData("https-rsa.crt", "https-rsa.key", null)]
|
||||
[InlineData("https-rsa.crt", "https-rsa-protected.key", "aspnetcore")]
|
||||
[InlineData("https-ecdsa.pem", "https-ecdsa.key", null)]
|
||||
[InlineData("https-ecdsa.pem", "https-ecdsa-protected.key", "aspnetcore")]
|
||||
[InlineData("https-ecdsa.crt", "https-ecdsa.key", null)]
|
||||
[InlineData("https-ecdsa.crt", "https-ecdsa-protected.key", "aspnetcore")]
|
||||
[InlineData("https-dsa.pem", "https-dsa.key", null)]
|
||||
[InlineData("https-dsa.pem", "https-dsa-protected.key", "test")]
|
||||
[InlineData("https-dsa.crt", "https-dsa.key", null)]
|
||||
[InlineData("https-dsa.crt", "https-dsa-protected.key", "test")]
|
||||
public void ConfigureEndpoint_CanLoadPemCertificates(string certificateFile, string certificateKey, string password)
|
||||
{
|
||||
var serverOptions = CreateServerOptions();
|
||||
var certificate = new X509Certificate2(TestResources.GetCertPath(Path.ChangeExtension(certificateFile, "crt")));
|
||||
|
||||
var ran1 = false;
|
||||
var config = new ConfigurationBuilder().AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("Endpoints:End1:Url", "https://*:5001"),
|
||||
new KeyValuePair<string, string>("Certificates:Default:Path", Path.Combine("shared", "TestCertificates", certificateFile)),
|
||||
new KeyValuePair<string, string>("Certificates:Default:KeyPath", Path.Combine("shared", "TestCertificates", certificateKey)),
|
||||
}
|
||||
.Concat(password != null ? new[] { new KeyValuePair<string, string>("Certificates:Default:Password", password) } : Array.Empty<KeyValuePair<string, string>>()))
|
||||
.Build();
|
||||
|
||||
serverOptions
|
||||
.Configure(config)
|
||||
.Endpoint("End1", opt =>
|
||||
{
|
||||
ran1 = true;
|
||||
Assert.True(opt.IsHttps);
|
||||
Assert.Equal(opt.HttpsOptions.ServerCertificate.SerialNumber, certificate.SerialNumber);
|
||||
}).Load();
|
||||
|
||||
Assert.True(ran1);
|
||||
Assert.NotNull(serverOptions.DefaultCertificate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureEndpointDevelopmentCertificateGetsIgnoredIfPasswordIsNotCorrect()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
<Compile Include="$(SharedSourceRoot)NullScope.cs" />
|
||||
<Compile Include="$(KestrelSharedSourceRoot)test\*.cs" LinkBase="shared" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.crt" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.key" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pem" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelRoot)Core\src\Internal\Http\HttpHeaders.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelRoot)Core\src\Internal\Http\HttpProtocol.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelRoot)Core\src\Internal\Infrastructure\HttpUtilities.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
*.key binary
|
||||
*.pem binary
|
||||
Binary file not shown.
|
|
@ -0,0 +1,30 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
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
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBoTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQI+PhdT1Kk/SkCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECGV1ZmaiQtz2BIIBUA/6pNqTkXpkOLlI
|
||||
22Lh0cm5+/foDRh3qTrAOSHHHV0Dz1xYvYMa9MFzONatLf55Rpb2ZPji3hXwUQfn
|
||||
gOJeTBRTaMNz5LaKJiOIWj0qDckhgKt9cmgiBzVTvXO4pERp1uz5zcvaUOKj2TSv
|
||||
ljxishj76MYQftIGMMkJQKf4OsHubCopuKUbzTPgJt0FuF4eT37+tiEMgbYrmA6p
|
||||
REPE0vT1aY+LYdJLV/Dax/l4lMvYmQYOWs9TCLPlI5RZQxxte6zbcA13ESg/qLE3
|
||||
4Mx8xgXrPvCxp3h8KBKNMaJR1xzpr7UQOpkI9qja++3cJAl6O/0mdeqZct0V9Z8P
|
||||
a3+wyUWo58z5sOPNdJHIMV6qw6m3w+IQoCJC7EbV0+Pyo5eSU5zbgm7YWZ9Yx6l8
|
||||
g1mCP4Q6Tqe6LjKfBsZAmYWSfKqoTKRjC3ocJMt53tIDpB5jFw==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
Binary file not shown.
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBSwIBADCCASsGByqGSM44BAEwggEeAoGBAJyiyioeXx1O98gRCMEjlPKMpr79
|
||||
KrcDkoroghtuXO1U6Cx34pBRjOQmQLDPqSOriEo5VuG6SJc/ppfZx9TrSrzqB26h
|
||||
KTUmiaOKmwpfIfzpi72wgsZeMOtU7JQ+FThfGyS8VxGh6G0h7xw26B/9ALxRw25z
|
||||
O1cy9ZJs0EY3hsHzAhUA/4dpclsck8K+SkWBTcPfU+x7wTUCgYB4LP6UvrvIiiFP
|
||||
xhk7AEGMMr0MhcJ3hhsgKWukUqIYsJKBM5MpKCnej5BHvnLXdKodIxygcKR4dJX7
|
||||
BRv69L+2RJk+UrYL1qBco5HpUslumA0e3gNdwRLoOoGD14dn1LD1LdESsyMgwfHH
|
||||
J0RRkYwacgCVXsvHv/eAkA8qq136dwQXAhUA216Tqp4OvdUBNv8QLv8Z5QPopGQ=
|
||||
-----END PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDWTCCAxWgAwIBAgIUFRQGA90GHC74cNK/hNzQDi7XJFYwCwYJYIZIAWUDBAMC
|
||||
MF0xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhWaXJnaW5pYTETMBEGA1UEBwwKQWxl
|
||||
eGFuZHJpYTEQMA4GA1UECgwHQ29udG9zbzEUMBIGA1UECwwLRGV2ZWxvcG1lbnQw
|
||||
HhcNMjAwNjE5MTkyODIwWhcNMjAwNzE5MTkyODIwWjBdMQswCQYDVQQGEwJVUzER
|
||||
MA8GA1UECAwIVmlyZ2luaWExEzARBgNVBAcMCkFsZXhhbmRyaWExEDAOBgNVBAoM
|
||||
B0NvbnRvc28xFDASBgNVBAsMC0RldmVsb3BtZW50MIIBtjCCASsGByqGSM44BAEw
|
||||
ggEeAoGBAJyiyioeXx1O98gRCMEjlPKMpr79KrcDkoroghtuXO1U6Cx34pBRjOQm
|
||||
QLDPqSOriEo5VuG6SJc/ppfZx9TrSrzqB26hKTUmiaOKmwpfIfzpi72wgsZeMOtU
|
||||
7JQ+FThfGyS8VxGh6G0h7xw26B/9ALxRw25zO1cy9ZJs0EY3hsHzAhUA/4dpclsc
|
||||
k8K+SkWBTcPfU+x7wTUCgYB4LP6UvrvIiiFPxhk7AEGMMr0MhcJ3hhsgKWukUqIY
|
||||
sJKBM5MpKCnej5BHvnLXdKodIxygcKR4dJX7BRv69L+2RJk+UrYL1qBco5HpUslu
|
||||
mA0e3gNdwRLoOoGD14dn1LD1LdESsyMgwfHHJ0RRkYwacgCVXsvHv/eAkA8qq136
|
||||
dwOBhAACgYAHltgzkK3zD8yGdcGY0YgvN5l3lna1voLmcK+XtmehjMVy7OSSFICN
|
||||
KybLBOvO8paydhCb1J0klkLPAoAjgP2cEd+KueeRyJpx+jD1MsjIEXIn5jtjXdUH
|
||||
d0JJmHWAyHdNzmhXrXC7JLnj4ri7xMAV3GZGDpAnYvvL0LiXzFyomqNTMFEwHQYD
|
||||
VR0OBBYEFF1l4ZrF3ND05CjGd//ev0dJLCB7MB8GA1UdIwQYMBaAFF1l4ZrF3ND0
|
||||
5CjGd//ev0dJLCB7MA8GA1UdEwEB/wQFMAMBAf8wCwYJYIZIAWUDBAMCAzEAMC4C
|
||||
FQD6plYf60MDCvMjf1yQ8SBaFX3YYwIVAKqRQklh2b0Qhv+US222hb8xySJV
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjGHXmGVX2JFwICCAAw
|
||||
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEN5v5Ytosv3NT48Qg8C/Zh0EgZDK
|
||||
aWxzYPTIuIA4Tb1kCTd7BVGTsdeBxb5clCbEehF3yIZskalbRfjDso4n2HtVY9eq
|
||||
+UZilRDSAt/XUhJqqViwbGg3pc+IHTdM2kTosG9vZK7WILRPvPphBFyn1NGwYPak
|
||||
zHeW1T2Y0PXdjxloqccS6xv4ySwHwv8Hp1pPbpUfRakH3KTrGzOlKouktkcrhfw=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
Binary file not shown.
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PARAMETERS-----
|
||||
BggqhkjOPQMBBw==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHteKGH6xLqUHhvsgtz9jIBuj+YCwAPHRg2C47rzX0L6oAoGCCqGSM49
|
||||
AwEHoUQDQgAES8Hf3hm1ygXcZ+4NLuNgrlY9mmyiQTA4bq+aW4s56IrorHy1Se0j
|
||||
WtOOngaYvYA7qvVV778h8DTKJcefzpxt1A==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICBjCCAa2gAwIBAgIUUHh7FUSJoSgSmhI5lnio2/R++gUwCgYIKoZIzj0EAwIw
|
||||
WTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIw
|
||||
MDcwMjEyMTIzOFoXDTIxMDcwMjEyMTIzOFowWTELMAkGA1UEBhMCQVUxEzARBgNV
|
||||
BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
|
||||
ZDESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
|
||||
S8Hf3hm1ygXcZ+4NLuNgrlY9mmyiQTA4bq+aW4s56IrorHy1Se0jWtOOngaYvYA7
|
||||
qvVV778h8DTKJcefzpxt1KNTMFEwHQYDVR0OBBYEFO6n94lr7Fjk6Es+XC//WkHU
|
||||
SA09MB8GA1UdIwQYMBaAFO6n94lr7Fjk6Es+XC//WkHUSA09MA8GA1UdEwEB/wQF
|
||||
MAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgEjgE6bKKqDqfgDMmEgeRtWMnb3fIkRTH
|
||||
dxdHLobgzKMCICyJ13K6RBh3LCQ9CtysvLFROQBON/DD2xgXRN7xr9lG
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
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
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
Binary file not shown.
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwK6M1tIuVqrKn
|
||||
JDT/uBvEz+dMR5dExiWh9Df0aHVL6ZIQs2upwiqoViJSduE3rvSdjZMpvOzE1YUO
|
||||
Mh8dAsHrcTkXzeF77yF4GnR8XA6FNvIWYhiCxSM1f/cOdLDv0wmaANHoNYHYtr9W
|
||||
nofuH4QQzI+njLWIE3ZEl95+YXM80nnP+L4ggD46nu2Dd5LRBcpFP6FkCthF+iN+
|
||||
IUMdVHylsxhRPY3Dj+xEccPmAUZvCchWXWgGwsW0UygFECqLhWupt0Ysd8rKGRTx
|
||||
HaI7z/5S1c8VlUgk4Q7FRxq7HiiNdbkrViJkES3ghJ2LbKYMwkGXmfbnam1qRagO
|
||||
BWnYnnZpAgMBAAECggEBAKlBs7Pke3tXHf/RnI3XX+6OZMX3vlDYIs3f6maKea9u
|
||||
f+RFzXmyz/MdliouhyFNmT1KCQq/tadDEWvbIeNog9Fl3ZmON0YwMLLIkAPvGhBJ
|
||||
AvwYUT5KkxJSmJWt7VTtKDtq8EEuL0t8AIcDFsvkQak2MAqk+L/9GtK6Koy3qdTT
|
||||
Nx0to6jcSvAz6cBC/WY4u2fmGJb6RoQR0K7KWdovkhb60/5PF+tI5afDF4zO6UzD
|
||||
c7qxb9/rPqhsqomC1isS+MdRWl6edW28RYzhZNxtux0KKy+HYfbrlya41HIYOdCN
|
||||
h9IEc46tOuEZ4aARHq0eNkLr8oBARcjHUlfPnBpmDGUCgYEA1DYAd45N13DTAITd
|
||||
MIwiKLHDH5XLmKdCGPk/LNd0asyw7Yw0ffJ2LUtCKt1HyvVKaRsCjzmC7pN1d/JG
|
||||
Sni+zDgdip9f9vERVF/F/sA9h+zH+Qwx5DUDhu6a4naey3t3t2hyRSbH+e+M7+1b
|
||||
4/i0nlsD35/lmwwfM7zgSZSmCIcCgYEA1IXOATUURWPilI9HoHt7yhGEvgXvquXC
|
||||
KF4K+1XNnC7AXO2jwz62xg6rnkFBxiPtvnN+fCVajMusyxCwarc/QyuctcQEm8jK
|
||||
+vOI1dJM4Qgy+MNzcat7MjJCBpi6oFXAKDu3CGzfUw0SKNepc9cST8x9FsMgcC8K
|
||||
OKbLWLK2dY8CgYAIgMlwAPG5ijnKMYizY0oTG1xYLaZkzX7mhUY0w8VUajNEsXOB
|
||||
AHAfzH4wPYGc7ks2/vARURqf+KSiU8DhRwlOIYl9fnlX6bzqBpRmasmMYr54ijaN
|
||||
kFo909286Uffm2jmnnbFspIcv66EBpzB+7sxBTCYi02l8sxlRFIwYJZujQKBgAO5
|
||||
2NPCl3lj9+v82xegMppnVjlypzIK1y2YAH9JkNJFK5A1hmJ87f1o8m9S25FavedR
|
||||
5QzOJtlDFON2hnFIhy5pTFUPe7kzewONU3/UMQ7c8u/TlWmPxRgrM2ckNFltR3It
|
||||
Idde+UdeekwHA+yI/8QwZJ0KjL4KxRYbLoN+lp5XAoGAbVNfX57Hjc/TxrC7nTyQ
|
||||
0Mqi8S1t7Yo/Je/5Ow/8W3zVrzMYTipwJyBrAMhhhOTuvWc6lnJFW6XkyftQPwI6
|
||||
RDD3i9DELPhIPhh4kz7ID5OPtRnf3hrvXDOyucSV66RpxSSb5l7i92a8wTFWeGlN
|
||||
nLbTYpaPuX1fCIbRnigXI3A=
|
||||
-----END PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDDCCAfSgAwIBAgIIS+Mx2/wTMMQwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UE
|
||||
AxMJbG9jYWxob3N0MB4XDTIwMDcwMTE5MjcwOVoXDTIxMDcwMTE5MjcwOVowFDES
|
||||
MBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAsCujNbSLlaqypyQ0/7gbxM/nTEeXRMYlofQ39Gh1S+mSELNrqcIqqFYiUnbh
|
||||
N670nY2TKbzsxNWFDjIfHQLB63E5F83he+8heBp0fFwOhTbyFmIYgsUjNX/3DnSw
|
||||
79MJmgDR6DWB2La/Vp6H7h+EEMyPp4y1iBN2RJfefmFzPNJ5z/i+IIA+Op7tg3eS
|
||||
0QXKRT+hZArYRfojfiFDHVR8pbMYUT2Nw4/sRHHD5gFGbwnIVl1oBsLFtFMoBRAq
|
||||
i4VrqbdGLHfKyhkU8R2iO8/+UtXPFZVIJOEOxUcaux4ojXW5K1YiZBEt4ISdi2ym
|
||||
DMJBl5n252ptakWoDgVp2J52aQIDAQABo2IwYDAMBgNVHRMBAf8EAjAAMA4GA1Ud
|
||||
DwEB/wQEAwIFoDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAXBgNVHREBAf8EDTAL
|
||||
gglsb2NhbGhvc3QwDwYKKwYBBAGCN1QBAQQBATANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||
ZD9JA++dIuBke7GYYlJuKTMHJB0Sm1Ug2idNi1JiocXYsCVzY05sd4Qh+34PcED7
|
||||
B6592o1h47bgOh1ISolrOkt/23VjJweWGsa9rqt1zMdmmCulmPPFOiWWzMSm1OkN
|
||||
Q/Q5pzWXojxp/ArWLZbrghA44t+A4WJpWyEpEKKu5pD+ufG6dX6oPgz7yRXpkyJw
|
||||
rln219tjGACm2pXLgTO/WQdesaaquv6v2MEb5jJcxFeK5cQN/anYFqhjJvth1Wr0
|
||||
FQwbO4drt1lD+a30r6VjL/sEIlKK2Mi68rHQzeHug+663GLTtw2bZyvAoMwZoxo4
|
||||
Vwy3e5F7dw23onqQB92IoQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -21,7 +21,11 @@ using Microsoft.AspNetCore.Server.Kestrel.Https;
|
|||
using Microsoft.AspNetCore.Server.Kestrel.Https.Internal;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
||||
|
|
@ -51,6 +55,41 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanReadAndWriteWithHttpsConnectionMiddlewareWithPemCertificate()
|
||||
{
|
||||
var configuration = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string>
|
||||
{
|
||||
["Certificates:Default:Path"] = Path.Combine("shared", "TestCertificates", "https-aspnet.crt"),
|
||||
["Certificates:Default:KeyPath"] = Path.Combine("shared", "TestCertificates", "https-aspnet.key"),
|
||||
["Certificates:Default:Password"] = "aspnetcore",
|
||||
}).Build();
|
||||
|
||||
var options = new KestrelServerOptions();
|
||||
var env = new Mock<IHostEnvironment>();
|
||||
env.SetupGet(e => e.ContentRootPath).Returns(Directory.GetCurrentDirectory());
|
||||
|
||||
options.ApplicationServices = new ServiceCollection().AddSingleton(env.Object).AddLogging().BuildServiceProvider();
|
||||
var loader = new KestrelConfigurationLoader(options, configuration, reloadOnChange: false);
|
||||
loader.Load();
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
listenOptions.KestrelServerOptions = options;
|
||||
listenOptions.UseHttps();
|
||||
};
|
||||
|
||||
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
|
||||
{
|
||||
var result = await server.HttpClientSlim.PostAsync($"https://localhost:{server.Port}/",
|
||||
new FormUrlEncodedContent(new[] {
|
||||
new KeyValuePair<string, string>("content", "Hello World?")
|
||||
}),
|
||||
validateCertificate: false);
|
||||
|
||||
Assert.Equal("content=Hello+World%3F", result);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandshakeDetailsAreAvailable()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
<Compile Include="$(SharedSourceRoot)NullScope.cs" />
|
||||
<Compile Include="$(KestrelSharedSourceRoot)test\*.cs" LinkBase="shared" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.crt" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.key" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pem" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" />
|
||||
<Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" />
|
||||
<Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue