Alexis Wilke
Alexis Wilke

Reputation: 20730

BIO_do_connect() fails seemingly because SSL v3 is used, is there a way to get more diagnostics?

I wrote a class to handle SSL connections that I use to communicate with Paypal.

It worked just fine for about a year and now it fails right away. From the error I get, it would seem that this happens because they (finally) turned off the SSLv3 cipher. Yet, I thought it was turned off on my end already.

There is the error I get when attempting my connection with my code:

139673112286976:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1262:SSL alert number 40

I get the exact same error if I try to connect with -ssl3 using the command line tool:

openssl s_client -connect api.sandbox.paypal.com:443 -ssl3

Note that the command line without the -ssl3 option works as expected.

And I have seen a couple of posts that say that the error means there is a problem with the cipher used, leading me to think that is the problem I'm running into.

For those interested, the whole class is found in our snapcpp git (go up one to get the .h and other files from the snapwebsites library).

There is the relevant code. I removed the error checking happening before the one that triggers the current failure:

std::shared_ptr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLSv1_client_method()), ssl_ctx_deleter);
SSL_CTX_set_verify_depth(ssl_ctx.get(), 4);
SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_COMPRESSION);
SSL_CTX_set_cipher_list(ssl_ctx.get(), "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4");
SSL_CTX_load_verify_locations(ssl_ctx.get(), NULL, "/etc/ssl/certs");
std::shared_ptr<BIO> bio(BIO_new_ssl_connect(ssl_ctx.get()), bio_deleter);
SSL * ssl(nullptr);
BIO_get_ssl(bio.get(), &ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
BIO_set_conn_hostname(bio.get(), const_cast<char *>(addr.c_str()));
BIO_set_conn_int_port(bio.get(), &port);
if(BIO_do_connect(bio.get()) <= 0)
{
    ERR_print_errors_fp(stderr);
    throw tcp_client_server_initialization_error("failed connecting BIO object to server");
}

So my class throws because the BIO_do_connect() gets the error I mentioned earlier. Yet I would think that these options:

SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1

would be enough to avoid SSLv3.

What else could be the culprit?

Upvotes: 1

Views: 470

Answers (1)

Leśny Rumcajs
Leśny Rumcajs

Reputation: 2516

You stated SSL_OP_NO_TLSv1 yet you use TLSv1 method.

Try changing TLSv1_client_method() to SSLv23_client_method(). This will alow usage of any method (in fact it will negotiate the highest available SSL/TLS version). You can limit it with SSL_CTX_set_options as you did in your code.

For some reasons the documentation says that SSLv23_method() is deprecated and one should use TLS_method(). Howerer, there isn't such thing in their newest (OpenSSL 1.0.2e) code.

Upvotes: 1

Related Questions