square / okhttp

Square’s meticulous HTTP client for the JVM, Android, and GraalVM.
https://square.github.io/okhttp/
Apache License 2.0
45.85k stars 9.16k forks source link

Hostname cannot be verified in case SSL certificate is issued for IP address #1467

Closed mnasyrov closed 8 years ago

mnasyrov commented 9 years ago

OkHttp v2.2.0.

Following exception happens when OkHttp tries to connect to a server using IP address:

Caused by: java.io.IOException: Hostname 192.168.1.1 not verified:
    certificate: sha1/5iMPVYXxMn4eoyIuLZCZPWL6myM=
    DN: CN=192.168.1.1
    subjectAltNames: []
    at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:260)
    at com.squareup.okhttp.Connection.connect(Connection.java:158)
    at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:174)
    at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
    at com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:131)
    at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:312)
    at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:235)
    at com.squareup.okhttp.Call.getResponse(Call.java:262)
    at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:219)
    at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:192)
    at com.squareup.okhttp.Call.execute(Call.java:79)
    at retrofit.client.OkClient.execute(OkClient.java:53)
    at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
    ... 67 common frames omitted

A server has a self-signed SSL certificate which was generated for server's IP addresses using following commands:

$ openssl req -x509 -newkey rsa:2048 -keyout server.key.pem -out server.cert.pem -days 365 -subj /CN=192.168.1.1
$ openssl rsa -in server.key.pem -out server.key.pem

As I see in current source codes, OkHostnameVerifier class tries to verify a hostname using only IP addresses in "alternate names" section of SSL certificate. I think it must try to verify a hostname using CN records before.

swankjesse commented 9 years ago

Pull requests welcome on this. They should include a test!

ilansas commented 8 years ago

+1 on this, any news ?

swankjesse commented 8 years ago

Pull requests welcome on this. They should include a test!

wzpan commented 8 years ago

+1

wzpan commented 8 years ago

So far I have to escape verifying via providing a super-permissive host verifier:

this.client.setHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        //TODO: Make this more restrictive
        return true;
    }
});
swankjesse commented 8 years ago

https://wiki.mozilla.org/CA:Problematic_Practices#Certificates_referencing_hostnames_or_private_IP_addresses

“It is not standards compliant for printable ASCII representations of IP addresses to be placed in any certificate field that is intended to hold DNS names, including the subject common name and the DNSName field of the Subject Alternative Names extension. There is a place in a certificate specifically intended to be where IP (v4 or v6) addresses may be placed. It is in the Subject Alternative Names extension. The SubjectAltNames extension has places for both additional DNS names and for IP addresses. The place for IP addresses takes them in binary form, not in printable ASCII (e.g. dotted decimal) form.”

ali-bagheri commented 6 years ago

Hi.

Please note SSL Certificate work only by Domain not work by IP address.

if you use IP ,insert below code

```

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { if(hostname.equals("127.0.0.1 your IP")) return true; } });

SaeedZhiany commented 6 years ago

@swankjesse

I tried binary form of my IP address

[ alternate_names ]
IP=11000000101010000111100100100011

but when I run following command:

openssl req -new -newkey rsa:2048 -nodes -keyout a.key -out a.csr -config C:\Apache24\conf\openssl.cnf

I got this error:

Error Loading extension section v3_ca
5020:error:22075076:X509 V3 routines:v2i_GENERAL_NAME_ex:bad ip address:.\crypto\x509v3\v3_alt.c:483:value=11000000101010000111100100100011
5020:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:.\crypto\x509v3\v3_conf.c:93:name=subjectAltName, value=@alternate_names

I haven't host name at all and I have to work with IP address.

@ali-bagheri 's solution seems Ok but it has a problem, I have to hard code IP address in my code. I prefer that use a better solution, if exists any one.

SaeedZhiany commented 6 years ago

I also tried create certificate using following config:

[ alternate_names ]

DNS=192.168.121.35

but same error log...

W/System.err: javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.121.35 not verified:
                  certificate: sha256/m9FP8M+x6TG02BC0wdGHC6ejPGc1/PQY0bJ28fgHueg=
W/System.err:     DN: CN=192.168.121.35,OU=Moein,O=Moein,L=Tehran,ST=Tehran,C=IR
                  subjectAltNames: []

subjectAltNames does not contains my IP address.