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

Use tls socket to retrieve distinguished name #21

Merged

Conversation

Lazin
Copy link

@Lazin Lazin commented Apr 25, 2022

Previously, it was possible to get DN using dn_callback passed to
credentials object. This callback is invoked on every handshake (if
'client_auth' is set to true) and accepts two parameters, subject and
issuer. But there is no way for the user of the tls library to connect
particular client connection with the DN string.

This commit adds a 'get_distinguished_name' method to connected socket
interface. This commit can be used to wait on a future that returns a
distinguished name or nullopt after a handshake. The handshake is
performed asynchrnously. Because of that the retrieval of the DN string
should also be asynchronous.

This commit also adds a unit test and scripts that generate a bunch of
certificates/keys for it.

src/net/tls.cc Outdated Show resolved Hide resolved
Copy link
Member

@dotnwat dotnwat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks awesome, and based on what I'd seen before in the TLS implementation it makes sense. I left a few comments / questions.

I guess in redpanda, src/v/net/server.cc - server::accept after we call accept on the socket we can co_await on the handshake / DN before setting up the final connection and handing it off to the protocol implementation (e.g. kafka).

Comment on lines 1162 to 1171
auto dn = fdn.get();
BOOST_REQUIRE(dn.has_value());
});
});

auto client_socket = tls::connect(cert_creds, addr).get();
auto client_fin = client_socket.input();
auto read_buf = client_fin.read_exactly(5).get();
client_fin.close().get();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this test a bit more sophisticated? Something that tests multiple clients and verifies the contents of the DN? I was thinking something like:

  1. generate server certs
  2. generate client1 certs with DN that contains some magic value 1 (e.g. some domain)
  3. generate client2 certs with DN that contains some magic value 2 (e.g. some other domain)
  4. start a server that writes the DN on its connection to the connection output
  5. each client connects, reads the output, verifies that it contains the expected magic value

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did that

src/net/tls.cc Show resolved Hide resolved
src/net/tls.cc Outdated
@@ -1336,7 +1347,7 @@ class session : public enable_lw_shared_from_this<session> {
return make_exception_future<>(std::system_error(ENOTCONN, std::system_category()));
}
if (!_connected) {
return handshake().then([this, p = std::move(p)]() mutable {
return handshake().discard_result().then([this, p = std::move(p)]() mutable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand why discard_result is used here. afaict handshake() already returns a future<>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artefact from previous implementation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed it

@Lazin Lazin force-pushed the feature/padd-dn-through-callback branch from 7ecfb52 to 3fac4fb Compare April 26, 2022 16:45
src/net/tls.cc Outdated Show resolved Hide resolved
src/net/tls.cc Outdated Show resolved Hide resolved
src/net/tls.cc Outdated Show resolved Hide resolved
src/net/tls.cc Outdated Show resolved Hide resolved
tests/unit/tls_test.cc Show resolved Hide resolved
Previously, it was possible to get DN using dn_callback passed to
credentials object. This callback is invoked on every handshake (if
'client_auth' is set to true) and accepts two parameters, subject and
issuer. But there is no way for the user of the tls library to connect
particular client connection with the DN string.

This commit adds a 'get_distinguished_name' method to connected socket
interface. This commit can be used to wait on a future that returns a
distinguished name or nullopt after a handshake. The handshake is
performed asynchrnously. Because of that the retrieval of the DN string
should also be asynchronous.

This commit also adds a unit test and scripts that generate a bunch of
certificates/keys for it.
@Lazin Lazin force-pushed the feature/padd-dn-through-callback branch from 3fac4fb to 8fe5b6e Compare April 27, 2022 11:55
@Lazin Lazin requested a review from dotnwat April 27, 2022 11:56
Copy link

@jcsp jcsp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zero comments from me, looks great:+1:

@dotnwat dotnwat merged commit 5531940 into redpanda-data:master Apr 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants