Net::HTTP SSL_CTX_set_cipher_list: no cipher match - ruby

I'm using ActiveResource to proxy a CRUD endpoint, but getting no cipher match errors when trying to connect. I have tried everything from explicitly setting the SSL version, to upgrading my local openssl client to setting the cipher list directly.
I wish I could provide more information, but I know the exception is raised here and that it throws a SSL_CTX_set_cipher_list: no cipher match error.
Do you know why I'm getting this error and how to fix?
Here is the connection information from Chrome:
Your connection to domain.com is encrypted with 128-bit encryption.
The connection uses TLS 1.0.
The connection is encrypted using AES_128_CBC, with SHA1 for message authentication and RSA as the key exchange mechanism.
The server does not support the TLS renegotiation extension.
Update
I ran the following command in terminal with openSSL to check the connection:
openssl s_client -showcerts -connect stage.example.com:13902
Here was the output:
CONNECTED(00000003)
140735228511072:error:140773F2:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert unexpected message:s23_clnt.c:762:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 308 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
Not exactly sure what that means. Chrome can parse the certificate just fine. Is this a bug with OpenSSL?

Related

Self-signed SSL cert works in IE & curl but no modern browsers

I'm experiencing a somewhat perplexing issue with a self-signed SSL certificate that Windows recognizes as valid, but which no modern browsers will accept.
The certificate is present in the system certificate store (accessed via the Certificates snap-in in MMC), within both the Personal and Trusted Root Certification Authorities folders, and marked as valid.
Per the utility SSL Certificate Verifier, the certificate and certificate chain are valid.
Here is its output:
**************************************************************************
Processing 'localhost'
**************************************************************************
Scan started: 21-09-2020 13:43:33
Generating connection string...
Connection string is: https://localhost:14006/
Entering certificate validation callback function...
Server returned 1 certificates.
Entering server certificate chain validation function...
Leaf certificate issued to: E=REDACTED, CN=localhost, O=localhost, L=New York, S=NY, C=US
Found Subject Alternative Names extension in the certificate.
Fetching SAN values:
DNS Name=localhost
DNS Name=127.0.0.1
DNS Name=::1
IP Address=0000:0000:0000:0000:0000:0000:0000:0001
IP Address=127.0.0.1
Certificate chain successfully passed all checks.
Finished!
Scan ended: 21-09-2020 13:43:33
If I attempt to access the service using Internet Explorer or curl, I get the expected 200 result from the service.
However, if I try to access the service using Edge, Chrome, Opera, or Firefox, I get ERR_CONNECTION_RESET. Before adding the certificate to Firefox's certificate store, I got PR_CONNECT_RESET_ERROR but now that also throws ERR_CONNECTION_RESET.
There are no proxies or VPNs active on my system or anything else that would interfere with Windows' networking. I'm at a complete loss. What on earth is happening here and how do I go about fixing it?
I had exactly the same symptoms - IE and curl working. Chrome, Edge and Firefox not, all reporting ERR_CONNECTION_RESET.
Ultimately it was pinned down to a corrupt HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002\Functions key.
nmap reported a single cipher in use when it was broken:
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (ecdh_x25519) - A
Reloaded the key with a correct value:
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp384r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp384r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (ecdh_x25519) - A
The absence of the GCM ciphers is the likely cause, given Chromium was reporting them as obsolete five years ago.
I had a similar problem on chrome where it said
NET::ERR_CERT_COMMON_NAME_INVALID
, turns out the error was with the certificate itself.
Try the to create a certificate with the below link:
SSL Certificate

'wrong version number (OpenSSL::SSL::SSLError)' in simple Ruby SSL client

I am writing a simple SSL client for pentester lab bootcamp module 4. I enabled SSL for the virtualhost and enabled the module. The SSL client is written in Ruby and when running the script I get the following error:
Traceback (most recent call last):
6: from 4-http_ssl.rb:8:in <main>
5: from /usr/lib/ruby/2.5.0/net/http.rb:1458:in request
4: from /usr/lib/ruby/2.5.0/net/http.rb:909:in start
3: from /usr/lib/ruby/2.5.0/net/http.rb:920:in do_start
2: from /usr/lib/ruby/2.5.0/net/http.rb:985:in connect
1: from /usr/lib/ruby/2.5.0/net/protocol.rb:44:in ssl_socket_connect
/usr/lib/ruby/2.5.0/net/protocol.rb:44:in connect_nonblock: SSL_connect returned=1 errno=0
state=error: wrong version number (OpenSSL::SSL::SSLError)
Here is my script
require "net/https"
require "uri"
http = Net::HTTP.new("vulnerable", 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(Net::HTTP::Get.new("/"))
response.code
response.body
response.status
Can someone throw me a line here? I've checked the example and the server files but can't find the error. This seems like shouldn't be much trouble. Am I missing some configuration steps?
As pointed out by Steffen Ullrich, I tried to run
openssl> s_client
and got the following output:
Openssl> s_client -connect vulnerable:443
CONNECTED(00000003)
140093579711616:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:332:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 293 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
error in s_client
What steps should I follow? I understand the server is not accepting SSL connections because of missing CA certificates, how can I fix this I know I can create a custom CA certificate for my ssl client any leads on this? Thanks in advance

Net:HTTP SSL negotiation timeout on Ubuntu 14.04

After a long day I managed to get to the bottom of what I believe is a SSL/TLS cipher negotiation issue with a server that doesn't support the latest and greatest versions.
Stack:
Ubuntu 14.04 fully patched
OpenSSL 1.0.1f 6 Jan 2014
irb 0.9.6(09/06/30)
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux] (using rbenv)
After 60 seconds the snippet below gives me an error:
require 'net/http'
require 'openssl'
uri = URI.parse('https://some_old_server/my/path')
http = Net::HTTP.new('some_old_server', 443)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true
response = http.request(Net::HTTP::Get.new(uri.request_uri))
Errno::ECONNRESET: Connection reset by peer - SSL_connect
If I add this to the code, it works:
(...)
http.ciphers = ['AES128-SHA']
(...)
=> #<Net::HTTPOK 200 OK readbody=true>
This isn't a ruby-specific issue but ideally there's a ruby solution. I can't lock the ciphers to 'AES128-SHA' because the same code handles a number of sites that may or may not support this cipher.
Has anyone ever come across this and found a generic solution?
EDIT: this seems to be caused by the "TLS hang bug" and was fixed in openssl 1.0.1g.
New question: is there a work-around that can be implemented on the ruby side?
More information.
A Gentoo server running OpenSSL 1.0.1j 15 Oct 2014 doesn't have this issue. I tried installing 1.0.1j on the Ubuntu 14.04 server, recompiling ruby (rbenv install 2.2.2) and the error was still present.
I've tried to monkey patch ext/openssl but that didn't work.
Using the whole cipher list from the link above doesn't work. However, using a small subset does work:
require 'net/http'
require 'openssl'
uri = URI.parse('https://some_old_server/my/path')
http = Net::HTTP.new('some_old_server', 443)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true
http.ciphers = %w{
AES128-GCM-SHA256
AES256-GCM-SHA384
AES128-SHA256
AES256-SHA256
AES128-SHA
AES256-SHA
ECDHE-ECDSA-RC4-SHA
ECDHE-RSA-RC4-SHA
RC4-SHA
}.join(":")
response = http.request(Net::HTTP::Get.new(uri.request_uri))
Openssl agrees with ruby (as it should). Running these, on the same system, replicates the issue as I see them in ruby:
openssl s_client -connect some_old_server:443
CONNECTED(00000003)
(...)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 295 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
Passing the cipher:
openssl s_client -cipher AES128-SHA -connect some_old_server:443
CONNECTED(00000003)
(...)
---
No client certificate CA names sent
---
SSL handshake has read 2721 bytes and written 425 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: removed
Session-ID-ctx:
Master-Key: removed
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1454394952
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---
I read somewhere to use
http.ssl_options = OpenSSL::SSL::OP_ALL
but ssl_options isn't available in Net::HTTP on ruby 2.2.2.
After spending more time on this than I'd care to admit, my solution was to upgrade from Ubuntu 14.04 to 15.10 which comes with OpenSSL 1.0.2d 9 Jul 2015.
While the TLS negotiation still hangs using the openssl CLI, in Ruby it does not:
require 'net/http'
require 'openssl'
require 'pp'
uri = URI.parse('https://broken_server/my/path')
http = Net::HTTP.new('broken_server', 443)
http.instance_eval {
#ssl_context = OpenSSL::SSL::SSLContext.new
#ssl_context.set_params({:options=>OpenSSL::SSL::OP_ALL})
}
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true
pp response = http.request(Net::HTTP::Get.new(uri.request_uri))
SSL context code above courtesy of #vinhboy.
The CLI equivalent of the above is turned-on with the -bugs option:
openssl s_client -bugs -connect broken_server:443

