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

feat(iroh)!: switch TLS authentication to raw public keys #2937

Merged
merged 17 commits into from
Mar 14, 2025

Conversation

dignifiedquire
Copy link
Contributor

@dignifiedquire dignifiedquire commented Nov 15, 2024

Description

This introduces the configuration of the TLS authentication method, allowing to enable the usage of raw public keys, which will lead to us being able to remove the hack of using self signed certificates.

Breaking Changes

By default iroh endpoints will now use the new RawPublicKey TLS configuration. This means they will not be able to talk to older iroh nodes. If needed, the old mechanism can still be used by configuring the endpoint like this

let endpoint = Endpoint::builder()
   .tls_x509() // <--- this enables the old style TLS authentication
   // ...
   .bind();

Closes #2798

Change checklist

  • Self-review.
  • Documentation updates following the style guide, if relevant.
  • Tests if relevant.
  • All breaking changes documented.

Sorry, something went wrong.

Copy link

github-actions bot commented Nov 15, 2024

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/iroh/pr/2937/docs/iroh/

Last updated: 2025-03-14T13:04:06Z

@dignifiedquire dignifiedquire added this to the v0.30.0 milestone Nov 15, 2024
Copy link

github-actions bot commented Nov 15, 2024

Netsim report & logs for this PR have been generated and is available at: LOGS
This report will remain available for 3 days.

Last updated for commit: 4b65c00

@matheus23
Copy link
Member

For a hot minute I was imagining a feature on rustls to disable all non-RPK paths, imagining that we could get rid of ASN.1/DER parsing code.
Then I remembered that we still use HTTPS 🙃

use crate::tls::Authentication;

#[derive(Debug)]
pub(crate) struct AlwaysResolvesCert {
Copy link
Member

Choose a reason for hiding this comment

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

Kind of annoying that rustls has all the implementations for ResolvesClientCert and ResolvesServerCert that we need, but they're not all exposed.

There's

