aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp
diff options
context:
space:
mode:
authorGravatar Tim Emiola <tbetbetbe@users.noreply.github.com>2015-03-03 16:24:33 -0800
committerGravatar Tim Emiola <tbetbetbe@users.noreply.github.com>2015-03-03 16:24:33 -0800
commit93adddcd2df056c0b75dcc25328dd3f53c875a52 (patch)
tree0f745c854e4e2711260d88f6b7bfabc9d4283120 /src/csharp
parent3de87ee4a99bf9e5d50c310f4f2658fcb48ba7b7 (diff)
parent1532923d65684ddd006914f82af18d26a6a91659 (diff)
Merge pull request #929 from jtattermusch/csharp_tls
C# client side support for TLS
Diffstat (limited to 'src/csharp')
-rw-r--r--src/csharp/Grpc.Core/Channel.cs55
-rw-r--r--src/csharp/Grpc.Core/ChannelArgs.cs112
-rw-r--r--src/csharp/Grpc.Core/Credentials.cs77
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj4
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs77
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs35
-rw-r--r--src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs64
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj13
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs25
-rw-r--r--src/csharp/Grpc.IntegrationTesting/data/README1
-rw-r--r--src/csharp/Grpc.IntegrationTesting/data/ca.pem15
-rw-r--r--src/csharp/Grpc.IntegrationTesting/data/server1.key16
-rw-r--r--src/csharp/Grpc.IntegrationTesting/data/server1.pem16
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c68
14 files changed, 545 insertions, 33 deletions
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 942651cf39..83d965debf 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -1,5 +1,4 @@
#region Copyright notice and license
-
// Copyright 2015, Google Inc.
// All rights reserved.
//
@@ -28,9 +27,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
#endregion
-
using System;
using System.Runtime.InteropServices;
using System.Threading;
@@ -39,18 +36,32 @@ using Grpc.Core.Internal;
namespace Grpc.Core
{
- public class Channel : IDisposable
- {
+ public class Channel : IDisposable
+ {
readonly ChannelSafeHandle handle;
readonly String target;
- // TODO: add way how to create grpc_secure_channel....
- // TODO: add support for channel args...
- public Channel(string target)
- {
- this.handle = ChannelSafeHandle.Create(target, IntPtr.Zero);
- this.target = target;
- }
+ /// <summary>
+ /// Creates a channel.
+ /// </summary>
+ public Channel(string target, Credentials credentials = null, ChannelArgs channelArgs = null)
+ {
+ using (ChannelArgsSafeHandle nativeChannelArgs = CreateNativeChannelArgs(channelArgs))
+ {
+ if (credentials != null)
+ {
+ using (CredentialsSafeHandle nativeCredentials = credentials.ToNativeCredentials())
+ {
+ this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, target, nativeChannelArgs);
+ }
+ }
+ else
+ {
+ this.handle = ChannelSafeHandle.Create(target, nativeChannelArgs);
+ }
+ }
+ this.target = GetOverridenTarget(target, channelArgs);
+ }
internal ChannelSafeHandle Handle
{
@@ -81,5 +92,23 @@ namespace Grpc.Core
handle.Dispose();
}
}
- }
+
+ private static string GetOverridenTarget(string target, ChannelArgs args)
+ {
+ if (args != null && !string.IsNullOrEmpty(args.GetSslTargetNameOverride()))
+ {
+ return args.GetSslTargetNameOverride();
+ }
+ return target;
+ }
+
+ private static ChannelArgsSafeHandle CreateNativeChannelArgs(ChannelArgs args)
+ {
+ if (args == null)
+ {
+ return ChannelArgsSafeHandle.CreateNull();
+ }
+ return args.ToNativeChannelArgs();
+ }
+ }
}
diff --git a/src/csharp/Grpc.Core/ChannelArgs.cs b/src/csharp/Grpc.Core/ChannelArgs.cs
new file mode 100644
index 0000000000..653a5780a3
--- /dev/null
+++ b/src/csharp/Grpc.Core/ChannelArgs.cs
@@ -0,0 +1,112 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
+
+namespace Grpc.Core
+{
+ // TODO: should we be using the builder pattern?
+ public class ChannelArgs
+ {
+ public const string SslTargetNameOverrideKey = "grpc.ssl_target_name_override";
+
+ public class Builder
+ {
+ Dictionary<string,string> stringArgs = new Dictionary<string,string>();
+ // TODO: AddInteger not supported yet.
+ public Builder AddString(string key, string value)
+ {
+ stringArgs.Add(key, value);
+ return this;
+ }
+
+ public ChannelArgs Build()
+ {
+ return new ChannelArgs(stringArgs);
+ }
+ }
+
+ Dictionary<string,string> stringArgs;
+
+ private ChannelArgs(Dictionary<string, string> stringArgs)
+ {
+ // TODO: use immutable dict?
+ this.stringArgs = new Dictionary<string, string>(stringArgs);
+ }
+
+ public string GetSslTargetNameOverride()
+ {
+ string result;
+ if (stringArgs.TryGetValue(SslTargetNameOverrideKey, out result))
+ {
+ return result;
+ }
+ return null;
+ }
+
+ public static Builder NewBuilder()
+ {
+ return new Builder();
+ }
+
+ /// <summary>
+ /// Creates native object for the channel arguments.
+ /// </summary>
+ /// <returns>The native channel arguments.</returns>
+ internal ChannelArgsSafeHandle ToNativeChannelArgs()
+ {
+ ChannelArgsSafeHandle nativeArgs = null;
+ try
+ {
+ nativeArgs = ChannelArgsSafeHandle.Create(stringArgs.Count);
+ int i = 0;
+ foreach (var entry in stringArgs)
+ {
+ nativeArgs.SetString(i, entry.Key, entry.Value);
+ i++;
+ }
+ return nativeArgs;
+ }
+ catch (Exception e)
+ {
+ if (nativeArgs != null)
+ {
+ nativeArgs.Dispose();
+ }
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Credentials.cs b/src/csharp/Grpc.Core/Credentials.cs
new file mode 100644
index 0000000000..5116c277f7
--- /dev/null
+++ b/src/csharp/Grpc.Core/Credentials.cs
@@ -0,0 +1,77 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using Grpc.Core.Internal;
+
+namespace Grpc.Core
+{
+ public abstract class Credentials
+ {
+ /// <summary>
+ /// Creates native object for the credentials.
+ /// </summary>
+ /// <returns>The native credentials.</returns>
+ internal abstract CredentialsSafeHandle ToNativeCredentials();
+ }
+
+ /// <summary>
+ /// Client-side SSL credentials.
+ /// </summary>
+ public class SslCredentials : Credentials
+ {
+ string pemRootCerts;
+
+ public SslCredentials(string pemRootCerts)
+ {
+ this.pemRootCerts = pemRootCerts;
+ }
+
+ /// <summary>
+ /// PEM encoding of the server root certificates.
+ /// </summary>
+ public string RootCerts
+ {
+ get
+ {
+ return this.pemRootCerts;
+ }
+ }
+
+ internal override CredentialsSafeHandle ToNativeCredentials()
+ {
+ return CredentialsSafeHandle.CreateSslCredentials(pemRootCerts);
+ }
+ }
+}
+
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 05d40d45a6..93d5430591 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -65,6 +65,10 @@
<Compile Include="Internal\BatchContextSafeHandleNotOwned.cs" />
<Compile Include="Utils\BenchmarkUtil.cs" />
<Compile Include="Utils\ExceptionHelper.cs" />
+ <Compile Include="Internal\CredentialsSafeHandle.cs" />
+ <Compile Include="Credentials.cs" />
+ <Compile Include="Internal\ChannelArgsSafeHandle.cs" />
+ <Compile Include="ChannelArgs.cs" />
</ItemGroup>
<Choose>
<!-- Under older versions of Monodevelop, Choose is not supported and is just
diff --git a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
new file mode 100644
index 0000000000..ca3c21d84c
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
@@ -0,0 +1,77 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// grpc_channel_args from <grpc/grpc.h>
+ /// </summary>
+ internal class ChannelArgsSafeHandle : SafeHandleZeroIsInvalid
+ {
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs);
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern void grpcsharp_channel_args_destroy(IntPtr args);
+
+ private ChannelArgsSafeHandle()
+ {
+ }
+
+ public static ChannelArgsSafeHandle CreateNull()
+ {
+ return new ChannelArgsSafeHandle();
+ }
+
+ public static ChannelArgsSafeHandle Create(int size)
+ {
+ return grpcsharp_channel_args_create(new UIntPtr((uint)size));
+ }
+
+ public void SetString(int index, string key, string value)
+ {
+ grpcsharp_channel_args_set_string(this, new UIntPtr((uint)index), key, value);
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ grpcsharp_channel_args_destroy(handle);
+ return true;
+ }
+ }
+}
+
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index f15ead3572..f046f4c6d0 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -1,5 +1,4 @@
#region Copyright notice and license
-
// Copyright 2015, Google Inc.
// All rights reserved.
//
@@ -28,9 +27,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
#endregion
-
using System;
using System.Runtime.InteropServices;
using System.Threading;
@@ -41,27 +38,35 @@ namespace Grpc.Core.Internal
/// <summary>
/// grpc_channel from <grpc/grpc.h>
/// </summary>
- internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
- {
+ internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
+ {
[DllImport("grpc_csharp_ext.dll")]
- static extern ChannelSafeHandle grpcsharp_channel_create(string target, IntPtr channelArgs);
+ static extern ChannelSafeHandle grpcsharp_channel_create(string target, ChannelArgsSafeHandle channelArgs);
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_channel_destroy(IntPtr channel);
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern ChannelSafeHandle grpcsharp_secure_channel_create(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern void grpcsharp_channel_destroy(IntPtr channel);
private ChannelSafeHandle()
{
}
- public static ChannelSafeHandle Create(string target, IntPtr channelArgs)
+ public static ChannelSafeHandle Create(string target, ChannelArgsSafeHandle channelArgs)
{
return grpcsharp_channel_create(target, channelArgs);
}
- protected override bool ReleaseHandle()
- {
- grpcsharp_channel_destroy(handle);
- return true;
- }
- }
+ public static ChannelSafeHandle CreateSecure(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
+ {
+ return grpcsharp_secure_channel_create(credentials, target, channelArgs);
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ grpcsharp_channel_destroy(handle);
+ return true;
+ }
+ }
}
diff --git a/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
new file mode 100644
index 0000000000..f361199068
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
@@ -0,0 +1,64 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// grpc_credentials from <grpc/grpc_security.h>
+ /// </summary>
+ internal class CredentialsSafeHandle : SafeHandleZeroIsInvalid
+ {
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ static extern CredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern void grpcsharp_credentials_release(IntPtr credentials);
+
+ private CredentialsSafeHandle()
+ {
+ }
+
+ public static CredentialsSafeHandle CreateSslCredentials(string pemRootCerts)
+ {
+ return grpcsharp_ssl_credentials_create(pemRootCerts, null, null);
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ grpcsharp_credentials_release(handle);
+ return true;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 6d6aaf5747..8f7a17efcb 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -62,8 +62,21 @@
<None Include="proto\test.proto" />
<None Include="proto\empty.proto" />
<None Include="proto\messages.proto" />
+ <None Include="data\README">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="data\ca.pem">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="data\server1.key">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="data\server1.pem">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
</ItemGroup>
<ItemGroup>
<Folder Include="proto\" />
+ <Folder Include="data\" />
</ItemGroup>
</Project>
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index a7a3c63e03..e560112a89 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -34,6 +34,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Google.ProtocolBuffers;
@@ -49,10 +50,10 @@ namespace Grpc.IntegrationTesting
private class ClientOptions
{
public bool help;
- public string serverHost;
- public string serverHostOverride;
+ public string serverHost= "127.0.0.1";
+ public string serverHostOverride = "foo.test.google.fr";
public int? serverPort;
- public string testCase;
+ public string testCase = "large_unary";
public bool useTls;
public bool useTestCa;
}
@@ -98,10 +99,24 @@ namespace Grpc.IntegrationTesting
GrpcEnvironment.Initialize();
string addr = string.Format("{0}:{1}", options.serverHost, options.serverPort);
- using (Channel channel = new Channel(addr))
+
+ Credentials credentials = null;
+ if (options.useTls)
{
- TestServiceGrpc.ITestServiceClient client = new TestServiceGrpc.TestServiceClientStub(channel);
+ // TODO: use also Env variable for location of the ca file.
+ credentials = new SslCredentials(File.ReadAllText("data/ca.pem"));
+ }
+
+ ChannelArgs channelArgs = null;
+ if (!string.IsNullOrEmpty(options.serverHostOverride))
+ {
+ channelArgs = ChannelArgs.NewBuilder()
+ .AddString(ChannelArgs.SslTargetNameOverrideKey, options.serverHostOverride).Build();
+ }
+ using (Channel channel = new Channel(addr, credentials, channelArgs))
+ {
+ TestServiceGrpc.ITestServiceClient client = new TestServiceGrpc.TestServiceClientStub(channel);
RunTestCase(options.testCase, client);
}
diff --git a/src/csharp/Grpc.IntegrationTesting/data/README b/src/csharp/Grpc.IntegrationTesting/data/README
new file mode 100644
index 0000000000..888d95b900
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/data/README
@@ -0,0 +1 @@
+CONFIRMEDTESTKEY
diff --git a/src/csharp/Grpc.IntegrationTesting/data/ca.pem b/src/csharp/Grpc.IntegrationTesting/data/ca.pem
new file mode 100644
index 0000000000..6c8511a73c
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/data/ca.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla
+Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT
+BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7
++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu
+g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd
+Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau
+sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m
+oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG
+Dfcog5wrJytaQ6UA0wE=
+-----END CERTIFICATE-----
diff --git a/src/csharp/Grpc.IntegrationTesting/data/server1.key b/src/csharp/Grpc.IntegrationTesting/data/server1.key
new file mode 100644
index 0000000000..143a5b8765
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/data/server1.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD
+M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf
+3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY
+AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm
+V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY
+tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p
+dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q
+K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR
+81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff
+DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd
+aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2
+ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3
+XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe
+F98XJ7tIFfJq
+-----END PRIVATE KEY-----
diff --git a/src/csharp/Grpc.IntegrationTesting/data/server1.pem b/src/csharp/Grpc.IntegrationTesting/data/server1.pem
new file mode 100644
index 0000000000..8e582e571f
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/data/server1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
+MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
+c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
+JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
+RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
+3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
+b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
+KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
+wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
+aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+-----END CERTIFICATE-----
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 8f5a414187..e24438704c 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -39,6 +39,7 @@
#include <grpc/support/slice.h>
#include <grpc/support/thd.h>
#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
#include <string.h>
@@ -266,6 +267,45 @@ grpcsharp_channel_create_call(grpc_channel *channel, grpc_completion_queue *cq,
return grpc_channel_create_call(channel, cq, method, host, deadline);
}
+/* Channel args */
+
+GPR_EXPORT grpc_channel_args *GPR_CALLTYPE
+grpcsharp_channel_args_create(size_t num_args) {
+ grpc_channel_args *args =
+ (grpc_channel_args *)gpr_malloc(sizeof(grpc_channel_args));
+ memset(args, 0, sizeof(grpc_channel_args));
+
+ args->num_args = num_args;
+ args->args = (grpc_arg *)gpr_malloc(sizeof(grpc_arg) * num_args);
+ memset(args->args, 0, sizeof(grpc_arg) * num_args);
+ return args;
+}
+
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_channel_args_set_string(grpc_channel_args *args, size_t index,
+ const char *key, const char *value) {
+ GPR_ASSERT(args);
+ GPR_ASSERT(index < args->num_args);
+ args->args[index].type = GRPC_ARG_STRING;
+ args->args[index].key = gpr_strdup(key);
+ args->args[index].value.string = gpr_strdup(value);
+}
+
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_channel_args_destroy(grpc_channel_args *args) {
+ size_t i;
+ if (args) {
+ for (i = 0; i < args->num_args; i++) {
+ gpr_free(args->args[i].key);
+ if (args->args[i].type == GRPC_ARG_STRING) {
+ gpr_free(args->args[i].value.string);
+ }
+ }
+ gpr_free(args->args);
+ gpr_free(args);
+ }
+}
+
/* Timespec */
GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); }
@@ -585,6 +625,34 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq,
&(ctx->server_rpc_new.request_metadata), cq, ctx);
}
+/* Security */
+
+GPR_EXPORT grpc_credentials *GPR_CALLTYPE
+grpcsharp_ssl_credentials_create(const char *pem_root_certs,
+ const char *key_cert_pair_cert_chain,
+ const char *key_cert_pair_private_key) {
+ grpc_ssl_pem_key_cert_pair key_cert_pair;
+ if (key_cert_pair_cert_chain || key_cert_pair_private_key) {
+ key_cert_pair.cert_chain = key_cert_pair_cert_chain;
+ key_cert_pair.private_key = key_cert_pair_private_key;
+ return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair);
+ } else {
+ GPR_ASSERT(!key_cert_pair_cert_chain);
+ GPR_ASSERT(!key_cert_pair_private_key);
+ return grpc_ssl_credentials_create(pem_root_certs, NULL);
+ }
+}
+
+GPR_EXPORT void grpcsharp_credentials_release(grpc_credentials *creds) {
+ grpc_credentials_release(creds);
+}
+
+GPR_EXPORT grpc_channel *GPR_CALLTYPE
+grpcsharp_secure_channel_create(grpc_credentials *creds, const char *target,
+ const grpc_channel_args *args) {
+ return grpc_secure_channel_create(creds, target, args);
+}
+
/* Logging */
typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, gpr_int32 line,