I'm using HttpClient on Android to connect to https://someUrl.com/somePath. The problem is that the site's certificate is for *.someUrl.com, not someUrl.com, so I get an SSLException. Lame on the part of the site, yes, but unless I can get it fixed, I'm stuck. Is there a way I can get HttpClient to relax and accept the certificate?
Asked
Active
Viewed 2.7k times
4 Answers
33
This is my (edited) solution:
class MyVerifier extends AbstractVerifier {
private final X509HostnameVerifier delegate;
public MyVerifier(final X509HostnameVerifier delegate) {
this.delegate = delegate;
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts)
throws SSLException {
boolean ok = false;
try {
delegate.verify(host, cns, subjectAlts);
} catch (SSLException e) {
for (String cn : cns) {
if (cn.startsWith("*.")) {
try {
delegate.verify(host, new String[] {
cn.substring(2) }, subjectAlts);
ok = true;
} catch (Exception e1) { }
}
}
if(!ok) throw e;
}
}
}
public DefaultHttpClient getTolerantClient() {
DefaultHttpClient client = new DefaultHttpClient();
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) client
.getConnectionManager().getSchemeRegistry().getScheme("https")
.getSocketFactory();
final X509HostnameVerifier delegate = sslSocketFactory.getHostnameVerifier();
if(!(delegate instanceof MyVerifier)) {
sslSocketFactory.setHostnameVerifier(new MyVerifier(delegate));
}
return client;
}
It has the advantage of not changing the default behavior unless there is a wildcard domain, and in that case it revalidates as though the 2 part domain (e.g., someUrl.com) were part of the certificate, otherwise the original exception is rethrown. That means truly invalid certs will still fail.

noah
- 21,289
- 17
- 64
- 88
-
I tried using the above, but sometimes get stack overflow exceptions - the verify() method never stops recursing. Out of a few hundred thousand installs, it happens about 80 times a week. Have you seen any issues with this? – user291701 Oct 28 '10 at 15:32
-
@user291701 I've edited the code to try and work around your problem. I would guess the problem is that you end up setting the verifier on the same factory again, so it ends up delegating to itself somehow... Feel free to edit my answer if you find a better way. – noah Nov 02 '10 at 13:41
-
In any case, I am facing `the server cannot service the request because the media type is unsupported`' error. Not getting any clue about the reason for this. – Jibran Khan Apr 05 '16 at 13:07
3
The BouncyCastle on Android is too old and it doesn't recognize wildcard certificate.
You can write your own X509TrustManager to check for wildcard.
or you can disable certificate check altogether if you can accept the risk. See this question,
-
Actually ZZ, if the OP is correct about the name of the site and the structure of the certificate, then the error message is correct: **.someUrl.com* is supposed to match www.someUrl.com and anything.someUrl.com, but *not* someUrl.com or this.that.someUrl.com. – President James K. Polk Jun 29 '10 at 00:00
1
If it wants *.someUrl.com
, then it seems like you could just give it www.someUrl.com/somePath
instead of someUrl.com/somePath
.

Melody Horn
- 778
- 2
- 6
- 22
-
1
-
I suppose that's useless, then. Do you really need https? I would guess so, but that would make life a lot easier. – Melody Horn Jun 28 '10 at 20:16
-
This is a great temporary solution when the site does NOT do a redirect! – Micah Hainline Apr 17 '12 at 13:12