Update "temporary" OpenSSL wrapper to support 1.1, and add HTTP/2 sample with docker (#2149)
This commit is contained in:
parent
73a37363e1
commit
065e9bb57a
|
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.16
|
||||
VisualStudioVersion = 15.0.27101.0
|
||||
MinimumVisualStudioVersion = 15.0.26730.03
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7972A5D6-3385-4127-9277-428506DD44FF}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
|
@ -121,6 +121,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kestrel.Transport.Libuv.Fun
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kestrel.Transport.Sockets.FunctionalTests", "test\Kestrel.Transport.Sockets.FunctionalTests\Kestrel.Transport.Sockets.FunctionalTests.csproj", "{9C7B6B5F-088A-436E-834B-6373EA36DEEE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Http2SampleApp", "samples\Http2SampleApp\Http2SampleApp.csproj", "{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -335,6 +337,18 @@ Global
|
|||
{9C7B6B5F-088A-436E-834B-6373EA36DEEE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9C7B6B5F-088A-436E-834B-6373EA36DEEE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9C7B6B5F-088A-436E-834B-6373EA36DEEE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -359,6 +373,7 @@ Global
|
|||
{B7B0EA74-528F-46B8-9BC4-909D9A67C194} = {D3273454-EA07-41D2-BF0B-FCC3675C2483}
|
||||
{74032D79-8EA7-4483-BD82-C38370420FFF} = {D3273454-EA07-41D2-BF0B-FCC3675C2483}
|
||||
{9C7B6B5F-088A-436E-834B-6373EA36DEEE} = {D3273454-EA07-41D2-BF0B-FCC3675C2483}
|
||||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA} = {8A3D00B8-1CCF-4BE6-A060-11104CE2D9CE}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2D10D020-6770-47CA-BB8D-2C23FE3AE071}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
FROM microsoft/aspnetcore:2.0.0-stretch
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libssl-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG CONFIGURATION=Debug
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./bin/${CONFIGURATION}/netcoreapp2.0/publish/ /app
|
||||
|
||||
ENTRYPOINT [ "/usr/bin/dotnet", "/app/Http2SampleApp.dll" ]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Kestrel\Kestrel.csproj" />
|
||||
<ProjectReference Include="..\..\src\Kestrel.Tls\Kestrel.Tls.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="../../test/shared/TestCertificates/testCert.pfx" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Http2SampleApp
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
if (!ushort.TryParse(configuration["BASE_PORT"], NumberStyles.None, CultureInfo.InvariantCulture, out var basePort))
|
||||
{
|
||||
basePort = 5000;
|
||||
}
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.ConfigureLogging((_, factory) =>
|
||||
{
|
||||
// Set logging to the MAX.
|
||||
factory.SetMinimumLevel(LogLevel.Trace);
|
||||
factory.AddConsole();
|
||||
})
|
||||
.UseKestrel(options =>
|
||||
{
|
||||
// Run callbacks on the transport thread
|
||||
options.ApplicationSchedulingMode = SchedulingMode.Inline;
|
||||
|
||||
options.Listen(IPAddress.Any, basePort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
|
||||
listenOptions.UseTls("testCert.pfx", "testPassword");
|
||||
listenOptions.UseConnectionLogging();
|
||||
});
|
||||
})
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseStartup<Startup>();
|
||||
|
||||
hostBuilder.Build().Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Http2SampleApp
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
await context.Response.WriteAsync("Hello World!");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
dotnet publish --framework netcoreapp2.0 "$PSScriptRoot/../Http2SampleApp.csproj"
|
||||
|
||||
docker build -t kestrel-http2-sample (Convert-Path "$PSScriptRoot/..")
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
dotnet publish --framework netcoreapp2.0 "$DIR/../Http2SampleApp.csproj"
|
||||
|
||||
docker build -t kestrel-http2-sample "$DIR/.."
|
||||
|
|
@ -0,0 +1 @@
|
|||
docker run -p 5000:5000 -it --rm kestrel-http2-sample
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
docker run -it -p 5000:5000 --rm kestrel-http2-sample
|
||||
|
|
@ -6,10 +6,6 @@
|
|||
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="testCert.pfx" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Kestrel\Kestrel.csproj" />
|
||||
<ProjectReference Include="..\..\src\Kestrel.Https\Kestrel.Https.csproj" />
|
||||
|
|
@ -19,4 +15,8 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="../../test/shared/TestCertificates/testCert.pfx" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||
{
|
||||
|
|
@ -40,5 +41,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
Payload.Slice(Length - padLength.Value).Fill(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void DataTraceFrame(ILogger logger)
|
||||
{
|
||||
logger.LogTrace("'DATA' Frame. Flags = {DataFlags}, PadLength = {PadLength}, PayloadLength = {PayloadLength}", DataFlags, DataPadLength, DataPayload.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
{
|
||||
public static class ListenOptionsTlsExtensions
|
||||
{
|
||||
public static ListenOptions UseTls(this ListenOptions listenOptions, string certificatePath, string privateKeyPath)
|
||||
public static ListenOptions UseTls(this ListenOptions listenOptions, string certificatePath, string password)
|
||||
{
|
||||
return listenOptions.UseTls(new TlsConnectionAdapterOptions
|
||||
{
|
||||
CertificatePath = certificatePath,
|
||||
PrivateKeyPath = privateKeyPath,
|
||||
Password = password,
|
||||
Protocols = listenOptions.Protocols
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,23 +15,46 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
public const int OPENSSL_NPN_NEGOTIATED = 1;
|
||||
public const int SSL_TLSEXT_ERR_OK = 0;
|
||||
public const int SSL_TLSEXT_ERR_NOACK = 3;
|
||||
public const int SSL_CTRL_CHAIN = 88;
|
||||
|
||||
private const int BIO_C_SET_BUF_MEM_EOF_RETURN = 130;
|
||||
private const int SSL_CTRL_SET_ECDH_AUTO = 94;
|
||||
|
||||
public static int SSL_library_init()
|
||||
public static void SSL_library_init()
|
||||
{
|
||||
return NativeMethods.SSL_library_init();
|
||||
try
|
||||
{
|
||||
// Try OpenSSL 1.0.2
|
||||
NativeMethods.SSL_library_init();
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// It's fine, OpenSSL 1.1 doesn't need initialization
|
||||
}
|
||||
}
|
||||
|
||||
public static void SSL_load_error_strings()
|
||||
{
|
||||
NativeMethods.SSL_load_error_strings();
|
||||
try
|
||||
{
|
||||
NativeMethods.SSL_load_error_strings();
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// Also fine, OpenSSL 1.1 doesn't need it.
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenSSL_add_all_algorithms()
|
||||
{
|
||||
NativeMethods.OPENSSL_add_all_algorithms_noconf();
|
||||
try
|
||||
{
|
||||
NativeMethods.OPENSSL_add_all_algorithms_noconf();
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// Also fine, OpenSSL 1.1 doesn't need it.
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr TLSv1_2_method()
|
||||
|
|
@ -49,6 +72,41 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
NativeMethods.SSL_CTX_free(ctx);
|
||||
}
|
||||
|
||||
public unsafe static int SSL_CTX_Set_Pfx(IntPtr ctx, string path, string password)
|
||||
{
|
||||
var pass = Marshal.StringToHGlobalAnsi(password);
|
||||
var key = IntPtr.Zero;
|
||||
var cert = IntPtr.Zero;
|
||||
var ca = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
var file = System.IO.File.ReadAllBytes(path);
|
||||
|
||||
fixed (void* f = file)
|
||||
{
|
||||
var buffer = (IntPtr)f;
|
||||
var pkcs = NativeMethods.d2i_PKCS12(IntPtr.Zero, ref buffer, file.Length);
|
||||
var result = NativeMethods.PKCS12_parse(pkcs, pass, ref key, ref cert, ref ca);
|
||||
if (result != 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (NativeMethods.SSL_CTX_use_certificate(ctx, cert) != 1) return -1;
|
||||
if (NativeMethods.SSL_CTX_use_PrivateKey(ctx, key) != 1) return -1;
|
||||
if (NativeMethods.SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN, 1, ca) != 1) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(pass);
|
||||
if (key != IntPtr.Zero) NativeMethods.EVP_PKEY_free(key);
|
||||
if (cert != IntPtr.Zero) NativeMethods.X509_free(cert);
|
||||
if (ca != IntPtr.Zero) NativeMethods.sk_X509_pop_free(ca);
|
||||
}
|
||||
}
|
||||
|
||||
public static int SSL_CTX_set_ecdh_auto(IntPtr ctx, int onoff)
|
||||
{
|
||||
return (int)NativeMethods.SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, onoff, IntPtr.Zero);
|
||||
|
|
@ -109,6 +167,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
return NativeMethods.SSL_get_error(ssl, ret);
|
||||
}
|
||||
|
||||
public static int ERR_get_error()
|
||||
{
|
||||
return NativeMethods.ERR_get_error();
|
||||
}
|
||||
|
||||
public static string ERR_error_string(int error)
|
||||
{
|
||||
var buf = NativeMethods.ERR_error_string(error, IntPtr.Zero);
|
||||
|
||||
// Don't free the buffer! It's a static buffer
|
||||
return Marshal.PtrToStringAnsi(buf);
|
||||
}
|
||||
|
||||
public static void SSL_set_accept_state(IntPtr ssl)
|
||||
{
|
||||
NativeMethods.SSL_set_accept_state(ssl);
|
||||
|
|
@ -263,6 +334,42 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ERR_load_BIO_strings();
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int ERR_get_error();
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ERR_error_string(int error, IntPtr buf);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr d2i_PKCS12(IntPtr unsused, ref IntPtr bufferPointer, long length);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int PKCS12_parse(IntPtr p12, IntPtr pass, ref IntPtr pkey, ref IntPtr cert, ref IntPtr ca);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void PKCS12_free(IntPtr p12);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void EVP_PKEY_free(IntPtr pkey);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void X509_free(IntPtr a);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void sk_X509_pop_free(IntPtr ca);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SSL_CTX_ctrl(IntPtr ctx, int cmd, int larg, IntPtr parg);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SSL_CTX_set1_chain(IntPtr ctx, IntPtr sk);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SSL_CTX_use_certificate(IntPtr ctx, IntPtr x509);
|
||||
|
||||
[DllImport("libssl", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SSL_CTX_use_PrivateKey(IntPtr ctx, IntPtr pkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
throw new ArgumentException("Certificate path must be non-null.", nameof(options));
|
||||
}
|
||||
|
||||
if (options.PrivateKeyPath == null)
|
||||
if (options.Password == null)
|
||||
{
|
||||
throw new ArgumentException("Private key path must be non-null.", nameof(options));
|
||||
throw new ArgumentException("Password must be non-null.", nameof(options));
|
||||
}
|
||||
|
||||
_options = options;
|
||||
|
|
@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
|
||||
private async Task<IAdaptedConnection> InnerOnConnectionAsync(ConnectionAdapterContext context)
|
||||
{
|
||||
var tlsStream = new TlsStream(context.ConnectionStream, _options.CertificatePath, _options.PrivateKeyPath, _serverProtocols);
|
||||
var tlsStream = new TlsStream(context.ConnectionStream, _options.CertificatePath, _options.Password, _serverProtocols);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
{
|
||||
public string CertificatePath { get; set; } = string.Empty;
|
||||
|
||||
public string PrivateKeyPath { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
public HttpProtocols Protocols { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,15 @@ using System.Runtime.InteropServices;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
||||
{
|
||||
public class TlsStream : Stream
|
||||
{
|
||||
// Error code that indicates that a handshake failed because unencrypted HTTP was sent
|
||||
private const int SSL_ERROR_HTTP_REQUEST = 336130204;
|
||||
|
||||
private static unsafe OpenSsl.alpn_select_cb_t _alpnSelectCallback = AlpnSelectCallback;
|
||||
|
||||
private readonly Stream _innerStream;
|
||||
|
|
@ -36,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
OpenSsl.OpenSSL_add_all_algorithms();
|
||||
}
|
||||
|
||||
public TlsStream(Stream innerStream, string certificatePath, string privateKeyPath, IEnumerable<string> protocols)
|
||||
public TlsStream(Stream innerStream, string certificatePath, string password, IEnumerable<string> protocols)
|
||||
{
|
||||
_innerStream = innerStream;
|
||||
_protocols = ToWireFormat(protocols);
|
||||
|
|
@ -49,18 +53,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
throw new Exception("Unable to create SSL context.");
|
||||
}
|
||||
|
||||
if(OpenSsl.SSL_CTX_Set_Pfx(_ctx, certificatePath, password) != 1)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to load PFX");
|
||||
}
|
||||
|
||||
OpenSsl.SSL_CTX_set_ecdh_auto(_ctx, 1);
|
||||
|
||||
if (OpenSsl.SSL_CTX_use_certificate_file(_ctx, certificatePath, 1) != 1)
|
||||
{
|
||||
throw new Exception("Unable to load certificate file.");
|
||||
}
|
||||
|
||||
if (OpenSsl.SSL_CTX_use_PrivateKey_file(_ctx, privateKeyPath, 1) != 1)
|
||||
{
|
||||
throw new Exception("Unable to load private key file.");
|
||||
}
|
||||
|
||||
|
||||
OpenSsl.SSL_CTX_set_alpn_select_cb(_ctx, _alpnSelectCallback, GCHandle.ToIntPtr(_protocolsHandle));
|
||||
|
||||
_ssl = OpenSsl.SSL_new(_ctx);
|
||||
|
|
@ -181,9 +180,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tls
|
|||
{
|
||||
var error = OpenSsl.SSL_get_error(_ssl, ret);
|
||||
|
||||
if (error != 2)
|
||||
if (error == 1)
|
||||
{
|
||||
throw new IOException($"TLS handshake failed: {nameof(OpenSsl.SSL_do_handshake)} error {error}.");
|
||||
// SSL error, get it from the OpenSSL error queue
|
||||
error = OpenSsl.ERR_get_error();
|
||||
if (error == SSL_ERROR_HTTP_REQUEST)
|
||||
{
|
||||
throw new InvalidOperationException("Unencrypted HTTP traffic was sent to an HTTPS endpoint");
|
||||
}
|
||||
var errorString = OpenSsl.ERR_error_string(error);
|
||||
throw new IOException($"TLS handshake failed: {nameof(OpenSsl.SSL_do_handshake)} error {error}. {errorString}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue