diff --git a/Cargo.lock b/Cargo.lock index 67ec831..69ae78b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,56 +39,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "anstream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - -[[package]] -name = "anstyle-parse" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", -] - [[package]] name = "async-trait" version = "0.1.92" @@ -154,12 +104,6 @@ version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.12.1" @@ -185,15 +129,12 @@ dependencies = [ [[package]] name = "cachekit-core" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93adc5646956ba8da140f4179a02e60a2cc7a401b83ebb1270cc4d03748e1fac" +checksum = "da83c6ae3ed61a36c8344bf5246d69528e6937b3df8445830d073f74d5327888" dependencies = [ "aes", "aes-gcm", - "byteorder", - "bytes", - "cbindgen", "generic-array", "getrandom 0.2.17", "hkdf", @@ -211,9 +152,9 @@ dependencies = [ [[package]] name = "cachekit-rs" -version = "0.9.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "792ee2d3467ba052d5d5c75192dc6c3d234eddaa348f3f4af82fdbcb213c775e" +checksum = "23db3fd71aa97e672e0f04be9eb62a8546fe401ac03a9f2d260d88f135f87733" dependencies = [ "async-trait", "blake2", @@ -235,25 +176,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "cbindgen" -version = "0.29.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ecb53484c9c167ba674026b656d8a27d7657a58e6066aa902bfb1a4aa00ae20" -dependencies = [ - "clap", - "heck", - "indexmap", - "log", - "proc-macro2", - "quote", - "serde", - "serde_json", - "syn 2.0.119", - "tempfile", - "toml", -] - [[package]] name = "cc" version = "1.5.1" @@ -297,39 +219,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clap" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" - -[[package]] -name = "colorchoice" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" - [[package]] name = "cpufeatures" version = "0.2.17" @@ -390,12 +279,6 @@ dependencies = [ "syn 3.0.6", ] -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - [[package]] name = "errno" version = "0.3.14" @@ -507,18 +390,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hex" version = "0.4.3" @@ -744,16 +615,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "indexmap" -version = "2.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" -dependencies = [ - "equivalent", - "hashbrown", -] - [[package]] name = "inout" version = "0.1.4" @@ -769,12 +630,6 @@ version = "2.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - [[package]] name = "itoa" version = "1.0.18" @@ -863,12 +718,6 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - [[package]] name = "opaque-debug" version = "0.3.1" @@ -1213,15 +1062,6 @@ dependencies = [ "zmij", ] -[[package]] -name = "serde_spanned" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" -dependencies = [ - "serde_core", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1299,12 +1139,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "subtle" version = "2.6.1" @@ -1438,45 +1272,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_parser" -version = "1.1.3+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" -dependencies = [ - "winnow 1.0.4", -] - -[[package]] -name = "toml_writer" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" - [[package]] name = "tower" version = "0.5.3" @@ -1605,12 +1400,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - [[package]] name = "uuid" version = "1.26.1" @@ -1816,18 +1605,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - -[[package]] -name = "winnow" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" - [[package]] name = "writeable" version = "0.6.4" diff --git a/Cargo.toml b/Cargo.toml index 3a56c27..f0f551e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,8 @@ unsafe_code = "deny" [dependencies] blake2 = "0.10" -cachekit-core = { version = "0.6", default-features = false, features = ["encryption"] } -cachekit-rs = { version = "0.9", default-features = false, features = ["cachekitio", "encryption", "file"] } +cachekit-core = { version = "0.7", default-features = false, features = ["encryption"] } +cachekit-rs = { version = "0.11.1", default-features = false, features = ["cachekitio", "encryption", "file"] } getrandom = "0.2" hex = "0.4" libc = "0.2" diff --git a/deny.toml b/deny.toml index 65824c9..a2378fa 100644 --- a/deny.toml +++ b/deny.toml @@ -4,14 +4,9 @@ [licenses] # Permissive licences only, each one carried by the real dependency graph. allow = ["MIT", "Apache-2.0", "BSD-3-Clause", "BSL-1.0", "ISC", "Unicode-3.0"] -# cbindgen is an unconditional build dependency of cachekit-core that its -# build script uses only under the `ffi` feature, which ck does not enable. -# It runs at build time and none of its code is linked into ck. -# # webpki-roots is the Mozilla root-certificate bundle that the SaaS backend's # TLS client trusts. It is data, not code, under a permissive data licence. exceptions = [ - { crate = "cbindgen", allow = ["MPL-2.0"] }, { crate = "webpki-roots", allow = ["CDLA-Permissive-2.0"] }, ] @@ -20,7 +15,14 @@ wildcards = "deny" # ck has no HTTP client of its own: every network call goes through # cachekit-rs, whose request paths are fixed. A direct HTTP client # dependency fails here. -deny = [{ crate = "reqwest", wrappers = ["cachekit-rs"] }] +# +# ck derives its cache-key hash key from cachekit-core and encrypts through +# cachekit-rs's EncryptionLayer. Two cachekit-core versions would let those +# drift apart and still build. +deny = [ + { crate = "reqwest", wrappers = ["cachekit-rs"] }, + { crate = "cachekit-core", deny-multiple-versions = true }, +] [sources] unknown-registry = "deny" diff --git a/src/keys.rs b/src/keys.rs index 4ddcbc7..ab23a1f 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -231,6 +231,16 @@ mod tests { } } + /// A known answer. A dependency bump that changes the key derivation + /// fails here, instead of turning every stored entry into a silent miss. + #[test] + fn value_key_known_answer() { + assert_eq!( + hasher().value_key(&"".into(), &os(&["op", "read"])), + "ns:ck-run:v1:041385329ef05862f32fad778ee6c2a69581637fd18926b3b0e8819aee6662ec" + ); + } + #[test] fn different_master_keys_give_disjoint_keys() { let other = KeyHasher::new(&[8u8; 32]).unwrap(); diff --git a/src/store.rs b/src/store.rs index 14effa6..6e30529 100644 --- a/src/store.rs +++ b/src/store.rs @@ -14,7 +14,7 @@ use crate::keys::TENANT; use crate::{warn, Fatal}; /// Each saas round trip gets this long. The cachekit-rs client's own -/// timeouts (30 s per request, 10 s to connect) cannot be changed. +/// timeouts run to several seconds and cannot be changed. pub(crate) const SAAS_DEADLINE: Duration = Duration::from_secs(1); /// The saas capture cap. The deadline covers the download too, so an entry @@ -280,6 +280,20 @@ impl Drop for Runtime { mod tests { use super::*; + /// An entry an earlier ck wrote still decrypts. The ciphertext came from + /// cachekit-rs 0.9.0 with cachekit-core 0.6.0, master key `[7; 32]`, under + /// the key from `keys::tests::value_key_known_answer`. + #[test] + fn an_older_entry_still_decrypts() { + let key = "ns:ck-run:v1:041385329ef05862f32fad778ee6c2a69581637fd18926b3b0e8819aee6662ec"; + let ciphertext = hex::decode( + "c90083142ccd441f0000000081198d2ce5728477cfab8528cb949c6393c0eeecc2dce5218b717e7fb3ea36", + ) + .unwrap(); + let layer = EncryptionLayer::new(&[7u8; 32], TENANT).unwrap(); + assert_eq!(layer.decrypt(&ciphertext, key).unwrap(), b"ck known answer"); + } + #[test] fn an_authentication_error_names_the_fix() { let e = BackendError::from_http_status(403, b"namespace not granted");