From d676c7b8db30ccc15611b9ef51ed9c6f2e8a954a Mon Sep 17 00:00:00 2001 From: Bradley Axen Date: Sun, 25 Oct 2026 23:42:55 -0700 Subject: [PATCH] fix(deps): bump p256 to 0.14 for RUSTSEC-2026-0387 (#8592) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary RustSec published [RUSTSEC-2026-0387](https://rustsec.org/advisories/RUSTSEC-2026-0387) against `crypto-bigint`. Some of its operations meant to be constant-time could compile to code that branches on secret values. Since the advisory came out, `cargo-deny check` reports advisories as failed. That breaks `Security Domain / Security` on `main` and on every PR that runs the Rust security job (for example #8575 and #8579). `crypto-bigint` 0.5.5 came in only through `p256` 0.13 → `elliptic-curve` 0.13 in `buzz-push-gateway`. The advisory has no 0.5.x fix; the patched line is 0.7.6+. This PR moves `buzz-push-gateway` to `p256` 0.14, which uses `crypto-bigint` 0.7.9. | Advisory | Crate | Change | |---|---|---| | [RUSTSEC-2026-0387](https://rustsec.org/advisories/RUSTSEC-2026-0387) | `crypto-bigint` | 0.5.5 → 0.7.9 (via `p256` 0.13.2 → 0.14.0) | **Code changes:** `p256` 0.14 renamed the SEC1 encoder from `ToEncodedPoint::to_encoded_point` to `ToSec1Point::to_sec1_point`. The gateway calls it in two places, both to re-encode an App Attest public key as uncompressed SEC1 bytes. The tests call it in five more. Nothing else in the gateway's API use changed. **Lockfile:** only the `p256` dependency chain changes: `ecdsa`, `elliptic-curve`, `ff`, `group`, `primeorder`, `rfc6979` and `sec1` move up a minor version. `primefield` and `wnaf` are added. The old `der`/`spki`/`pkcs8`/`pem-rfc7468`/`const-oid` 0.x versions that only this chain used are removed. `desktop/src-tauri/Cargo.lock` and the `buzz-feature-flags` fixture lockfile don't contain `crypto-bigint`, so they're unchanged. **Exposure, for context:** in production the gateway uses `p256` only to verify App Attest signatures against public keys. Signing with a private key happens only in tests. So the timing issue didn't realistically apply here, but the bump clears the advisory instead of ignoring it. ### Related issue N/A. I searched open and closed PRs for `RUSTSEC-2026-0387` and `crypto-bigint` and found none. ### Testing - `cargo-deny check`: `advisories ok, bans ok, licenses ok, sources ok`. On `origin/main` the Security job fails on this advisory. - `cargo test -p buzz-push-gateway --all-features`: 82 passed, 18 ignored (the same tests are `#[ignore]` on `main`). - `cargo clippy -p buzz-push-gateway --all-targets --all-features -- -D warnings` is clean. - `cargo check --workspace --all-targets` passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Bradley Axen Co-authored-by: ART Co-authored-by: Claude Opus 5.5 --- Cargo.lock | 185 +++++++++--------- crates/buzz-push-gateway/Cargo.toml | 2 +- .../src/app_attest/authenticator.rs | 4 +- .../src/app_attest/certificate.rs | 4 +- .../src/app_attest_assertion_tests.rs | 16 +- 5 files changed, 99 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 467774efcd..fd257fd6c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2039,12 +2039,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - [[package]] name = "const-oid" version = "0.10.2" @@ -2304,12 +2298,16 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "d811ea23fdfbcce2e2d5132344d471abdb8f901ac496a0893a3df92e70525e52" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "getrandom 0.4.3", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] @@ -2401,6 +2399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d28fb6aa7dd680b3ffd1a3e64e115c177bdba63c0ae7f9cd48129ff05c4fa0" dependencies = [ "cmov", + "subtle", ] [[package]] @@ -2596,7 +2595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -2666,25 +2665,14 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid 0.9.6", - "pem-rfc7468 0.7.0", - "zeroize", -] - [[package]] name = "der" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ - "const-oid 0.10.2", - "pem-rfc7468 1.0.0", + "const-oid", + "pem-rfc7468", "zeroize", ] @@ -2788,7 +2776,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "const-oid 0.9.6", "crypto-common 0.1.7", "subtle", ] @@ -2800,7 +2787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", - "const-oid 0.10.2", + "const-oid", "crypto-common 0.2.2", "ctutils", ] @@ -2898,16 +2885,17 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ - "der 0.7.10", - "digest 0.10.7", + "der", + "digest 0.11.3", "elliptic-curve", "rfc6979", - "signature 2.2.0", - "spki 0.7.3", + "signature 3.0.0", + "spki", + "zeroize", ] [[package]] @@ -2916,7 +2904,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ - "pkcs8 0.11.0", + "pkcs8", "serdect", "signature 3.0.0", ] @@ -2948,19 +2936,20 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "900f37e7e18d74a2347389af6cd69e3a30d5cc9e697f40004865679aa75e9c7c" dependencies = [ - "base16ct 0.2.0", + "base16ct 1.0.0", "crypto-bigint", - "digest 0.10.7", + "crypto-common 0.2.2", + "digest 0.11.3", "ff", - "generic-array", "group", - "pem-rfc7468 0.7.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", + "hybrid-array", + "pem-rfc7468", + "pkcs8", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", @@ -3199,11 +3188,11 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -3633,12 +3622,12 @@ dependencies = [ [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -4018,7 +4007,9 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ + "subtle", "typenum", + "zeroize", ] [[package]] @@ -7138,14 +7129,15 @@ dependencies = [ [[package]] name = "p256" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +checksum = "d2c9239b2dbc807adbbe147e8cf72ea7450c3a0aabe62cb8e75ff4ec22e1f72a" dependencies = [ "ecdsa", "elliptic-curve", + "primefield", "primeorder", - "sha2 0.10.9", + "sha2 0.11.0", ] [[package]] @@ -7270,15 +7262,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - [[package]] name = "pem-rfc7468" version = "1.0.0" @@ -7467,24 +7450,14 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.10", - "spki 0.7.3", -] - [[package]] name = "pkcs8" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ - "der 0.8.2", - "spki 0.8.0", + "der", + "spki", ] [[package]] @@ -7683,12 +7656,30 @@ dependencies = [ ] [[package]] -name = "primeorder" -version = "0.13.6" +name = "primefield" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.2", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ "elliptic-curve", + "once_cell", + "primefield", + "serdect", + "wnaf", ] [[package]] @@ -8617,12 +8608,12 @@ checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ - "hmac 0.12.1", - "subtle", + "crypto-bigint", + "hmac 0.13.0", ] [[package]] @@ -9061,14 +9052,14 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ - "base16ct 0.2.0", - "der 0.7.10", - "generic-array", - "pkcs8 0.10.2", + "base16ct 1.0.0", + "ctutils", + "der", + "hybrid-array", "subtle", "zeroize", ] @@ -9517,7 +9508,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", "rand_core 0.6.4", ] @@ -9527,6 +9517,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ + "digest 0.11.3", "rand_core 0.10.1", ] @@ -9808,16 +9799,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.10", -] - [[package]] name = "spki" version = "0.8.0" @@ -9825,7 +9806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", - "der 0.8.2", + "der", ] [[package]] @@ -12266,6 +12247,18 @@ dependencies = [ "windows-core 0.62.2", ] +[[package]] +name = "wnaf" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" +dependencies = [ + "ff", + "group", + "hybrid-array", + "primefield", +] + [[package]] name = "writeable" version = "0.6.3" diff --git a/crates/buzz-push-gateway/Cargo.toml b/crates/buzz-push-gateway/Cargo.toml index 29dc8d2137..2a0884d01c 100644 --- a/crates/buzz-push-gateway/Cargo.toml +++ b/crates/buzz-push-gateway/Cargo.toml @@ -23,7 +23,7 @@ personal-dev-app-attest = [] aes-gcm = "0.10" aws-lc-rs = { version = "1", default-features = false } minicbor = { version = "0.25", features = ["std", "half"] } -p256 = { version = "0.13", features = ["ecdsa"] } +p256 = { version = "0.14", features = ["ecdsa"] } rustls-pki-types = { version = "1", features = ["std"] } webpki = { package = "rustls-webpki", version = "0.103.9", default-features = false, features = ["aws-lc-rs", "alloc"] } x509-parser = { version = "0.18.1", default-features = false } diff --git a/crates/buzz-push-gateway/src/app_attest/authenticator.rs b/crates/buzz-push-gateway/src/app_attest/authenticator.rs index 7bc4ed060d..a73c4e2726 100644 --- a/crates/buzz-push-gateway/src/app_attest/authenticator.rs +++ b/crates/buzz-push-gateway/src/app_attest/authenticator.rs @@ -5,7 +5,7 @@ use super::{ properties::ClientProperties, }; use aws_lc_rs::digest::{digest, SHA256}; -use p256::elliptic_curve::sec1::ToEncodedPoint; +use p256::elliptic_curve::sec1::ToSec1Point; pub(super) struct Checked { pub counter: u32, @@ -130,7 +130,7 @@ fn credential_key(tail: &[u8]) -> Result<([u8; 65], usize), Error> { let key = p256::PublicKey::from_sec1_bytes(&encoded).map_err(|_| Error::InvalidPublicKey)?; Ok(( - key.to_encoded_point(false) + key.to_sec1_point(false) .as_bytes() .try_into() .map_err(|_| Error::InvalidPublicKey)?, diff --git a/crates/buzz-push-gateway/src/app_attest/certificate.rs b/crates/buzz-push-gateway/src/app_attest/certificate.rs index 4d60c41274..6a7656df01 100644 --- a/crates/buzz-push-gateway/src/app_attest/certificate.rs +++ b/crates/buzz-push-gateway/src/app_attest/certificate.rs @@ -1,7 +1,7 @@ //! Apple certificate adapters; path and signature validation remain in webpki. use super::error::AppAttestError as Error; use aws_lc_rs::digest::{digest, SHA256}; -use p256::elliptic_curve::sec1::ToEncodedPoint; +use p256::elliptic_curve::sec1::ToSec1Point; use rustls_pki_types::{CertificateDer, UnixTime}; use x509_parser::{certificate::X509Certificate, parse_x509_certificate}; @@ -86,7 +86,7 @@ pub(super) fn public_key(bytes: &[u8]) -> Result<[u8; 65], Error> { } let key = p256::PublicKey::from_sec1_bytes(spki.subject_public_key.data.as_ref()) .map_err(|_| Error::InvalidPublicKey)?; - key.to_encoded_point(false) + key.to_sec1_point(false) .as_bytes() .try_into() .map_err(|_| Error::InvalidPublicKey) diff --git a/crates/buzz-push-gateway/src/app_attest_assertion_tests.rs b/crates/buzz-push-gateway/src/app_attest_assertion_tests.rs index 6e85e4958d..6fbb55dfbb 100644 --- a/crates/buzz-push-gateway/src/app_attest_assertion_tests.rs +++ b/crates/buzz-push-gateway/src/app_attest_assertion_tests.rs @@ -48,10 +48,7 @@ fn verify(cbor: &[u8]) -> Result { verifier.verify_assertion( &STANDARD.encode(cbor), TRANSCRIPT, - signing_key() - .verifying_key() - .to_encoded_point(false) - .as_ref(), + signing_key().verifying_key().to_sec1_point(false).as_ref(), 0, "challenge", "challenge", @@ -117,10 +114,7 @@ mod conformance { cbor, TRANSCRIPT, APP_ID, - signing_key() - .verifying_key() - .to_encoded_point(false) - .as_ref(), + signing_key().verifying_key().to_sec1_point(false).as_ref(), 0, ) } @@ -179,7 +173,7 @@ mod conformance { #[test] fn signed_bytes_identity_key_and_replay_preserved() { let cbor = signed_assertion(&auth_data(b"\xa1\x61x\x01")); - let key = signing_key().verifying_key().to_encoded_point(false); + let key = signing_key().verifying_key().to_sec1_point(false); assert!(verify_bytes(&cbor, b"changed", APP_ID, key.as_ref(), 0).is_err()); assert!(verify_bytes(&cbor, TRANSCRIPT, "other.app", key.as_ref(), 0).is_err()); assert!(verify_bytes(&cbor, TRANSCRIPT, APP_ID, key.as_ref(), 1).is_err()); @@ -189,7 +183,7 @@ mod conformance { &cbor, TRANSCRIPT, APP_ID, - other.verifying_key().to_encoded_point(false).as_ref(), + other.verifying_key().to_sec1_point(false).as_ref(), 0 ) .is_err()); @@ -438,7 +432,7 @@ mod properties { #[test] fn maximum_counter_is_accepted_once_and_cannot_wrap() { - let key = signing_key().verifying_key().to_encoded_point(false); + let key = signing_key().verifying_key().to_sec1_point(false); let mut auth = auth_data(b"\xa0"); auth[33..37].copy_from_slice(&u32::MAX.to_be_bytes()); let signed = signed_assertion(&auth);