mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-09-16 14:51:37 +02:00
Work through the open Dependabot PRs (#663)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
31d55440c1
commit
3d6c31440c
@@ -7,7 +7,7 @@ publish = false
|
||||
[dependencies]
|
||||
base32 = "0.5.1" # For encoding human-readable key
|
||||
base64 = "0.22.1" # For encoding in the database
|
||||
chacha20poly1305 = "0.10.1"
|
||||
chacha20poly1305 = "0.11.0"
|
||||
keyring = { workspace = true, features = ["apple-native", "windows-native", "sync-secret-service"] }
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::error::Error::{DecryptionError, EncryptionError, InvalidEncryptedData};
|
||||
use crate::error::Result;
|
||||
use chacha20poly1305::aead::generic_array::typenum::Unsigned;
|
||||
use chacha20poly1305::aead::{Aead, AeadCore, Key, KeyInit, OsRng};
|
||||
use chacha20poly1305::XChaCha20Poly1305;
|
||||
use chacha20poly1305::aead::array::typenum::Unsigned;
|
||||
use chacha20poly1305::aead::{Aead, AeadCore, Generate, Key, KeyInit};
|
||||
use chacha20poly1305::{XChaCha20Poly1305, XNonce};
|
||||
|
||||
const ENCRYPTION_TAG: &str = "yA4k3nC";
|
||||
const ENCRYPTION_VERSION: u8 = 1;
|
||||
|
||||
pub(crate) fn encrypt_data(data: &[u8], key: &Key<XChaCha20Poly1305>) -> Result<Vec<u8>> {
|
||||
let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
|
||||
let nonce = XNonce::generate();
|
||||
let cipher = XChaCha20Poly1305::new(&key);
|
||||
let ciphered_data = cipher.encrypt(&nonce, data).map_err(|_| EncryptionError)?;
|
||||
|
||||
@@ -34,11 +34,12 @@ pub(crate) fn decrypt_data(cipher_data: &[u8], key: &Key<XChaCha20Poly1305>) ->
|
||||
return Err(InvalidEncryptedData);
|
||||
}
|
||||
|
||||
let nonce_bytes = <XChaCha20Poly1305 as AeadCore>::NonceSize::to_usize();
|
||||
let nonce_bytes = <XChaCha20Poly1305 as AeadCore>::NonceSize::USIZE;
|
||||
let (nonce, ciphered_data) = rest.split_at_checked(nonce_bytes).ok_or(InvalidEncryptedData)?;
|
||||
|
||||
let nonce: &XNonce = nonce.try_into().map_err(|_| InvalidEncryptedData)?;
|
||||
let cipher = XChaCha20Poly1305::new(&key);
|
||||
cipher.decrypt(nonce.into(), ciphered_data).map_err(|_e| DecryptionError)
|
||||
cipher.decrypt(nonce, ciphered_data).map_err(|_e| DecryptionError)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -46,12 +47,12 @@ mod test {
|
||||
use crate::encryption::{decrypt_data, encrypt_data};
|
||||
use crate::error::Error::InvalidEncryptedData;
|
||||
use crate::error::Result;
|
||||
use chacha20poly1305::aead::OsRng;
|
||||
use chacha20poly1305::{KeyInit, XChaCha20Poly1305};
|
||||
use chacha20poly1305::aead::{Generate, Key};
|
||||
use chacha20poly1305::XChaCha20Poly1305;
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_decrypt() -> Result<()> {
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
let encrypted = encrypt_data("hello world".as_bytes(), &key)?;
|
||||
let decrypted = decrypt_data(encrypted.as_slice(), &key)?;
|
||||
assert_eq!(String::from_utf8(decrypted).unwrap(), "hello world");
|
||||
@@ -60,7 +61,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_decrypt_empty() -> Result<()> {
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
let encrypted = encrypt_data(&[], &key)?;
|
||||
assert_eq!(encrypted.len(), 48);
|
||||
let decrypted = decrypt_data(encrypted.as_slice(), &key)?;
|
||||
@@ -70,7 +71,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_decrypt_bad_version() -> Result<()> {
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
let mut encrypted = encrypt_data("hello world".as_bytes(), &key)?;
|
||||
encrypted[7] = 0;
|
||||
let decrypted = decrypt_data(encrypted.as_slice(), &key);
|
||||
@@ -80,7 +81,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_decrypt_bad_tag() -> Result<()> {
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
let mut encrypted = encrypt_data("hello world".as_bytes(), &key)?;
|
||||
encrypted[0] = 2;
|
||||
let decrypted = decrypt_data(encrypted.as_slice(), &key);
|
||||
@@ -90,9 +91,29 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_decrypt_unencrypted_data() -> Result<()> {
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
let decrypted = decrypt_data("123".as_bytes(), &key);
|
||||
assert!(matches!(decrypted, Err(InvalidEncryptedData)));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod compatibility {
|
||||
use super::*;
|
||||
|
||||
/// Produced by chacha20poly1305 0.10.1. Decrypting it here proves a crate
|
||||
/// upgrade hasn't changed the on-disk format, which users already have
|
||||
/// rows of in their databases.
|
||||
const V1_FROM_0_10: &str = "7941346b336e43017c7cb13467eecaa963b11734be636f9cc4152de348584fb27e95d1a70973e557cd335cf29e12d0d305d63ca0aa168f1b17003b1690a9d49140f0";
|
||||
|
||||
#[test]
|
||||
fn decrypts_data_written_by_the_previous_release() {
|
||||
let bytes: Vec<u8> = (0..V1_FROM_0_10.len())
|
||||
.step_by(2)
|
||||
.map(|i| u8::from_str_radix(&V1_FROM_0_10[i..i + 2], 16).unwrap())
|
||||
.collect();
|
||||
let key = Key::<XChaCha20Poly1305>::from([7u8; 32]);
|
||||
assert_eq!(decrypt_data(&bytes, &key).unwrap(), b"yaak golden vector");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::encryption::{decrypt_data, encrypt_data};
|
||||
use crate::error::Error::GenericError;
|
||||
use crate::error::Result;
|
||||
use base32::Alphabet;
|
||||
use chacha20poly1305::aead::{Key, KeyInit, OsRng};
|
||||
use chacha20poly1305::aead::{Generate, Key};
|
||||
use chacha20poly1305::XChaCha20Poly1305;
|
||||
use keyring::{Entry, Error};
|
||||
use log::info;
|
||||
@@ -24,11 +24,12 @@ impl MasterKey {
|
||||
let without_prefix = encoded.strip_prefix(HUMAN_PREFIX).unwrap_or(&encoded);
|
||||
let key_bytes = base32::decode(Alphabet::Crockford {}, &without_prefix)
|
||||
.ok_or(GenericError("Failed to decode master key".to_string()))?;
|
||||
Key::<XChaCha20Poly1305>::clone_from_slice(key_bytes.as_slice())
|
||||
Key::<XChaCha20Poly1305>::try_from(key_bytes.as_slice())
|
||||
.map_err(|_| GenericError("Master key is the wrong length".to_string()))?
|
||||
}
|
||||
Err(Error::NoEntry) => {
|
||||
info!("Creating new master key");
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
let encoded = base32::encode(Alphabet::Crockford {}, key.as_slice());
|
||||
let with_prefix = format!("{HUMAN_PREFIX}{encoded}");
|
||||
entry.set_password(&with_prefix)?;
|
||||
@@ -50,9 +51,7 @@ impl MasterKey {
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn test_key() -> Self {
|
||||
let key: Key<XChaCha20Poly1305> = Key::<XChaCha20Poly1305>::clone_from_slice(
|
||||
"00000000000000000000000000000000".as_bytes(),
|
||||
);
|
||||
let key = Key::<XChaCha20Poly1305>::from(*b"00000000000000000000000000000000");
|
||||
Self { key }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::encryption::{decrypt_data, encrypt_data};
|
||||
use crate::error::Error::InvalidHumanKey;
|
||||
use crate::error::Result;
|
||||
use base32::Alphabet;
|
||||
use chacha20poly1305::aead::{Key, KeyInit, OsRng};
|
||||
use chacha20poly1305::aead::{Generate, Key};
|
||||
use chacha20poly1305::{KeySizeUser, XChaCha20Poly1305};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -39,7 +39,9 @@ impl WorkspaceKey {
|
||||
}
|
||||
|
||||
pub(crate) fn from_raw_key(key: &[u8]) -> Self {
|
||||
Self { key: Key::<XChaCha20Poly1305>::clone_from_slice(key) }
|
||||
Self {
|
||||
key: Key::<XChaCha20Poly1305>::try_from(key).expect("workspace key must be 32 bytes"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn raw_key(&self) -> &[u8] {
|
||||
@@ -47,7 +49,7 @@ impl WorkspaceKey {
|
||||
}
|
||||
|
||||
pub(crate) fn create() -> Result<Self> {
|
||||
let key = XChaCha20Poly1305::generate_key(OsRng);
|
||||
let key = Key::<XChaCha20Poly1305>::generate();
|
||||
Ok(Self::from_raw_key(key.as_slice()))
|
||||
}
|
||||
|
||||
|
||||
@@ -13,15 +13,15 @@ hyper-rustls = { version = "0.27.7", default-features = false, features = ["http
|
||||
hyper-util = { version = "0.1.13", default-features = false, features = ["client-legacy"] }
|
||||
log = { workspace = true }
|
||||
md5 = "0.7.0"
|
||||
prost = "0.13.4"
|
||||
prost-reflect = { version = "0.14.4", default-features = false, features = ["serde", "derive"] }
|
||||
prost-types = "0.13.4"
|
||||
prost = "0.14.4"
|
||||
prost-reflect = { version = "0.16.5", default-features = false, features = ["serde", "derive"] }
|
||||
prost-types = "0.14.4"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs", "process"] }
|
||||
tokio-stream = "0.1.14"
|
||||
tonic = { version = "0.12.3", default-features = false, features = ["transport"] }
|
||||
tonic-reflection = "0.12.3"
|
||||
tonic = { version = "0.14.6", default-features = false, features = ["transport"] }
|
||||
tonic-reflection = "0.14.6"
|
||||
uuid = { version = "1.7.0", features = ["v4"] }
|
||||
yaak-common = { workspace = true }
|
||||
yaak-tls = { workspace = true }
|
||||
|
||||
@@ -10,7 +10,7 @@ use log::debug;
|
||||
use std::collections::BTreeMap;
|
||||
use tokio_stream::StreamExt;
|
||||
use tonic::Request;
|
||||
use tonic::body::BoxBody;
|
||||
use tonic::body::Body;
|
||||
use tonic::transport::Uri;
|
||||
use tonic_reflection::pb::v1::server_reflection_request::MessageRequest;
|
||||
use tonic_reflection::pb::v1::server_reflection_response::MessageResponse;
|
||||
@@ -22,7 +22,7 @@ use tonic_reflection::pb::v1::{ExtensionRequest, FileDescriptorResponse};
|
||||
use tonic_reflection::pb::{v1, v1alpha};
|
||||
use yaak_tls::ClientCertificateConfig;
|
||||
|
||||
pub struct AutoReflectionClient<T = Client<HttpsConnector<HttpConnector>, BoxBody>> {
|
||||
pub struct AutoReflectionClient<T = Client<HttpsConnector<HttpConnector>, Body>> {
|
||||
use_v1alpha: bool,
|
||||
client_v1: v1::server_reflection_client::ServerReflectionClient<T>,
|
||||
client_v1alpha: v1alpha::server_reflection_client::ServerReflectionClient<T>,
|
||||
|
||||
@@ -27,7 +27,7 @@ use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio_stream::StreamExt;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tonic::body::BoxBody;
|
||||
use tonic::body::Body;
|
||||
use tonic::metadata::{MetadataKey, MetadataValue};
|
||||
use tonic::transport::Uri;
|
||||
use tonic::{IntoRequest, IntoStreamingRequest, Request, Response, Status, Streaming};
|
||||
@@ -36,7 +36,7 @@ use yaak_tls::ClientCertificateConfig;
|
||||
#[derive(Clone)]
|
||||
pub struct GrpcConnection {
|
||||
pool: Arc<RwLock<DescriptorPool>>,
|
||||
conn: Client<HttpsConnector<HttpConnector>, BoxBody>,
|
||||
conn: Client<HttpsConnector<HttpConnector>, Body>,
|
||||
pub uri: Uri,
|
||||
use_reflection: bool,
|
||||
max_message_size: usize,
|
||||
@@ -338,10 +338,10 @@ impl GrpcConnection {
|
||||
}
|
||||
|
||||
fn grpc_client(
|
||||
conn: Client<HttpsConnector<HttpConnector>, BoxBody>,
|
||||
conn: Client<HttpsConnector<HttpConnector>, Body>,
|
||||
uri: Uri,
|
||||
max_message_size: usize,
|
||||
) -> tonic::client::Grpc<Client<HttpsConnector<HttpConnector>, BoxBody>> {
|
||||
) -> tonic::client::Grpc<Client<HttpsConnector<HttpConnector>, Body>> {
|
||||
tonic::client::Grpc::with_origin(conn, uri)
|
||||
.max_decoding_message_size(max_message_size)
|
||||
.max_encoding_message_size(max_message_size)
|
||||
|
||||
@@ -4,7 +4,7 @@ use hyper_util::client::legacy::Client;
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
use log::info;
|
||||
use tonic::body::BoxBody;
|
||||
use tonic::body::Body;
|
||||
use yaak_tls::{ClientCertificateConfig, get_tls_config};
|
||||
|
||||
// I think ALPN breaks this because we're specifying http2_only
|
||||
@@ -13,7 +13,7 @@ const WITH_ALPN: bool = false;
|
||||
pub(crate) fn get_transport(
|
||||
validate_certificates: bool,
|
||||
client_cert: Option<ClientCertificateConfig>,
|
||||
) -> Result<Client<HttpsConnector<HttpConnector>, BoxBody>> {
|
||||
) -> Result<Client<HttpsConnector<HttpConnector>, Body>> {
|
||||
let tls_config = get_tls_config(validate_certificates, WITH_ALPN, client_cert.clone())?;
|
||||
|
||||
let mut http = HttpConnector::new();
|
||||
|
||||
Reference in New Issue
Block a user