rust-libp2p icon indicating copy to clipboard operation
rust-libp2p copied to clipboard

transports: Deterministic certificate generation

Open melekes opened this issue 3 years ago • 11 comments

Presently (https://github.com/libp2p/rust-libp2p/pull/2622), the certificate is supposed to be generated and stored somewhere along the node's key. This could be improved. As it was pointed out in the spec, we should be able to derive a TLS certificate from node's key. This will improve dev experience.

melekes avatar Oct 20 '22 13:10 melekes

I've spent today looking into ways of doing it. One way is

        // Convert `identity::KeyPair` into `rcgen::KeyPair`.
        let der = id_keys.serialize_der();
        let key_pair = rcgen::KeyPair::from_der(der).map_err(ConfigError::CertificateGenError)?;
        params.key_pair = Some(key_pair);

convert identity::KeyPair to DER and create rcgen::KeyPair from it.

@thomaseizinger pointed out that it might be simpler to use HKDF that will act as the seed for randomness (at what point? during certificate creation https://docs.rs/rcgen/0.10.0/rcgen/struct.CertificateParams.html#structfield.serial_number?).

melekes avatar Oct 20 '22 13:10 melekes

@thomaseizinger pointed out that it might be simpler to use HKDF that will act as the seed for randomness (at what point? during certificate creation https://docs.rs/rcgen/0.10.0/rcgen/struct.CertificateParams.html#structfield.serial_number?).

I think we need to patch rcgen to allow for configuration of the randomness source to put in a deterministic one based off a seed. You can then use a HKDF to generate the seed.

There is also randomness in the ECDSA signature on the certificate itself so if you want truly deterministic certificates, that needs to be fixed too. Just the same Keypair doesn't cut it.

For the HKDF, it is probably better to generate the certificate seed and the keypair from different derivations from a common secret and not the certificate from the keypair.

thomaseizinger avatar Oct 20 '22 13:10 thomaseizinger

I would guess @MarcoPolo has opinions here given his related work on https://github.com/libp2p/go-libp2p/pull/1833.

mxinden avatar Oct 21 '22 15:10 mxinden

If patching rcgen is too hard, we might also just inline the certificate generation. ring does all the heavy lifting of the crypto anyway and we don't need much configuration for our usecase so this could turn out quite clean actually.

thomaseizinger avatar Oct 21 '22 22:10 thomaseizinger

As mentioned in https://github.com/melekes/rust-libp2p/pull/12, this is blocked on https://github.com/briansmith/ring/commit/fe9e4d08c1727bea42d31e0d31ee58c4e8e4dc4e getting released and webrtc updating to that new ring release.

thomaseizinger avatar Oct 26 '22 08:10 thomaseizinger

I think this would also be easier to resolve with #3659 because str0m depends on openssl and to parse the cerificate, meaning we don't necessarily need to use ring to generate it.

thomaseizinger avatar Apr 16 '23 09:04 thomaseizinger

This now also affects WebTransport: https://github.com/libp2p/rust-libp2p/pull/4874

thomaseizinger avatar Dec 22 '23 08:12 thomaseizinger

While its possible to get around this by generating the cert outside of the behaviour, i think until ring does ever support RFC6979, we should probably do a workaround, though might be considered hacky, but would get the job done to make the cert deterministic out of the box for webrtc (and webtransport when the server side is implemented in libp2p) vs outside workarounds.

dariusc93 avatar May 04 '24 22:05 dariusc93