-
Notifications
You must be signed in to change notification settings - Fork 280
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
PeerIDs and QUIC #37
Comments
Option 3 has the advantage that it's usually hard (impossible?) to get the peer's public key exported from the Go TLS implementation (and also from mint, the TLS 1.3 implementation I'm using for QUIC). The certificate (chain) would be easily accessible via the |
I implemented option 3 using TLS 1.2 as a proof of concept: https://gist.github.com/marten-seemann/33482be37e31dc8288c53af0b2abf13a. You can run this gist, it will create a server instance and connect to it with a client, each peer verifying the other's identity. For this PoC, I implemented peers from scratch (and didn't use go-libp2p-peer and go-libp2p-crypto), because I need access to raw ECDSA keys, which the libp2p libs currently don't provide. The handshake works as follows:
Note that for the sake of simplicity, in my PoC, I'm using a global self-signed CA certificate to sign the peer's certificate. This cert is shared by client and server and added to the root CA pool. The only reason for doing this is such that I can the Go standard library certificate verification. In IPFS, we probably don't want to hardcode a CA cert into every node. That means we will have to do the cert chain verification manually, instead of relying on the standard library doing this for us (this is not too hard: parse the certificates, check that the chain is correctly signed, and check a few metadata cert fields, e.g. the expiry dates). I'll be happy to update the code if we decide to move forward with this. Authenticating a peer in that scheme is straightforward. The peers dial a TLS connection, and once the handshake completes, the verified certificate chain can be obtained from the TLS connection state. The peer then looks at the certificate in the chain that was created using the remote peer's public / private key pair, and checks that the hash of the public key matches the peer ID. I'm hoping to get feedback about this from as many people as possible. Tagging @jbenet, @Stebalien, @whyrusleeping, @Kubuxu, @diasdavid, @lgierth here (please tag anyone I've forgotten here as well). This handshake might be terribly broken. My background is not in crypto engineering, so I don't trust it at all at this moment, but I hope that this is a good starting point for a thorough analysis and discussion. |
@jbenet, @Stebalien, @whyrusleeping, @Kubuxu, @diasdavid, @lgierth: Any feedback? |
Sorry, I thought I responded to this ages ago. LGTM as long as we don't expose the connection until we've checked the signatures.
Agreed. Also, in the certificate generated by the peer ID, we should probably encode some statement to the effect: "this (ephemeral) key may be used to authenticate connections to peer $self". That way, we can extend this in the future to add support for, e.g., delegation. Unfortunately, I'm not familiar enough with x509 to know where this information should go. |
Option 3 sounds good to me! Will the setup with TLS 1.3 be the same as you described above? I'm thinking there's not much need for TLS 1.2 in a new system. Otherwise I think this LGTM 👍 :) |
As far as I can tell both the discussion and the Golang implementation have settled on option (3), thus I am closing here. If I am not mistaken a libp2p QUIC specification is yet to be written. |
For posterity, you should use the peer authentication scheme in the libp2p spec to tie a peer id to a QUIC connection. |
Question: Given that QUIC has built-in crypto, how should we associate PeerIDs with QUIC connections.
Our options are:
@whyrusleeping @Kubuxu @lgierth @marten-seemann
The text was updated successfully, but these errors were encountered: