Unable to connect to https://api.kucoin.com due to javax.net.ssl.SSLException: error:0A000410:SSL routines::sslv3 alert handshake failure
essessen1 opened this issue · 0 comments
Hi folks. I am not sure if this is the right place to raise this but I thought I would create an issue none the less. Please feel free to move it to the appropriate place or close it out if this is not an issue.
I was attempting to use the HttpClient provided by one nio but I was unable to get it to connect to https://api.kucoin.com
. The client works with other servers that I have tried with but for this one server, it fails. I tried with both one-nio-1.5.0.jar and the latest one-nio-1.6.1.jar. For 1.5.0, I used openssl1.1 and for 1.6.1, I used openssl3.0. I cloned the repo and built it myself and ensured that the libonenio.so object exists in the jar and then compiled it with my client code shown below.
import one.nio.http.HttpClient;
import one.nio.http.HttpException;
import one.nio.net.ConnectionString;
import one.nio.pool.PoolException;
import java.io.IOException;
public class MyHttpClient {
public HttpClient client;
public MyHttpClient(String hostPort) {
this.client = new HttpClient(new ConnectionString(hostPort));
}
public void syncGet(String path) {
try {
System.out.println(this.client.get(path));
} catch (InterruptedException | PoolException | IOException | HttpException e) {
throw new RuntimeException(e);
}
}
}
However, I always ran into the following error when attempting to connect to the server:
Testing Kucoin connection
Exception in thread "main" java.lang.RuntimeException: one.nio.pool.PoolException: SocketPool[api.kucoin.com:443] createObject failed: javax.net.ssl.SSLException: error:0A000410:SSL routines::sslv3 alert handshake failure
at util.http.MyHttpClient.syncGet(MyHttpClient.java:24)
From the error message, it looks like the issue might be with sslv3. It's possible that the server here doesn't support sslv3 but my question is why is one.nio/openssl using SSLV3 to connect to the server? I would have thought that it would use TLSv1.2. I tried to forcefully disable sslv3 in but was still unsuccessful. I modified ssl.c as shown below.
https://wiki.openssl.org/index.php/List_of_SSL_OP_Flags
src/one/nio/net/native/ssl.c
JNIEXPORT jlong JNICALL
Java_one_nio_net_NativeSslContext_ctxNew(JNIEnv* env, jclass cls) {
AppData* appData = create_app_data();
if (appData == NULL) {
throw_by_name(env, "javax/net/ssl/SSLException", "Cannot allocate SSL app data");
return 0;
}
SSL_CTX* ctx = SSL_CTX_new(TLS_method());
if (ctx == NULL) {
free_app_data(appData);
throw_ssl_exception(env);
return 0;
}
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
fprintf(stderr, "\nSetting options to disable compression and ssl v3\n");
unsigned long currOptions = SSL_CTX_get_options(ctx);
fprintf(stderr, "\nCurrent options(pre set): %d\n", currOptions);
SSL_CTX_clear_options(ctx, currOptions); // Disable TLSv1.3 compat mode.
currOptions = SSL_CTX_get_options(ctx);
fprintf(stderr, "\nCurrent options(post clear): %d\n", currOptions);
currOptions |= SSL_OP_BIT(17); // Disable compression.
currOptions |= SSL_OP_BIT(25); // Disable SSL V3.
currOptions |= SSL_OP_BIT(29); // Disable TLSv1.3
SSL_CTX_set_options(ctx, currOptions);
fprintf(stderr, "\nCurrent options(post set): %d\n", SSL_CTX_get_options(ctx));
fprintf(stderr, "\nSuccessfully set options to disable compression and ssl v3\n");
// Disable read-ahead until premature socket close is fixed
// SSL_CTX_set_read_ahead(ctx, 1);
SSL_CTX_set_info_callback(ctx, ssl_info_callback);
SSL_CTX_set_app_data(ctx, appData);
setup_dh_params(ctx);
setup_ecdh_params(ctx);
return (jlong)(intptr_t)ctx;
}
The output looks as follows:
Testing Kucoin connection
Setting options to disable compression and ssl v3
Current options(pre set): 1179648
Current options(post clear): 0
Current options(post set): 570556416
Successfully set options to disable compression and ssl v3
Exception in thread "main" java.lang.RuntimeException: one.nio.pool.PoolException: SocketPool[api.kucoin.com:443] createObject failed: javax.net.ssl.SSLException: error:0A000410:SSL routines::sslv3 alert handshake failure
at util.http.MyHttpClient.syncGet(MyHttpClient.java:24)
570556416 === 0b100010000000100000000000000000
(17th, 25th and 29th bit are set)
[ubuntu@ip-10-20-82-90 ~]$ openssl s_client -connect api.kucoin.com:443 -tls1_2
CONNECTED(00000003)
depth=1 C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = kucoin.com
verify return:1
....
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2746 bytes and written 296 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.2, Cipher is ECDHE-ECDSA-CHACHA20-POLY1305
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-ECDSA-CHACHA20-POLY1305
I would be really grateful if someone can help me out with this. Please do let me know if this is a known issue which has workarounds. I went through the issues posted previously but was unable to find any that matched this.