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

Add example of generating a new CA and a new server cert signed by it #99

Closed

Conversation

iamjpotts
Copy link
Contributor

Resolves #79

@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch 2 times, most recently from 1651a13 to 9316961 Compare October 31, 2022 02:24
@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch 3 times, most recently from 1c6f6d6 to c5afc0b Compare August 24, 2023 19:15
@iamjpotts
Copy link
Contributor Author

Build failure related to parsing a revoked certificate might be fixed by #142.

@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch 2 times, most recently from 0c67396 to 1d8dbfe Compare August 25, 2023 04:44
@@ -33,7 +33,9 @@ default = ["pem"]
features = ["x509-parser"]

[dev-dependencies]
native-tls = "0.2"
Copy link
Member

Choose a reason for hiding this comment

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

If we do this with rustls we can don't even need the pipe crate, and we can avoid relying on C libraries.

(Honestly, I'm not sure it makes sense to include a whole TLS setup in the example -- that seems to be more like a testing thing?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I liked having a complete end-to-end example because it shows how everything ties together, leaving less to research/guess. Some users of the crate may be coming to it with a significant amount of TLS knowledge, and others may be coming into it looking for a solution to some problem, but only basic TLS knowledge. A larger example will help people in the latter group (personally I'm somewhere between the two).

I'll take a look into using rustls instead of nativetls

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In my case the 'solution to a problem' was 'how can i create temporary servers for testing with temporary TLS/SSL certificates, and connect clients without suppressing TLS/SSL validations' - a common testing scenario.

@iamjpotts iamjpotts changed the title Add example of generating a new CA and a new server cert signed by it Do not merge: Add example of generating a new CA and a new server cert signed by it Aug 25, 2023
@iamjpotts
Copy link
Contributor Author

I've added a commit to replace usage of nativetls with rustls but I'm stuck trying to fix a bug.

write_all hangs in both the client thread and server thread.

I'm sure I'm missing something obvious, lol.

@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch from 502f04c to 5a4a92c Compare August 25, 2023 17:20
@iamjpotts
Copy link
Contributor Author

Here's the current output:

Joining client
Client creating
Server creating
Server accepting
Server reading tls
Client connecting
Client sending
Server accepted
Server created
Server sending

Client gets stuck at Client sending (write_all) and server gets stuck at Server sending (also a write_all).

I'm sure this is a lack of understanding on my part of one of the crates I'm trying to use. Help would be appreciated.

@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch from 5a4a92c to b0f24f3 Compare August 25, 2023 17:58
@iamjpotts
Copy link
Contributor Author

It's getting stuck in the handshake step (is_handshaking() is true for both server and client connections).

@iamjpotts
Copy link
Contributor Author

Current output after additional commits:


Joining client
Client creating
Server creating
Server accepting
Server reading tls
Client connecting
Client handshaking? true
Client handshaking? true
Client flushing
Server accepted
Server created
Server handshaking? true
Server handshaking? true
Server flushing

Gets stuck in same places.

@cpu
Copy link
Member

cpu commented Aug 25, 2023

It's getting stuck in the handshake step (is_handshaking() is true for both server and client connections).

I haven't had a chance to review the code you have in progress, but you might be able to crib from the rustls/rustls/tests/common/mod.rs code used by the api.rs integration tests, in particular the do_handshake helper

@iamjpotts
Copy link
Contributor Author

It's getting stuck in the handshake step (is_handshaking() is true for both server and client connections).

I haven't had a chance to review the code you have in progress, but you might be able to crib from the rustls/rustls/tests/common/mod.rs code used by the api.rs integration tests, in particular the do_handshake helper

Thanks for the suggestion. I've looked thru that code (as well as transfer and make_pair_for_arc_configs) and it requires shared knowledge of both the client and server connections. I'm trying to setup an example where the only shared knowledge is a bidirectional pipe and CA certificate, and the creation of the rustls client is completely independent of creation of the rustls server. It seems like it should be possible.

It was pretty easy to get it working with nativetls

@iamjpotts
Copy link
Contributor Author

This isn't a problem specific to the rustls implementation in my PR; the nativetls has the same problem.

I added write_all to that version (not pushed yet) and it has the same problem hanging at write_all in both client and server.

Thanks for your help, I'll keep digging.

@iamjpotts iamjpotts marked this pull request as draft August 25, 2023 19:22
@est31
Copy link
Member

est31 commented Aug 25, 2023

Late to the discussion but +1 to using the rustls crate because it means less dependencies.

@iamjpotts
Copy link
Contributor Author

Late to the discussion but +1 to using the rustls crate because it means less dependencies.

Agree.