SSLv3 certificate verify failure when TLSv1 was specified?

Can someone help me figure this out. I've seen this asked all over the web, but no one has an adequate answer.
I am on Ubuntu, Ruby 1.8.7, and OpenSSL 1.0.1
Net::HTTP.ssl_context_accessor 'ssl_version'
uri = URI.parse("https://www.paypal.com")
http = Net::HTTP.new(uri.host, uri.port)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.use_ssl = true
http.ssl_version = :TLSv1
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
It returns
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Why is it complaining about SSLv3, if I am specifying TLSv1?
I know it's using TLSv1 because if I did
http.ssl_version = :SSLv3
It will return
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server hello A: sslv3 alert handshake failure
Which is expected.
I am not sure what to make of this error, my ca-certificates are up to date.
I can't do any of that fancy OpenSSL::SSL::OP_NO_SSLv3 stuff because Ruby 1.8.7 does not support any of those options.
Thanks for your help.
Related and helpful answers, but not the solution
How to set TLS context options in Ruby (like OpenSSL::SSL::SSL_OP_NO_SSLv2)
Faraday Throws Error When Setting SSL Version
So as I said in the comments, this is most likely a bug that affects Ruby 1.8.7 and OpenSSL 1.0.1 - When you try to connect to a server that has SSLv3 disabled using TLSv1, it will return a certificate verify failed error.
After a lot of searching around, here is what I did
http.instance_eval {
#ssl_context = OpenSSL::SSL::SSLContext.new
#ssl_context.set_params({:options=>OpenSSL::SSL::OP_NO_SSLv3})
}
This hack allows you to set the OpenSSL::SSL::OP_NO_SSLv3 option, which fixes the problem.
Thanks to a tip from https://www.ruby-forum.com/topic/200072
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed...
Why is it complaining about SSLv3, if I am specifying TLSv1?
Its an artifact of the error messages in OpenSSL. Don't worry too much about it (other than the take away of "verification failed").
You did not ask this question, but here's how to fix it. You should include ca_file:
Net::HTTP.ssl_context_accessor 'ssl_version'
uri = URI.parse("https://www.paypal.com")
http = Net::HTTP.new(uri.host, uri.port)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.use_ssl = true
http.ssl_version = :TLSv1
http.ca_file = File.join(File.dirname(__FILE__), "ca.pem")
ca.pem should be a PEM encoded version of VeriSign's Class 3 Public Primary Certification Authority or VeriSign Class 3 Public Primary Certification Authority - G5. You can fetch it from the Symantec's website under Use of Root Certificates.
You can discover the needed CA certificate with the following command. You are usually interested in the last Issuer in the chain.
The issuer is the one displayed with the "i:", like i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority. The "s:" is used for Subject, and that's who the certificate was issued to.
$ openssl s_client -connect www.paypal.com:443 -tls1 -servername www.paypal.com -showcerts
CONNECTED(00000003)
depth=2 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
0 s:/jurisdictionC=US/jurisdictionST=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com
i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G2
-----BEGIN CERTIFICATE-----
MIIG0jCCBbqgAwIBAgIQB2T3ui0CFx+cSA3+e2W7bzANBgkqhkiG9w0BAQUFADB3
MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
IENsYXNzIDMgRVYgU1NMIENBIC0gRzIwHhcNMTUwNDIyMDAwMDAwWhcNMTUxMDMx
MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
AhMIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEERQKOTUxMzEtMjAyMTET
MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxQIU2FuIEpvc2UxFjAUBgNVBAkU
DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoUDFBheVBhbCwgSW5jLjEUMBIGA1UECxQL
Q0ROIFN1cHBvcnQxFzAVBgNVBAMUDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPisQKaRu+4RFWHn4T5QUeeoQ0H5U6KXTdXp
EfjvdCDhAJQjDA4qwHw514zBcgrVIV/c22yUsr+RBnBYZ/rdlCiZGPT0kVYal9ts
XJyBFfvS3q2XMAzBg5I171geP7G46VbMBXfVkAoH1zND7O7AcNjb7z44oJgELvym
almQzTrfmN7RPjosfGJrQzCnMATT0Up94yIt1Imv5yCavWrIY1ImcuSjUMxTHaRy
D3jtnp2aBC+jhfoZYJ8a2uM6+j5h0gYpaEsLq5ilFWpvsHoKa1ZQit2/p/yE9+6U
oCAuJHYJRicHMNv3EdZMt7xVi5MKFCX7H+ZOmHHuZidDeL0gUQIDAQABo4ICxDCC
AsAwbgYDVR0RBGcwZYIMYy5wYXlwYWwuY29tgg1jNi5wYXlwYWwuY29tghRkZXZl
bG9wZXIucGF5cGFsLmNvbYISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5j
b22CDnd3dy5wYXlwYWwuY29tMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBmBgNVHSAEXzBdMFsGC2CGSAGG
+EUBBxcGMEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUG
CCsGAQUFBwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaA
FEv6LeTuMzLi3w0BoYbToDs6uayuMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
dC5zeW1jYi5jb20vc3QuY3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYT
aHR0cDovL3N0LnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3N0LnN5bWNi
LmNvbS9zdC5jcnQwggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdgCkuQmQtBhYFIe7
E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAUzjP5slAAAEAwBHMEUCIFvjUjcbhLRI
0c2PUzTVMSItRsGRsoZqdz433/3MnXilAiEA3paAILaCCR6OSp/H7js1R4IxsdCx
Y/d9UhzFxUFevxoAdQBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAA
AUzjP5waAAAEAwBGMEQCICcbFi1Lzw4R+ptZUnTBHJGRSTUUjptEljDAVNZmI7Xi
AiAM/Gly9qoF18kqaPIRZIibSoh+JnYYFuTpec2vNi12XzANBgkqhkiG9w0BAQUF
AAOCAQEAoUACGhsYuAMEt+420Y+q97KpGBGfRDw+5mJFuER1e3p69KAsFZRBufJb
BjJCbY3yWgqnNTvF+klDvok499g8I51+3fo/wdROX+fyeor+0W8Nv7Q/tNQ3J5gZ
CaoNT4yYOdT2wyswOzHLaQJhNNcTlbxy0lEh3f3S04MnhpB4jVCakRvORlU0FD2R
G4oHGhNJqthJc54f5yvlvhXi5ac9hHd8n+G86dS6QI/QWvkg2EXm0/6huSLP2Bvt
z6CSbS+tefVGVei0hvFvlM/ZVkaWGyJvQXli9MnQd1Fh+CkhGgOJSaGJ2/PM47zz
Gp3OLqh4jMEbNLobkIdLkZ2F9jYMDw==
-----END CERTIFICATE-----
1 s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G2
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
-----BEGIN CERTIFICATE-----
MIIFKzCCBBOgAwIBAgIQNmWFB3qIZ6tY9KCU+BA3MzANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB3MQsw
CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIENs
YXNzIDMgRVYgU1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDa7MVqNhGG2yAho+xMIf0PxVw6vuyibpgOgplrenrrbvIlyS1gIF3WK+bd
mdnxVFx2mwv5J0IkfOrU5jwqziOf+3jJFUT0VixVzla3MPBJif4N2G4BfGHTRJlm
XpZIGIcJyMNJ6TXsu0x6FZFV7WCAlQvXGPOnS+bodAwua0X0F/nLv1RW7jbUTubP
rR9NfY+zVTXdYtJuVIWeRVN67mCWIn+4Gq9voA6mjhO2haHMXIyerR1xuAiU5s68
ONDR6T9xQ/uXI6hs9DHcAjveKVXyoL4eIWyvGlzfajdkAprQUXGlf7ppxSyJZ3A7
EwVy7SEjECsjKhquOglkI3onYhLRAgMBAAGjggFdMIIBWTAvBggrBgEFBQcBAQQj
MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/BAgw
BgEB/wIBADBlBgNVHSAEXjBcMFoGBFUdIAAwUjAmBggrBgEFBQcCARYaaHR0cDov
L3d3dy5zeW1hdXRoLmNvbS9jcHMwKAYIKwYBBQUHAgIwHBoaaHR0cDovL3d3dy5z
eW1hdXRoLmNvbS9ycGEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3MxLnN5bWNi
LmNvbS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0RBCIwIKQeMBwx
GjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTMyMB0GA1UdDgQWBBRL+i3k7jMy4t8N
AaGG06A7OrmsrjAfBgNVHSMEGDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzANBgkq
hkiG9w0BAQUFAAOCAQEARqb1s+ikVsm4NPD3/vMsLmORYyzp1RR/E5P2TN5NgpnM
a8l4YfsSLUgPcOonb3jo9wM+yrg7usnfsDri3iLQMS1m2m4RJUL1eyTC3ksSd81W
2PuGgLoKU27lAQgb0cmydZ2rBics8lKPWb2uHXT648b8RE1bSmzJuDnZ91qE+aAD
wjhOizKlQNrCdfS8yvlX+YYHdVvudjUwhQdz0lxG7Q965X9sPTfBveaFSWC6jfnv
2qxKMeFk9nlnvz9v4pVS3k+NydQ9/L07uDHw9dn1QQRU4CafmYP5BTYlccTLwSse
g1CoewuMVg6qXabpL6Fn/jcgxT6d/J2sIP17u5y4IA==
-----END CERTIFICATE-----
2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
-----BEGIN CERTIFICATE-----
MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC
BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA
A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K
lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ
tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/
-----END CERTIFICATE-----
I am not sure what to make of this error, my ca-certificates are up to date.
Don't add the CA Zoo (ca-certs.pem). You know the CA that certifies PayPal, so use it. There's no need to bring in an addition 300 or so CAs (299 which are incorrect).
Probably Ruby can't find any trustworthy root certificates, see for example this question, among others. Your ruby version is really old, I'd assume your certificate bundle is, too. You should update. Some weeks ago the support for Ruby 1.9.3 ended, let alone support for Ruby 1.8.7. The current version is Ruby 2.2.2. There won't be any fixes for versions that old anymore.

