From 3363b136c6afa6de071ee189ceaead49107470d6 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 13 Aug 2012 13:44:16 -0400 Subject: [PATCH] Pass SSL certificate chain, not just collection, to Mono.Android.dll Fixes BCL half of: https://bugzilla.xamarin.com/show_bug.cgi?id=6501 Today I learned that the SSL certificate collection (as held in X509CertificateCollection) is a potentially unordered sequence of SSL certificates, which not all versions of Android will validate. The fix is to use the properly ordered SSL certificate chain (as held in X509Chain), and have Android validate that. --- .../System/System.Net/ServicePointManager.cs | 13 +--- mcs/class/System/System/AndroidPlatform.cs | 77 +++++++++++++++++++ mcs/class/System/monodroid_System.dll.sources | 1 + 3 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 mcs/class/System/System/AndroidPlatform.cs diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index 23c56bd28e7..d64f58cd1e5 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -408,19 +408,8 @@ namespace System.Net static bool is_macosx = System.IO.File.Exists (MSX.OSX509Certificates.SecurityLibrary); static X509RevocationMode revocation_mode; -#if MONODROID - static readonly Converter monodroidCallback; -#endif - static ChainValidationHelper () { -#if MONODROID - monodroidCallback = (Converter) - Delegate.CreateDelegate (typeof(Converter), - Type.GetType ("Android.Runtime.AndroidEnvironment, Mono.Android", true) - .GetMethod ("TrustEvaluateSsl", - System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)); -#endif #if !MONOTOUCH revocation_mode = X509RevocationMode.NoCheck; try { @@ -524,7 +513,7 @@ namespace System.Net #endif #if MONODROID - result = monodroidCallback (certs); + result = AndroidPlatform.TrustEvaluateSsl (certs, sender, leaf, chain, errors); if (result) { status11 = 0; errors = 0; diff --git a/mcs/class/System/System/AndroidPlatform.cs b/mcs/class/System/System/AndroidPlatform.cs new file mode 100644 index 00000000000..9719ea7af58 --- /dev/null +++ b/mcs/class/System/System/AndroidPlatform.cs @@ -0,0 +1,77 @@ +// +// System.AndroidPlatform.cs +// +// Author: +// Jonathan Pryor (jonp@xamarin.com) +// +// Copyright (C) 2012 Xamarin Inc (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#if MONODROID +using System; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; + +using MSX = Mono.Security.X509; + +namespace System { + + internal static class AndroidPlatform { + +#if SECURITY_DEP + static readonly Converter trustEvaluateSsl; + static readonly Func trustEvaluateSsl2; +#endif // SECURITY_DEP + + + static AndroidPlatform () + { +#if SECURITY_DEP + var t = Type.GetType ("Android.Runtime.AndroidEnvironment, Mono.Android", throwOnError:true); + trustEvaluateSsl2 = (Func) + Delegate.CreateDelegate ( + typeof (Func), + t, + "TrustEvaluateSsl2", + ignoreCase:false, + throwOnBindFailure:false); + if (trustEvaluateSsl2 == null) + trustEvaluateSsl = (Converter) + Delegate.CreateDelegate (typeof (Converter), + t, + "TrustEvaluateSsl", + ignoreCase:false, + throwOnBindFailure:true); +#endif // SECURITY_DEP + } + +#if SECURITY_DEP + internal static bool TrustEvaluateSsl (MSX.X509CertificateCollection collection, object sender, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors errors) + { + if (trustEvaluateSsl2 != null) + return trustEvaluateSsl2 (collection, sender, certificate, chain, errors); + return trustEvaluateSsl (collection); + } +#endif // SECURITY_DEP + } +} +#endif // MONODROID diff --git a/mcs/class/System/monodroid_System.dll.sources b/mcs/class/System/monodroid_System.dll.sources index be5e81d6e53..019f8681bd1 100644 --- a/mcs/class/System/monodroid_System.dll.sources +++ b/mcs/class/System/monodroid_System.dll.sources @@ -1,2 +1,3 @@ #include mobile_System.dll.sources +System/AndroidPlatform.cs System.CodeDom.Compiler/IndentedTextWriter.cs -- 2.25.1