It's basically what the title says, the ciphers ain't supported in jruby-openssl
, and I've got a production issue. I need one of these:
ECDHE-RSA-AES256-GCM-SHA384 TLS1.2
ECDHE-RSA-AES256-SHA384 TLS1.2
ECDHE-RSA-AES256-CBC-SHA TLS1.2
ECDHE-ECDSA-AES256-SHA384 TLS1.2
ECDHE-ECDSA-AES256-SHA TLS1.2
ECDH-RSA-AES256-SHA384 TLS1.2
ECDH-ECDSA-AES256-SHA384 TLS1.2
ECDH-RSA-AES256-SHA TLS1.2
ECDH-ECDSA-AES256-SHA TLS1.2
from all of these - 1 is supported by the MRI Ruby AES256-SHA256 (according to OpenSSL nomenclature), but MRI Ruby is not an option. Yet.
The basic script I've been playing with is:
uri = URI.parse(ds_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :"TLSv1_2"
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # OpenSSL::SSL::VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE
http.cert = client_cert
http.key = client_key
http.ca_file = ds_cert_file
http.ciphers = OpenSSL::SSL::SSLContext.new.ciphers.map do |c|
c[0].gsub("-", "+")
end
puts http.ciphers.inspect
resp = http.post(uri.request_uri, http_body, 'Content-Type' => 'application/xml; charset=utf-8')
resp.body
but it simply results in a 'socket closed' error, only playing with a variation of this amazing one-liner I managed to pinpoint the issue - lack of compatible ciphers.
Since the Manticore HTTP client for JRuby seemingly utilizes a different crypto adapter to BouncyCastle
I tried that one too, but this one just started dragging me into a wormhole of funny Java errors such as
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
The code for the manticore implementation is similar:
client = Manticore::Client.new(socket_timeout: 5, ssl: {
ca_file: "ca.pem",
client_cert: 'cert.pem',
client_key: 'key.pem'
}) do |http_client_builder, request_builder|
binding.pry
end
rv = client.post(ds_url)
rv.body
and it results with the aforementioned error, then things get hotter with a:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
and at that point I gave up on this approach, for now. Manticore does open up some apis to let you play with org.apache.http.impl.client.HttpClientBuilder
but the Java-fu quickly makes my eyes turn watery.
At this point, I'm even tempted to follow the gloryhole of "calling Java from JRuby", learning about the eco-system of Java HTTP libs and all that, but this isn't really my forte and I'm strapped for time.
Is there a kind & knowledgeable soul who can help? I'm looking for one of these:
In the end, after much research and chagrin, we wrote a Java library that sends the HTTP requests and exposed the relevant arguments for this particular use case. Writing Java for JRuby is typically the worst of both worlds, but in this case - the requirements being so simple - it was quite painless.
Here's how things look in the end ruby-side:
java_import "com.mycompany.http.HttpClient"
java_import "com.mycompany.http.SSLOptions"
#
# ...
#
ssl_options = SSLOptions.createFromStrings client_cert, client_key, ca_cert
rv = HttpClient.create(url, ssl_options, 60000, "changeit", "changeit").send(request)
if rv.responseSuccess
# log.merge(response: rv.responseSuccess.payload)
rv.responseSuccess.payload
else
raise rv.responseFailure.cause
end