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: PatternXX and testing with go #406

Merged
merged 22 commits into from
Feb 28, 2020

Conversation

mhchia
Copy link
Contributor

@mhchia mhchia commented Feb 15, 2020

What was wrong?

#375

How was it fixed?

Based on #405

  • Feature
    • Noise
      • Handshake
        • Pattern XX
      • Encryption/decryption
        • SecureSession(a buffered stream reader originally used in secio) is refactored and used by both Noise and Secio now.
  • Refactor
    • msgio: dedup the original similar implementations.
      • MsgReadWriter
      • FixedSizeLenMsgReadWriter
        • NoiseReadWriter
      • VarIntLengthMsgReadWriter
        • PlaintextHandshakeReadWriter
  • Fix
  • Tests
    • Transport, encryption/decryption, security multistream.
    • Interop test with go implementation
      • through the modified go-libp2p-daemon against different security protocol.
        • Plaintext
        • Noise: go-libp2p-noise
          • Issue: msg#3(initiator sends the payload to the responder) is different from the one in go implementation. Workaround this through ignoring the first 32 bytes for now. Will investigate what is wrong later.
  • Misc
    • Re-compile protobufs
      • noise.proto
      • plaintext.proto

TODO

  • Confirm why msg#3 is different between py and go.
  • Add more exceptions and handling.
  • Add more comments.

Reference

Cute Animal Picture

put a cute animal picture link inside the parentheses

@mhchia mhchia changed the title [WIP] Noise: PatternXX Noise: PatternXX and testing with go Feb 26, 2020
@mhchia
Copy link
Contributor Author

mhchia commented Feb 26, 2020

Though there are things to be added and confirmed, I think this should be ready for review. We can talk with go implementation through noise now. 🎉

Copy link
Contributor

@ralexstokes ralexstokes left a comment

Choose a reason for hiding this comment

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

great! i think we are fine to just focus on the XX pattern for now. i like how you refactored the packet reading/writing so that we don't duplicate all of that across the various security transports.

excited for the interop tests!

Copy link
Contributor

@pipermerriam pipermerriam left a comment

Choose a reason for hiding this comment

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

Some idle comments. This is large enough and I know little enough about the noise protocol that I was only able to provide superficial review.

return int.from_bytes(length_bytes, byteorder=BYTE_ORDER)


def encode_msg_with_length(msg_bytes: bytes) -> bytes:
len_prefix = len(msg_bytes).to_bytes(SIZE_LEN_BYTES, "big")
def encode_msg_with_length(msg_bytes: bytes, size_len_bytes: int) -> bytes:
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is the size passed in here instead of measuring it from len(msg_bytes)?

Copy link
Contributor Author

@mhchia mhchia Feb 27, 2020

Choose a reason for hiding this comment

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

size_len_bytes means the size of the length field in the message. In noise, it's 2 bytes. len(msg_bytes) is encoded and put in this length field, and therefore len(msg_bytes) should be < 2**(8*2) = 65536.

read_closer: ReadCloser
next_length: Optional[int]
@abstractmethod
def encode_msg(self, msg: bytes) -> bytes:
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be public? Is it used as an external API or only called internally?

Copy link
Contributor Author

@mhchia mhchia Feb 27, 2020

Choose a reason for hiding this comment

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

It's only called internally, but I expect subclasses to implement it to make write_msg work. So as next_msg_len, which is used internally but needs to be implemented by the subclasses to make read_msg work.

Copy link
Contributor Author

@mhchia mhchia left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the review!

read_closer: ReadCloser
next_length: Optional[int]
@abstractmethod
def encode_msg(self, msg: bytes) -> bytes:
Copy link
Contributor Author

@mhchia mhchia Feb 27, 2020

Choose a reason for hiding this comment

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

It's only called internally, but I expect subclasses to implement it to make write_msg work. So as next_msg_len, which is used internally but needs to be implemented by the subclasses to make read_msg work.

return int.from_bytes(length_bytes, byteorder=BYTE_ORDER)


def encode_msg_with_length(msg_bytes: bytes) -> bytes:
len_prefix = len(msg_bytes).to_bytes(SIZE_LEN_BYTES, "big")
def encode_msg_with_length(msg_bytes: bytes, size_len_bytes: int) -> bytes:
Copy link
Contributor Author

@mhchia mhchia Feb 27, 2020

Choose a reason for hiding this comment

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

size_len_bytes means the size of the length field in the message. In noise, it's 2 bytes. len(msg_bytes) is encoded and put in this length field, and therefore len(msg_bytes) should be < 2**(8*2) = 65536.

TODO
- Figure out why `state.rs` is erased at some moment(even handshake
is not done).
- Refactor
- Add tests
TODO: Add a buffer to read only `n` bytes in `read(n)`
- Abstract it as `MsgReadWriter`
- `MsgIOReadWriter` as a subclass of `MsgReadWriter`
Make security sessions(secio, noise) share the same implementation
`BaseSession` to avoid duplicate implementation of buffered read.
`connection.py` is removed.
- Change `BaseMsgReadWriter` to encode/decode messages with abstract
method, which can be implemented by the subclasses. This allows us to
create subclasses `FixedSizeLenMsgReadWriter` and
`VarIntLenMsgReadWriter`.
@mhchia
Copy link
Contributor Author

mhchia commented Feb 28, 2020

I'm merging this PR since it gets too large and it already works fine with the go implementation. Will open a new one if everything gets updated.

@mhchia mhchia merged commit 9d68de8 into libp2p:master Feb 28, 2020
@mhchia mhchia deleted the feature/noise-patterxx branch February 28, 2020 09:13
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.

3 participants