client side support for TLS

pull/929/head
Jan Tattermusch 10 years ago
parent d318bba527
commit 1532923d65
  1. 55
      src/csharp/Grpc.Core/Channel.cs
  2. 112
      src/csharp/Grpc.Core/ChannelArgs.cs
  3. 77
      src/csharp/Grpc.Core/Credentials.cs
  4. 4
      src/csharp/Grpc.Core/Grpc.Core.csproj
  5. 77
      src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
  6. 35
      src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
  7. 64
      src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
  8. 13
      src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
  9. 25
      src/csharp/Grpc.IntegrationTesting/InteropClient.cs
  10. 1
      src/csharp/Grpc.IntegrationTesting/data/README
  11. 15
      src/csharp/Grpc.IntegrationTesting/data/ca.pem
  12. 16
      src/csharp/Grpc.IntegrationTesting/data/server1.key
  13. 16
      src/csharp/Grpc.IntegrationTesting/data/server1.pem
  14. 68
      src/csharp/ext/grpc_csharp_ext.c

@ -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();
}
}
}

@ -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;
}
}
}
}

@ -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);
}
}
}

@ -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

@ -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;
}
}
}

@ -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;
}
}
}

@ -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;
}
}
}

@ -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>

@ -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);
}

@ -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-----

@ -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-----

@ -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-----

@ -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,

Loading…
Cancel
Save