Skip to content
Snippets Groups Projects
Commit 1532923d authored by Jan Tattermusch's avatar Jan Tattermusch
Browse files

client side support for TLS

parent d318bba5
No related branches found
No related tags found
No related merge requests found
Showing
with 545 additions and 33 deletions
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015, Google Inc.
// All rights reserved. // All rights reserved.
// //
...@@ -28,9 +27,7 @@ ...@@ -28,9 +27,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
...@@ -39,18 +36,32 @@ using Grpc.Core.Internal; ...@@ -39,18 +36,32 @@ using Grpc.Core.Internal;
namespace Grpc.Core namespace Grpc.Core
{ {
public class Channel : IDisposable public class Channel : IDisposable
{ {
readonly ChannelSafeHandle handle; readonly ChannelSafeHandle handle;
readonly String target; readonly String target;
// TODO: add way how to create grpc_secure_channel.... /// <summary>
// TODO: add support for channel args... /// Creates a channel.
public Channel(string target) /// </summary>
{ public Channel(string target, Credentials credentials = null, ChannelArgs channelArgs = null)
this.handle = ChannelSafeHandle.Create(target, IntPtr.Zero); {
this.target = target; 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 internal ChannelSafeHandle Handle
{ {
...@@ -81,5 +92,23 @@ namespace Grpc.Core ...@@ -81,5 +92,23 @@ namespace Grpc.Core
handle.Dispose(); 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();
}
}
} }
#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;
}
}
}
}
#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 @@ ...@@ -65,6 +65,10 @@
<Compile Include="Internal\BatchContextSafeHandleNotOwned.cs" /> <Compile Include="Internal\BatchContextSafeHandleNotOwned.cs" />
<Compile Include="Utils\BenchmarkUtil.cs" /> <Compile Include="Utils\BenchmarkUtil.cs" />
<Compile Include="Utils\ExceptionHelper.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> </ItemGroup>
<Choose> <Choose>
<!-- Under older versions of Monodevelop, Choose is not supported and is just <!-- Under older versions of Monodevelop, Choose is not supported and is just
......
#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;
}
}
}
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015, Google Inc.
// All rights reserved. // All rights reserved.
// //
...@@ -28,9 +27,7 @@ ...@@ -28,9 +27,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
...@@ -41,27 +38,35 @@ namespace Grpc.Core.Internal ...@@ -41,27 +38,35 @@ namespace Grpc.Core.Internal
/// <summary> /// <summary>
/// grpc_channel from <grpc/grpc.h> /// grpc_channel from <grpc/grpc.h>
/// </summary> /// </summary>
internal class ChannelSafeHandle : SafeHandleZeroIsInvalid internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] [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")] [DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_destroy(IntPtr channel); 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() private ChannelSafeHandle()
{ {
} }
public static ChannelSafeHandle Create(string target, IntPtr channelArgs) public static ChannelSafeHandle Create(string target, ChannelArgsSafeHandle channelArgs)
{ {
return grpcsharp_channel_create(target, channelArgs); return grpcsharp_channel_create(target, channelArgs);
} }
protected override bool ReleaseHandle() public static ChannelSafeHandle CreateSecure(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
{ {
grpcsharp_channel_destroy(handle); return grpcsharp_secure_channel_create(credentials, target, channelArgs);
return true; }
}
} protected override bool ReleaseHandle()
{
grpcsharp_channel_destroy(handle);
return true;
}
}
} }
#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 @@ ...@@ -62,8 +62,21 @@
<None Include="proto\test.proto" /> <None Include="proto\test.proto" />
<None Include="proto\empty.proto" /> <None Include="proto\empty.proto" />
<None Include="proto\messages.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>
<ItemGroup> <ItemGroup>
<Folder Include="proto\" /> <Folder Include="proto\" />
<Folder Include="data\" />
</ItemGroup> </ItemGroup>
</Project> </Project>
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Google.ProtocolBuffers; using Google.ProtocolBuffers;
...@@ -49,10 +50,10 @@ namespace Grpc.IntegrationTesting ...@@ -49,10 +50,10 @@ namespace Grpc.IntegrationTesting
private class ClientOptions private class ClientOptions
{ {
public bool help; public bool help;
public string serverHost; public string serverHost= "127.0.0.1";
public string serverHostOverride; public string serverHostOverride = "foo.test.google.fr";
public int? serverPort; public int? serverPort;
public string testCase; public string testCase = "large_unary";
public bool useTls; public bool useTls;
public bool useTestCa; public bool useTestCa;
} }
...@@ -98,10 +99,24 @@ namespace Grpc.IntegrationTesting ...@@ -98,10 +99,24 @@ namespace Grpc.IntegrationTesting
GrpcEnvironment.Initialize(); GrpcEnvironment.Initialize();
string addr = string.Format("{0}:{1}", options.serverHost, options.serverPort); 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); RunTestCase(options.testCase, client);
} }
......
CONFIRMEDTESTKEY
-----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-----
-----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-----
-----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 @@ ...@@ -39,6 +39,7 @@
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
#include <grpc/support/thd.h> #include <grpc/support/thd.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <string.h> #include <string.h>
...@@ -266,6 +267,45 @@ grpcsharp_channel_create_call(grpc_channel *channel, grpc_completion_queue *cq, ...@@ -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); 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 */ /* Timespec */
GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); } 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, ...@@ -585,6 +625,34 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq,
&(ctx->server_rpc_new.request_metadata), cq, ctx); &(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 */ /* Logging */
typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, gpr_int32 line, typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, gpr_int32 line,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment