OpenSSL error from ruby script - ruby

SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert handshake failure (OpenSSL::SSL::SSLError)
This error is a pretty common one to anyone using ruby on windows.
For me, the solution has always been this. It has worked great on any computer I have put it on and I've loved it.
Just this week it stopped working. Has anyone else had this happen?
I've tried getting the cert from curl again just in case the cert was no longer valid. I tried removing and adding the environmental I use mechanize and tried to reference it as suggested here.
I've also tried going to different urls, "https://google.com" and others, for example.
Nothing so far. Anyone have a better solution for this? It has happened on all windows computers that I have this cert referenced this way.

Your problem seems to be different to the one you linked to. There it failed to verify the certificate returned by the server. Here it erros earlier when it reads the server hello. Do you have any more debug information eg stacktrace or a pcap of the interaction?
A (highly) speculative explanation is that you sent an sslv2 compatible client hello and the server returned an ssl alert as it will only accept sslv3/tls format client hello

Related

Hostname does not match the server certificate - using old expired certificate

I am trying to connect via TCP socket to an old, unmaintained game server. When I try to do so using OpenSSL and Socketry, I get following error.
hostname "xxx" does not match the server certificate
This is how my code works.
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
ssl_context.ciphers = "AES128-SHA"
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("certificate.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("certificate.key"))
socket = Socketry::SSL::Socket.new(ssl_context: ssl_context)
socket.connect(address, port)
I've had to force cipher to AES128-SHA, as otherwise I would get a different error.
SSL_connect returned=1 errno=0 state=error: dh key too small (OpenSSL::SSL::SSLError)
How can I bypass these errors and just force connection to said server? The certificate itself has expired 10 years ago.
Socketry doesn't include much documentation about this, so you need to turn to the source. Depending on exactly what you're trying to do, you might try one of the following:
Passing verify_hostname: false to Socket#connect.
Rescuing Socketry::SSL::HostnameError yourself.
Rescuing Socketry::SSL::CertificateVerifyError.
At least one of these ought to address your specific issue. If not, the source offers other places you might monkey-patch or refine for your use case.

read tcp [addr]->[addr] use of closed network connection

I'm using Google's simplehttp2server go-lang program to run some tests and have encountered a recurring error. Upon executing the TLS handshake I receive the following error:
2019/12/12 12:42:55 http: TLS handshake error from 127.0.0.1:36202: read tcp 127.0.0.1:5000->127.0.0.1:36202: use of closed network connection
I have updated my go version to 1.13.5 from 1.12.9 and tried two browsers (brave + chrome) plus curl and receive the same error code each time. It happens over HTTP/2 and HTTP/1.1. I have seem other answers from across the web but am still running into this error (ex1, ex2, ex3, ex4).
Very much appreciate any feedback, advice, or admonishment. Anything to help the migraine this problem is giving me!
edit: screenshot from my curl and running of simplehttp2server
example image from curl and simplehttp2server
This error happens when you have two websockets connected to a singular address using the same port from the same machine. One of the websockets will be able to connect fine but the other wont be able to make the connection.
I was making the same mistake and when I removed the duplicate connection the error resolved.

Faraday with net-http-persistent leaves connections open, resulting in "Errno::EMFILE: Too many open files"

We have a process (Rake task) that runs for a long period of time, making HTTPS requests to remote hosts using Faraday with the net_http_persistent adapter. After several hours to days of runtime, it stops making requests.
The process is also making some requests using Excon (to report exceptions to our exception-reporting service), and both HTTP clients are logging the same error, with slight difference in wording. The two errors are:
Faraday::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=error: certificate verify failed
Excon::Error::Certificate: SSL_connect SYSCALL returned=5 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError) Unable to verify certificate. This may be an issue with the remote host or with Excon. Excon has certificates bundled, but these can be customized:
Our exception-reporting service is failing to receive any of these exceptions. So we only found these errors in the log.
In order to reproduce this issue, I ran a loop of Faraday requests until it failed. What I found is that while the exception raised was Faraday::SSLError, once I tried to perform any other action in the REPL that required the opening of a file, it raised Errno::EMFILE: Too many open files.
Finally I had my clue. The red herring was caused by the OpenSSL library catching the EMFILE system error, and instead raising a general SSL connection failure. Both Faraday and Excon (used by the exception-reporting tool) did this, making it impossible to see the real problem.
The underlying problem was that the process had reached the limit of open files. This was caused by the way that net-http-persistent keeps connections open until instructed to shut down combined with the fact that Faraday has no mechanism to instruct its adapter to shut down.
The solution was switching from net-http-persistent to Excon, which supports persistent connections as long as it's configured to do so:
Faraday.new(url: url) do |faraday|
faraday.adapter :excon, persistent: true
end

