Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions include/amqpcpp/linux_tcp/tcpconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ class TcpConnection :
if (_handler) _handler->onConnected(this);
}

/**
* Method that is called to get a user-provided SSL context
* @param state
* @return SSL_CTX*
*/
virtual SSL_CTX *onSecuring(TcpState *state) override
{
// pass on to user-space
if (_handler) return _handler->onSecuring(this);
}

/**
* Method that is called when right before connection is being secured
* @param state
Expand Down
14 changes: 14 additions & 0 deletions include/amqpcpp/linux_tcp/tcphandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ class TcpHandler
(void) connection;
}

/**
* Method that is called after a TCP connection has been set up, and right before
* the SSL handshake is going to be performed to secure the connection (only for
* amqps:// connections). If a user space implementation returns a pointer to an
* existing OpenSSL SSL_CTX here, that context will be used to create new SSL
* sessions from. Otherwise, if nullptr is returned, a default SSL_CTX is created.
* @param connection The TCP connection
* @return SSL_CTX * A user-provided, pre-configured SSL_CTX, will not be freed.
*/
virtual SSL_CTX *onSecuring(TcpConnection *connection)
{
return nullptr;
}

/**
* Method that is called after a TCP connection has been set up, and right before
* the SSL handshake is going to be performed to secure the connection (only for
Expand Down
9 changes: 8 additions & 1 deletion include/amqpcpp/linux_tcp/tcpparent.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ class TcpParent
* @param state
*/
virtual void onConnected(TcpState *state) = 0;


/**
* Method that is called to get a user-provided SSL context
* @param state
* @return SSL_CTX*
*/
virtual SSL_CTX *onSecuring(TcpState *state) = 0;

/**
* Method that is called right before a connection is secured and that allows userspac to change SSL
* @param state
Expand Down
34 changes: 26 additions & 8 deletions src/linux_tcp/sslcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,56 @@ class SslContext
* The wrapped context
* @var SSL_CTX
*/
SSL_CTX *_ctx;
SSL_CTX *_ctx = nullptr;

/**
* If set to true, the SSL context is owned by this wrapper and will be
* freed by the destructor.
* @var owned
*/
bool _owned = false;

public:
/**
* Constructor
* Constructor accepting a preconfigured SSL_CTX.
* @param ctx preconfigured SSL_CTX to use
* @throws std::runtime_error if ctx is null
*/
explicit SslContext(SSL_CTX *ctx) : _ctx(ctx)
{
// report error
if (_ctx == nullptr) throw std::runtime_error("no ssl context");
}

/**
* Constructor creating a new SSL_CTX wuth default verification paths.
* @param method the connect method to use
* @throws std::runtime_error
*/
SslContext(const SSL_METHOD *method) : _ctx(OpenSSL::SSL_CTX_new(method))
explicit SslContext(const SSL_METHOD *method) : _ctx(OpenSSL::SSL_CTX_new(method)), _owned(true)
{
// report error
if (_ctx == nullptr) throw std::runtime_error("failed to construct ssl context");

// set the context to accept a moving write buffer. note that SSL_CTX_set_mode is a macro
// that expands to SSL_CTX_ctrl, so that is the real function that is used
OpenSSL::SSL_CTX_set_mode(_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
// use the default directories for verifying certificates
OpenSSL::SSL_CTX_set_default_verify_paths(_ctx);
}

/**
* Copy constructor is delete because the object is refcounted,
* and we do not have a decent way to update the refcount in openssl 1.0
* @param that
*/
SslContext(SslContext &that) = delete;
SslContext(const SslContext &that) = delete;
SslContext(SslContext &&that) noexcept = default;

/**
* Destructor
*/
virtual ~SslContext()
{
// free resource (this updates the refcount -1, and may destruct it)
OpenSSL::SSL_CTX_free(_ctx);
if (_owned) OpenSSL::SSL_CTX_free(_ctx);
}

/**
Expand Down
13 changes: 9 additions & 4 deletions src/linux_tcp/sslhandshake.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,19 @@ class SslHandshake : public TcpExtState
* @param buffer The buffer that was already built
* @throws std::runtime_error
*/
SslHandshake(TcpExtState *state, const std::string &hostname, TcpOutBuffer &&buffer) :
SslHandshake(TcpExtState *state, const std::string &hostname, TcpOutBuffer &&buffer) :
TcpExtState(state),
_ctx(OpenSSL::TLS_client_method()),
_ctx([&] {
// allow userspace to provide SSL context, create default one if it didn't
auto context = _parent->onSecuring(this);
return context ? SslContext(context) : SslContext(OpenSSL::TLS_client_method());
}()),
_ssl(_ctx),
_out(std::move(buffer))
{
// use the default directories for verifying certificates
OpenSSL::SSL_CTX_set_default_verify_paths(_ctx);
// set the context to accept a moving write buffer. note that SSL_CTX_set_mode is a macro
// that expands to SSL_CTX_ctrl, so that is the real function that is used
OpenSSL::SSL_set_mode(_ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

// we will be using the ssl context as a client
OpenSSL::SSL_set_connect_state(_ssl);
Expand Down