Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit dbe32b5

Browse files
authored
fix: update UseServerCertificateSelector to call the original selector (#290)
1 parent ba32cda commit dbe32b5

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
</PropertyGroup>
3535

3636
<PropertyGroup>
37-
<VersionPrefix>1.3.0</VersionPrefix>
37+
<VersionPrefix>1.3.1</VersionPrefix>
3838
<VersionSuffix>beta</VersionSuffix>
3939
<IncludePreReleaseLabelInPackageVersion Condition="'$(IS_STABLE_BUILD)' != 'true'">true</IncludePreReleaseLabelInPackageVersion>
4040
<BuildNumber Condition=" '$(BuildNumber)' == '' ">$([MSBuild]::ValueOrDefault($(BUILD_NUMBER), 0))</BuildNumber>

src/Kestrel.Certificates/KestrelHttpsOptionsExtensions.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@ public static HttpsConnectionAdapterOptions UseServerCertificateSelector(
2222
this HttpsConnectionAdapterOptions httpsOptions,
2323
IServerCertificateSelector certificateSelector)
2424
{
25-
httpsOptions.ServerCertificateSelector = certificateSelector.Select!;
25+
var fallbackSelector = httpsOptions.ServerCertificateSelector;
26+
httpsOptions.ServerCertificateSelector = (connectionContext, domainName) =>
27+
{
28+
var primaryCert = certificateSelector.Select(connectionContext!, domainName);
29+
// fallback to the original selector if the injected selector fails to find a certificate.
30+
return primaryCert ?? fallbackSelector?.Invoke(connectionContext, domainName);
31+
};
32+
2633
return httpsOptions;
2734
}
2835
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Nate McMaster.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Security.Cryptography.X509Certificates;
5+
using McMaster.AspNetCore.Kestrel.Certificates;
6+
using Microsoft.AspNetCore.Connections;
7+
using Microsoft.AspNetCore.Hosting;
8+
using Microsoft.AspNetCore.Server.Kestrel.Https;
9+
using Moq;
10+
using Xunit;
11+
12+
namespace LettuceEncrypt.UnitTests;
13+
14+
using SelectorFunc = Func<ConnectionContext, string, X509Certificate2>;
15+
16+
public class KestrelHttpsOptionsExtensionsTests
17+
{
18+
[Fact]
19+
public void UseServerCertificateSelectorFallsbackToOriginalSelector()
20+
{
21+
var injectedSelector = new Mock<IServerCertificateSelector>();
22+
injectedSelector
23+
.Setup(c => c.Select(It.IsAny<ConnectionContext>(), It.IsAny<string>()))
24+
.Returns(() => null);
25+
26+
var originalSelectorWasCalled = false;
27+
SelectorFunc originalSelector = (_, __) => { originalSelectorWasCalled = true; return null; };
28+
29+
var options = new HttpsConnectionAdapterOptions
30+
{
31+
ServerCertificateSelector = originalSelector
32+
};
33+
34+
KestrelHttpsOptionsExtensions.UseServerCertificateSelector(options, injectedSelector.Object);
35+
options.ServerCertificateSelector(null, null);
36+
37+
Assert.NotSame(options.ServerCertificateSelector, originalSelector);
38+
Assert.True(originalSelectorWasCalled);
39+
injectedSelector.VerifyAll();
40+
}
41+
42+
[Fact]
43+
public void UseServerCertificateSelectorDoesNotCallFallback()
44+
{
45+
var injectedSelector = new Mock<IServerCertificateSelector>();
46+
injectedSelector
47+
.Setup(c => c.Select(It.IsAny<ConnectionContext>(), It.IsAny<string>()))
48+
.Returns(() => TestUtils.CreateTestCert("foo.test"));
49+
50+
var originalSelectorWasCalled = false;
51+
SelectorFunc originalSelector = (_, __) => { originalSelectorWasCalled = true; return null; };
52+
53+
var options = new HttpsConnectionAdapterOptions
54+
{
55+
ServerCertificateSelector = originalSelector
56+
};
57+
58+
KestrelHttpsOptionsExtensions.UseServerCertificateSelector(options, injectedSelector.Object);
59+
options.ServerCertificateSelector(null, null);
60+
61+
Assert.NotSame(options.ServerCertificateSelector, originalSelector);
62+
Assert.False(originalSelectorWasCalled);
63+
injectedSelector.VerifyAll();
64+
}
65+
}

0 commit comments

Comments
 (0)