@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch from 35b27d1 to 671fe5f Compare August 25, 2023 22:27
@iamjpotts
Copy link
Contributor Author

iamjpotts commented Aug 25, 2023

@est31 / @cpu / @djc there's a difference in behavior between rustls and nativetls when the client and server are communicating over a bidirectional pipe from the pipe crate.

Let's assume the following behavior (implemented in all three examples):

  • Client and server start independently, on separate threads
  • Client sends a message and then reads, blocking waiting for a response
  • Server blocks waiting for a message, then sends a response

With nativetls, both client and server run to completion, whether the pipe bipipe is buffered or unbuffered.

With rustls, both the client and server block indefinitely, whether the pipe bipipe is buffered or unbuffered. It seems rustls gets stuck handshaking.

plumber has the same client/server behaviors, but without any tls implementation on top. Client writes then reads, while server reads then writes. plumber will run to completion whether its buffered or unbuffered.

If plumber is altered so both client and server write before reading, only pipe::bipipe_buffered will allow both client and server to run to completion; pipe::bipipe (unbuffered) blocks indefinitely.

If nativetls is altered so both client and server write before reading, using pipe::bipipe_buffered does not fix the indefinite blocking.

Is there a bug in rustls - should it be able to run on a buffered bidirectional pipe with a rusttls client hooked up to one end of the pipe and a rusttls server hooked up to the other end?

@iamjpotts
Copy link
Contributor Author

Also, while I have included plumber.rs and a nativetls based version of the example, those are temporary for comparison to the rustls behavior, and will be removed once the issues with the rusttls example are resolved.

@iamjpotts iamjpotts marked this pull request as ready for review August 25, 2023 22:40
@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch from 671fe5f to e2cbb8b Compare August 25, 2023 23:09
// Does not work with either buffered or unbuffered bipipe, even when we use the same message
// pattern as with the nativetls example, where client sends then reads, and server reads and
// then sends. Client blocks sending a message; server blocks reading a message.
let (mut p_client, mut p_server) = pipe::bipipe_buffered();
Copy link
Member

Choose a reason for hiding this comment

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

Note that there's really no need to use a pipe thing here. You can just directly use a Vec<u8> buffer (or two) that one side writes into and the other side then reads from.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The vectors couldn't be moved into the server thread and client threads, because it would require moving each vector twice.

@iamjpotts iamjpotts force-pushed the 20221030-autogen-ca-tls-example branch from e2cbb8b to b3d2ef1 Compare August 28, 2023 13:22
@codecov
Copy link

codecov bot commented Aug 28, 2023

Codecov Report

Merging #99 (b3d2ef1) into main (9714b8f) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##             main      #99   +/-   ##
=======================================
  Coverage   71.60%   71.60%           
=======================================
  Files           7        7           
  Lines        1729     1729           
=======================================
  Hits         1238     1238           
  Misses        491      491           

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@cpu
Copy link
Member

cpu commented Sep 20, 2023

Is the status of this branch still accurately reflected in the "Do not merge" PR title?

I appreciate the effort you've put into this work, and I do agree that better examples are needed. However, I think the approach taken here is too heavy-weight. It's more of an example of using the downstream TLS crates vs using rcgen. In general I worry we're duplicating code that would be better offered as an example maintained in those upstream repositories where it would be kept in-sync with project changes. I also think the choice to try and make a bi-directionally communicating client/server pair complicates the code and doesn't match what I expect most users want to do: create a client, or create a server, and use those with a TCP socket based transport.

I would feel a lot better about examples that focused exclusively on certificate generation, the domain of rcgen. If it's true that there are still gaps that make it challenging for a new user to use the generated certificates with Rustls then I think the best course of action would be to try and extend the existing Rustls examples to better resolve those challenges.

Apologies for not voicing these opinions earlier.

@iamjpotts
Copy link
Contributor Author

No worries. I was actually starting to get that same feeling myself - like the scope of the proposed code changes had changed, and that at least some portion of what it became might belong in another crate.

It was here originally to show how to use rcgen to solve a problem, and provide an end-to-end solution.

I am a little concerned about the different behavior of the tls implementations I documented in a comment above, but that may belong elsewhere also:

"there's a difference in behavior between rustls and nativetls when the client and server are communicating over a bidirectional pipe from the pipe crate."

Let me think about it a bit and I may proactively refactor or close the PR.

@iamjpotts iamjpotts changed the title Do not merge: Add example of generating a new CA and a new server cert signed by it Add example of generating a new CA and a new server cert signed by it Sep 27, 2023
@iamjpotts iamjpotts closed this Sep 27, 2023
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

Successfully merging this pull request may close these issues.

Add example to demonstrate how to create a CA and a certificate signed with that CA.
4 participants