Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
489 changes: 396 additions & 93 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,15 @@ proptest = { version = "1.9.0", default-features = false }
proptest-state-machine = { version = "0.6.0", default-features = false }
pyo3 = { version = "0.25.1", default-features = false }
quote = { version = "1.0.44", default-features = false }
rand = { version = "0.8.5", default-features = false }
rand = { version = "0.10.0-rc.9", default-features = false }
rand8 = { package = "rand", version = "0.8.5", default-features = false }
regex = { version = "1.12.2", default-features = false }
regex-syntax = { version = "0.8.8", default-features = false }
reqwest = { version = "0.13.1", default-features = false }
rexpect = "0.6.3"
rmp-serde = { version = "1.3.1", default-features = false }
rpassword = { version = "7.4.0", default-features = false }
rsa = { version = "0.8.2", default-features = false }
rsa = { version = "0.10.0-rc.15", default-features = false }
rstest = { version = "0.26.1", default-features = false }
rstest_reuse = { version = "0.7.0", default-features = false }
rustls-pki-types = { version = "1.14.0", default-features = false }
Expand Down
7 changes: 4 additions & 3 deletions libparsec/crates/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ ed25519-dalek = { workspace = true, features = [
] } # Optional rustcrypto dep
generic-array = { workspace = true, features = ["serde"] } # Optional rustcrypto dep
lazy_static = { workspace = true } # Optional rustcrypto dep
rsa = { workspace = true, features = ["std", "pem"] } # Optional rustcrypto dep
rsa = { workspace = true, features = ["std", "encoding", "sha2"] } # Optional rustcrypto dep
sha2 = { workspace = true, features = ["std"] } # Optional rustcrypto dep
# This is exceptionally allowed since no significant changes
# were made from the last stable version to this major pre-release version.
Expand All @@ -142,8 +142,9 @@ crypto_secretbox = { workspace = true, features = [
] } # Optional rustcrypto dep
# Cryptographic randomness is required for generating SecretKey, SigningKey and PrivateKey
# `getrandom` is a dependency of `rand`, we specify it here in order to configure its `wasm-unknown-unknown` web support (see [target] part).
getrandom = { workspace = true } # Optional rustcrypto dep
rand = { workspace = true, features = ["std", "std_rng"] } # Optional rustcrypto dep
getrandom = { workspace = true } # Optional rustcrypto dep
rand = { workspace = true, features = ["std", "sys_rng"] } # Optional rustcrypto dep
rand8 = { workspace = true, features = ["std", "std_rng"] } # Optional rustcrypto dep
# Need to list previous version of `getrandom@0.2` to be able to enable the `js` feature
_getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] }

Expand Down
6 changes: 4 additions & 2 deletions libparsec/crates/crypto/src/rustcrypto/key_derivation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
ArrayLength, GenericArray,
};
use rand::{rngs::OsRng, RngCore};
use rand::{rngs::SysRng, Rng, TryRng};

Check warning on line 12 in libparsec/crates/crypto/src/rustcrypto/key_derivation.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

unused import: `Rng`

Check failure on line 12 in libparsec/crates/crypto/src/rustcrypto/key_derivation.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

unused import: `Rng`
use serde::Deserialize;
use serde_bytes::Bytes;

Expand All @@ -29,7 +29,9 @@

pub fn generate() -> Self {
let mut bytes = [0u8; Self::SIZE];
OsRng.fill_bytes(&mut bytes);
SysRng
.try_fill_bytes(&mut bytes)
.expect("Failed to generate random data");
Self(bytes.into())
}

Expand Down
8 changes: 4 additions & 4 deletions libparsec/crates/crypto/src/rustcrypto/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

//re-export keys
pub use crypto_box::{PublicKey, SecretKey};
use rand::rngs::OsRng;
use rand::rngs::SysRng;

Check warning on line 18 in libparsec/crates/crypto/src/rustcrypto/private.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

