Hi!
tcp-stream is currently the only thing holding the pbkdf2 0.12 generation in place for the whole lapin dependency tree.
The chain
tcp-stream 0.34.14 → p12-keystore ^0.2
p12-keystore 0.2.1 → pkcs5 ^0.7
pkcs5 0.7.1 → pbkdf2 ^0.12
The newer generation already exists upstream:
p12-keystore 0.3.1 → pkcs5 ^0.8
pkcs5 0.8.1 → pbkdf2 ^0.13
lapin, amq-protocol and amq-protocol-tcp are all already at their latest releases, so tcp-stream is the only place in the chain where this can move.
Why it matters downstream
Any tree combining lapin with a crate that has moved to pbkdf2 0.13 ends up with two pbkdf2 majors. In our case it's the mongodb driver: 3.8.0 requires pbkdf2 ^0.13, lapin transitively requires ^0.12, and with cargo deny's [bans] multiple-versions = "deny" there's no version of either we can pick that resolves it. The same will apply to anyone else on the RustCrypto formats train.
Proposed patch
p12-keystore is used in exactly one place (the private rustls_identity() in src/rustls_impl.rs) and 0.3 has three mechanical breaking changes:
KeyStore::from_pkcs12 takes a new Pkcs12ImportPolicy
PrivateKeyChain::chain() → certs()
PrivateKeyChain::key() returns &PrivateKey instead of &[u8]
Cargo.toml:
[dependencies.p12-keystore]
-version = "^0.2"
+version = "^0.3"
optional = true
src/rustls_impl.rs:
Identity::PKCS12 { der, password } => {
- let pfx =
- p12_keystore::KeyStore::from_pkcs12(der, password).map_err(io::Error::other)?;
+ let pfx = p12_keystore::KeyStore::from_pkcs12(
+ der,
+ password,
+ p12_keystore::Pkcs12ImportPolicy::Strict,
+ )
+ .map_err(io::Error::other)?;
let Some((_, keychain)) = pfx.private_key_chain() else {
return Err(io::Error::other("No private key in pkcs12 DER"));
};
let certs = keychain
- .chain()
+ .certs()
.iter()
.map(|cert| CertificateDer::from(cert.as_der().to_vec()))
.collect();
(
certs,
- PrivateKeyDer::from(PrivatePkcs8KeyDer::from(keychain.key().to_vec())),
+ PrivateKeyDer::from(PrivatePkcs8KeyDer::from(keychain.key().as_der().to_vec())),
)
}
Pkcs12ImportPolicy::Strict is the #[default], and it reproduces 0.2's behaviour exactly. The policy is read in three places in from_pkcs12, and under Strict all three collapse to what 0.2 did unconditionally: keys are linked to certificates by local_key_id, keys with no match are dropped (0.2 had no else branch there), and standalone certificates are imported only when local_key_id.is_none() && trusted. The issuer-chain walk is unchanged apart from chain being renamed to certs. So this should be a no-op for existing users of the rustls feature.
Verified
Applied to a local copy of 0.34.14 (src/rustls_impl.rs on main is identical to the published crate, so it applies as-is):
cargo check — clean
cargo test — passes (the doctest; no unit tests in the crate)
- resolved graph becomes
p12-keystore 0.3.1, pkcs5 0.8.1, pbkdf2 0.13.0
- MSRV is fine:
p12-keystore 0.3.1 declares rust-version = "1.85", tcp-stream already declares 1.88.0
Caveats
p12-keystore 0.3.1 pulls pre-release RustCrypto crates:
cms 0.3.0-pre.1
pkcs12 0.2.0-pre.0
Completely understandable if you don't want a stable tcp-stream release depending on pre-release dependencies. I'm mostly filing this so the change is written down and ready to go the day cms 0.3 and pkcs12 0.2 stabilise.
Happy to open a PR with the above whenever you'd find it useful, just say the word.
Thanks for maintaining all of this.
Hi!
tcp-streamis currently the only thing holding thepbkdf20.12 generation in place for the wholelapindependency tree.The chain
The newer generation already exists upstream:
lapin,amq-protocolandamq-protocol-tcpare all already at their latest releases, sotcp-streamis the only place in the chain where this can move.Why it matters downstream
Any tree combining
lapinwith a crate that has moved topbkdf2 0.13ends up with twopbkdf2majors. In our case it's themongodbdriver: 3.8.0 requirespbkdf2 ^0.13,lapintransitively requires^0.12, and withcargo deny's[bans] multiple-versions = "deny"there's no version of either we can pick that resolves it. The same will apply to anyone else on the RustCrypto formats train.Proposed patch
p12-keystoreis used in exactly one place (the privaterustls_identity()insrc/rustls_impl.rs) and 0.3 has three mechanical breaking changes:KeyStore::from_pkcs12takes a newPkcs12ImportPolicyPrivateKeyChain::chain()→certs()PrivateKeyChain::key()returns&PrivateKeyinstead of&[u8]Cargo.toml:src/rustls_impl.rs:Identity::PKCS12 { der, password } => { - let pfx = - p12_keystore::KeyStore::from_pkcs12(der, password).map_err(io::Error::other)?; + let pfx = p12_keystore::KeyStore::from_pkcs12( + der, + password, + p12_keystore::Pkcs12ImportPolicy::Strict, + ) + .map_err(io::Error::other)?; let Some((_, keychain)) = pfx.private_key_chain() else { return Err(io::Error::other("No private key in pkcs12 DER")); }; let certs = keychain - .chain() + .certs() .iter() .map(|cert| CertificateDer::from(cert.as_der().to_vec())) .collect(); ( certs, - PrivateKeyDer::from(PrivatePkcs8KeyDer::from(keychain.key().to_vec())), + PrivateKeyDer::from(PrivatePkcs8KeyDer::from(keychain.key().as_der().to_vec())), ) }Pkcs12ImportPolicy::Strictis the#[default], and it reproduces 0.2's behaviour exactly. The policy is read in three places infrom_pkcs12, and underStrictall three collapse to what 0.2 did unconditionally: keys are linked to certificates bylocal_key_id, keys with no match are dropped (0.2 had noelsebranch there), and standalone certificates are imported only whenlocal_key_id.is_none() && trusted. The issuer-chain walk is unchanged apart fromchainbeing renamed tocerts. So this should be a no-op for existing users of therustlsfeature.Verified
Applied to a local copy of 0.34.14 (
src/rustls_impl.rsonmainis identical to the published crate, so it applies as-is):cargo check— cleancargo test— passes (the doctest; no unit tests in the crate)p12-keystore 0.3.1,pkcs5 0.8.1,pbkdf2 0.13.0p12-keystore 0.3.1declaresrust-version = "1.85",tcp-streamalready declares1.88.0Caveats
p12-keystore 0.3.1pulls pre-release RustCrypto crates:Completely understandable if you don't want a stable
tcp-streamrelease depending on pre-release dependencies. I'm mostly filing this so the change is written down and ready to go the daycms0.3 andpkcs120.2 stabilise.Happy to open a PR with the above whenever you'd find it useful, just say the word.
Thanks for maintaining all of this.