Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Example for onSecuring for SSL certficate? #527

Open
harsszegi opened this issue Apr 11, 2024 · 2 comments
Open

[question] Example for onSecuring for SSL certficate? #527

harsszegi opened this issue Apr 11, 2024 · 2 comments

Comments

@harsszegi
Copy link

Hi,
I'm trying to use SSL and I fail to do so:

bool onSecuring(AMQP::TcpConnection* /* connection /, SSL ssl) override
{
auto* ssl_ctx = SSL_get_SSL_CTX(ssl);

if (!connection_parameters_.tls_params_.has_value())
{
  return false;
}

if (SSL_CTX_load_verify_locations(ssl_ctx, connection_parameters_.tls_params_->ca_cert_path_.c_str(), nullptr) != 1)
{
  std::cout << "Invalid ca cert" << std::endl;
  ERR_print_errors_fp(stderr);
  return false;
}

if (SSL_CTX_use_certificate_chain_file(ssl_ctx, connection_parameters_.tls_params_->client_cert_path_.c_str()) != 1)
{
  std::cout << "Invalid client cert" << std::endl;
  ERR_print_errors_fp(stderr);
  return false;
}

if (SSL_CTX_use_PrivateKey_file(ssl_ctx, connection_parameters_.tls_params_->client_key_path_.c_str(), SSL_FILETYPE_PEM) != 1)
{
  std::cout << "Invalid client private key" << std::endl;
  ERR_print_errors_fp(stderr);
  return false;
}

if (SSL_CTX_check_private_key(ssl_ctx) != 1)
{
  std::cout << "Check failed client private key" << std::endl;
  ERR_print_errors_fp(stderr);
  return false;
}

if (connection_parameters_.tls_params_->verify_peer_)
{
  SSL_set_verify(ssl, SSL_VERIFY_PEER, nullptr);
}
else
{
  SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr);
}

return true;

}

This works fine, context is configured, however the server rejects this with "no_client_certificate_provided".

The same set of certificates with SimpleAmqpClient work fine, e.g. I can connect to the same broker.
Any documentation / hint how to use SSL with amqp-cpp?
Thanks,

@harsszegi
Copy link
Author

Hmmm afaik I know what is going on. OpenSSL is initialized a bit "upside-down". First you need to the create SSL_CTX, then you need to create SSL with the preconfigured SSL_CTX. During SSL creation OpenSSL copies a whole lot of stuff from the SSL_CTX to SSL. So if OnSecuring is called after the SSL is initialized, you are way to late. I have modified amqp-cpp locally, basically like this:

SslHandshake(TcpExtState *state, const std::string &hostname, TcpOutBuffer &&buffer) : 
    TcpExtState(state),
    _ctx(OpenSSL::TLS_client_method()),
    _out(std::move(buffer))
{
    // use the default directories for verifying certificates
    OpenSSL::SSL_CTX_set_default_verify_paths(_ctx);

    // we allow userspace to make changes to the SSL structure
    if (!_parent->onSecuring(this, _ctx)) throw std::runtime_error("failed to initialize SSL structure in user space");

    _ssl = std::make_unique<SslWrapper>(_ctx);

    // we will be using the ssl context as a client
    OpenSSL::SSL_set_connect_state(*_ssl);
    
    // associate domain name with the connection
    OpenSSL::SSL_ctrl(*_ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (void *)hostname.data());
    
    // associate the ssl context with the socket filedescriptor
    if (OpenSSL::SSL_set_fd(*_ssl, _socket) == 0) throw std::runtime_error("failed to associate filedescriptor with ssl socket");
    
    // we are going to wait until the socket becomes writable before we start the handshake
    _parent->onIdle(this, _socket, writable);
}

and it seems to fix my issue

@AstroGoGo
Copy link

Tibor Harsszegi, thanks plenty! I was really hitting the wall with the same problem because I couldn't do two-way SSL until I saw your fix. I did make it to trying to configure the onSecuring but I hit the same wall you did...until I read your post. I ended up throwing my SSL_CTX_use_PrivateKey_file call in the SslContext constructor and calling it a day. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants