From d27dfa78409aecb80ffc3e1ddf69d73576b429fa Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Aug 2015 18:10:54 -0700 Subject: [PATCH] enable forcing client auth --- .../Internal/ServerCredentialsSafeHandle.cs | 7 ++--- src/csharp/Grpc.Core/ServerCredentials.cs | 27 ++++++++++++++++--- .../SslCredentialsTest.cs | 2 +- src/csharp/ext/grpc_csharp_ext.c | 7 ++--- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs index 59238a452cf..37a4f5256bf 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs @@ -42,7 +42,7 @@ namespace Grpc.Core.Internal internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid { [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs); + static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth); [DllImport("grpc_csharp_ext.dll")] static extern void grpcsharp_server_credentials_release(IntPtr credentials); @@ -51,12 +51,13 @@ namespace Grpc.Core.Internal { } - public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray) + public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth) { Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length); return grpcsharp_ssl_server_credentials_create(pemRootCerts, keyCertPairCertChainArray, keyCertPairPrivateKeyArray, - new UIntPtr((ulong)keyCertPairCertChainArray.Length)); + new UIntPtr((ulong)keyCertPairCertChainArray.Length), + forceClientAuth); } protected override bool ReleaseHandle() diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs index 32ed4b78a1f..b0bdee3bfc8 100644 --- a/src/csharp/Grpc.Core/ServerCredentials.cs +++ b/src/csharp/Grpc.Core/ServerCredentials.cs @@ -80,18 +80,26 @@ namespace Grpc.Core { readonly IList keyCertificatePairs; readonly string rootCertificates; + readonly bool forceClientAuth; /// /// Creates server-side SSL credentials. /// - /// PEM encoded client root certificates used to authenticate client. /// Key-certificates to use. - public SslServerCredentials(IEnumerable keyCertificatePairs, string rootCertificates) + /// PEM encoded client root certificates used to authenticate client. + /// If true, client will be rejected unless it proves its unthenticity using against rootCertificates. + public SslServerCredentials(IEnumerable keyCertificatePairs, string rootCertificates, bool forceClientAuth) { this.keyCertificatePairs = new List(keyCertificatePairs).AsReadOnly(); Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0, "At least one KeyCertificatePair needs to be provided"); + if (forceClientAuth) + { + Preconditions.CheckNotNull(rootCertificates, + "Cannot force client authentication unless you provide rootCertificates."); + } this.rootCertificates = rootCertificates; + this.forceClientAuth = forceClientAuth; } /// @@ -100,7 +108,7 @@ namespace Grpc.Core /// using client root certificates. /// /// Key-certificates to use. - public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null) + public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null, false) { } @@ -126,6 +134,17 @@ namespace Grpc.Core } } + /// + /// If true, the authenticity of client check will be enforced. + /// + public bool ForceClientAuthentication + { + get + { + return this.forceClientAuth; + } + } + internal override ServerCredentialsSafeHandle ToNativeCredentials() { int count = keyCertificatePairs.Count; @@ -136,7 +155,7 @@ namespace Grpc.Core certChains[i] = keyCertificatePairs[i].CertificateChain; keys[i] = keyCertificatePairs[i].PrivateKey; } - return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys); + return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys, forceClientAuth); } } } diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index 1baf40eea2e..3069dceced0 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -62,7 +62,7 @@ namespace Grpc.IntegrationTesting File.ReadAllText(TestCredentials.ServerCertChainPath), File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); - var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert); + var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, true); var clientCredentials = new SslCredentials(rootCert, keyCertPair); server = new Server(); diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 28c2791cac0..139a6b8a6d2 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -792,7 +792,8 @@ grpcsharp_secure_channel_create(grpc_credentials *creds, const char *target, GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE grpcsharp_ssl_server_credentials_create( const char *pem_root_certs, const char **key_cert_pair_cert_chain_array, - const char **key_cert_pair_private_key_array, size_t num_key_cert_pairs) { + const char **key_cert_pair_private_key_array, size_t num_key_cert_pairs, + int force_client_auth) { size_t i; grpc_server_credentials *creds; grpc_ssl_pem_key_cert_pair *key_cert_pairs = @@ -807,9 +808,9 @@ grpcsharp_ssl_server_credentials_create( key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i]; } } - /* TODO: Add a force_client_auth parameter and pass it here. */ creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs, - num_key_cert_pairs, 0); + num_key_cert_pairs, + force_client_auth); gpr_free(key_cert_pairs); return creds; }