diff --git a/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs b/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs index 036634954fb..357dc2c5556 100644 --- a/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs +++ b/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs @@ -219,6 +219,20 @@ string EncodeUrl (Uri url) return bldr.ToString (); } + /// + /// Returns a custom host name verifier for a HTTPS connection. By default it returns null and + /// thus the connection uses whatever host name verification mechanism the operating system defaults to. + /// Override in your class to define custom host name verification behavior. The overriding class should + /// not set the property directly on the passed + /// + /// + /// Instance of IHostnameVerifier to be used for this HTTPS connection + /// HTTPS connection object. + protected virtual IHostnameVerifier GetSSLHostnameVerifier (HttpsURLConnection connection) + { + return null; + } + /// /// Creates, configures and processes an asynchronous request to the indicated resource. /// @@ -241,7 +255,19 @@ string EncodeUrl (Uri url) }; while (true) { URL java_url = new URL (EncodeUrl (redirectState.NewUrl)); - URLConnection java_connection = java_url.OpenConnection (); + URLConnection java_connection; + if (UseProxy) + java_connection = java_url.OpenConnection (); + else + java_connection = java_url.OpenConnection (Java.Net.Proxy.NoProxy); + + var httpsConnection = java_connection as HttpsURLConnection; + if (httpsConnection != null) { + IHostnameVerifier hnv = GetSSLHostnameVerifier (httpsConnection); + if (hnv != null) + httpsConnection.HostnameVerifier = hnv; + } + if (ConnectTimeout != TimeSpan.Zero) java_connection.ConnectTimeout = checked ((int)ConnectTimeout.TotalMilliseconds); @@ -729,11 +755,33 @@ void AppendEncoding (string encoding, ref List list) return httpConnection; } + /// + /// Configure and return a custom for the passed HTTPS . If the class overriding the method returns anything but the default + /// null, the SSL setup code will not call the nor the + /// methods used to configure a custom trust manager which is + /// then used to create a default socket factory. + /// Deriving class must perform all the key manager and trust manager configuration to ensure proper + /// operation of the returned socket factory. + /// + /// Instance of SSLSocketFactory ready to use with the HTTPS connection. + /// HTTPS connection to return socket factory for + protected virtual SSLSocketFactory ConfigureCustomSSLSocketFactory (HttpsURLConnection connection) + { + return null; + } + void SetupSSL (HttpsURLConnection httpsConnection) { if (httpsConnection == null) return; + SSLSocketFactory socketFactory = ConfigureCustomSSLSocketFactory (httpsConnection); + if (socketFactory != null) { + httpsConnection.SSLSocketFactory = socketFactory; + return; + } + KeyStore keyStore = KeyStore.GetInstance (KeyStore.DefaultType); keyStore.Load (null, null); bool gotCerts = TrustedCerts?.Count > 0;