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)!: Make retrieving NodeID and ALPN infallible #3147

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

flub
Copy link
Contributor

@flub flub commented Jan 23, 2025

Description

Our crypto setup makese some guarantees here. But we do need to be
careful not to unwrap something that can be triggered by a modified or
custom remote.

Breaking Changes

TODO

iroh

  • Removes Connecting::handshake_data.
  • Removes Connection::handshake_data.
  • Removes Connection::peer_identity.
  • Error type for Connecting::alpn changed to ConnectionError.
  • Connection::alpn is now infallible.
  • Connection::remote_node_id is now infallible.

Notes & open questions

Change checklist

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

Our crypto setup makese some guarantees here.  But we do need to be
careful not to unwrap something that can be triggered by a modified or
custom remote.
@flub flub requested a review from matheus23 January 23, 2025 14:43
Copy link

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

Last updated: 2025-01-23T14:45:00Z

@flub flub changed the title feat(iroh): Make retrieving NodeID and ALPN infallible feat(iroh)!: Make retrieving NodeID and ALPN infallible Jan 23, 2025
Copy link

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: 6e58bc3

@@ -179,7 +179,7 @@ async fn provide(
}
};
let conn = connecting.await?;
let node_id = conn.remote_node_id()?;
let node_id = conn.remote_node_id();
info!(
"new connection from {node_id} with ALPN {} (coming from {})",
String::from_utf8_lossy(TRANSFER_ALPN),
Copy link
Member

Choose a reason for hiding this comment

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

err... unrelated, but maybe this should actually pull out the conn.alpn()

Comment on lines 1290 to 1291
// Note, we could totally provide this method to be on a Connection as well. But we'd
// need to wrap Connection too.
Copy link
Member

Choose a reason for hiding this comment

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

I think we can delete this note

Comment on lines +1292 to 1298
pub async fn alpn(&mut self) -> Result<Vec<u8>, ConnectionError> {
let data = self.inner.handshake_data().await?;
let data = data
.downcast::<quinn::crypto::rustls::HandshakeData>()
.expect("crypto setup for iroh");
Ok(data.protocol.expect("ALPN required by iroh crypto setup"))
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
pub async fn alpn(&mut self) -> Result<Vec<u8>, ConnectionError> {
let data = self.inner.handshake_data().await?;
let data = data
.downcast::<quinn::crypto::rustls::HandshakeData>()
.expect("crypto setup for iroh");
Ok(data.protocol.expect("ALPN required by iroh crypto setup"))
}
pub async fn alpn(&mut self) -> Result<Vec<u8>, ConnectionError> {
let data = self.inner.handshake_data().await?;
let data = data
.downcast::<quinn::crypto::rustls::HandshakeData>()
.expect("invariant checked by iroh's custom rustls verifier");
Ok(data.protocol.expect("invariant upheld by iroh's custom rustls verifier"))
}

Ideally insert the function names of whatever is actually verifying these invariants here.

Comment on lines +1550 to +1560
pub fn remote_node_id(&self) -> NodeId {
let data = self
.inner
.peer_identity()
.expect("required by iroh crypto setup");
let certs = data
.downcast::<Vec<rustls::pki_types::CertificateDer>>()
.expect("iroh crypto setup");
debug_assert_eq!(certs.len(), 1);
let cert = tls::certificate::parse(&certs[0]).expect("TODO: is this guaranteed by now?");
cert.peer_id()
Copy link
Member

Choose a reason for hiding this comment

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

I'd like better expect messages here, too. "required by iroh crypto setup" doesn't suffice IMO.
The message should mention the place that the peer_identity field is populated.
I tried figuring this out, but yeah - it's probably not that easy (flows through quinn, right?).

let data = data
.downcast::<quinn::crypto::rustls::HandshakeData>()
.expect("iroh crypto setup");
data.protocol.expect("ALPN required by iroh crypto setup")
Copy link
Contributor

Choose a reason for hiding this comment

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

Guaranteed to be set if a nonempty list of protocols was specified for this connection.

Are we sure this will always be the case from the public api usage?

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

Successfully merging this pull request may close these issues.

3 participants