ServicePointManager.ServerCertificateValidationCallback is not invoked

I have the following code in Android, iOS and WPF application layers.

ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate pCertificate, System.Security.Cryptography.X509Certificates.X509Chain pChain, System.Net.Security.SslPolicyErrors pSSLPolicyErrors) { return true; };

In WPF the callback is invoked but in iOS and Android I see no invocation of the callback.

Answers

  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    Without seeing more code, it is hard to know for sure why that callback is not being invoked. However I do know that it will not be invoked for any UIWebViews on iOS or WebViews on Android. In other words, that call back will only be invoked for .NET web request APIs, like HttpClient or WebRequest, but not when you are loading a url into any native web view or using any other platform native web request methods since those are not .NET APIs.

  • I use HTTPClient, with ModernHttpClient delegate handler.

  • GtasGtas USMember

    I use HTTPClient, with ModernHttpClient delegate handler.

  • AlbertKAlbertK MYMember ✭✭✭

    @JGoldberger said:
    Without seeing more code, it is hard to know for sure why that callback is not being invoked. However I do know that it will not be invoked for any UIWebViews on iOS or WebViews on Android. In other words, that call back will only be invoked for .NET web request APIs, like HttpClient or WebRequest, but not when you are loading a url into any native web view or using any other platform native web request methods since those are not .NET APIs.

    Hi,

    I have the following code targeting Android as shown below and it does not work with self signed SSL. For the HttpClient only I get the
    error 03-11 10:21:51.037 I/HttpApp ( 3788): Http Error :An error occurred while sending the request

    With the AndroidClientHandler, I get the error
    03-11 10:18:47.840 E/mono-rt ( 3566): [ERROR] FATAL UNHANDLED EXCEPTION: System.NotImplementedException: The method or operation is not implemented.

    VS 2015 v14.0.25425.01 Update3
    Xamarin 4.3.784
    Xamarin.Android 7.1.0.41

    System.Uri tt = new System.Uri("https://192.168.100.1/");
    
               System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) =>
                {
                    Toast.MakeText(this, "Certificate ", ToastLength.Short).Show();
    
                    System.Diagnostics.Debug.WriteLine(cert.GetSerialNumberString());
                    System.Diagnostics.Debug.WriteLine(cert.Issuer);
                    System.Diagnostics.Debug.WriteLine(cert.Subject);
                    return true;
                };
    
                using (HttpClient myhttp = new HttpClient()
                {
    
                    try
                    {
                        var response = await myhttp.GetAsync(tt);
                        var header = response.Headers;
    
                        if (response.IsSuccessStatusCode)
                        {
                            var restxt = await response.Content.ReadAsStringAsync();
                            Log.Info(TAG, restxt.ToString());
                        }
                    }
                    catch(HttpRequestException httpex)
                    {
                        Log.Info(TAG, "Http Error :" + httpex.Message);
                    }
                    catch(Exception ex )
                    {
                        Log.Info(TAG, "System Error :" + ex.Message);
                    }
                }
    

    // AndroidClientHandler Example

    System.Uri tt = new System.Uri("https://192.168.100.1/");
    
               Xamarin.Android.Net.AndroidClientHandler androidHandler = new Xamarin.Android.Net.AndroidClientHandler();
            androidHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslpolicy) => { return true; };
    
                using (HttpClient myhttp = new HttpClient(new AndroidClientHander())
                {
    
                    try
                    {
                        var response = await myhttp.GetAsync(tt);
                        var header = response.Headers;
    
                        if (response.IsSuccessStatusCode)
                        {
                            var restxt = await response.Content.ReadAsStringAsync();
                            Log.Info(TAG, restxt.ToString());
                        }
                    }
                    catch(HttpRequestException httpex)
                    {
                        Log.Info(TAG, "Http Error :" + httpex.Message);
                    }
                    catch(Exception ex )
                    {
                        Log.Info(TAG, "System Error :" + ex.Message);
                    }
                }
    
  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    @AlbertK

    I am personally not very familiar with using self-signed certificates, but I found what seems to be a good blog post on the subject:
    https://dotnetdevaddict.co.za/2015/07/31/self-signed-certificates-and-xamarin-android/

    In addition to other discussions on this forum:
    https://forums.xamarin.com/discussion/52394/self-signed-certificates-and-httpclient
    https://forums.xamarin.com/discussion/27314/allowing-self-signed-certificates-with-the-httpclient

  • AlbertKAlbertK MYMember ✭✭✭

    @JGoldberger said:
    @AlbertK

    I am personally not very familiar with using self-signed certificates, but I found what seems to be a good blog post on the subject:
    https://dotnetdevaddict.co.za/2015/07/31/self-signed-certificates-and-xamarin-android/

    In addition to other discussions on this forum:
    https://forums.xamarin.com/discussion/52394/self-signed-certificates-and-httpclient
    https://forums.xamarin.com/discussion/27314/allowing-self-signed-certificates-with-the-httpclient

    @JGoldberger, May I know of the ServerCertificateCustomValidationCallback delegated is implemented in AndroidClientHandler Class then? From the error message it seems that it is just an empty place holder. Thanks.

  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    @AlbertK

    May I know of the ServerCertificateCustomValidationCallback delegated is implemented in AndroidClientHandler Class then?

    I am not 100% sure, but my understanding is that ServerCertificateCustomValidationCallback is only invoked when using the full Mono/.NET stack, i.e. using HttpClientHandler.

    The source code for AndroidClientHandler does have some info on using self-signed certificates. See:
    https://github.com/xamarin/xamarin-android/blob/c68f79ad387d8254ec2f29c4e8eb00ec8ea1eb1e/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L49

    From the above:

    AndroidClientHandler also supports requests to servers with "invalid" (e.g. self-signed) SSL certificates. Since this process is a bit convoluted using the Java APIs, AndroidClientHandler defines two ways to handle the situation. First, easier, is to store the necessary certificates (either CA or server certificates) in the <see cref="TrustedCerts"/> collection or, after deriving a custom class from AndroidClientHandler, by overriding one or more methods provided for this purpose (<see cref="ConfigureTrustManagerFactory"/>, <see cref="ConfigureKeyManagerFactory"/> and <see cref="ConfigureKeyStore"/>). The former method should be sufficient for most use cases, the latter allows the application to provide fully customized key store, trust manager and key manager, if needed. Note that the instance of AndroidClientHandler configured to accept an "invalid" certificate from the particular server will most likely fail to validate certificates from other servers (even if they use a certificate with a fully validated trust chain) unless you store the CA certificates from your Android system in <see cref="TrustedCerts"/> along with the self-signed certificate(s).

  • wobuntuwobuntu Member
    I struggled with the same problem for a while now, however by just setting the HTTP implementation in your android project settings to "Managed" instead of native solved it finally.
  • RoyaRoya USMember ✭✭

    @wobuntu said:
    I struggled with the same problem for a while now, however by just setting the HTTP implementation in your android project settings to "Managed" instead of native solved it finally.

    Hi, I am also struggling with the same problem, could you please explain it more how do you solve it? thank you.

  • wobuntuwobuntu Member

    @Roya said:
    Hi, I am also struggling with the same problem, could you please explain it more how do you solve it? thank you.

    • Sure, simply right click your Android project in the Project Explorer and select "Properties".
    • In the project settings window which opened now, change to tab "Android-Settings".
    • At the bottom of the page, you see a button "Advanced" or similar, just click it (my VS is not set to an English layout, names may vary)
    • In the newly opened window, you just choose "Managed" for the last two options (HTTP and TLS implementation).

    After that, you'll be able to override the System.Net.ServicePointManager.ServerCertificateValidationCallback like others did in the previous answers.

    However, if you can, you should definitely go for the native implementations, since they are faster and support a higher TLS version with more features. If you do so, you must override the platform specific handlers for the TLS certificate validation, but I didn't do that until now, so I'm not able to give you details on how this would work.

  • VarunBabuSVarunBabuS INMember ✭✭✭

    @wobuntu Thanks for detailed step this helped my day!!

Sign In or Register to comment.