SSL mode flags - verification of certificates: is it safe to use :none?

I am writing a soap request over SSL using Savon and HTTPi, a Ruby soap client and an interface for Ruby HTTP clients, respectively. Here's the code:
client = Savon::Client.new(original_class.constantize.wsdl_url)
client.http.auth.ssl.cert_key_file = "path_to_the_key"
client.http.auth.ssl.cert_key_password = 'secret'
client.http.auth.ssl.cert_file = "path_to_the_certification"
client.http.auth.ssl.verify_mode = :none
#response = client.request :ins0, action do
soap.body = encoded_body
end
That's the only way I get this to work. But, I know that there is three others verify modes, which are:
:peer (SSL_VERIFY_PEER)
:fail_if_no_peer_cert (SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
:client_once (SSL_VERIFY_CLIENT_ONCE)
If I change the verify mode to any other of the above, I get this error:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Then comes my questions (among others I have):
Am I doing wrong if I keep the verify mode to :none? Is there any lack of security?
What does the error really mean? That my code is wrong or that my certificate (which is self-assigned --- I am in development environment) is not good?
I read the OpenSSL documentation about verify modes:
http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
About SSL_VERIFY_NONE, on Client Mode, says:
The result of the certificate verification process can be checked
after the TLS/SSL handshake using the SSL_get_verify_result(3)
function. The handshake will be continued regardless of the
verification result.
Should I be worried about it? Should I see verify mode :none as a dangerous thing?
I am asking that because since I can't make it work with the others verify modes, I would like to release the soap request over SSL feature the way it is working now. But I surely wouldn't do it if that could be dangerous.
It is NOT safe to set verify mode to :none (SSL_VERIFY_NONE). This opens up the code to being susceptible to man-in-the-middle attacks. With :none, there will be not server authentication. If an attacker intercepts the connection from my client, my client will not detect the difference and will give any sensitive data communicated through this socket to the attacker.
The mode flags :fail_if_not_peer_cert and :client_once are only for a server; meaning nothing to the client, it ignores them.
For client purpose, :peer (SSL_VERIFY_PEER) is the only one the matters. In order to use :peer, I need to have the root certificate used by the certificate in the client trustedstore.
A big thanks to Dave Thompson from OpenSSL User Support Mailing List. After I joined this list, I finally got help.

Google TV Pairing Protocol -- SSL Handshake Error with Go (golang)

I'm writing a Go package for the Google TV Pairing Protocol. But I seem to be hitting a problem with the TLS handshake.
sock, err := tls.Dial("tcp", "10.8.0.1:9552", &tls.Config{InsecureSkipVerify: true})
That line gives me a handshake error. The exact error message is: remote error: handshake failure. If I try the same host/port via curl, it gives curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure as well.
Any ideas? Is the Google TV expecting a client cert maybe? I haven't seen any references to the need for a client cert anywhere.
If anyone wants to help figure it out, here's the code:
https://github.com/dustywilson/go-polo
The README file has the easy code to check it out. You will have to know the IP address for your Google TV box since this doesn't use mDNS. If you (someone, anyone) run this and you get different results, let me know.
I've already gone through the Google TV Remote code at google-tv-remote. A more useful one is google-tv-pairing-protocol which is the equivalent Java/Android project to what I'm doing. Of course I've already poured over that code. I think it's a problem either with Go itself (unlikely), a problem with the Go TLS package not knowing how to read the Google TV's certificate (I know it was a problem a year ago), or a problem with my code (typically would be most likely, but I'm just not seeing it).
By the way, I'm testing this on a Logitech Revue and it has a self-signed SSL certificate. It's not rooted or modified in any way.
My resulting code will be open source, of course. Thanks for the assistance.
Client certs are generated by the Java remote client at runtime, and stored for future use. Check out the code at:
http://code.google.com/p/google-tv-remote/source/browse/src/com/google/android/apps/tvremote/KeyStoreManager.java
You might be running into an invalid cert. According to the code, you need a specific CN.
/* Returns the name that should be used in a new certificate.
* The format is: "CN=anymote/PRODUCT/DEVICE/MODEL/unique identifier"
*/

Resources