1

I am using java 1.6.0_111 which doesn't support tlsv1.2, but my server only accepts tlsv1.2, So I tried with bouncycastle provider but still it is not working it throwing the connection reset error. even though i increased connecttimeout to 30000 it still getting error at conn.getoutputstream.

Below is my code:

Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
Security.insertProviderAt(new BouncyCastleProvider(), 1);

Security.removeProvider(BouncyCastleJsseProvider.PROVIDER_NAME);
Security.insertProviderAt(new BouncyCastleJsseProvider(), 2);

SSLContext sslContext = SSLContext.getInstance("TLSv1.2", new BouncyCastleJsseProvider());

log("The Supported Protocols are::"+Arrays.asList(protocols));

/*sslContext.init(null, tmf.getTrustManagers(), null);
SSLContext.setDefault(sslContext);;*/
String https_url ="myprodurl";
String json = mattArray.toString().trim();
URL url = new URL(https_url);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
log("after opening connection");
conn.setConnectTimeout(30000);
log("step1");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
log("step2");
OutputStream os = conn.getOutputStream();
log("step3");
os.write(json.getBytes("UTF-8"));
log("step4");
os.close();
log("after closing outputstream");
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = IOUtils.toString(in, "UTF-8");
log("Result after Reading JSON Response\n\n");
log(response);

The error I got:

2020-02-04 21:00:42,386 [system] [DEBUG] test - ERROR2 :java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:168)
    at com.ibm.jsse2.a.a(a.java:148)
    at com.ibm.jsse2.a.a(a.java:96)
    at com.ibm.jsse2.tc.a(tc.java:302)
    at com.ibm.jsse2.tc.g(tc.java:208)
    at com.ibm.jsse2.tc.a(tc.java:482)
    at com.ibm.jsse2.tc.startHandshake(tc.java:597)
    at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:44)
    at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:36)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
    at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:66)
David Buck
  • 3,752
  • 35
  • 31
  • 35
Bharath
  • 81
  • 1
  • 11
  • 1
    (1) reset and timeout are completely different and unrelated things (2) the stacktrace makes clear you aren't actually using the BC implementation, even though you put it in the provider list; check if any other (previous) code sets the `SSLContext` default _or_ the `HttpsURLConnection` default factory -- and/or uncomment the setting of `SSLContext` default here or substitute a setting of either default or instance factory for `HttpsURLConnection` – dave_thompson_085 Feb 05 '20 at 07:57
  • Please help by providing modification to above code which works – Bharath Feb 05 '20 at 10:24

1 Answers1

0

I can't test IBM j6, but with Sun/Oracle j6 (6u45, last free release) which has the same limitation to TLS1.0, your method of setting the providerlist works for me given I have no other code changing the defaults, and so does explicitly setting either the SSLContext default, the HttpsURLConnection default, or the connection instance, as I said. The latter three do need bcprov in the provider list if the server wants to use ECC, as many servers today do, because Sun j6 didn't have an ECC provider; I'm not sure about IBM j6. For my test server I can use my default truststore (because I have previously set my default truststore to handle my test servers); this may differ for you. OTOH I have to use an explicit not default random source or I get mysterious errors.

My test code for these four methods (with option to include bcprov in latter three) is:

static void SO60068561BouncyTLS (String[] args) throws Exception {
    String url = args[0];
    int n = Integer.parseInt (args[1]);
    Provider p1 = (Provider)Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider").newInstance();
    Provider p2 = (Provider)Class.forName("org.bouncycastle.jsse.provider.BouncyCastleJsseProvider").newInstance();
    SSLContext ctx = null;
    if( n == 1 ){ Security.insertProviderAt(p1, 1); Security.insertProviderAt(p2, 2); }
    else{ ctx = SSLContext.getInstance("TLSv1.2", p2); ctx.init(null, null, new SecureRandom()); }
    if( n < 0 ){ Security.addProvider(p1); n = -n; }

    if( n == 2 ) SSLContext.setDefault (ctx);
    else if( n == 3 ) HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
    HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
    if( n == 4 ) conn.setSSLSocketFactory(ctx.getSocketFactory());
    conn.connect();
    System.out.println (conn.getCipherSuite()+" "+conn.getResponseCode());
}
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • I didn't understand what is "n" value – Bharath Feb 12 '20 at 14:33
  • As I said there are four methods of doing this, with a variation on three of them. `n` is a number supplied as input to the program -- specifically, via `args[1]` -- which controls which of these methods is executed, so I need only one program instead of seven. – dave_thompson_085 Feb 14 '20 at 01:12