1

I'm writing simple notepad for android that sync data over internet with my server. I used https and free certificate from startssl and everything worked smooth. Later I added new virtualhost with it's own ssl certificate and my app suddenly stoped connscting to server. It throws:

javax.net.ssl.SSLException: hostname in certificate didn't match: <www.rapidnote.emendus.ovh> != <othersite.emendus.ovh> OR <othersite.emendus.ovh> OR <emendus.ovh>

It tries to verify totally different certificate from different apache virtual host. My apache config for rapidnote virtual host is:

<VirtualHost *:80>
  ServerName                rapidnote.emendus.ovh
  ServerAlias               www.rapidnote.emendus.ovh
  Redirect Permanent        /   https://www.rapidnote.emendus.ovh
</VirtualHost>

<VirtualHost *:443>
  ServerName                rapidnote.emendus.ovh
  DocumentRoot              /var/www/rapidnote
  SSLEngine                 on
  SSLCertificateFile        cert_location/rapidnote.emendus.ovh.crt
  SSLCertificateKeyFile     key_location/rapidnote.emendus.ovh.key
  SSLCertificateChainFile   cert_location/sub.class1.server.ca.pem
</VirtualHost>

<VirtualHost *:443>
  ServerName                www.rapidnote.emendus.ovh
  DocumentRoot              /var/www/rapidnote
  SSLEngine                 on
  SSLCertificateFile        cert_location/www.rapidnote.emendus.ovh.crt
  SSLCertificateKeyFile     key_location/www.rapidnote.emendus.ovh.key
  SSLCertificateChainFile   cert_location/sub.class1.server.ca.pem
</VirtualHost>

My code looks following:

HttpClient   httpClient = new DefaultHttpClient();
HttpPost     httpPost   = new HttpPost("https://www.rapidnote.emendus.ovh/" + paramScriptName);
HttpResponse response   = httpClient.execute(httpPost);

If i turn off othersite.emendus.ovh virtual host in apache, then SSLException message says:

<www.rapidnote.emendus.ovh> != <rapidnote.emendus.ovh> OR <rapidnote.emendus.ovh> OR <emendus.ovh> 

and if then I change "https://www.rapidnote.emendus.ovh/" to "https://rapidnote.emendus.ovh/", it starts to work. I checked both (www. and non www) certificates and common names in both are correct. I think it should verify a certificate for domain that I gave him in HttpPost constructor, not some other random cert from my server...

I used some testing website to verify my ssl configuration and it stated that it's all fine.

Everything happend on android 4.2.2 (API 17). I build app with min SDK 14 and target SDK API 20 Android 4.4 (KitKat Wear)

How can I tell him to verify correct cert, specified for this domain? Is the problem on site of application or apache?

hooknc
  • 4,854
  • 5
  • 31
  • 60
Dzarafata
  • 558
  • 3
  • 11
  • Why not redirect all :80 requests and the :443 www requests to a single 443 rapidnote.emendus.ovh address instead of trying to use a single SSL to cover multiple endpoints? – Matt T. Oct 20 '14 at 23:20
  • 1
    Because SSL verification happens before redirection, so it would fail and stop just at the begining. – Dzarafata Oct 21 '14 at 08:47

3 Answers3

5

Your server is configured to present distinct certificates using Server Name Indication (SNI).

As far as I know, the Apache HTTP Client version bundled with Android does not support SNI. You could try using HttpsURLConnection instead of HttpClient, this should support SNI in versions of Android that are not too old. There are more details in the answers to this question.

Note that you'll still need the certificate you present for a host name to be valid for that host name, i.e. it will need a Subject Alternative Name entry for that name (or the CN of the Subject DN would need to be that name if there are no DNS SANs). (Wildcards can also be used, if you have such a certificate.)

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
0

SSL Certificates are looked up by IP address not domain name.

Therefore, when checking a certificate the first entry is the one that wins, which in your case is: rapidnote.emendus.ovh

If you switched your entries around, the www.rapidnote.emendus.ovh entry would work and not the other.

I think there is a way to get the www and non www domain names to work on one certificate, but I can't remember the exact process, sorry. Hopefully, someone will fill in this detail and we'll both learn. I think some CA's will just give you both addresses, but again, I'm not sure how they make that certificate.

I would recommend looking into wildcard and universal communication certificates if you have to only use one IP address.

If you can have multiple IP addresses, then assign a different IP address to each url. But this does look like a production server since you're using 80/433 directly. This advice is not super recommended. I like having one IP address for both my www and non-www urls.

hooknc
  • 4,854
  • 5
  • 31
  • 60
  • I'm using SNI to have multiple CA on one IP, one for each domain name and it's working flawless with webbrowser, but like Bruno said, it seems that Android Apache HTTp Client do not support SNI. – Dzarafata Oct 21 '14 at 08:50
0

If your code is big and you prefer not to change the connection library, workaround is setting different ports for each VirtualHost. This fixed my problem.