enable forcing client auth

pull/2797/head
Jan Tattermusch 9 years ago
parent 50d8ed91be
commit d27dfa7840
  1. 7
      src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
  2. 27
      src/csharp/Grpc.Core/ServerCredentials.cs
  3. 2
      src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
  4. 7
      src/csharp/ext/grpc_csharp_ext.c

@ -42,7 +42,7 @@ namespace Grpc.Core.Internal
internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] [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")] [DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_credentials_release(IntPtr credentials); 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); Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
return grpcsharp_ssl_server_credentials_create(pemRootCerts, return grpcsharp_ssl_server_credentials_create(pemRootCerts,
keyCertPairCertChainArray, keyCertPairPrivateKeyArray, keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
new UIntPtr((ulong)keyCertPairCertChainArray.Length)); new UIntPtr((ulong)keyCertPairCertChainArray.Length),
forceClientAuth);
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()

@ -80,18 +80,26 @@ namespace Grpc.Core
{ {
readonly IList<KeyCertificatePair> keyCertificatePairs; readonly IList<KeyCertificatePair> keyCertificatePairs;
readonly string rootCertificates; readonly string rootCertificates;
readonly bool forceClientAuth;
/// <summary> /// <summary>
/// Creates server-side SSL credentials. /// Creates server-side SSL credentials.
/// </summary> /// </summary>
/// <param name="rootCertificates">PEM encoded client root certificates used to authenticate client.</param>
/// <param name="keyCertificatePairs">Key-certificates to use.</param> /// <param name="keyCertificatePairs">Key-certificates to use.</param>
public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates) /// <param name="rootCertificates">PEM encoded client root certificates used to authenticate client.</param>
/// <param name="forceClientAuth">If true, client will be rejected unless it proves its unthenticity using against rootCertificates.</param>
public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth)
{ {
this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly(); this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly();
Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0, Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0,
"At least one KeyCertificatePair needs to be provided"); "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.rootCertificates = rootCertificates;
this.forceClientAuth = forceClientAuth;
} }
/// <summary> /// <summary>
@ -100,7 +108,7 @@ namespace Grpc.Core
/// using client root certificates. /// using client root certificates.
/// </summary> /// </summary>
/// <param name="keyCertificatePairs">Key-certificates to use.</param> /// <param name="keyCertificatePairs">Key-certificates to use.</param>
public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs) : this(keyCertificatePairs, null) public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs) : this(keyCertificatePairs, null, false)
{ {
} }
@ -126,6 +134,17 @@ namespace Grpc.Core
} }
} }
/// <summary>
/// If true, the authenticity of client check will be enforced.
/// </summary>
public bool ForceClientAuthentication
{
get
{
return this.forceClientAuth;
}
}
internal override ServerCredentialsSafeHandle ToNativeCredentials() internal override ServerCredentialsSafeHandle ToNativeCredentials()
{ {
int count = keyCertificatePairs.Count; int count = keyCertificatePairs.Count;
@ -136,7 +155,7 @@ namespace Grpc.Core
certChains[i] = keyCertificatePairs[i].CertificateChain; certChains[i] = keyCertificatePairs[i].CertificateChain;
keys[i] = keyCertificatePairs[i].PrivateKey; keys[i] = keyCertificatePairs[i].PrivateKey;
} }
return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys); return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys, forceClientAuth);
} }
} }
} }

@ -62,7 +62,7 @@ namespace Grpc.IntegrationTesting
File.ReadAllText(TestCredentials.ServerCertChainPath), File.ReadAllText(TestCredentials.ServerCertChainPath),
File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); 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); var clientCredentials = new SslCredentials(rootCert, keyCertPair);
server = new Server(); server = new Server();

@ -792,7 +792,8 @@ grpcsharp_secure_channel_create(grpc_credentials *creds, const char *target,
GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE
grpcsharp_ssl_server_credentials_create( grpcsharp_ssl_server_credentials_create(
const char *pem_root_certs, const char **key_cert_pair_cert_chain_array, 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; size_t i;
grpc_server_credentials *creds; grpc_server_credentials *creds;
grpc_ssl_pem_key_cert_pair *key_cert_pairs = 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]; 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, 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); gpr_free(key_cert_pairs);
return creds; return creds;
} }

Loading…
Cancel
Save