alexrainman / ModernHttpClient

ModernHttpClient
MIT License
126 stars 28 forks source link

(Android) IllegalArgumentException: Invalid input to toASCII when hostname includes illegal character #30

Closed tbaggett closed 3 years ago

tbaggett commented 5 years ago

Hi, thanks for the great work on updating modernhttpclient! I just discovered your nuget today and had some difficulties getting it to work on Android. I haven't tested iOS yet.

I installed the latest 2.8.0 version in the NetStandard library portion of a Xamarin Forms project. I have run into two different issues.

The first issue I'm seeing is a HttpRequestException exception ("Trust anchor for certification path not found.") when trying to connect to a dev environment with a self-signed certificate even with the EnableUntrustedCertificates property set to true. I read your comment in issue #23, "It will be fixed in the next release but support for untrusted certificates will be removed." Does that mean setting EnableUntrustedCertificates to true no longer allows self-signed certificates to be used with v2.8.0?

The second issue is a HttpRequestException: ("Invalid input to toASCII: {hostname}") when trying to connect to a test environment with a purchased certificate. The environment host name contains an underscore, for example "test_environment.client.com". Is there any way around this issue (understanding it isn't specific to your library) besides having the host name changed to remove the underscore character?

Thanks again,

Tommy

alexrainman commented 5 years ago

@tbaggett yes, version 2.7.2 has been out for a while and has become the standard replacement for the original one.

EnableUntrustedCertificates hasn't been removed, I just need figure it out why it is not working for you.

About the _ character, I have to see how I can provide a fix for that.

alexrainman commented 5 years ago

@tbaggett I cannot reproduce your exception related to the _ character in the hostname and, sadly, I don't have a server with that naming convention.

I cannot really find where your problem is.

Can you download the repo and run the Demo.Droid? Change the url to your server in MainViewModel in Demo library. Debug OkHttpNetworkHandler to find our where the problem is.

alexrainman commented 5 years ago

@tbaggett "Trust anchor for certification path not found." is fixed.

tbaggett commented 5 years ago

Thanks so much for investigating my issues and fixing the "trust anchor" one. I can provide further details on the _ character issue. I used the demo app in the repo to diagnose it yesterday. The exception is caught in the OkHttpNetworkHandler.OnFailure method. Here's the stacktrace:

{Javax.Net.Ssl.SSLHandshakeException: java.lang.IllegalArgumentException: Invalid input to toASCII: name_changed.forprivacy.com ---> Java.Security.Cert.CertificateException: java.lang.IllegalArgumentException: Invalid input to toASCII: name_changed.forprivacy.com ---> Java.Lang.IllegalArgumentException: Invalid input to toASCII: name_changed.forprivacy.com ---> Android.Icu.Text.StringPrepParseException: The input does not conform to the STD 3 ASCII rules --- End of inner exception stack trace --- --- End of inner exception stack trace --- --- End of inner exception stack trace --- --- End of managed Javax.Net.Ssl.SSLHandshakeException stack trace --- javax.net.ssl.SSLHandshakeException: java.lang.IllegalArgumentException: Invalid input to toASCII: name_changed.forprivacy.com at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361) at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:281) at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:251) at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:151) at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:195) at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121) at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135) at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) Caused by: java.security.cert.CertificateException: java.lang.IllegalArgumentException: Invalid input to toASCII: name_changed.forprivacy.com at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:617) at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357) ... 23 more Caused by: java.lang.IllegalArgumentException: Invalid input to toASCII: name_changed.forprivacy.com at java.net.IDN.toASCII(IDN.java:112) at javax.net.ssl.SNIHostName.(SNIHostName.java:99) at com.android.org.conscrypt.Platform.getSSLParameters(Platform.java:133) at com.android.org.conscrypt.OpenSSLSocketImpl.getSSLParameters(OpenSSLSocketImpl.java:1320) at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:302) at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)

There are differing online opinions on the validity of the underscore character in the host name, for example https://stackoverflow.com/questions/2180465/can-domain-name-subdomains-have-an-underscore-in-it and https://stackoverflow.com/questions/51563859/javax-net-ssl-sslhandshakeexception-java-lang-illegalargumentexception-invalid.

alexrainman commented 5 years ago

@tbaggett I cannot fix the _ issue. It is an internal bug in OkHttp3.

Take a look at this: https://stackoverflow.com/questions/51563859/javax-net-ssl-sslhandshakeexception-java-lang-illegalargumentexception-invalid

And this: https://github.com/square/retrofit/issues/2606