  • AlwaysResolvesClientCert
  • AlwaysResolvesServerCert
  • AlwaysResolvesClientRawPublicKeyCert
  • AlwaysResolvesServerRawPublicKeyCert

I'd rather not have to implement a trait outside the crate where it's defined, but eh.
Also it's super annoying that they split it up into client/server like that.

@dignifiedquire
Copy link
Contributor Author

Going to wait with pushing this forward until we know if rustls/rustls#2258 might happen

@dignifiedquire dignifiedquire removed this from the v0.30.0 milestone Dec 10, 2024
@dignifiedquire dignifiedquire self-assigned this Feb 10, 2025
@dignifiedquire dignifiedquire added this to the v0.33.0 milestone Feb 10, 2025
@dignifiedquire
Copy link
Contributor Author

Going to wait with pushing this forward until we know if rustls/rustls#2258 might happen

looks like this is not happening, or at least not soon, so moving forward with this

@dignifiedquire dignifiedquire marked this pull request as ready for review February 11, 2025 10:08
@dignifiedquire dignifiedquire changed the title [WIP] feat: implement support for raw public keys in TLS feat(iroh)!: implement support for raw public keys in TLS Feb 11, 2025

#[tokio::test]
#[traced_test]
async fn test_two_devices_roundtrip_quinn_rebinding_conn() -> Result<()> {
Copy link
Member

Choose a reason for hiding this comment

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

Hm. Are we sure we want to delete these tests?
I see it's weird to see a test that tests "quinn", but I think what this is actually doing is testing UdpConn (without depending on iroh being correct).
Instead of deleting these, perhaps they should be renamed & moved to udp_conn.rs?

iroh/src/tls.rs Outdated
/// Error for generating iroh p2p TLS configs.
/// TLS Authentication mechanism
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub enum Authentication {
Copy link
Member

Choose a reason for hiding this comment

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

I personally find it a little confusing if we have mod tls; in lib.rs, but then use pub enum etc. here.
Can we make it pub(crate) enum (and also the same with pub mod certificate etc.)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cleaned this up

Copy link
Contributor

Choose a reason for hiding this comment

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

This enum also should be pub(crate) should it not?

@ramfox ramfox modified the milestones: v0.33.0, v0.34.0 Feb 25, 2025
Copy link
Member

@matheus23 matheus23 left a comment

Choose a reason for hiding this comment

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

I'm happy with the changes, and I'd be down for this to get merged.

But I do wonder why you've removed 4 tests? Do you think they're not useful anymore? The tests are:

  • magicsock::test_two_devices_roundtrip_quinn_raw
  • magicsock::test_two_devices_roundtrip_quinn_rebinding_conn
  • magicsock::udp_conn::test_rebinding_conn_send_recv_ipv4
  • magicsock::udp_conn::test_rebinding_conn_send_recv_ipv6

I guess they're related to this PR because they use tls::make_client_config and tls::make_server_config. Was there some problem in getting them to work?

Copy link
Contributor

@flub flub left a comment

Choose a reason for hiding this comment

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

Can an external observer looking at intercepted datagrams distinguish which mechanism is used?

///
/// For details see the libp2p spec at <https://github.com/libp2p/specs/blob/master/tls/tls.md>
///
/// This is the only mechanism available in `iroh@0.33.0` and earlier.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also add that this method will be removed at some time in the future? Like to make it really clear that you should only use this to transition, but don't just use it and forget about it.

iroh/src/tls.rs Outdated
/// Error for generating iroh p2p TLS configs.
/// TLS Authentication mechanism
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub enum Authentication {
Copy link
Contributor

Choose a reason for hiding this comment

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

This enum also should be pub(crate) should it not?

@dignifiedquire
Copy link
Contributor Author

But I do wonder why you've removed 4 tests? Do you think they're not useful anymore? The tests are:

They were pretty painful to update, and I am not convinced of their usefulness tbh, as they don't really test much of our code anymore. But happy to hear other arguments

@matheus23
Copy link
Member

Can an external observer looking at intercepted datagrams distinguish which mechanism is used?

Yes
image

@dignifiedquire
Copy link
Contributor Author

Can an external observer looking at intercepted datagrams distinguish which mechanism is used?

My understanding is that as long as we don't have encrypted client hello, this is observable during the handshake

@matheus23
Copy link
Member

Can an external observer looking at intercepted datagrams distinguish which mechanism is used?

My understanding is that as long as we don't have encrypted client hello, this is observable during the handshake

Yeah I was about to write that.
Even without RPK, iroh traffic is somewhat detectable via the ALPN extension, via the server-name-indication (it's .iroh.invalid).
I think with encrypted client hello we'd fix that.
But for that we need:

  • to switch away from ring, because it doesn't implement some crypto we'd need for ECH, and probably won't in the future
  • ECH to be implemented in rustls and quinn (? I think).

@dignifiedquire
Copy link
Contributor Author

I have moved the test discussion into an issue, to not block merging this #3229

dignifiedquire and others added 16 commits March 14, 2025 13:55

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
this was only used in tests, and those only tested quinn isolation things, which have been removed
Co-authored-by: Philipp Krüger <philipp.krueger1@gmail.com>
@dignifiedquire dignifiedquire changed the title feat(iroh)!: implement support for raw public keys in TLS feat(iroh)!: switch TLS authentication to raw public keys Mar 14, 2025
@dignifiedquire dignifiedquire added this pull request to the merge queue Mar 14, 2025
github-merge-queue bot pushed a commit that referenced this pull request Mar 14, 2025
## Description

This introduces the configuration of the TLS authentication method,
allowing to enable the usage of raw public keys, which will lead to us
being able to remove the hack of using self signed certificates.

## Breaking Changes

By default iroh endpoints will now use the new `RawPublicKey` TLS
configuration. This means they will not be able to talk to older iroh
nodes. If needed, the old mechanism can still be used by configuring the
endpoint like this

```rust
let endpoint = Endpoint::builder()
   .tls_x509() // <--- this enables the old style TLS authentication
   // ...
   .bind();
```

Closes #2798 


## Change checklist

- [x] Self-review.
- [x] Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.
- [x] Tests if relevant.
- [x] All breaking changes documented.

---------

Co-authored-by: Philipp Krüger <philipp.krueger1@gmail.com>
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 14, 2025
@dignifiedquire dignifiedquire added this pull request to the merge queue Mar 14, 2025
Merged via the queue into main with commit d8c8c8e Mar 14, 2025
25 of 26 checks passed
@dignifiedquire dignifiedquire deleted the feat-raw-public-key branch March 14, 2025 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

feat: use Raw Public Keys (RFC 7250) instead of self signed certificates
4 participants