unused import: `rand::rngs::SysRng`

Check failure on line 18 in libparsec/crates/crypto/src/rustcrypto/private.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

unused import: `rand::rngs::SysRng`

const BOX_NONCE_LENGTH: usize = 24;
const BOX_OVERHEAD: usize = 16;
Expand Down Expand Up @@ -49,7 +49,7 @@
pub fn seal(data: &[u8], pk: &PublicKey) -> Vec<u8> {
let mut out = Vec::with_capacity(SEALED_OVERHEAD + data.len());

let ep_sk = SecretKey::generate(&mut OsRng);
let ep_sk = SecretKey::generate(&mut rand8::rngs::OsRng);
let ep_pk = ep_sk.public_key();
out.extend_from_slice(ep_pk.as_bytes());

Expand Down Expand Up @@ -96,7 +96,7 @@
use blake2::Blake2b512;
use crypto_box::KEY_SIZE;
use digest::Digest;
use rand::rngs::OsRng;
use rand::rngs::SysRng;

Check warning on line 99 in libparsec/crates/crypto/src/rustcrypto/private.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

unused import: `rand::rngs::SysRng`

Check failure on line 99 in libparsec/crates/crypto/src/rustcrypto/private.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

unused import: `rand::rngs::SysRng`
use serde::{Deserialize, Serialize};
use serde_bytes::Bytes;
use zeroize::Zeroizing;
Expand Down Expand Up @@ -136,7 +136,7 @@
}

pub fn generate() -> Self {
Self(crypto_box::SecretKey::generate(&mut OsRng))
Self(crypto_box::SecretKey::generate(&mut rand8::rngs::OsRng))
}

pub fn decrypt_from_self(&self, ciphered: &[u8]) -> Result<Vec<u8>, CryptoError> {
Expand Down
6 changes: 3 additions & 3 deletions libparsec/crates/crypto/src/rustcrypto/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
typenum::{consts::U64, IsLessOrEqual, LeEq, NonZero},
ArrayLength, GenericArray,
};
use rand::rngs::OsRng;
use rand::rngs::SysRng;

Check warning on line 11 in libparsec/crates/crypto/src/rustcrypto/secret.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

unused import: `rand::rngs::SysRng`

Check failure on line 11 in libparsec/crates/crypto/src/rustcrypto/secret.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

unused import: `rand::rngs::SysRng`
use serde::Deserialize;
use serde_bytes::Bytes;

Expand All @@ -23,15 +23,15 @@
pub const SIZE: usize = XSalsa20Poly1305::KEY_SIZE;

pub fn generate() -> Self {
Self(XSalsa20Poly1305::generate_key(OsRng))
Self(XSalsa20Poly1305::generate_key(rand8::rngs::OsRng))
}

pub fn encrypt(&self, data: &[u8]) -> Vec<u8> {
// Returned format: NONCE | MAC | CIPHERTEXT
// TODO: zero copy with pre-allocated buffer
// let mut ciphered = Vec::with_capacity(NONCE_SIZE + TAG_SIZE + data.len());
let cipher = XSalsa20Poly1305::new(&self.0);
let nonce = XSalsa20Poly1305::generate_nonce(OsRng);
let nonce = XSalsa20Poly1305::generate_nonce(rand8::rngs::OsRng);
// TODO: handle this error?
let mut ciphered = cipher.encrypt(&nonce, data).expect("encryption failure !");
let mut res = vec![];
Expand Down
48 changes: 20 additions & 28 deletions libparsec/crates/crypto/src/rustcrypto/sequester.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
// Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS

use rand::rngs::OsRng;
use rand::rngs::SysRng;
use rsa::{
oaep::Oaep,
pkcs8::{
der::zeroize::Zeroizing, DecodePrivateKey, DecodePublicKey, EncodePrivateKey,
EncodePublicKey,
},
pss::{Signature, SigningKey, VerifyingKey},
signature::{RandomizedSigner, Verifier},
PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey,
sha2::Sha256,
signature::{RandomizedSigner, SignatureEncoding, Verifier},
traits::PublicKeyParts,
RsaPrivateKey, RsaPublicKey,
};
use serde::{Deserialize, Serialize};
use serde_bytes::Bytes;
use sha2::Sha256;

use crate::{
deserialize_with_armor, serialize_with_armor, CryptoError, CryptoResult, SecretKey,
Expand Down Expand Up @@ -43,15 +44,15 @@
const ALGORITHM: &'static str = "RSAES-OAEP-SHA256-XSALSA20-POLY1305";

pub fn generate_pair(size_in_bits: SequesterKeySize) -> (Self, SequesterPublicKeyDer) {
let priv_key = RsaPrivateKey::new(&mut OsRng, size_in_bits as usize)
let priv_key = RsaPrivateKey::new(&mut SysRng, size_in_bits as usize)

Check failure on line 47 in libparsec/crates/crypto/src/rustcrypto/sequester.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

type mismatch resolving `<SysRng as TryRng>::Error == Infallible`

Check failure on line 47 in libparsec/crates/crypto/src/rustcrypto/sequester.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

type mismatch resolving `<SysRng as TryRng>::Error == Infallible`
.expect("Cannot generate the RSA key");
let pub_key = RsaPublicKey::from(&priv_key);

(Self(priv_key), SequesterPublicKeyDer(pub_key))
}

pub fn size_in_bytes(&self) -> usize {
self.0.n().bits() / 8
self.0.n().bits() as usize / 8
}

pub fn dump(&self) -> Zeroizing<Vec<u8>> {
Expand All @@ -73,7 +74,7 @@
pub fn decrypt(&self, data: &[u8]) -> CryptoResult<Vec<u8>> {
let (cipherkey, ciphertext) =
deserialize_with_armor(data, self.size_in_bytes(), Self::ALGORITHM)?;
let padding = Oaep::new::<Sha256>();
let padding = Oaep::<rsa::sha2::Sha256>::new();

let clearkey = SecretKey::try_from(
&self
Expand Down Expand Up @@ -127,7 +128,7 @@
const ALGORITHM: &'static str = "RSAES-OAEP-SHA256-XSALSA20-POLY1305";

pub fn size_in_bytes(&self) -> usize {
self.0.n().bits() / 8
self.0.n().bits() as usize / 8
}

pub fn dump(&self) -> Vec<u8> {
Expand All @@ -149,11 +150,11 @@
// Encryption format:
// <algorithm name>:<encrypted secret key with RSA key><encrypted data with secret key>
pub fn encrypt(&self, data: &[u8]) -> Vec<u8> {
let padding = Oaep::new::<Sha256>();
let padding = Oaep::<rsa::sha2::Sha256>::new();
let secret_key = SecretKey::generate();
let secret_key_encrypted = self
.0
.encrypt(&mut OsRng, padding, secret_key.as_ref())
.encrypt(&mut SysRng, padding, secret_key.as_ref())

Check failure on line 157 in libparsec/crates/crypto/src/rustcrypto/sequester.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

type mismatch resolving `<SysRng as TryRng>::Error == Infallible`

Check failure on line 157 in libparsec/crates/crypto/src/rustcrypto/sequester.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

type mismatch resolving `<SysRng as TryRng>::Error == Infallible`
.expect("Unreachable");

// RSAES-OAEP uses 42 bytes for padding, hence even with an insecure
Expand All @@ -172,17 +173,11 @@
* SigningKey
*/

#[derive(Clone)]
#[derive(Clone, PartialEq)]
pub struct SequesterSigningKeyDer(SigningKey<Sha256>);

crate::impl_key_debug!(SequesterSigningKeyDer);

impl PartialEq for SequesterSigningKeyDer {
fn eq(&self, other: &Self) -> bool {
self.0.as_ref() == other.0.as_ref()
}
}

impl Eq for SequesterSigningKeyDer {}

impl TryFrom<&[u8]> for SequesterSigningKeyDer {
Expand All @@ -208,7 +203,7 @@
}

pub fn size_in_bytes(&self) -> usize {
self.0.as_ref().n().bits() / 8
self.0.as_ref().n().bits() as usize / 8
}

pub fn dump(&self) -> Zeroizing<Vec<u8>> {
Expand All @@ -230,10 +225,13 @@
// Signature format:
// <algorithm name>:<signature><data>
pub fn sign(&self, data: &[u8]) -> Vec<u8> {
let signature = self.0.sign_with_rng(&mut OsRng, data);
let signature = self
.0
.try_sign_with_rng(&mut SysRng, data)
.expect("Failed to generate signature");

serialize_with_armor(
signature.as_ref(),
signature.to_bytes().as_ref(),
data,
self.size_in_bytes(),
Self::ALGORITHM,
Expand All @@ -245,18 +243,12 @@
* VerifyKey
*/

#[derive(Clone, Deserialize)]
#[derive(Clone, Deserialize, PartialEq)]
#[serde(try_from = "&Bytes")]
pub struct SequesterVerifyKeyDer(VerifyingKey<Sha256>);

crate::impl_key_debug!(SequesterVerifyKeyDer);

impl PartialEq for SequesterVerifyKeyDer {
fn eq(&self, other: &Self) -> bool {
self.0.as_ref() == other.0.as_ref()
}
}

impl Eq for SequesterVerifyKeyDer {}

impl TryFrom<&[u8]> for SequesterVerifyKeyDer {
Expand Down Expand Up @@ -291,7 +283,7 @@
const ALGORITHM: &'static str = "RSASSA-PSS-SHA256";

pub fn size_in_bytes(&self) -> usize {
self.0.as_ref().n().bits() / 8
self.0.as_ref().n().bits() as usize / 8
}

pub fn dump(&self) -> Vec<u8> {
Expand Down
4 changes: 2 additions & 2 deletions libparsec/crates/crypto/src/rustcrypto/sign.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS

use ed25519_dalek::{Signature, Signer, Verifier};
use rand::rngs::OsRng;
use rand::rngs::SysRng;

Check warning on line 4 in libparsec/crates/crypto/src/rustcrypto/sign.rs

View workflow job for this annotation

GitHub Actions / python / (🐧 Linux only): 🐍 Python server tests

unused import: `rand::rngs::SysRng`

Check failure on line 4 in libparsec/crates/crypto/src/rustcrypto/sign.rs

View workflow job for this annotation

GitHub Actions / rust / 🐧 Linux: 🦀 Rust tests

unused import: `rand::rngs::SysRng`
use serde::{Deserialize, Serialize};
use serde_bytes::Bytes;

Expand Down Expand Up @@ -37,7 +37,7 @@
}

pub fn generate() -> Self {
Self(ed25519_dalek::SigningKey::generate(&mut OsRng))
Self(ed25519_dalek::SigningKey::generate(&mut rand8::rngs::OsRng))
}

/// Sign the message and prefix it with the signature.
Expand Down
4 changes: 2 additions & 2 deletions libparsec/crates/crypto/src/rustcrypto/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use generic_array::{
typenum::{consts::U64, IsLessOrEqual, LeEq, NonZero},
ArrayLength, GenericArray,
};
use rand::{rngs::OsRng, RngCore};
use rand::{rngs::SysRng, TryRng};

pub(crate) fn generate_rand(out: &mut [u8]) {
OsRng.fill_bytes(out);
SysRng.try_fill_bytes(out).expect("Failed to fill bytes")
}

pub(crate) fn blake2b_hash<'a, Size>(data: impl Iterator<Item = &'a [u8]>) -> GenericArray<u8, Size>
Expand Down
Loading