Boost Asio with Ecdsa Certificate Issue

boost asio with ECDSA certificate issue

No sorry buddy I found the answer after lot of research.

The problem is with the cipher list and not with the code / certificate.

The same certificate uses ECDHE-ECDSA-AES256-SHA cipher with openssl client-server while used ECDH-ECDSA-AES256-SHA cipher for boost asio SSL client-server.

Anyways thanks @rkyser for your help!

Excessive message size with boost asio and SSL

Try to configure a specific SSL protocol version (e.g. only SSLv3). This reduces the list of items to be sent.

Also, consider sending a minimized certificate bundle (in the certificate file on the server) because the client won't be interested in most root certificates in the chain, unless it already knows them anyways

nghttp2::asio_http2::client with TLS 1.3 - SSL_CTX_set_cipher_list doesnt add cipher suite in cipher suites

If you go to the documentation for SSL_CTX_get_ciphers it states:

SSL_CTX_set_cipher_list() sets the list of available ciphers (TLSv1.2
and below)

and

This function does not impact TLSv1.3 ciphersuites. Use
SSL_CTX_set_ciphersuites() to configure those.

So you need to go read the SSL_CTX_set_cipher_list API as the v1.3 cipher list is a lot different and much smaller than up to v1.2 cipher list.

setting up an openssl client with a specific cipher in c++

ECDSA ciphers require a ECC certificate. This certificate is only configured by the server when the client uses SNI, i.e. sends the intended hostname inside the ClientHello. openssl 1.1.1 (which you use) does SNI by default but your code does not use SNI.

For comparison s_client with (the default) SNI (using openssl 1.1.1):

$ openssl s_client -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256' -connect www.googleapis.com:443 -tls1_2
...
Cipher : ECDHE-ECDSA-AES128-GCM-SHA256

And without SNI:

$ openssl s_client -noservername -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256' -connect www.googleapis.com:443 -tls1_2
CONNECTED(00000005)
140265233306048:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1528:SSL alert number 40
...
Cipher : 0000

As for setting SNI in your own code see How to implement Server Name Indication (SNI)
or see this code example with boost::asio which also implements SNI using SSL_set_tlsext_host_name.

tlsv1 alert internal error during handshake

These two are a bad combination:

-cipher ECDHE-ECDSA-AES128-GCM-SHA256

And:

error:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c

OpenSSL 0.9.8 does not have full EC support. And it does not support TLS 1.1 or 1.2. To get the AEAD cipher suites, you need to use TLS 1.2. That means you need OpenSSL 1.0.0 or above (IIRC).

OpenSSL 1.0.1 and 1.0.2 have them, so its probably better to use those versions.


 openssl s_client -connect thepiratebay.gd:443 ...

The command you are looking for is: openssl s_client -connect thepiratebay.gd:443 -tls1_2 -servername thepiratebay.gd -CAfile XXX. -servername enlists SNI.

When I hit the site, the server was certified by AddTrust External CA Root. When you hit the site, it was certified by DigiCert High Assurance EV Root CA. And when you hit the site again, it was certified by COMODO ECC Certification Authority.

The different CAs and configurations speak to a distributed site behind a load balancer, with each participating web server in a slightly different configuration.


In addition to multiple web servers and configurations, some of the web servers themselves are misconfigured. They are misconfigured because they do not send the chain required to build a path for validation.

The chain should include (1) the server certificate; (2) Subordinate CAs or intermediates that form the chain to the "root". For (2), there may be one or more intermediates.

The chain should not include the root. You have to have the root, and it must be trusted.


This website seem to open fine using web browser or curl, however, I was not able to find a way to connect to it via openssl...

This is because the browsers carry around a list of hundreds of Root CAs and Subordinate CAs due to web server misconfigurations :) The list includes AddTrust External CA Root, DigiCert High Assurance EV Root CA, and COMODO ECC Root Certificate Authority.


Can anyone advice how to connect to this particular website using openssl?

OK, for the OpenSSL command, you should use -CAfile. Usually, you just use something like openssl s_client -connect ... -CAfile DigiCertHighAssuranceEVRootCA.crt (for the server certified with DigiCert High Assurance EV Root CA). But that won't work in this case.

You have to create a single file with the required Root and Subordinate CAs. The file should be a concatenation of the Root CAs and Subordinate CAs in PEM format required to build a path to validate the server certificate. It looks like it will need at least 3 or 4 certificates.

Or, you could forgo building you own file, and use something like cacert.pem. But there is some risk in using the CA Zoo (my affectionate term for them). For some of the risks, see Is cacert.pem unique to my computer?.

Programmatically, you would use SSL_CTX_load_verify_locations in OpenSSL. The concatenated PEM file is passed though CAfile.

I'm not sure what you would use in PHP.


Related, cacert.pem has 155 roots and subordinates. Most of them are not needed to certify the site thepiratebay.gd:

$ cat cacert.pem | grep BEGIN | wc -l
155

Hence the reason you want to restrict your CAfile to only those necessary to certify the site.


(comment) Not sure this is the correct thread to ask, but now I wonder if there is a way to skip some of these checks programmatically to reduce number of false negatives...

I would probably not forgo the checks. Now that you understand what's going on, it should be easier to work with the system rather than abandoning it.

To reiterate, either:

  1. Use only necessary Root and Subordinate CAs

    1. You build it, concatenation of PEM certificates
    2. Create file piratebay-certs.pem
    3. Add necessary CAs
  2. Use a CA Zoo with predifined trusted Root and Subordinate CAs

    1. You download it
    2. cacert.pem

The third option is to get the site to fix its web server configurations. But if it has not happened by now, it probably won't happen. (And it could be a design decision - the site may be using multiple CAs to ensure no one CA can DoS the site. But that does not address the incomplete chain).


And the more general observation:

I have a PHP script that checks URLs availability (basically, the script should return true for a given URL when the URL could be opened in browser and vice versa

Moving away from piratebay.gd in particular to checking random URLs, you will probably have to use cacert.pem. That's because a random sample of 1 million sites will likely use all of them.

If piratebay.gd still fails, then find out what is missing from cacert.pem, and then:

cat cacert.pem > my-expanded-cacert.pem
cat missing-cert.pem >> my-expanded-cacert.pem

TLS 1.2 set cipher list

Based on https://www.openssl.org/docs/man1.0.2/man1/ciphers.html "The cipher list consists of one or more cipher strings separated by colons. Commas or spaces are also acceptable separators but colons are normally used."

I would say 'ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:ECDHE_ECDSA_WITH_AES_128_GCM_SHA256'



Related Topics



Leave a reply



Submit