aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs')
-rw-r--r--src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs143
1 files changed, 131 insertions, 12 deletions
diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
index 152d8feab9..b3c47c2d8d 100644
--- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
@@ -37,20 +37,24 @@ namespace Grpc.IntegrationTesting
public class SslCredentialsTest
{
const string Host = "localhost";
+ const string IsPeerAuthenticatedMetadataKey = "test_only_is_peer_authenticated";
Server server;
Channel channel;
TestService.TestServiceClient client;
- [OneTimeSetUp]
- public void Init()
+ string rootCert;
+ KeyCertificatePair keyCertPair;
+
+ public void InitClientAndServer(bool clientAddKeyCertPair,
+ SslClientCertificateRequestType clientCertRequestType)
{
- var rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath);
- var keyCertPair = new KeyCertificatePair(
+ rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath);
+ keyCertPair = new KeyCertificatePair(
File.ReadAllText(TestCredentials.ServerCertChainPath),
File.ReadAllText(TestCredentials.ServerPrivateKeyPath));
- var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, true);
- var clientCredentials = new SslCredentials(rootCert, keyCertPair);
+ var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, clientCertRequestType);
+ var clientCredentials = clientAddKeyCertPair ? new SslCredentials(rootCert, keyCertPair) : new SslCredentials(rootCert);
// Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
@@ -72,19 +76,133 @@ namespace Grpc.IntegrationTesting
[OneTimeTearDown]
public void Cleanup()
{
- channel.ShutdownAsync().Wait();
- server.ShutdownAsync().Wait();
+ if (channel != null)
+ {
+ channel.ShutdownAsync().Wait();
+ }
+ if (server != null)
+ {
+ server.ShutdownAsync().Wait();
+ }
}
[Test]
- public void AuthenticatedClientAndServer()
+ public async Task NoClientCert_DontRequestClientCertificate_Accepted()
{
- var response = client.UnaryCall(new SimpleRequest { ResponseSize = 10 });
- Assert.AreEqual(10, response.Payload.Body.Length);
+ InitClientAndServer(
+ clientAddKeyCertPair: false,
+ clientCertRequestType: SslClientCertificateRequestType.DontRequest);
+
+ await CheckAccepted(expectPeerAuthenticated: false);
}
[Test]
- public async Task AuthContextIsPopulated()
+ public async Task ClientWithCert_DontRequestClientCertificate_AcceptedButPeerNotAuthenticated()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: true,
+ clientCertRequestType: SslClientCertificateRequestType.DontRequest);
+
+ await CheckAccepted(expectPeerAuthenticated: false);
+ }
+
+ [Test]
+ public async Task NoClientCert_RequestClientCertificateButDontVerify_Accepted()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: false,
+ clientCertRequestType: SslClientCertificateRequestType.RequestButDontVerify);
+
+ await CheckAccepted(expectPeerAuthenticated: false);
+ }
+
+ [Test]
+ public async Task NoClientCert_RequestClientCertificateAndVerify_Accepted()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: false,
+ clientCertRequestType: SslClientCertificateRequestType.RequestAndVerify);
+
+ await CheckAccepted(expectPeerAuthenticated: false);
+ }
+
+ [Test]
+ public async Task ClientWithCert_RequestAndRequireClientCertificateButDontVerify_Accepted()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: true,
+ clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireButDontVerify);
+
+ await CheckAccepted(expectPeerAuthenticated: true);
+ await CheckAuthContextIsPopulated();
+ }
+
+ [Test]
+ public async Task ClientWithCert_RequestAndRequireClientCertificateAndVerify_Accepted()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: true,
+ clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireAndVerify);
+
+ await CheckAccepted(expectPeerAuthenticated: true);
+ await CheckAuthContextIsPopulated();
+ }
+
+ [Test]
+ public void NoClientCert_RequestAndRequireClientCertificateButDontVerify_Rejected()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: false,
+ clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireButDontVerify);
+
+ CheckRejected();
+ }
+
+ [Test]
+ public void NoClientCert_RequestAndRequireClientCertificateAndVerify_Rejected()
+ {
+ InitClientAndServer(
+ clientAddKeyCertPair: false,
+ clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireAndVerify);
+
+ CheckRejected();
+ }
+
+ [Test]
+ public void Constructor_LegacyForceClientAuth()
+ {
+ var creds = new SslServerCredentials(new[] { keyCertPair }, rootCert, true);
+ Assert.AreEqual(SslClientCertificateRequestType.RequestAndRequireAndVerify, creds.ClientCertificateRequest);
+
+ var creds2 = new SslServerCredentials(new[] { keyCertPair }, rootCert, false);
+ Assert.AreEqual(SslClientCertificateRequestType.DontRequest, creds2.ClientCertificateRequest);
+ }
+
+ [Test]
+ public void Constructor_NullRootCerts()
+ {
+ var keyCertPairs = new[] { keyCertPair };
+ Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.DontRequest));
+ Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndVerify));
+ Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireButDontVerify));
+ Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireAndVerify));
+ }
+
+ private async Task CheckAccepted(bool expectPeerAuthenticated)
+ {
+ var call = client.UnaryCallAsync(new SimpleRequest { ResponseSize = 10 });
+ var response = await call;
+ Assert.AreEqual(10, response.Payload.Body.Length);
+ Assert.AreEqual(expectPeerAuthenticated.ToString(), call.GetTrailers().First((entry) => entry.Key == IsPeerAuthenticatedMetadataKey).Value);
+ }
+
+ private void CheckRejected()
+ {
+ var ex = Assert.Throws<RpcException>(() => client.UnaryCall(new SimpleRequest { ResponseSize = 10 }));
+ Assert.AreEqual(StatusCode.Unavailable, ex.Status.StatusCode);
+ }
+
+ private async Task CheckAuthContextIsPopulated()
{
var call = client.StreamingInputCall();
await call.RequestStream.CompleteAsync();
@@ -96,6 +214,7 @@ namespace Grpc.IntegrationTesting
{
public override Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
{
+ context.ResponseTrailers.Add(IsPeerAuthenticatedMetadataKey, context.AuthContext.IsPeerAuthenticated.ToString());
return Task.FromResult(new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) });
}