How do I pass a specific ca cert or path to the Sekken constructor?

When I try to create a new Sekken client, it throws an OpenSSL error that there is a self signed certificate in the chain.
require 'sekken'
url = "https://bridgerinsighteu.lexisnexis.com/webservicesapi/9.0/xgservices.svc?wsdl"
client = Sekken.new(url)
I can duplicate the error from OpenSSL, and I can fix it by passing the location for the SSL cert store.
openssl s_client -showcerts -connect bridgerinsighteu.lexisnexis.com:443
errors with return code 19 (self signed certificate in certificate chain) but
openssl s_client -showcerts -CApath /etc/ssl/certs -connect bridgerinsighteu.lexisnexis.com:443
returns code 0 (ok)
So I'm not sure how or what I need to do to pass that cert path to Sekken to use for the openssl check. Sekken does provide for an HTTPClient gem object to be passed to the constructor, so maybe something there? But I just can't quite get my head around this. Or possibly an environment variable? Does anyone have any ideas about how I can get the Sekken constructor to use a specific cert path or cert?
Machine is Ubuntu 14.04 x64, ruby via rvm is ruby 2.1.1p76, sekken is installed via a Gemfile from github.
openssl s_client -showcerts -CApath /etc/ssl/certs -connect bridgerinsighteu.lexisnexis.com:443
Ignore this. The server is misconfigured, and its sending the CA Root. The server should only send the server's certificate and all intermediates required to build a path to a root. Its up to the client to trust the root.
Here's what your command should look like (avoiding the CA Zoo in /etc/ssl/certs, and trusting only what is needed):
openssl s_client -connect bridgerinsighteu.lexisnexis.com:443 -CAfile <Trustwave Root CA>
You can get <Trustwave Root CA> from Trustwave SSL - Support - Root Download. Get the one named Trustwave Extended Validation CA in PEM format.
Here's what it looks like when using the Trustwave Extended Validation CA (evca.crt). Notice the Verify return code: 0 (ok) at the tail of the output.
$ openssl s_client -connect bridgerinsighteu.lexisnexis.com:443 -CAfile evca.crt
CONNECTED(00000003)
depth=2 C = US, O = SecureTrust Corporation, CN = SecureTrust CA
verify return:1
depth=1 C = US, ST = Illinois, L = Chicago, O = "Trustwave Holdings, Inc.", CN = "Trustwave Organization Validation CA, Level 2", emailAddress = ca#trustwave.com
verify return:1
depth=0 CN = *.lexisnexis.com, O = LexisNexis, L = Miamisburg, ST = Ohio, C = US
verify return:1
---
Certificate chain
0 s:/CN=*.lexisnexis.com/O=LexisNexis/L=Miamisburg/ST=Ohio/C=US
i:/C=US/ST=Illinois/L=Chicago/O=Trustwave Holdings, Inc./CN=Trustwave Organization Validation CA, Level 2/emailAddress=ca#trustwave.com
1 s:/C=US/ST=Illinois/L=Chicago/O=Trustwave Holdings, Inc./CN=Trustwave Organization Validation CA, Level 2/emailAddress=ca#trustwave.com
i:/C=US/O=SecureTrust Corporation/CN=SecureTrust CA
2 s:/C=US/O=SecureTrust Corporation/CN=SecureTrust CA
i:/C=US/O=SecureTrust Corporation/CN=SecureTrust CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFJzCCBA+gAwIBAgITBiMcj33v1H9svkXvkWOYn2JyTTANBgkqhkiG9w0BAQUF
ADCBrjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQHEwdD
aGljYWdvMSEwHwYDVQQKExhUcnVzdHdhdmUgSG9sZGluZ3MsIEluYy4xNjA0BgNV
BAMTLVRydXN0d2F2ZSBPcmdhbml6YXRpb24gVmFsaWRhdGlvbiBDQSwgTGV2ZWwg
MjEfMB0GCSqGSIb3DQEJARYQY2FAdHJ1c3R3YXZlLmNvbTAeFw0xMzA1MTUwOTE5
NThaFw0xNjA3MDcxNTE5NThaMGExGTAXBgNVBAMMECoubGV4aXNuZXhpcy5jb20x
EzARBgNVBAoMCkxleGlzTmV4aXMxEzARBgNVBAcMCk1pYW1pc2J1cmcxDTALBgNV
BAgMBE9oaW8xCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAvsygjRx3DKUm/gmceKny65HMUmRzm8FP0Te9eXsQ76OLa3co4hWrF5ZS
bXlDzB6dgCTFnQOwRcsLpVyXlazDugdibjfnqdyStcjI75+J2emRYzHVJ7P9p+Bw
pL1k01POV/pes87abX1ffodK+OwnWDkfABqLaaJlsluv/NJd5cdGTn8C1+7mw3MR
KxUTGuGdsTgV/H5aEQFAP6BIklpywhk+QJb1BN28bR2UMTi0QB6qBNP+oe5aWG6Q
rq/ghb31FF0jmL9pCGVJfY5eewIXjBiEwFSdkxv8rxPmkmjDV9E5/OGKXuALtJIE
SFfM9WwTKHV3rs79QV38yD6Cbf3yVQIDAQABo4IBiDCCAYQwDAYDVR0TAQH/BAIw
ADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0G
A1UdDgQWBBQUma9eMJEc5IUlSe4n6X7eViCS9zAfBgNVHSMEGDAWgBRd2ZaaQMcn
yyybouzPGavIr8yGSDBIBgNVHSAEQTA/MD0GDysGAQQBge0YAwMDAwQEAzAqMCgG
CCsGAQUFBwIBFhxodHRwczovL3NzbC50cnVzdHdhdmUuY29tL0NBME8GA1UdEQRI
MEaCECoubGV4aXNuZXhpcy5jb22CDmxleGlzbmV4aXMuY29tghEqLmxleGlzLW5l
eGlzLmNvbYIPbGV4aXMtbmV4aXMuY29tMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6
Ly9jcmwudHJ1c3R3YXZlLmNvbS9PVkNBX0wyLmNybDA2BggrBgEFBQcBAQQqMCgw
JgYIKwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRydXN0d2F2ZS5jb20vMA0GCSqGSIb3
DQEBBQUAA4IBAQAXvdGvtggb6dfa46IFX81rGr69ank7rON6VQaqUrUeExqmSyhw
r+n8wh0YFo69GKVx1LFa1+eWIz48ROtOhveSr/Gib4ujBLtq5urITOcmH4IYj3sw
2VFuaCZ0+TNgqmt6HPTPfBwWjcCRLbtDYPeFFo52HMu+ObeNeVR1Ll58Iijl4sOo
CwaDNFYiveLwcPXgGQhvYn6NFXW0D2cRpeTJzjXOjcLebPY9h//Fl6loZh/APwGT
gKz43mIChdcTQz/caeDjj0VkiSpJ4XDXYRDabSkpzvwJ5AXDC4f4jZy8jxnx9sSP
NnGvKxaJwr2ArewSfYX7W/JtVUAF+wIEVPux
-----END CERTIFICATE-----
subject=/CN=*.lexisnexis.com/O=LexisNexis/L=Miamisburg/ST=Ohio/C=US
issuer=/C=US/ST=Illinois/L=Chicago/O=Trustwave Holdings, Inc./CN=Trustwave Organization Validation CA, Level 2/emailAddress=ca#trustwave.com
---
No client certificate CA names sent
---
SSL handshake has read 3569 bytes and written 831 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : RC4-SHA
Session-ID: 684051C7B37B4A255AE51BFC67CFC4BF...
Session-ID-ctx:
Master-Key: 53C559C9F85A6CB1788BFC20E1A1997C...
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1399081838
Timeout : 300 (sec)
Verify return code: 0 (ok)
So I'm not sure how or what I need to do to pass that cert path to Sekken to use for the openssl check.
All you need to do is specify Trustwave Extended Validation CA (evca.crt) as the root to use in Sekken when building the validation path. I'm not a Sekken guy, but I know how to do it in other languages and libraries like .Net, Java, OpenSSL, PERL, Python, etc.
Since you specified the Ruby tag, here's a test script I was using for some PKI testing with Ruby:
#!/usr/bin/ruby
require 'net/http'
uri = URI('https://bridgerinsighteu.lexisnexis.com:443')
http = Net::HTTP.new(uri.host, uri.port)
# Enable SSL/TLS ?
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = File.join(File.dirname(__FILE__), "evca.crt")
end
req = Net::HTTP::Get.new('/')
http.request(req)
This is just bike shedding... You have the Trustwave Extended Validation CA in /etc/ssl/certs. If the certificate was missing, then s_client would have failed when using CApath.
Trustwave has proven itself to be very untrustworthy. In the past, it facilitated interception of all SSL/TLS traffic by issuing certificates for domains not under the control of the person who wanted the certificates.
"Trust" is tricky to define. One of the better definitions I have seen is "X expects Y to do Z". That is, X expects or trusts Y to do Z because (1) Y says it does Z and (2) X accepts or approves of Z.
If you plug in PKI: "Users expect CAs to follow their CP and CPS". CP is "Certification Practice" and its policy; and CPS Is Certification Practice Statement and its procedure. So the CP and CPS specifies how the CA operates by defining policies (CP), and procedures to implement or enforce the policies (CPS).
If Trustwave followed their own published policies and procedures, then Trustwave would not have issued the certificates to intercept the SSL/TLS traffic. Trustwave did not follow their own policies and procedures, so they have proven themselves to be untrustworthy. Quod erat demonstrandum.
So ok, looks like you can pass an instance of an HTTPClient to the Sekken constructor. But there's a bug in the constructor that keeps it from using the passed client. I hacked my way around it, but hopefully the owner will fix it better? https://github.com/savonrb/sekken/issues/10
Once that is fixed, this is how I solved the problem. I created an instance of the HTTPClient then added the Trustwave root CA cert to the instance cert store and passed that to the Sekken constructor.
require 'sekken'
require 'httpclient'
url = "https://bridgerinsighteu.lexisnexis.com/webservicesapi/9.0/xgservices.svc?wsdl"
# this is the secure trust CA
cert = "/etc/ssl/certs/stca.pem"
http = HTTPClient.new
http.ssl_config.cert_store.add_file cert
client = Sekken.new(url, http)

Resources