Compare commits
5 Commits
c5b51f4b70
...
47108ed8ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47108ed8ad | ||
|
|
359df73c2e | ||
|
|
ce03b7e15d | ||
|
|
e4038d9188 | ||
|
|
c82339d764 |
44
server/Cargo.lock
generated
44
server/Cargo.lock
generated
@@ -94,7 +94,6 @@ dependencies = [
|
|||||||
"rustls",
|
"rustls",
|
||||||
"secrecy",
|
"secrecy",
|
||||||
"smlang",
|
"smlang",
|
||||||
"statig",
|
|
||||||
"strum",
|
"strum",
|
||||||
"test-log",
|
"test-log",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -1725,28 +1724,6 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error-attr2"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error2"
|
|
||||||
version = "2.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-error-attr2",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.115",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.106"
|
version = "1.0.106"
|
||||||
@@ -2229,27 +2206,6 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "statig"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "03c04b4a9f2d66294d63bdd8df834caad9f8e181997c3cf766b6b4f6d12d4fbc"
|
|
||||||
dependencies = [
|
|
||||||
"statig_macro",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "statig_macro"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8090ca395ee30c4b38fee68cf4ddf0bcc5f01aa83364cd4c3ec737a1596dab4d"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-error2",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.115",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string_morph"
|
name = "string_morph"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ zeroize = { version = "1.8.2", features = ["std", "simd"] }
|
|||||||
kameo.workspace = true
|
kameo.workspace = true
|
||||||
x25519-dalek = { version = "2.0.1", features = ["getrandom"] }
|
x25519-dalek = { version = "2.0.1", features = ["getrandom"] }
|
||||||
chacha20poly1305 = { version = "0.10.1", features = ["std"] }
|
chacha20poly1305 = { version = "0.10.1", features = ["std"] }
|
||||||
statig = { version = "0.4.1", features = ["async"] }
|
|
||||||
argon2 = { version = "0.5.3", features = ["zeroize"] }
|
argon2 = { version = "0.5.3", features = ["zeroize"] }
|
||||||
restructed = "0.2.2"
|
restructed = "0.2.2"
|
||||||
strum = { version = "0.27.2", features = ["derive"] }
|
strum = { version = "0.27.2", features = ["derive"] }
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
create table if not exists aead_encrypted (
|
|
||||||
id INTEGER not null PRIMARY KEY,
|
|
||||||
current_nonce blob not null default(1), -- if re-encrypted, this should be incremented
|
|
||||||
ciphertext blob not null,
|
|
||||||
tag blob not null,
|
|
||||||
schema_version integer not null default(1), -- server would need to reencrypt, because this means that we have changed algorithm
|
|
||||||
created_at integer not null default(unixepoch ('now'))
|
|
||||||
) STRICT;
|
|
||||||
|
|
||||||
create table if not exists root_key_history (
|
create table if not exists root_key_history (
|
||||||
id INTEGER not null PRIMARY KEY,
|
id INTEGER not null PRIMARY KEY,
|
||||||
-- root key stored as aead encrypted artifact, with only difference that it's decrypted by unseal key (derived from user password)
|
-- root key stored as aead encrypted artifact, with only difference that it's decrypted by unseal key (derived from user password)
|
||||||
@@ -18,6 +9,21 @@ create table if not exists root_key_history (
|
|||||||
salt blob not null -- for key deriviation
|
salt blob not null -- for key deriviation
|
||||||
) STRICT;
|
) STRICT;
|
||||||
|
|
||||||
|
create table if not exists aead_encrypted (
|
||||||
|
id INTEGER not null PRIMARY KEY,
|
||||||
|
current_nonce blob not null default(1), -- if re-encrypted, this should be incremented
|
||||||
|
ciphertext blob not null,
|
||||||
|
tag blob not null,
|
||||||
|
schema_version integer not null default(1), -- server would need to reencrypt, because this means that we have changed algorithm
|
||||||
|
associated_root_key_id integer not null references root_key_history (id) on delete RESTRICT,
|
||||||
|
created_at integer not null default(unixepoch ('now'))
|
||||||
|
) STRICT;
|
||||||
|
|
||||||
|
create unique index if not exists uniq_nonce_per_root_key on aead_encrypted (
|
||||||
|
current_nonce,
|
||||||
|
associated_root_key_id
|
||||||
|
);
|
||||||
|
|
||||||
-- This is a singleton
|
-- This is a singleton
|
||||||
create table if not exists arbiter_settings (
|
create table if not exists arbiter_settings (
|
||||||
id INTEGER not null PRIMARY KEY CHECK (id = 1), -- singleton row, id must be 1
|
id INTEGER not null PRIMARY KEY CHECK (id = 1), -- singleton row, id must be 1
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ use diesel::{
|
|||||||
dsl::{insert_into, update},
|
dsl::{insert_into, update},
|
||||||
};
|
};
|
||||||
use diesel_async::{AsyncConnection, RunQueryDsl};
|
use diesel_async::{AsyncConnection, RunQueryDsl};
|
||||||
use kameo::{Actor, messages};
|
use kameo::{Actor, Reply, messages};
|
||||||
use memsafe::MemSafe;
|
use memsafe::MemSafe;
|
||||||
|
use strum::{EnumDiscriminants, IntoDiscriminant};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -18,19 +19,17 @@ use crate::{
|
|||||||
|
|
||||||
pub mod v1;
|
pub mod v1;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, EnumDiscriminants)]
|
||||||
|
#[strum_discriminants(derive(Reply), vis(pub))]
|
||||||
enum State {
|
enum State {
|
||||||
#[default]
|
#[default]
|
||||||
Unbootstrapped,
|
Unbootstrapped,
|
||||||
Sealed {
|
Sealed {
|
||||||
encrypted_root_key: RootKeyHistory,
|
root_key_history_id: i32,
|
||||||
data_encryption_nonce: v1::Nonce,
|
|
||||||
root_key_encryption_nonce: v1::Nonce,
|
|
||||||
},
|
},
|
||||||
Unsealed {
|
Unsealed {
|
||||||
root_key_history_id: i32,
|
root_key_history_id: i32,
|
||||||
root_key: KeyCell,
|
root_key: KeyCell,
|
||||||
nonce: v1::Nonce,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,13 +70,13 @@ pub enum Error {
|
|||||||
/// Provides API for encrypting and decrypting data using the vault root key.
|
/// Provides API for encrypting and decrypting data using the vault root key.
|
||||||
/// Abstraction over database to make sure nonces are never reused and encryption keys are never exposed in plaintext outside of this actor.
|
/// Abstraction over database to make sure nonces are never reused and encryption keys are never exposed in plaintext outside of this actor.
|
||||||
#[derive(Actor)]
|
#[derive(Actor)]
|
||||||
pub struct KeyHolderActor {
|
pub struct KeyHolder {
|
||||||
db: db::DatabasePool,
|
db: db::DatabasePool,
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[messages]
|
#[messages]
|
||||||
impl KeyHolderActor {
|
impl KeyHolder {
|
||||||
pub async fn new(db: db::DatabasePool) -> Result<Self, Error> {
|
pub async fn new(db: db::DatabasePool) -> Result<Self, Error> {
|
||||||
let state = {
|
let state = {
|
||||||
let mut conn = db.get().await?;
|
let mut conn = db.get().await?;
|
||||||
@@ -90,21 +89,7 @@ impl KeyHolderActor {
|
|||||||
|
|
||||||
match root_key_history {
|
match root_key_history {
|
||||||
Some(root_key_history) => State::Sealed {
|
Some(root_key_history) => State::Sealed {
|
||||||
data_encryption_nonce: Nonce::try_from(
|
root_key_history_id: root_key_history.id,
|
||||||
root_key_history.data_encryption_nonce.as_slice(),
|
|
||||||
)
|
|
||||||
.map_err(|_| {
|
|
||||||
error!("Broken database: invalid data encryption nonce");
|
|
||||||
Error::BrokenDatabase
|
|
||||||
})?,
|
|
||||||
root_key_encryption_nonce: Nonce::try_from(
|
|
||||||
root_key_history.root_key_encryption_nonce.as_slice(),
|
|
||||||
)
|
|
||||||
.map_err(|_| {
|
|
||||||
error!("Broken database: invalid root key encryption nonce");
|
|
||||||
Error::BrokenDatabase
|
|
||||||
})?,
|
|
||||||
encrypted_root_key: root_key_history,
|
|
||||||
},
|
},
|
||||||
None => State::Unbootstrapped,
|
None => State::Unbootstrapped,
|
||||||
}
|
}
|
||||||
@@ -113,6 +98,44 @@ impl KeyHolderActor {
|
|||||||
Ok(Self { db, state })
|
Ok(Self { db, state })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exclusive transaction to avoid race condtions if multiple keyholders write
|
||||||
|
// additional layer of protection against nonce-reuse
|
||||||
|
async fn get_new_nonce(pool: &db::DatabasePool, root_key_id: i32) -> Result<Nonce, Error> {
|
||||||
|
let mut conn = pool.get().await?;
|
||||||
|
|
||||||
|
let nonce = conn
|
||||||
|
.exclusive_transaction(|conn| {
|
||||||
|
Box::pin(async move {
|
||||||
|
let current_nonce: Vec<u8> = schema::root_key_history::table
|
||||||
|
.filter(schema::root_key_history::id.eq(root_key_id))
|
||||||
|
.select(schema::root_key_history::data_encryption_nonce)
|
||||||
|
.first(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut nonce =
|
||||||
|
v1::Nonce::try_from(current_nonce.as_slice()).map_err(|_| {
|
||||||
|
error!(
|
||||||
|
"Broken database: invalid nonce for root key history id={}",
|
||||||
|
root_key_id
|
||||||
|
);
|
||||||
|
Error::BrokenDatabase
|
||||||
|
})?;
|
||||||
|
nonce.increment();
|
||||||
|
|
||||||
|
update(schema::root_key_history::table)
|
||||||
|
.filter(schema::root_key_history::id.eq(root_key_id))
|
||||||
|
.set(schema::root_key_history::data_encryption_nonce.eq(nonce.to_vec()))
|
||||||
|
.execute(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Result::<_, Error>::Ok(nonce)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(nonce)
|
||||||
|
}
|
||||||
|
|
||||||
#[message]
|
#[message]
|
||||||
pub async fn bootstrap(&mut self, seal_key_raw: MemSafe<Vec<u8>>) -> Result<(), Error> {
|
pub async fn bootstrap(&mut self, seal_key_raw: MemSafe<Vec<u8>>) -> Result<(), Error> {
|
||||||
if !matches!(self.state, State::Unbootstrapped) {
|
if !matches!(self.state, State::Unbootstrapped) {
|
||||||
@@ -122,6 +145,7 @@ impl KeyHolderActor {
|
|||||||
let mut seal_key = v1::derive_seal_key(seal_key_raw, &salt);
|
let mut seal_key = v1::derive_seal_key(seal_key_raw, &salt);
|
||||||
let mut root_key = KeyCell::new_secure_random();
|
let mut root_key = KeyCell::new_secure_random();
|
||||||
|
|
||||||
|
// Zero nonces are fine because they are one-time
|
||||||
let root_key_nonce = v1::Nonce::default();
|
let root_key_nonce = v1::Nonce::default();
|
||||||
let data_encryption_nonce = v1::Nonce::default();
|
let data_encryption_nonce = v1::Nonce::default();
|
||||||
|
|
||||||
@@ -168,7 +192,6 @@ impl KeyHolderActor {
|
|||||||
self.state = State::Unsealed {
|
self.state = State::Unsealed {
|
||||||
root_key,
|
root_key,
|
||||||
root_key_history_id,
|
root_key_history_id,
|
||||||
nonce: data_encryption_nonce,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Keyholder bootstrapped successfully");
|
info!("Keyholder bootstrapped successfully");
|
||||||
@@ -179,36 +202,52 @@ impl KeyHolderActor {
|
|||||||
#[message]
|
#[message]
|
||||||
pub async fn try_unseal(&mut self, seal_key_raw: MemSafe<Vec<u8>>) -> Result<(), Error> {
|
pub async fn try_unseal(&mut self, seal_key_raw: MemSafe<Vec<u8>>) -> Result<(), Error> {
|
||||||
let State::Sealed {
|
let State::Sealed {
|
||||||
encrypted_root_key,
|
root_key_history_id,
|
||||||
data_encryption_nonce,
|
} = &self.state
|
||||||
root_key_encryption_nonce,
|
|
||||||
} = &mut self.state
|
|
||||||
else {
|
else {
|
||||||
return Err(Error::NotBootstrapped);
|
return Err(Error::NotBootstrapped);
|
||||||
};
|
};
|
||||||
|
|
||||||
let salt = &encrypted_root_key.salt;
|
// We don't want to hold connection while doing expensive KDF work
|
||||||
|
let current_key = {
|
||||||
|
let mut conn = self.db.get().await?;
|
||||||
|
schema::root_key_history::table
|
||||||
|
.filter(schema::root_key_history::id.eq(*root_key_history_id))
|
||||||
|
.select(schema::root_key_history::data_encryption_nonce )
|
||||||
|
.select(RootKeyHistory::as_select() )
|
||||||
|
.first(&mut conn)
|
||||||
|
.await?
|
||||||
|
};
|
||||||
|
|
||||||
|
let salt = ¤t_key.salt;
|
||||||
let salt = v1::Salt::try_from(salt.as_slice()).map_err(|_| {
|
let salt = v1::Salt::try_from(salt.as_slice()).map_err(|_| {
|
||||||
error!("Broken database: invalid salt for root key");
|
error!("Broken database: invalid salt for root key");
|
||||||
Error::BrokenDatabase
|
Error::BrokenDatabase
|
||||||
})?;
|
})?;
|
||||||
let mut seal_key = v1::derive_seal_key(seal_key_raw, &salt);
|
let mut seal_key = v1::derive_seal_key(seal_key_raw, &salt);
|
||||||
|
|
||||||
let mut root_key = MemSafe::new(encrypted_root_key.ciphertext.clone()).unwrap();
|
let mut root_key = MemSafe::new(current_key.ciphertext.clone()).unwrap();
|
||||||
|
|
||||||
|
let nonce = v1::Nonce::try_from(current_key.root_key_encryption_nonce.as_slice()).map_err(
|
||||||
|
|_| {
|
||||||
|
error!("Broken database: invalid nonce for root key");
|
||||||
|
Error::BrokenDatabase
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
seal_key
|
seal_key
|
||||||
.decrypt_in_place(root_key_encryption_nonce, v1::ROOT_KEY_TAG, &mut root_key)
|
.decrypt_in_place(&nonce, v1::ROOT_KEY_TAG, &mut root_key)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
error!(?err, "Failed to unseal root key: invalid seal key");
|
error!(?err, "Failed to unseal root key: invalid seal key");
|
||||||
Error::InvalidKey
|
Error::InvalidKey
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.state = State::Unsealed {
|
self.state = State::Unsealed {
|
||||||
root_key_history_id: encrypted_root_key.id,
|
root_key_history_id: current_key.id,
|
||||||
root_key: v1::KeyCell::try_from(root_key).map_err(|err| {
|
root_key: v1::KeyCell::try_from(root_key).map_err(|err| {
|
||||||
error!(?err, "Broken database: invalid encryption key size");
|
error!(?err, "Broken database: invalid encryption key size");
|
||||||
Error::BrokenDatabase
|
Error::BrokenDatabase
|
||||||
})?,
|
})?,
|
||||||
nonce: std::mem::take(data_encryption_nonce), // we are replacing state, so it's safe to take the nonce out of it
|
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Keyholder unsealed successfully");
|
info!("Keyholder unsealed successfully");
|
||||||
@@ -222,14 +261,17 @@ impl KeyHolderActor {
|
|||||||
let State::Unsealed { root_key, .. } = &mut self.state else {
|
let State::Unsealed { root_key, .. } = &mut self.state else {
|
||||||
return Err(Error::NotBootstrapped);
|
return Err(Error::NotBootstrapped);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let row: models::AeadEncrypted = {
|
||||||
let mut conn = self.db.get().await?;
|
let mut conn = self.db.get().await?;
|
||||||
let row: models::AeadEncrypted = schema::aead_encrypted::table
|
schema::aead_encrypted::table
|
||||||
.select(models::AeadEncrypted::as_select())
|
.select(models::AeadEncrypted::as_select())
|
||||||
.filter(schema::aead_encrypted::id.eq(aead_id))
|
.filter(schema::aead_encrypted::id.eq(aead_id))
|
||||||
.first(&mut conn)
|
.first(&mut conn)
|
||||||
.await
|
.await
|
||||||
.optional()?
|
.optional()?
|
||||||
.ok_or(Error::NotFound)?;
|
.ok_or(Error::NotFound)?
|
||||||
|
};
|
||||||
|
|
||||||
let nonce = v1::Nonce::try_from(row.current_nonce.as_slice()).map_err(|_| {
|
let nonce = v1::Nonce::try_from(row.current_nonce.as_slice()).map_err(|_| {
|
||||||
error!(
|
error!(
|
||||||
@@ -249,14 +291,14 @@ impl KeyHolderActor {
|
|||||||
let State::Unsealed {
|
let State::Unsealed {
|
||||||
root_key,
|
root_key,
|
||||||
root_key_history_id,
|
root_key_history_id,
|
||||||
nonce,
|
|
||||||
} = &mut self.state
|
} = &mut self.state
|
||||||
else {
|
else {
|
||||||
return Err(Error::NotBootstrapped);
|
return Err(Error::NotBootstrapped);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut conn = self.db.get().await?;
|
// Order matters here - `get_new_nonce` acquires connection, so we need to call it before next acquire
|
||||||
nonce.increment();
|
// Borrow checker note: &mut borrow a few lines above is disjoint from this field
|
||||||
|
let nonce = Self::get_new_nonce(&self.db, *root_key_history_id).await?;
|
||||||
|
|
||||||
let mut ciphertext_buffer = plaintext.write().unwrap();
|
let mut ciphertext_buffer = plaintext.write().unwrap();
|
||||||
let ciphertext_buffer: &mut Vec<u8> = ciphertext_buffer.as_mut();
|
let ciphertext_buffer: &mut Vec<u8> = ciphertext_buffer.as_mut();
|
||||||
@@ -264,43 +306,41 @@ impl KeyHolderActor {
|
|||||||
|
|
||||||
let ciphertext = std::mem::take(ciphertext_buffer);
|
let ciphertext = std::mem::take(ciphertext_buffer);
|
||||||
|
|
||||||
let aead_id: i32 = conn
|
let mut conn = self.db.get().await?;
|
||||||
.transaction(|conn| {
|
|
||||||
Box::pin(async move {
|
|
||||||
let aead_id: i32 = insert_into(schema::aead_encrypted::table)
|
let aead_id: i32 = insert_into(schema::aead_encrypted::table)
|
||||||
.values(&models::NewAeadEncrypted {
|
.values(&models::NewAeadEncrypted {
|
||||||
ciphertext,
|
ciphertext,
|
||||||
tag: v1::TAG.to_vec(),
|
tag: v1::TAG.to_vec(),
|
||||||
current_nonce: nonce.to_vec(),
|
current_nonce: nonce.to_vec(),
|
||||||
schema_version: 1,
|
schema_version: 1,
|
||||||
|
associated_root_key_id: *root_key_history_id,
|
||||||
created_at: chrono::Utc::now().timestamp() as i32,
|
created_at: chrono::Utc::now().timestamp() as i32,
|
||||||
})
|
})
|
||||||
.returning(schema::aead_encrypted::id)
|
.returning(schema::aead_encrypted::id)
|
||||||
.get_result(conn)
|
.get_result(&mut conn)
|
||||||
.await?;
|
|
||||||
|
|
||||||
update(schema::root_key_history::table)
|
|
||||||
.filter(schema::root_key_history::id.eq(*root_key_history_id))
|
|
||||||
.set(schema::root_key_history::data_encryption_nonce.eq(nonce.to_vec()))
|
|
||||||
.execute(conn)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Result::<_, diesel::result::Error>::Ok(aead_id)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(aead_id)
|
Ok(aead_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message]
|
||||||
|
pub fn get_state(&self) -> StateDiscriminants {
|
||||||
|
self.state.discriminant()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use diesel::dsl::insert_into;
|
use diesel::dsl::{insert_into, sql_query, update};
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
|
use futures::stream::TryUnfold;
|
||||||
|
use kameo::actor::{ActorRef, Spawn as _};
|
||||||
use memsafe::MemSafe;
|
use memsafe::MemSafe;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use tokio::task::JoinSet;
|
||||||
|
|
||||||
use crate::db::{self, models::ArbiterSetting};
|
use crate::db::{self, models::ArbiterSetting};
|
||||||
|
|
||||||
@@ -320,20 +360,49 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn bootstrapped_actor(db: &db::DatabasePool) -> KeyHolderActor {
|
async fn bootstrapped_actor(db: &db::DatabasePool) -> KeyHolder {
|
||||||
seed_settings(db).await;
|
seed_settings(db).await;
|
||||||
let mut actor = KeyHolderActor::new(db.clone()).await.unwrap();
|
let mut actor = KeyHolder::new(db.clone()).await.unwrap();
|
||||||
let seal_key = MemSafe::new(b"test-seal-key".to_vec()).unwrap();
|
let seal_key = MemSafe::new(b"test-seal-key".to_vec()).unwrap();
|
||||||
actor.bootstrap(seal_key).await.unwrap();
|
actor.bootstrap(seal_key).await.unwrap();
|
||||||
actor
|
actor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn write_concurrently(
|
||||||
|
actor: ActorRef<KeyHolder>,
|
||||||
|
prefix: &'static str,
|
||||||
|
count: usize,
|
||||||
|
) -> Vec<(i32, Vec<u8>)> {
|
||||||
|
let mut set = JoinSet::new();
|
||||||
|
for i in 0..count {
|
||||||
|
let actor = actor.clone();
|
||||||
|
set.spawn(async move {
|
||||||
|
let plaintext = format!("{prefix}-{i}").into_bytes();
|
||||||
|
let id = {
|
||||||
|
actor
|
||||||
|
.ask(CreateNew {
|
||||||
|
plaintext: MemSafe::new(plaintext.clone()).unwrap(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
(id, plaintext)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut out = Vec::with_capacity(count);
|
||||||
|
while let Some(res) = set.join_next().await {
|
||||||
|
out.push(res.unwrap());
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[test_log::test]
|
#[test_log::test]
|
||||||
async fn test_bootstrap() {
|
async fn test_bootstrap() {
|
||||||
let db = db::create_test_pool().await;
|
let db = db::create_test_pool().await;
|
||||||
seed_settings(&db).await;
|
seed_settings(&db).await;
|
||||||
let mut actor = KeyHolderActor::new(db.clone()).await.unwrap();
|
let mut actor = KeyHolder::new(db.clone()).await.unwrap();
|
||||||
|
|
||||||
assert!(matches!(actor.state, State::Unbootstrapped));
|
assert!(matches!(actor.state, State::Unbootstrapped));
|
||||||
|
|
||||||
@@ -389,7 +458,7 @@ mod tests {
|
|||||||
async fn test_create_new_before_bootstrap_fails() {
|
async fn test_create_new_before_bootstrap_fails() {
|
||||||
let db = db::create_test_pool().await;
|
let db = db::create_test_pool().await;
|
||||||
seed_settings(&db).await;
|
seed_settings(&db).await;
|
||||||
let mut actor = KeyHolderActor::new(db).await.unwrap();
|
let mut actor = KeyHolder::new(db).await.unwrap();
|
||||||
|
|
||||||
let err = actor
|
let err = actor
|
||||||
.create_new(MemSafe::new(b"data".to_vec()).unwrap())
|
.create_new(MemSafe::new(b"data".to_vec()).unwrap())
|
||||||
@@ -403,7 +472,7 @@ mod tests {
|
|||||||
async fn test_decrypt_before_bootstrap_fails() {
|
async fn test_decrypt_before_bootstrap_fails() {
|
||||||
let db = db::create_test_pool().await;
|
let db = db::create_test_pool().await;
|
||||||
seed_settings(&db).await;
|
seed_settings(&db).await;
|
||||||
let mut actor = KeyHolderActor::new(db).await.unwrap();
|
let mut actor = KeyHolder::new(db).await.unwrap();
|
||||||
|
|
||||||
let err = actor.decrypt(1).await.unwrap_err();
|
let err = actor.decrypt(1).await.unwrap_err();
|
||||||
assert!(matches!(err, Error::NotBootstrapped));
|
assert!(matches!(err, Error::NotBootstrapped));
|
||||||
@@ -426,7 +495,7 @@ mod tests {
|
|||||||
let actor = bootstrapped_actor(&db).await;
|
let actor = bootstrapped_actor(&db).await;
|
||||||
drop(actor);
|
drop(actor);
|
||||||
|
|
||||||
let actor2 = KeyHolderActor::new(db).await.unwrap();
|
let actor2 = KeyHolder::new(db).await.unwrap();
|
||||||
assert!(matches!(actor2.state, State::Sealed { .. }));
|
assert!(matches!(actor2.state, State::Sealed { .. }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +564,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
drop(actor);
|
drop(actor);
|
||||||
|
|
||||||
let mut actor = KeyHolderActor::new(db.clone()).await.unwrap();
|
let mut actor = KeyHolder::new(db.clone()).await.unwrap();
|
||||||
assert!(matches!(actor.state, State::Sealed { .. }));
|
assert!(matches!(actor.state, State::Sealed { .. }));
|
||||||
|
|
||||||
let seal_key = MemSafe::new(b"test-seal-key".to_vec()).unwrap();
|
let seal_key = MemSafe::new(b"test-seal-key".to_vec()).unwrap();
|
||||||
@@ -520,7 +589,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
drop(actor);
|
drop(actor);
|
||||||
|
|
||||||
let mut actor = KeyHolderActor::new(db.clone()).await.unwrap();
|
let mut actor = KeyHolder::new(db.clone()).await.unwrap();
|
||||||
assert!(matches!(actor.state, State::Sealed { .. }));
|
assert!(matches!(actor.state, State::Sealed { .. }));
|
||||||
|
|
||||||
// wrong password
|
// wrong password
|
||||||
@@ -580,4 +649,291 @@ mod tests {
|
|||||||
assert_eq!(*d1.read().unwrap(), plaintext);
|
assert_eq!(*d1.read().unwrap(), plaintext);
|
||||||
assert_eq!(*d2.read().unwrap(), plaintext);
|
assert_eq!(*d2.read().unwrap(), plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[test_log::test]
|
||||||
|
async fn concurrent_create_new_no_duplicate_nonces_() {
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let actor = KeyHolder::spawn(bootstrapped_actor(&db).await);
|
||||||
|
|
||||||
|
let writes = write_concurrently(actor, "nonce-unique", 32).await;
|
||||||
|
assert_eq!(writes.len(), 32);
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
let rows: Vec<models::AeadEncrypted> = schema::aead_encrypted::table
|
||||||
|
.select(models::AeadEncrypted::as_select())
|
||||||
|
.load(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(rows.len(), 32);
|
||||||
|
|
||||||
|
let nonces: Vec<&Vec<u8>> = rows.iter().map(|r| &r.current_nonce).collect();
|
||||||
|
let unique: HashSet<&Vec<u8>> = nonces.iter().copied().collect();
|
||||||
|
assert_eq!(nonces.len(), unique.len(), "all nonces must be unique");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[test_log::test]
|
||||||
|
async fn concurrent_create_new_root_nonce_never_moves_backward() {
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let actor = KeyHolder::spawn(bootstrapped_actor(&db).await);
|
||||||
|
|
||||||
|
write_concurrently(actor, "root-max", 24).await;
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
let rows: Vec<models::AeadEncrypted> = schema::aead_encrypted::table
|
||||||
|
.select(models::AeadEncrypted::as_select())
|
||||||
|
.load(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let max_nonce = rows
|
||||||
|
.iter()
|
||||||
|
.map(|r| r.current_nonce.clone())
|
||||||
|
.max()
|
||||||
|
.expect("at least one row");
|
||||||
|
|
||||||
|
let root_row: models::RootKeyHistory = schema::root_key_history::table
|
||||||
|
.select(models::RootKeyHistory::as_select())
|
||||||
|
.first(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(root_row.data_encryption_nonce, max_nonce);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[test_log::test]
|
||||||
|
async fn nonce_monotonic_even_when_nonce_allocation_interleaves() {
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let mut actor = bootstrapped_actor(&db).await;
|
||||||
|
let root_key_history_id = match actor.state {
|
||||||
|
State::Unsealed {
|
||||||
|
root_key_history_id,
|
||||||
|
..
|
||||||
|
} => root_key_history_id,
|
||||||
|
_ => panic!("expected unsealed state"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let n1 = KeyHolder::get_new_nonce(&db, root_key_history_id)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let n2 = KeyHolder::get_new_nonce(&db, root_key_history_id)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(n2.to_vec() > n1.to_vec(), "nonce must increase");
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
let root_row: models::RootKeyHistory = schema::root_key_history::table
|
||||||
|
.select(models::RootKeyHistory::as_select())
|
||||||
|
.first(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(root_row.data_encryption_nonce, n2.to_vec());
|
||||||
|
|
||||||
|
let id = actor
|
||||||
|
.create_new(MemSafe::new(b"post-interleave".to_vec()).unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let row: models::AeadEncrypted = schema::aead_encrypted::table
|
||||||
|
.filter(schema::aead_encrypted::id.eq(id))
|
||||||
|
.select(models::AeadEncrypted::as_select())
|
||||||
|
.first(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
row.current_nonce > n2.to_vec(),
|
||||||
|
"next write must advance nonce"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[test_log::test]
|
||||||
|
async fn insert_failure_does_not_create_partial_row() {
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let mut actor = bootstrapped_actor(&db).await;
|
||||||
|
let root_key_history_id = match actor.state {
|
||||||
|
State::Unsealed {
|
||||||
|
root_key_history_id,
|
||||||
|
..
|
||||||
|
} => root_key_history_id,
|
||||||
|
_ => panic!("expected unsealed state"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
let before_count: i64 = schema::aead_encrypted::table
|
||||||
|
.count()
|
||||||
|
.get_result(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let before_root_nonce: Vec<u8> = schema::root_key_history::table
|
||||||
|
.filter(schema::root_key_history::id.eq(root_key_history_id))
|
||||||
|
.select(schema::root_key_history::data_encryption_nonce)
|
||||||
|
.first(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
sql_query(
|
||||||
|
"CREATE TRIGGER fail_aead_insert BEFORE INSERT ON aead_encrypted BEGIN SELECT RAISE(ABORT, 'forced test failure'); END;",
|
||||||
|
)
|
||||||
|
.execute(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
drop(conn);
|
||||||
|
|
||||||
|
let err = actor
|
||||||
|
.create_new(MemSafe::new(b"should fail".to_vec()).unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
assert!(matches!(err, Error::DatabaseTransaction(_)));
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
sql_query("DROP TRIGGER fail_aead_insert;")
|
||||||
|
.execute(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let after_count: i64 = schema::aead_encrypted::table
|
||||||
|
.count()
|
||||||
|
.get_result(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
before_count, after_count,
|
||||||
|
"failed insert must not create row"
|
||||||
|
);
|
||||||
|
|
||||||
|
let after_root_nonce: Vec<u8> = schema::root_key_history::table
|
||||||
|
.filter(schema::root_key_history::id.eq(root_key_history_id))
|
||||||
|
.select(schema::root_key_history::data_encryption_nonce)
|
||||||
|
.first(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
after_root_nonce > before_root_nonce,
|
||||||
|
"current behavior allows nonce gap on failed insert"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[test_log::test]
|
||||||
|
async fn decrypt_roundtrip_after_high_concurrency() {
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let actor = KeyHolder::spawn(bootstrapped_actor(&db).await);
|
||||||
|
|
||||||
|
let writes = write_concurrently(actor, "roundtrip", 40).await;
|
||||||
|
let expected: HashMap<i32, Vec<u8>> = writes.into_iter().collect();
|
||||||
|
|
||||||
|
let mut decryptor = KeyHolder::new(db.clone()).await.unwrap();
|
||||||
|
decryptor
|
||||||
|
.try_unseal(MemSafe::new(b"test-seal-key".to_vec()).unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for (id, plaintext) in expected {
|
||||||
|
let mut decrypted = decryptor.decrypt(id).await.unwrap();
|
||||||
|
assert_eq!(*decrypted.read().unwrap(), plaintext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[tokio::test]
|
||||||
|
// #[test_log::test]
|
||||||
|
// async fn swapping_ciphertext_and_nonce_between_rows_changes_logical_binding() {
|
||||||
|
// let db = db::create_test_pool().await;
|
||||||
|
// let mut actor = bootstrapped_actor(&db).await;
|
||||||
|
|
||||||
|
// let plaintext1 = b"entry-one";
|
||||||
|
// let plaintext2 = b"entry-two";
|
||||||
|
// let id1 = actor
|
||||||
|
// .create_new(MemSafe::new(plaintext1.to_vec()).unwrap())
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
// let id2 = actor
|
||||||
|
// .create_new(MemSafe::new(plaintext2.to_vec()).unwrap())
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
|
// let mut conn = db.get().await.unwrap();
|
||||||
|
// let row1: models::AeadEncrypted = schema::aead_encrypted::table
|
||||||
|
// .filter(schema::aead_encrypted::id.eq(id1))
|
||||||
|
// .select(models::AeadEncrypted::as_select())
|
||||||
|
// .first(&mut conn)
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
// let row2: models::AeadEncrypted = schema::aead_encrypted::table
|
||||||
|
// .filter(schema::aead_encrypted::id.eq(id2))
|
||||||
|
// .select(models::AeadEncrypted::as_select())
|
||||||
|
// .first(&mut conn)
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
|
// update(schema::aead_encrypted::table.filter(schema::aead_encrypted::id.eq(id1)))
|
||||||
|
// .set((
|
||||||
|
// schema::aead_encrypted::ciphertext.eq(row2.ciphertext.clone()),
|
||||||
|
// schema::aead_encrypted::current_nonce.eq(row2.current_nonce.clone()),
|
||||||
|
// ))
|
||||||
|
// .execute(&mut conn)
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
// update(schema::aead_encrypted::table.filter(schema::aead_encrypted::id.eq(id2)))
|
||||||
|
// .set((
|
||||||
|
// schema::aead_encrypted::ciphertext.eq(row1.ciphertext.clone()),
|
||||||
|
// schema::aead_encrypted::current_nonce.eq(row1.current_nonce.clone()),
|
||||||
|
// ))
|
||||||
|
// .execute(&mut conn)
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
|
// let mut d1 = actor.decrypt(id1).await.unwrap();
|
||||||
|
// let mut d2 = actor.decrypt(id2).await.unwrap();
|
||||||
|
// assert_eq!(*d1.read().unwrap(), plaintext2);
|
||||||
|
// assert_eq!(*d2.read().unwrap(), plaintext1);
|
||||||
|
// }
|
||||||
|
#[tokio::test]
|
||||||
|
#[test_log::test]
|
||||||
|
async fn broken_db_nonce_format_fails_closed() {
|
||||||
|
// malformed root_key_history nonce must fail create_new
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let mut actor = bootstrapped_actor(&db).await;
|
||||||
|
let root_key_history_id = match actor.state {
|
||||||
|
State::Unsealed {
|
||||||
|
root_key_history_id,
|
||||||
|
..
|
||||||
|
} => root_key_history_id,
|
||||||
|
_ => panic!("expected unsealed state"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
update(
|
||||||
|
schema::root_key_history::table
|
||||||
|
.filter(schema::root_key_history::id.eq(root_key_history_id)),
|
||||||
|
)
|
||||||
|
.set(schema::root_key_history::data_encryption_nonce.eq(vec![1, 2, 3]))
|
||||||
|
.execute(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
drop(conn);
|
||||||
|
|
||||||
|
let err = actor
|
||||||
|
.create_new(MemSafe::new(b"must fail".to_vec()).unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
assert!(matches!(err, Error::BrokenDatabase));
|
||||||
|
|
||||||
|
// malformed per-row nonce must fail decrypt
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let mut actor = bootstrapped_actor(&db).await;
|
||||||
|
let id = actor
|
||||||
|
.create_new(MemSafe::new(b"decrypt target".to_vec()).unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
update(schema::aead_encrypted::table.filter(schema::aead_encrypted::id.eq(id)))
|
||||||
|
.set(schema::aead_encrypted::current_nonce.eq(vec![7, 8]))
|
||||||
|
.execute(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
drop(conn);
|
||||||
|
|
||||||
|
let err = actor.decrypt(id).await.unwrap_err();
|
||||||
|
assert!(matches!(err, Error::BrokenDatabase));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use rand::{
|
|||||||
|
|
||||||
pub const ROOT_KEY_TAG: &[u8] = "arbiter/seal/v1".as_bytes();
|
pub const ROOT_KEY_TAG: &[u8] = "arbiter/seal/v1".as_bytes();
|
||||||
pub const TAG: &[u8] = "arbiter/private-key/v1".as_bytes();
|
pub const TAG: &[u8] = "arbiter/private-key/v1".as_bytes();
|
||||||
|
|
||||||
pub const NONCE_LENGTH: usize = 24;
|
pub const NONCE_LENGTH: usize = 24;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub struct AeadEncrypted {
|
|||||||
pub tag: Vec<u8>,
|
pub tag: Vec<u8>,
|
||||||
pub current_nonce: Vec<u8>,
|
pub current_nonce: Vec<u8>,
|
||||||
pub schema_version: i32,
|
pub schema_version: i32,
|
||||||
|
pub associated_root_key_id: i32, // references root_key_history.id
|
||||||
pub created_at: i32,
|
pub created_at: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ diesel::table! {
|
|||||||
ciphertext -> Binary,
|
ciphertext -> Binary,
|
||||||
tag -> Binary,
|
tag -> Binary,
|
||||||
schema_version -> Integer,
|
schema_version -> Integer,
|
||||||
|
associated_root_key_id -> Integer,
|
||||||
created_at -> Integer,
|
created_at -> Integer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +53,7 @@ diesel::table! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::joinable!(aead_encrypted -> root_key_history (associated_root_key_id));
|
||||||
diesel::joinable!(arbiter_settings -> root_key_history (root_key_id));
|
diesel::joinable!(arbiter_settings -> root_key_history (root_key_id));
|
||||||
|
|
||||||
diesel::allow_tables_to_appear_in_same_query!(
|
diesel::allow_tables_to_appear_in_same_query!(
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
|
||||||
# cargo-vet audits file
|
# cargo-vet audits file
|
||||||
|
|
||||||
|
[[audits.similar]]
|
||||||
|
who = "hdbg <httpdebugger@protonmail.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "2.2.1"
|
||||||
|
|
||||||
[[audits.test-log]]
|
[[audits.test-log]]
|
||||||
who = "hdbg <httpdebugger@protonmail.com>"
|
who = "hdbg <httpdebugger@protonmail.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -11,6 +16,12 @@ who = "hdbg <httpdebugger@protonmail.com>"
|
|||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
delta = "0.2.18 -> 0.2.19"
|
delta = "0.2.18 -> 0.2.19"
|
||||||
|
|
||||||
|
[[trusted.cc]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 55123 # rust-lang-owner
|
||||||
|
start = "2022-10-29"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|
||||||
[[trusted.h2]]
|
[[trusted.h2]]
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
user-id = 359 # Sean McArthur (seanmonstar)
|
user-id = 359 # Sean McArthur (seanmonstar)
|
||||||
@@ -29,6 +40,12 @@ user-id = 359 # Sean McArthur (seanmonstar)
|
|||||||
start = "2022-01-15"
|
start = "2022-01-15"
|
||||||
end = "2027-02-14"
|
end = "2027-02-14"
|
||||||
|
|
||||||
|
[[trusted.libc]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 55123 # rust-lang-owner
|
||||||
|
start = "2024-08-15"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|
||||||
[[trusted.rustix]]
|
[[trusted.rustix]]
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
user-id = 6825 # Dan Gohman (sunfishcode)
|
user-id = 6825 # Dan Gohman (sunfishcode)
|
||||||
@@ -46,3 +63,33 @@ criteria = "safe-to-deploy"
|
|||||||
user-id = 3618 # David Tolnay (dtolnay)
|
user-id = 3618 # David Tolnay (dtolnay)
|
||||||
start = "2019-03-01"
|
start = "2019-03-01"
|
||||||
end = "2027-02-14"
|
end = "2027-02-14"
|
||||||
|
|
||||||
|
[[trusted.thread_local]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 2915 # Amanieu d'Antras (Amanieu)
|
||||||
|
start = "2019-09-07"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|
||||||
|
[[trusted.toml]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 6743 # Ed Page (epage)
|
||||||
|
start = "2022-12-14"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|
||||||
|
[[trusted.toml_parser]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 6743 # Ed Page (epage)
|
||||||
|
start = "2025-07-08"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|
||||||
|
[[trusted.tonic-build]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 10
|
||||||
|
start = "2019-09-10"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|
||||||
|
[[trusted.windows-sys]]
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
user-id = 64539 # Kenny Kerr (kennykerr)
|
||||||
|
start = "2021-11-15"
|
||||||
|
end = "2027-02-16"
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ url = "https://raw.githubusercontent.com/google/supply-chain/main/audits.toml"
|
|||||||
[imports.mozilla]
|
[imports.mozilla]
|
||||||
url = "https://raw.githubusercontent.com/mozilla/supply-chain/main/audits.toml"
|
url = "https://raw.githubusercontent.com/mozilla/supply-chain/main/audits.toml"
|
||||||
|
|
||||||
|
[imports.zcash]
|
||||||
|
url = "https://raw.githubusercontent.com/zcash/rust-ecosystem/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
[[exemptions.addr2line]]
|
[[exemptions.addr2line]]
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -41,10 +44,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.1.89"
|
version = "0.1.89"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.autocfg]]
|
|
||||||
version = "1.5.0"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.aws-lc-rs]]
|
[[exemptions.aws-lc-rs]]
|
||||||
version = "1.15.4"
|
version = "1.15.4"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -193,10 +192,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.dunce]]
|
|
||||||
version = "1.0.5"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.dyn-clone]]
|
[[exemptions.dyn-clone]]
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -209,10 +204,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "3.0.0-pre.6"
|
version = "3.0.0-pre.6"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.errno]]
|
|
||||||
version = "0.3.14"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.fiat-crypto]]
|
[[exemptions.fiat-crypto]]
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -261,10 +252,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.http-body]]
|
|
||||||
version = "1.0.1"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.http-body-util]]
|
[[exemptions.http-body-util]]
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -329,10 +316,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.libc]]
|
|
||||||
version = "0.2.181"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.libsqlite3-sys]]
|
[[exemptions.libsqlite3-sys]]
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -525,10 +508,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.1.27"
|
version = "0.1.27"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.rustc_version]]
|
|
||||||
version = "0.4.1"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.rusticata-macros]]
|
[[exemptions.rusticata-macros]]
|
||||||
version = "4.1.0"
|
version = "4.1.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -545,10 +524,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.103.9"
|
version = "0.103.9"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.rustversion]]
|
|
||||||
version = "1.0.22"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.scoped-futures]]
|
[[exemptions.scoped-futures]]
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -653,10 +628,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "2.0.18"
|
version = "2.0.18"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.thread_local]]
|
|
||||||
version = "1.1.9"
|
|
||||||
criteria = "safe-to-run"
|
|
||||||
|
|
||||||
[[exemptions.time]]
|
[[exemptions.time]]
|
||||||
version = "0.3.47"
|
version = "0.3.47"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -689,14 +660,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.7.18"
|
version = "0.7.18"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.toml]]
|
|
||||||
version = "0.9.11+spec-1.1.0"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.toml_parser]]
|
|
||||||
version = "1.0.6+spec-1.1.0"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.tonic]]
|
[[exemptions.tonic]]
|
||||||
version = "0.14.3"
|
version = "0.14.3"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -741,10 +704,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.3.22"
|
version = "0.3.22"
|
||||||
criteria = "safe-to-run"
|
criteria = "safe-to-run"
|
||||||
|
|
||||||
[[exemptions.try-lock]]
|
|
||||||
version = "0.2.5"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.typenum]]
|
[[exemptions.typenum]]
|
||||||
version = "1.19.0"
|
version = "1.19.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -769,10 +728,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "1.20.0"
|
version = "1.20.0"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.want]]
|
|
||||||
version = "0.3.1"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.wasi]]
|
[[exemptions.wasi]]
|
||||||
version = "0.11.1+wasi-snapshot-preview1"
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -817,10 +772,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.59.3"
|
version = "0.59.3"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.windows-link]]
|
|
||||||
version = "0.2.1"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.windows-result]]
|
[[exemptions.windows-result]]
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -829,18 +780,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.windows-sys]]
|
|
||||||
version = "0.52.0"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.windows-sys]]
|
|
||||||
version = "0.60.2"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.windows-sys]]
|
|
||||||
version = "0.61.2"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.windows-targets]]
|
[[exemptions.windows-targets]]
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -925,10 +864,6 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|
||||||
[[exemptions.zeroize]]
|
|
||||||
version = "1.8.2"
|
|
||||||
criteria = "safe-to-deploy"
|
|
||||||
|
|
||||||
[[exemptions.zmij]]
|
[[exemptions.zmij]]
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ user-id = 359
|
|||||||
user-login = "seanmonstar"
|
user-login = "seanmonstar"
|
||||||
user-name = "Sean McArthur"
|
user-name = "Sean McArthur"
|
||||||
|
|
||||||
|
[[publisher.libc]]
|
||||||
|
version = "0.2.182"
|
||||||
|
when = "2026-02-13"
|
||||||
|
user-id = 55123
|
||||||
|
user-login = "rust-lang-owner"
|
||||||
|
|
||||||
[[publisher.rustix]]
|
[[publisher.rustix]]
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
when = "2025-12-23"
|
when = "2025-12-23"
|
||||||
@@ -63,12 +69,33 @@ user-login = "dtolnay"
|
|||||||
user-name = "David Tolnay"
|
user-name = "David Tolnay"
|
||||||
|
|
||||||
[[publisher.syn]]
|
[[publisher.syn]]
|
||||||
version = "2.0.114"
|
version = "2.0.115"
|
||||||
when = "2026-01-07"
|
when = "2026-02-12"
|
||||||
user-id = 3618
|
user-id = 3618
|
||||||
user-login = "dtolnay"
|
user-login = "dtolnay"
|
||||||
user-name = "David Tolnay"
|
user-name = "David Tolnay"
|
||||||
|
|
||||||
|
[[publisher.thread_local]]
|
||||||
|
version = "1.1.9"
|
||||||
|
when = "2025-06-12"
|
||||||
|
user-id = 2915
|
||||||
|
user-login = "Amanieu"
|
||||||
|
user-name = "Amanieu d'Antras"
|
||||||
|
|
||||||
|
[[publisher.toml]]
|
||||||
|
version = "0.9.12+spec-1.1.0"
|
||||||
|
when = "2026-02-10"
|
||||||
|
user-id = 6743
|
||||||
|
user-login = "epage"
|
||||||
|
user-name = "Ed Page"
|
||||||
|
|
||||||
|
[[publisher.toml_parser]]
|
||||||
|
version = "1.0.8+spec-1.1.0"
|
||||||
|
when = "2026-02-12"
|
||||||
|
user-id = 6743
|
||||||
|
user-login = "epage"
|
||||||
|
user-name = "Ed Page"
|
||||||
|
|
||||||
[[publisher.unicode-width]]
|
[[publisher.unicode-width]]
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
when = "2024-09-19"
|
when = "2024-09-19"
|
||||||
@@ -120,6 +147,34 @@ version = "0.244.0"
|
|||||||
when = "2026-01-06"
|
when = "2026-01-06"
|
||||||
trusted-publisher = "github:bytecodealliance/wasm-tools"
|
trusted-publisher = "github:bytecodealliance/wasm-tools"
|
||||||
|
|
||||||
|
[[publisher.windows-sys]]
|
||||||
|
version = "0.52.0"
|
||||||
|
when = "2023-11-15"
|
||||||
|
user-id = 64539
|
||||||
|
user-login = "kennykerr"
|
||||||
|
user-name = "Kenny Kerr"
|
||||||
|
|
||||||
|
[[publisher.windows-sys]]
|
||||||
|
version = "0.59.0"
|
||||||
|
when = "2024-07-30"
|
||||||
|
user-id = 64539
|
||||||
|
user-login = "kennykerr"
|
||||||
|
user-name = "Kenny Kerr"
|
||||||
|
|
||||||
|
[[publisher.windows-sys]]
|
||||||
|
version = "0.60.2"
|
||||||
|
when = "2025-06-12"
|
||||||
|
user-id = 64539
|
||||||
|
user-login = "kennykerr"
|
||||||
|
user-name = "Kenny Kerr"
|
||||||
|
|
||||||
|
[[publisher.windows-sys]]
|
||||||
|
version = "0.61.2"
|
||||||
|
when = "2025-10-06"
|
||||||
|
user-id = 64539
|
||||||
|
user-login = "kennykerr"
|
||||||
|
user-name = "Kenny Kerr"
|
||||||
|
|
||||||
[[publisher.wit-bindgen]]
|
[[publisher.wit-bindgen]]
|
||||||
version = "0.51.0"
|
version = "0.51.0"
|
||||||
when = "2026-01-12"
|
when = "2026-01-12"
|
||||||
@@ -265,6 +320,12 @@ criteria = "safe-to-deploy"
|
|||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
notes = "Contains `unsafe` code but it's well-documented and scoped to what it's intended to be doing. Otherwise a well-focused and straightforward crate."
|
notes = "Contains `unsafe` code but it's well-documented and scoped to what it's intended to be doing. Otherwise a well-focused and straightforward crate."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.cipher]]
|
||||||
|
who = "Andrew Brown <andrew.brown@intel.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.4.4"
|
||||||
|
notes = "Most unsafe is hidden by `inout` dependency; only remaining unsafe is raw-splitting a slice and an unreachable hint. Older versions of this regularly reach ~150k daily downloads."
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.core-foundation-sys]]
|
[[audits.bytecode-alliance.audits.core-foundation-sys]]
|
||||||
who = "Dan Gohman <dev@sunfishcode.online>"
|
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -279,6 +340,23 @@ who = "Nick Fitzgerald <fitzgen@gmail.com>"
|
|||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
delta = "0.2.4 -> 0.2.5"
|
delta = "0.2.4 -> 0.2.5"
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.errno]]
|
||||||
|
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.3.0"
|
||||||
|
notes = "This crate uses libc and windows-sys APIs to get and set the raw OS error value."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.errno]]
|
||||||
|
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.0 -> 0.3.1"
|
||||||
|
notes = "Just a dependency version bump and a bug fix for redox"
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.errno]]
|
||||||
|
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.9 -> 0.3.10"
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.fastrand]]
|
[[audits.bytecode-alliance.audits.fastrand]]
|
||||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -385,11 +463,28 @@ criteria = "safe-to-deploy"
|
|||||||
delta = "0.4.1 -> 0.5.0"
|
delta = "0.4.1 -> 0.5.0"
|
||||||
notes = "Minor changes for a `no_std` upgrade but otherwise everything looks as expected."
|
notes = "Minor changes for a `no_std` upgrade but otherwise everything looks as expected."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.http-body]]
|
||||||
|
who = "Pat Hickey <phickey@fastly.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "1.0.0-rc.2"
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.http-body]]
|
||||||
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.0-rc.2 -> 1.0.0"
|
||||||
|
notes = "Only minor changes made for a stable release."
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.iana-time-zone-haiku]]
|
[[audits.bytecode-alliance.audits.iana-time-zone-haiku]]
|
||||||
who = "Dan Gohman <dev@sunfishcode.online>"
|
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.inout]]
|
||||||
|
who = "Andrew Brown <andrew.brown@intel.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.1.3"
|
||||||
|
notes = "A part of RustCrypto/utils, this crate is designed to handle unsafe buffers and carefully documents the safety concerns throughout. Older versions of this tally up to ~130k daily downloads."
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.leb128fmt]]
|
[[audits.bytecode-alliance.audits.leb128fmt]]
|
||||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -443,6 +538,24 @@ criteria = "safe-to-deploy"
|
|||||||
delta = "0.8.5 -> 0.8.9"
|
delta = "0.8.5 -> 0.8.9"
|
||||||
notes = "No new unsafe code, just refactorings."
|
notes = "No new unsafe code, just refactorings."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.nu-ansi-term]]
|
||||||
|
who = "Pat Hickey <phickey@fastly.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.46.0"
|
||||||
|
notes = "one use of unsafe to call windows specific api to get console handle."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.nu-ansi-term]]
|
||||||
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.46.0 -> 0.50.1"
|
||||||
|
notes = "Lots of stylistic/rust-related chanegs, plus new features, but nothing out of the ordrinary."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.nu-ansi-term]]
|
||||||
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.50.1 -> 0.50.3"
|
||||||
|
notes = "CI changes, Rust changes, nothing out of the ordinary."
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.num-traits]]
|
[[audits.bytecode-alliance.audits.num-traits]]
|
||||||
who = "Andrew Brown <andrew.brown@intel.com>"
|
who = "Andrew Brown <andrew.brown@intel.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -537,12 +650,38 @@ criteria = "safe-to-run"
|
|||||||
delta = "0.2.16 -> 0.2.18"
|
delta = "0.2.16 -> 0.2.18"
|
||||||
notes = "Standard macro changes, nothing out of place"
|
notes = "Standard macro changes, nothing out of place"
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.tracing-log]]
|
||||||
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.1.3"
|
||||||
|
notes = """
|
||||||
|
This is a standard adapter between the `log` ecosystem and the `tracing`
|
||||||
|
ecosystem. There's one `unsafe` block in this crate and it's well-scoped.
|
||||||
|
"""
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.tracing-log]]
|
||||||
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.1.3 -> 0.2.0"
|
||||||
|
notes = "Nothing out of the ordinary, a typical major version update and nothing awry."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.try-lock]]
|
||||||
|
who = "Pat Hickey <phickey@fastly.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.2.4"
|
||||||
|
notes = "Implements a concurrency primitive with atomics, and is not obviously incorrect"
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.vcpkg]]
|
[[audits.bytecode-alliance.audits.vcpkg]]
|
||||||
who = "Pat Hickey <phickey@fastly.com>"
|
who = "Pat Hickey <phickey@fastly.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
notes = "no build.rs, no macros, no unsafe. It reads the filesystem and makes copies of DLLs into OUT_DIR."
|
notes = "no build.rs, no macros, no unsafe. It reads the filesystem and makes copies of DLLs into OUT_DIR."
|
||||||
|
|
||||||
|
[[audits.bytecode-alliance.audits.want]]
|
||||||
|
who = "Pat Hickey <phickey@fastly.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.3.0"
|
||||||
|
|
||||||
[[audits.bytecode-alliance.audits.wasm-metadata]]
|
[[audits.bytecode-alliance.audits.wasm-metadata]]
|
||||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -591,6 +730,13 @@ criteria = "safe-to-deploy"
|
|||||||
delta = "0.243.0 -> 0.244.0"
|
delta = "0.243.0 -> 0.244.0"
|
||||||
notes = "The Bytecode Alliance is the author of this crate"
|
notes = "The Bytecode Alliance is the author of this crate"
|
||||||
|
|
||||||
|
[[audits.google.audits.autocfg]]
|
||||||
|
who = "Manish Goregaokar <manishearth@google.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "1.4.0"
|
||||||
|
notes = "Contains no unsafe"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
[[audits.google.audits.base64]]
|
[[audits.google.audits.base64]]
|
||||||
who = "amarjotgill <amarjotgill@google.com>"
|
who = "amarjotgill <amarjotgill@google.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -719,6 +865,89 @@ delta = "0.2.9 -> 0.2.13"
|
|||||||
notes = "Audited at https://fxrev.dev/946396"
|
notes = "Audited at https://fxrev.dev/946396"
|
||||||
aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT"
|
aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.proc-macro-error-attr]]
|
||||||
|
who = "George Burgess IV <gbiv@google.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "1.0.4"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rand_core]]
|
||||||
|
who = "Lukasz Anforowicz <lukasza@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.6.4"
|
||||||
|
notes = """
|
||||||
|
For more detailed unsafe review notes please see https://crrev.com/c/6362797
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "Lukasz Anforowicz <lukasza@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "1.0.14"
|
||||||
|
notes = """
|
||||||
|
Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'``
|
||||||
|
and there were no hits except for:
|
||||||
|
|
||||||
|
* Using trivially-safe `unsafe` in test code:
|
||||||
|
|
||||||
|
```
|
||||||
|
tests/test_const.rs:unsafe fn _unsafe() {}
|
||||||
|
tests/test_const.rs:const _UNSAFE: () = unsafe { _unsafe() };
|
||||||
|
```
|
||||||
|
|
||||||
|
* Using `unsafe` in a string:
|
||||||
|
|
||||||
|
```
|
||||||
|
src/constfn.rs: "unsafe" => Qualifiers::Unsafe,
|
||||||
|
```
|
||||||
|
|
||||||
|
* Using `std::fs` in `build/build.rs` to write `${OUT_DIR}/version.expr`
|
||||||
|
which is later read back via `include!` used in `src/lib.rs`.
|
||||||
|
|
||||||
|
Version `1.0.6` of this crate has been added to Chromium in
|
||||||
|
https://source.chromium.org/chromium/chromium/src/+/28841c33c77833cc30b286f9ae24c97e7a8f4057
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "Adrian Taylor <adetaylor@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.14 -> 1.0.15"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "danakj <danakj@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.15 -> 1.0.16"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "Dustin J. Mitchell <djmitche@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.16 -> 1.0.17"
|
||||||
|
notes = "Just updates windows compat"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "Liza Burakova <liza@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.17 -> 1.0.18"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "Dustin J. Mitchell <djmitche@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.18 -> 1.0.19"
|
||||||
|
notes = "No unsafe, just doc changes"
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.rustversion]]
|
||||||
|
who = "Daniel Cheng <dcheng@chromium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.19 -> 1.0.20"
|
||||||
|
notes = "Only minor updates to documentation and the mock today used for testing."
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
[[audits.google.audits.smallvec]]
|
[[audits.google.audits.smallvec]]
|
||||||
who = "Manish Goregaokar <manishearth@google.com>"
|
who = "Manish Goregaokar <manishearth@google.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -736,6 +965,28 @@ Previously reviewed during security review and the audit is grandparented in.
|
|||||||
"""
|
"""
|
||||||
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.strum]]
|
||||||
|
who = "danakj@chromium.org"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.25.0"
|
||||||
|
notes = """
|
||||||
|
Reviewed in https://crrev.com/c/5171063
|
||||||
|
|
||||||
|
Previously reviewed during security review and the audit is grandparented in.
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
|
[[audits.google.audits.strum_macros]]
|
||||||
|
who = "danakj@chromium.org"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.25.3"
|
||||||
|
notes = """
|
||||||
|
Reviewed in https://crrev.com/c/5171063
|
||||||
|
|
||||||
|
Previously reviewed during security review and the audit is grandparented in.
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
|
||||||
|
|
||||||
[[audits.mozilla.wildcard-audits.core-foundation-sys]]
|
[[audits.mozilla.wildcard-audits.core-foundation-sys]]
|
||||||
who = "Bobby Holley <bobbyholley@gmail.com>"
|
who = "Bobby Holley <bobbyholley@gmail.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -812,6 +1063,12 @@ criteria = "safe-to-deploy"
|
|||||||
delta = "0.2.3 -> 0.2.4"
|
delta = "0.2.3 -> 0.2.4"
|
||||||
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.errno]]
|
||||||
|
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.1 -> 0.3.3"
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
[[audits.mozilla.audits.fastrand]]
|
[[audits.mozilla.audits.fastrand]]
|
||||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -929,6 +1186,16 @@ yet, but it's all valid. Otherwise it's a pretty simple crate.
|
|||||||
"""
|
"""
|
||||||
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.rustc_version]]
|
||||||
|
who = "Nika Layzell <nika@thelayzells.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.4.0"
|
||||||
|
notes = """
|
||||||
|
Use of powerful capabilities is limited to invoking `rustc -vV` to get version
|
||||||
|
information for parsing version information.
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
[[audits.mozilla.audits.serde_spanned]]
|
[[audits.mozilla.audits.serde_spanned]]
|
||||||
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
|
who = "Ben Dean-Kawamura <bdk@mozilla.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -955,6 +1222,12 @@ criteria = "safe-to-deploy"
|
|||||||
delta = "1.1.0 -> 1.3.0"
|
delta = "1.1.0 -> 1.3.0"
|
||||||
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.similar]]
|
||||||
|
who = "Nika Layzell <nika@thelayzells.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "2.2.1 -> 2.7.0"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
[[audits.mozilla.audits.smallvec]]
|
[[audits.mozilla.audits.smallvec]]
|
||||||
who = "Erich Gubler <erichdongubler@gmail.com>"
|
who = "Erich Gubler <erichdongubler@gmail.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -967,6 +1240,30 @@ criteria = "safe-to-deploy"
|
|||||||
delta = "0.10.0 -> 0.11.1"
|
delta = "0.10.0 -> 0.11.1"
|
||||||
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.strum]]
|
||||||
|
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.25.0 -> 0.26.3"
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.strum]]
|
||||||
|
who = "Erich Gubler <erichdongubler@gmail.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.26.3 -> 0.27.1"
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.strum_macros]]
|
||||||
|
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.25.3 -> 0.26.4"
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.strum_macros]]
|
||||||
|
who = "Erich Gubler <erichdongubler@gmail.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.26.4 -> 0.27.1"
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
[[audits.mozilla.audits.synstructure]]
|
[[audits.mozilla.audits.synstructure]]
|
||||||
who = "Nika Layzell <nika@thelayzells.com>"
|
who = "Nika Layzell <nika@thelayzells.com>"
|
||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
@@ -1038,3 +1335,153 @@ who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
|||||||
criteria = "safe-to-deploy"
|
criteria = "safe-to-deploy"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
|
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.windows-link]]
|
||||||
|
who = "Mark Hammond <mhammond@skippinet.com.au>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "0.1.1"
|
||||||
|
notes = "A microsoft crate allowing unsafe calls to windows apis."
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.windows-link]]
|
||||||
|
who = "Erich Gubler <erichdongubler@gmail.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.1.1 -> 0.2.0"
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.mozilla.audits.zeroize]]
|
||||||
|
who = "Benjamin Beurdouche <beurdouche@mozilla.com>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "1.8.1"
|
||||||
|
notes = """
|
||||||
|
This code DOES contain unsafe code required to internally call volatiles
|
||||||
|
for deleting data. This is expected and documented behavior.
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.autocfg]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.4.0 -> 1.5.0"
|
||||||
|
notes = "Filesystem change is to remove the generated LLVM IR output file after probing."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.dunce]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
version = "1.0.5"
|
||||||
|
notes = """
|
||||||
|
Does what it says on the tin. No `unsafe`, and the only IO is `std::fs::canonicalize`.
|
||||||
|
Path and string handling looks plausibly correct.
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.errno]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.3 -> 0.3.8"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.errno]]
|
||||||
|
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.8 -> 0.3.9"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.errno]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.10 -> 0.3.11"
|
||||||
|
notes = "The `__errno` location for vxworks and cygwin looks correct from a quick search."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.errno]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.11 -> 0.3.13"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.errno]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.13 -> 0.3.14"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.http-body]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.0 -> 1.0.1"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.inout]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.1.3 -> 0.1.4"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.rustc_version]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.4.0 -> 0.4.1"
|
||||||
|
notes = "Changes to `Command` usage are to add support for `RUSTC_WRAPPER`."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.rustversion]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.20 -> 1.0.21"
|
||||||
|
notes = "Build script change is to fix building with `-Zfmt-debug=none`."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.rustversion]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.0.21 -> 1.0.22"
|
||||||
|
notes = "Changes to generated code are to prepend a clippy annotation."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.strum]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.27.1 -> 0.27.2"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.strum_macros]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.27.1 -> 0.27.2"
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.try-lock]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.2.4 -> 0.2.5"
|
||||||
|
notes = "Bumps MSRV to remove unsafe code block."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.want]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.3.0 -> 0.3.1"
|
||||||
|
notes = """
|
||||||
|
Migrates to `try-lock 0.2.4` to replace some unsafe APIs that were not marked
|
||||||
|
`unsafe` (but that were being used safely).
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.windows-link]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "0.2.0 -> 0.2.1"
|
||||||
|
notes = "No code changes at all."
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml"
|
||||||
|
|
||||||
|
[[audits.zcash.audits.zeroize]]
|
||||||
|
who = "Jack Grigg <jack@electriccoin.co>"
|
||||||
|
criteria = "safe-to-deploy"
|
||||||
|
delta = "1.8.1 -> 1.8.2"
|
||||||
|
notes = """
|
||||||
|
Changes to `unsafe` code are to alter how `core::mem::size_of` is named; no actual changes
|
||||||
|
to the `unsafe` logic.
|
||||||
|
"""
|
||||||
|
aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml"
|
||||||
|
|||||||
Reference in New Issue
Block a user