anaisbetts / ModernHttpClient

HttpClient implementations that use platform-native HTTP clients for :rocket:
MIT License
658 stars 261 forks source link

Enable using self-signed certificates for development purposes #43

Closed AndreasPolito closed 10 years ago

AndreasPolito commented 10 years ago

Hi there,

I have a Problem to use your OkHttpNetworkHandler with a Https Site

What do i wrong or is this a bug ?!?

see the code below

public JContainer  Login(Context context, string hardwareId, string user, string secret, string loginHash)
        {
            using (var client = new HttpClient(new OkHttpNetworkHandler()))
            {
                ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback;
                Uri uri = new Uri("URL");

                HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, uri);

                requestMessage.Headers.Add("Accept-Language", CultureInfo.CurrentCulture.ToString());

                var content = new FormUrlEncodedContent(new[]
                    {
                        new KeyValuePair<string, string>("q", "Test"),
                    });

                requestMessage.Content = content;
                try
                {
                    var response = client.SendAsync(requestMessage);
                    if (response.Result.IsSuccessStatusCode)
                    {
                        var responseContent = response.Result.Content;
                        string responseString = responseContent.ReadAsStringAsync().Result;

                        return (JContainer) JsonConvert.DeserializeObject(responseString);
                    }

                    return null;
                }
                catch (Exception e)
                {
                    return null;
                }
            }
        }

        private bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
anaisbetts commented 10 years ago
ServicePointManager.ServerCertificateValidationCallback

This isn't supported in ModernHttpClient. You should get a real SSL certificate so you don't have to hack things, they're quite inexpensive these days :)

AndreasPolito commented 10 years ago

I have a certificate now.

But how can i add it ?!?

normaly i can add a WebRequestHandler like this...

var certHandler = new WebRequestHandler(); certHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
certHandler.UseDefaultCredentials = false;

    var certificate = new X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); //Must be renewed and replaced every year.
    certHandler.ClientCertificates.Add(certificate);            

    //Execute the command            
    var client = new HttpClient(certHandler);

But i cant figure out how to use your class XD

anaisbetts commented 10 years ago

Hey @AndreasPolito,

Sorry I wasn't clear earlier. What OkHttp is trying to tell you is that your server's HTTPS certificate is invalid. You need to fix this on the server side, not in your app.

AndreasPolito commented 10 years ago

Ah ok... :)

I will give you a feedback asap

kobynet commented 10 years ago

Any feedback on this since it's not s o clear how to handle SSL handshake using ModernHttpClient.

anaisbetts commented 10 years ago

@kobynet If your SSL certificate is valid, you don't have to do anything

countrywide commented 10 years ago

Hi @paulcbetts,

you are saying "ServicePointManager.ServerCertificateValidationCallback" is not supported in ModernHttpClient. Can you please advise another method of validating a self-signed certificate so I could connect to my development server using HTTPS and ModernHttpClient? At the moment I can't use ModernHttpClient on HTTPS due to self-signed certificate issue at all. I can't get a proper certificate for a development server!

abog commented 10 years ago

So ModernHttpClient cannot be used in the development environmet with a self signed certificate. Is it correct?

anaisbetts commented 10 years ago

So ModernHttpClient cannot be used in the development environment with a self signed certificate. Is it correct?

Not at the moment. For now, either make your server HTTP or use the standard HttpClient for self-signed certificates

countrywide commented 10 years ago

Any thoughts on when this could be supported in ModernHttpClient? This way I can't use it at all, because surely I don't want to test using the standard HttpClient but in production to use ModernHttpClient. That would not be a good 1 to 1 comparison testing.

kobynet commented 10 years ago

I join this request if possible :)

anaisbetts commented 10 years ago

I'm going to reopen this, a lot of people are asking for it

chadbr commented 10 years ago

Yes, please.

countrywide commented 10 years ago

Do you have an ETA for this feature? This is the only reason why I can't use ModernHttpClient client at all for now.

anaisbetts commented 10 years ago

On iOS it's blocked by a Xamarin marshaling bug, and on OkHttp they make it Real Hard for you to not do this because it's a bad idea. It's really seriously, like $5 for a 1yr SSL cert, if you're not doing this because of costs, things are Way Different Now

chadbr commented 10 years ago

5$/yr cert? Link?

anaisbetts commented 10 years ago

Ah sorry, it's $10/yr: https://cheapsslsecurity.com/comodo/essentialssl.html

chadbr commented 10 years ago

You're the man... Sweet.

Qonstrukt commented 10 years ago

I know this is an older issue, but the main reason I can't just buy a certificate hasn't been named yet; It is because our development environments use .local domain names for which you can't get validated certificates. (At least not when I looked for it.) And we haven't come around setting up our own CA for it yet.

Other than that, disabling HTTPS for development is an option for us fortunately, but it would still be nice to be able to do this. Ex: I've built some apps in the past that would allow the user to toggle wether certificated should be verified, since we're connecting to a user-specified address, but I guess using ModernHTTPClient wouldn't allow me to do this. (But apparently some other Xamarin issues are blocking this as well, so I won't complain any longer. And I could of course submit a PR myself.)

Thanks for the great work so far though, very much appreciated. :-)

anaisbetts commented 10 years ago

Other than that, disabling HTTPS for development is an option for us fortunately

Just do this

anaisbetts commented 10 years ago

This is fixed as of ModernHttpClient 2.1.0

chadbr commented 10 years ago

woohoo! Thanks!

kobynet commented 10 years ago

Awesome!

countrywide commented 9 years ago

I've just tried it with ModernHttpClient 2.1.4 and when trying to connect via HTTPS to our development server with self-signed certificate (it works OK on HTTP), it throws:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374) at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:183) at com.squareup.okhttp.Connection.connect(Connection.java:151) at com.squareup.okhttp.OkHttpClient$1.connect(OkHttpClient.java:84) at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:321) at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241) at com.squareup.okhttp.Call.getResponse(Call.java:198) at com.squareup.okhttp.Call.access$200(Call.java:36) at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:143) at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856)

Has it really been fixed and if so how to use the fix? Is there a property/parameter I need to set on the HttpClient side?

tedrog36 commented 9 years ago

I am getting the example same exception with my self signed certificate that works fine with default handler. I would really like to use ModernHttpClient, it seems like a great solution.

I second the question above: Is there a property/parameter I need to set on the HttpClient side?

geirsagberg commented 9 years ago

According to this commit, there is a parameter you need to pass into the constructor: public NativeMessageHandler(bool throwOnCaptiveNetwork, bool customSSLVerification)

tedrog36 commented 9 years ago

@geirsagberg thanks, but I tried setting customSSLVerification but that did not help.

anaisbetts commented 9 years ago

Hi all - I've decided to make this a paid feature, please see http://log.paulbetts.org/modernhttpclient-pro-edition/ for more info

PaulVipond commented 7 years ago

@paulcbetts Hi, just to be clear on this. I'd like to use modernhttpclient with certificate pinning. Does ServicePointManager.ServerCertificateValidationCallback get called in either the free or paid version so I can validate the server certificate? If not, would you consider adding this as a feature if it's possible?