aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jan.tattermusch@gmail.com>2016-02-02 06:39:10 -0800
committerGravatar Jan Tattermusch <jtattermusch@google.com>2016-02-02 12:23:42 -0800
commit660c15b844ffb5496435437379bb8ac45b7ce4bd (patch)
treef113a63e8cc9bb75e9507477de028ddf794ba7a2 /src/csharp
parent4d48522f0075884b2b57ff24a65fee76b918e52f (diff)
add roots.pem as a resource
Diffstat (limited to 'src/csharp')
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj9
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs72
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeExtension.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMethods.cs7
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c25
5 files changed, 115 insertions, 0 deletions
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 307c0e8783..9587503e4b 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -128,6 +128,7 @@
<Compile Include="Profiling\ProfilerScope.cs" />
<Compile Include="Profiling\IProfiler.cs" />
<Compile Include="Profiling\Profilers.cs" />
+ <Compile Include="Internal\DefaultSslRootsOverride.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Grpc.Core.nuspec" />
@@ -135,4 +136,12 @@
</ItemGroup>
<Import Project="NativeDeps.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ItemGroup>
+ <Folder Include="Resources\" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="..\..\..\etc\roots.pem">
+ <Link>Resources\roots.pem</Link>
+ </EmbeddedResource>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
new file mode 100644
index 0000000000..eeaa7add81
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
@@ -0,0 +1,72 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, 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.Concurrent;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Overrides the content of default SSL roots.
+ /// </summary>
+ internal static class DefaultSslRootsOverride
+ {
+ const string RootsPemResourceName = "Grpc.Core.Resources.roots.pem";
+ static object staticLock = new object();
+
+ /// <summary>
+ /// Overrides C core's default roots with roots.pem loaded as embedded resource.
+ /// </summary>
+ public static void Override(NativeMethods native)
+ {
+ lock (staticLock)
+ {
+ var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(RootsPemResourceName);
+ if (stream == null)
+ {
+ throw new IOException(string.Format("Error loading the embedded resource \"{0}\"", RootsPemResourceName));
+ }
+ using (var streamReader = new StreamReader(stream))
+ {
+ var pemRootCerts = streamReader.ReadToEnd();
+ native.grpcsharp_override_default_ssl_roots(pemRootCerts);
+ }
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
index 137533b3ef..e14d33ea50 100644
--- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -60,6 +60,8 @@ namespace Grpc.Core.Internal
// to make sure we don't lose any logs.
NativeLogRedirector.Redirect(this.nativeMethods);
+ DefaultSslRootsOverride.Override(this.nativeMethods);
+
Logger.Debug("gRPC native library loaded successfully.");
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index af37d61c73..19a573581e 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -97,6 +97,7 @@ namespace Grpc.Core.Internal
public readonly Delegates.grpcsharp_channel_args_set_integer_delegate grpcsharp_channel_args_set_integer;
public readonly Delegates.grpcsharp_channel_args_destroy_delegate grpcsharp_channel_args_destroy;
+ public readonly Delegates.grpcsharp_override_default_ssl_roots grpcsharp_override_default_ssl_roots;
public readonly Delegates.grpcsharp_ssl_credentials_create_delegate grpcsharp_ssl_credentials_create;
public readonly Delegates.grpcsharp_composite_channel_credentials_create_delegate grpcsharp_composite_channel_credentials_create;
public readonly Delegates.grpcsharp_channel_credentials_release_delegate grpcsharp_channel_credentials_release;
@@ -203,6 +204,7 @@ namespace Grpc.Core.Internal
this.grpcsharp_channel_args_set_integer = GetMethodDelegate<Delegates.grpcsharp_channel_args_set_integer_delegate>(library);
this.grpcsharp_channel_args_destroy = GetMethodDelegate<Delegates.grpcsharp_channel_args_destroy_delegate>(library);
+ this.grpcsharp_override_default_ssl_roots = GetMethodDelegate<Delegates.grpcsharp_override_default_ssl_roots>(library);
this.grpcsharp_ssl_credentials_create = GetMethodDelegate<Delegates.grpcsharp_ssl_credentials_create_delegate>(library);
this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_channel_credentials_create_delegate>(library);
this.grpcsharp_channel_credentials_release = GetMethodDelegate<Delegates.grpcsharp_channel_credentials_release_delegate>(library);
@@ -306,6 +308,7 @@ namespace Grpc.Core.Internal
this.grpcsharp_channel_args_set_integer = PInvokeMethods.grpcsharp_channel_args_set_integer;
this.grpcsharp_channel_args_destroy = PInvokeMethods.grpcsharp_channel_args_destroy;
+ this.grpcsharp_override_default_ssl_roots = PInvokeMethods.grpcsharp_override_default_ssl_roots;
this.grpcsharp_ssl_credentials_create = PInvokeMethods.grpcsharp_ssl_credentials_create;
this.grpcsharp_composite_channel_credentials_create = PInvokeMethods.grpcsharp_composite_channel_credentials_create;
this.grpcsharp_channel_credentials_release = PInvokeMethods.grpcsharp_channel_credentials_release;
@@ -449,6 +452,7 @@ namespace Grpc.Core.Internal
public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args);
+ public delegate void grpcsharp_override_default_ssl_roots(string pemRootCerts);
public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials);
@@ -658,6 +662,9 @@ namespace Grpc.Core.Internal
// ChannelCredentialsSafeHandle
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts);
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
[DllImport("grpc_csharp_ext.dll")]
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 26f1537398..8c362cf7c2 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -835,6 +835,30 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq,
/* Security */
+static char *default_pem_root_certs = NULL;
+
+static grpc_ssl_roots_override_result override_ssl_roots_handler(
+ char **pem_root_certs) {
+ if (!default_pem_root_certs) {
+ *pem_root_certs = NULL;
+ return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY;
+ }
+ *pem_root_certs = gpr_strdup(default_pem_root_certs);
+ return GRPC_SSL_ROOTS_OVERRIDE_OK;
+}
+
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_override_default_ssl_roots(
+ const char *pem_root_certs) {
+ /*
+ * This currently wastes ~300kB of memory by keeping a copy of roots
+ * in a static variable, but for desktop/server use, the overhead
+ * is negligible. In the future, we might want to change the behavior
+ * for mobile (e.g. Xamarin).
+ */
+ default_pem_root_certs = gpr_strdup(pem_root_certs);
+ grpc_set_ssl_roots_override_callback(override_ssl_roots_handler);
+}
+
GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE
grpcsharp_ssl_credentials_create(const char *pem_root_certs,
const char *key_cert_pair_cert_chain,
@@ -917,6 +941,7 @@ GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_composite_call_credenti
return grpc_composite_call_credentials_create(creds1, creds2, NULL);
}
+
/* Metadata credentials plugin */
GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin(