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

noise: add an option to allow unknown peer ID in SecureOutbound #1823

Merged

Conversation

ckousik
Copy link
Contributor

@ckousik ckousik commented Oct 12, 2022

Allows the SecureOutbound call to be called with an unknown peer ID (empty string). This is required for libp2p/specs#412 (comment)

@marten-seemann
Copy link
Contributor

Can we make this a separate function, that has a very clear warning of the risks. Dialing nodes without a peer ID makes you susceptible to MITM attacks, see discussion in libp2p/specs#458.

@ckousik
Copy link
Contributor Author

ckousik commented Oct 17, 2022

@marten-seemann Could you take another look at this?

Copy link
Contributor

@marten-seemann marten-seemann left a comment

Choose a reason for hiding this comment

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

This seems quite complicated. Have you considered my suggestion of making this a separate method, as I suggested in my last review?

// if (s.initiator && s.remoteID != id) || (!s.initiator && s.remoteID != "" && s.remoteID != id) {
// // use Pretty() as it produces the full b58-encoded string, rather than abbreviated forms.
// return nil, fmt.Errorf("peer id mismatch: expected %s, but remote key matches %s", s.remoteID.Pretty(), id.Pretty())
// }
Copy link
Contributor

Choose a reason for hiding this comment

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

No commented code please.

@ckousik
Copy link
Contributor Author

ckousik commented Oct 18, 2022

This seems quite complicated. Have you considered my suggestion of making this a separate method, as I suggested in my last review?

@marten-seemann I considered it but wanted to adhere strictly to the SecureTransport interface. Adding that will not be difficult since noise.Transport is already exposed.

Copy link
Contributor

@marten-seemann marten-seemann 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 not sure I understand why SecureOutboundForAnyPeerID is needed on the Transport and on the SessionTransport.

This PR would also need to be rebased, after recent changes to our Noise transport.

p2p/security/noise/transport.go Outdated Show resolved Hide resolved
p2p/security/noise/session_transport.go Outdated Show resolved Hide resolved
@ckousik ckousik force-pushed the ckousik/initiator-noise-handshake branch from 039bd70 to a2913e6 Compare October 27, 2022 15:32
@ckousik
Copy link
Contributor Author

ckousik commented Oct 27, 2022

@marten-seemann I want to keep the interface consistent between SessionTransport and Transport. We also use SessionTransport in webrtc for the noise prologue.

@marten-seemann
Copy link
Contributor

Sorry for the long response time here, and for changing my mind. I think we should indeed go with an option, implementing this method on both the Transport and the SessionTransport doesn't seem very nice.
To follow Go conventions (the default should be secure), let's not name it CheckPeerID(enable bool) though. What about DisablePeerIDCheck()?

@marten-seemann marten-seemann changed the title Allow unknown peer ID in SecureOutbound noise: add an option to allow unknown peer ID in SecureOutbound Nov 9, 2022
func (t *Transport) WithSessionOptions(opts ...SessionOption) (sec.SecureTransport, error) {
st := &SessionTransport{t: t}
func (t *Transport) WithSessionOptions(opts ...SessionOption) (*SessionTransport, error) {
st := &SessionTransport{t: t, disablePeerIdCheck: false}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
st := &SessionTransport{t: t, disablePeerIdCheck: false}
st := &SessionTransport{t: t}


initiatorEarlyDataHandler, responderEarlyDataHandler EarlyDataHandler
}

// SecureInbound runs the Noise handshake as the responder.
// If p is empty, connections from any peer are accepted.
func (i *SessionTransport) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) {
c, err := newSecureSession(i.t, ctx, insecure, p, i.prologue, i.initiatorEarlyDataHandler, i.responderEarlyDataHandler, false)
c, err := newSecureSession(i.t, ctx, insecure, p, i.prologue, i.initiatorEarlyDataHandler, i.responderEarlyDataHandler, false, p != "" || i.disablePeerIdCheck)
Copy link
Contributor

Choose a reason for hiding this comment

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

@ckousik Why are you setting checkPeerID = true when i.disalbePeerIdCheck?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is to keep behaviour consistent with setting an empty string as peer id.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not p != "" || !i.disablePeerIDCheck?

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 added a quick test and the correct conditional here was p != "" && !i.disablePeerIDCheck, since on the inbound call we will only check the peer ID if the ID provided in the argument is not empty, and the ID check is not disabled.

var _ sec.SecureTransport = &SessionTransport{}

// SessionTransport can be used
// to provide per-connection options
type SessionTransport struct {
t *Transport
// options
prologue []byte
prologue []byte
disablePeerIdCheck bool
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
disablePeerIdCheck bool
disablePeerIDCheck bool

Copy link
Contributor

@marten-seemann marten-seemann left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks @ckousik!

@marten-seemann marten-seemann merged commit c334288 into libp2p:master Nov 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants