Open melekes opened 2 years ago
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?).
@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.
I would guess @MarcoPolo has opinions here given his related work on https://github.com/libp2p/go-libp2p/pull/1833.
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.
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.
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.
This now also affects WebTransport: https://github.com/libp2p/rust-libp2p/pull/4874
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.
This crate might help: https://docs.rs/x509-cert.
Credits to @pinkforest for pointing me to it.
Draft for generating deterministic(?) certificates: https://gist.github.com/nnathan/73ccb767ba706ccd07686066e0fde0f5
Also cc @dgarus
Draft for generating deterministic(?) certificates: https://gist.github.com/nnathan/73ccb767ba706ccd07686066e0fde0f5
Also cc @dgarus
Forgotten all about x509-cert crate honestly. Hopefully we can use this in a meaningful way in rust-libp2p
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.