0

I had a perfectly working oauth with a self-signed client certificate, until suddenly it stopped working. I get SocketException: Connection Reset. According to Xero, the API that I'm integrating with, everything is ok on their side now, but they did have SSL problem one week ago.

Since the last time it worked we moved to Java 8, which I rolledback for this test. Initially I had it working with this oauth project, because it was the only one that would, kind of, support self-signed client certificates. Today I hacked Scribe a bit, in order to add the certificate to the request. When I finally got it working, I got the same exception again.

The certificate that I have is in a KeyStore (.p12), which I exported into my java cacerts. This step should not be needed though, since it was working without it.

So, this is how I create the SSLContext that is injected in the HttpClient (in the oauth project) and in the HttpsUrlConnection (in Scribe).

Set<KeyManager> keymanagers = new HashSet<KeyManager>();
final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
    KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(entrustStore, password.toCharArray());
final KeyManager[] kms = kmfactory.getKeyManagers();
if (kms != null) {
    for (final KeyManager km : kms) {
        keymanagers.add(km);
    }
}

// TrustManagerFactory tmf =
//     TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// tmf.init(keyStore);

SSLContext sslContext = SSLContext.getInstance(SSLSocketFactory.TLS);
sslContext.init(
    keymanagers.toArray(new KeyManager[keymanagers.size()]),
    null, // tmf.getTrustManagers()
    null);


// in the oauth project
SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
Scheme scheme = new Scheme("https", 443, socketFactory);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(scheme);
BasicClientConnectionManager cm = 
    new BasicClientConnectionManager(schemeRegistry);
httpClient = new DefaultHttpClient(cm);

// ---------------------------------

// in Scribe
HttpsURLConnection connection = 
    (HttpsURLConnection) new URL(completeUrl).openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());

I suspect this is the code that might be causing the exception, since this is the only common part between both implementations.

Oliveira
  • 1,281
  • 1
  • 11
  • 19

1 Answers1

1

The issue was related to TLS version after all. Using TLSv1.1 did the trick.

Oliveira
  • 1,281
  • 1
  • 11
  • 19
  • I have a concern, since i'm facing the same problem using TLSv1.1 you mean to say changing the Java Config properties – Santosh Giri Jul 17 '15 at 06:11
  • The api that I was integrating with dropped the support to TLSv1.2, so I had to force my client to use v1.1. You can find my solution here: http://stackoverflow.com/questions/28391798/how-to-set-tls-version-on-apache-httpclient/31294623#31294623 – Oliveira Jul 19 '15 at 18:37
  • Can you please post the changes you did with scribe? I am modifying the Response.java but still having the same problem. Xero is still telling me that i need a certificate. – Sebb77 Sep 24 '15 at 15:05
  • I'm not using Scribe. Unfortunately, by the time I implemented it, Scribe didn't support self signed certificates. I did, however got it working with Scribe, some time later, but never really released it to production. I remember what I had to do was to override a couple of methods in a request object, in Scribe, and inject the certificate into the http client. However, since the methods were package protected my override class had to be in the same package, making the whole thing just a big hack that I didn't like. But some time went by and maybe Scribe fixed it. – Oliveira Sep 26 '15 at 09:32