Skip to content

Commit

Permalink
Fix sodiumoxide SequesterCrypto
Browse files Browse the repository at this point in the history
  • Loading branch information
TimeEngineer committed Mar 31, 2023
1 parent 551ddff commit 91f88ca
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 23 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions oxidation/libparsec/crates/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ base32 = "0.4.0"

sodiumoxide = { version = "0.2.7", optional = true }
libsodium-sys = { version = "0.2.7", optional = true }
openssl = { version = "0.10", optional = true, features = ["vendored"] }
zeroize = { version = "1", optional = true, features = ["alloc"]}
openssl = { version = "0.10.48", optional = true, features = ["vendored"] }
zeroize = { version = "1.6.0", optional = true, features = ["alloc"]}

argon2 = { version = "0.4.1", optional = true }
blake2 = { version = "0.10.6", optional = true }
Expand Down
11 changes: 11 additions & 0 deletions oxidation/libparsec/crates/crypto/src/rustcrypto/sequester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ impl SequesterSigningKeyDer {
(Self(signing_key), SequesterVerifyKeyDer(verify_key))
}

pub fn generate_pair_with_salt_len(
size_in_bits: SequesterKeySize,
salt_len: usize,
) -> (Self, SequesterVerifyKeyDer) {
let (priv_key, pub_key) = SequesterPrivateKeyDer::generate_pair(size_in_bits);
let signing_key = SigningKey::new_with_salt_len(priv_key.0, salt_len);
let verify_key = VerifyingKey::from(pub_key.0);

(Self(signing_key), SequesterVerifyKeyDer(verify_key))
}

pub fn size_in_bytes(&self) -> usize {
self.0.as_ref().n().bits() / 8
}
Expand Down
70 changes: 53 additions & 17 deletions oxidation/libparsec/crates/crypto/src/sodiumoxide/sequester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,16 @@ impl SequesterPublicKeyDer {
*/

#[derive(Clone)]
pub struct SequesterSigningKeyDer(PKey<Private>);
pub struct SequesterSigningKeyDer {
inner: PKey<Private>,
salt_len: Option<usize>,
}

crate::impl_key_debug!(SequesterSigningKeyDer);

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

Expand All @@ -230,11 +233,14 @@ impl TryFrom<&[u8]> for SequesterSigningKeyDer {

fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
let key = PKey::private_key_from_der(bytes)
.map(Self)
.map(|inner| Self {
inner,
salt_len: None,
})
.map_err(|err| CryptoError::SequesterPublicKeyDer(err.to_string()))?;

// Verify it's RSA key
key.0
key.inner
.rsa()
.map_err(|err| CryptoError::SequesterPrivateKeyDer(err.to_string()))?;

Expand All @@ -250,30 +256,56 @@ impl SequesterSigningKeyDer {
let signing_key = PKey::from_rsa(priv_key.0).expect("Unreachable");
let verify_key = PKey::from_rsa(pub_key.0).expect("Unreachable");

(Self(signing_key), SequesterVerifyKeyDer(verify_key))
(
Self {
inner: signing_key,
salt_len: None,
},
SequesterVerifyKeyDer(verify_key),
)
}

pub fn generate_pair_with_salt_len(
size_in_bits: SequesterKeySize,
salt_len: usize,
) -> (Self, SequesterVerifyKeyDer) {
let (priv_key, pub_key) = SequesterPrivateKeyDer::generate_pair(size_in_bits);
let signing_key = PKey::from_rsa(priv_key.0).expect("Unreachable");
let verify_key = PKey::from_rsa(pub_key.0).expect("Unreachable");

(
Self {
inner: signing_key,
salt_len: Some(salt_len),
},
SequesterVerifyKeyDer(verify_key),
)
}

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

pub fn dump(&self) -> Zeroizing<Vec<u8>> {
Zeroizing::new(self.0.private_key_to_der().expect("Unreachable"))
Zeroizing::new(self.inner.private_key_to_der().expect("Unreachable"))
}

pub fn dump_pem(&self) -> Zeroizing<String> {
let pkey_pem = self.0.private_key_to_pem_pkcs8().expect("Unreachable");
let pkey_pem = self.inner.private_key_to_pem_pkcs8().expect("Unreachable");

Zeroizing::new(String::from_utf8(pkey_pem).expect("Unreachable"))
}

pub fn load_pem(s: &str) -> CryptoResult<Self> {
let key = PKey::private_key_from_pem(s.as_bytes())
.map(Self)
.map(|inner| Self {
inner,
salt_len: None,
})
.map_err(|err| CryptoError::SequesterPrivateKeyDer(err.to_string()))?;

// Verify it's RSA key
key.0
key.inner
.rsa()
.map_err(|err| CryptoError::SequesterPrivateKeyDer(err.to_string()))?;

Expand All @@ -284,14 +316,21 @@ impl SequesterSigningKeyDer {
// <algorithm name>:<signature><data>
pub fn sign(&self, data: &[u8]) -> Vec<u8> {
let mut signer =
Signer::new(MessageDigest::sha256(), &self.0).expect("Unable to build a Signer");
Signer::new(MessageDigest::sha256(), &self.inner).expect("Unable to build a Signer");

signer
.set_rsa_padding(Padding::PKCS1_PSS)
.expect("OpenSSL error");
signer
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
.expect("OpenSSL error");

if let Some(salt_len) = self.salt_len {
signer
.set_rsa_pss_saltlen(RsaPssSaltlen::custom(salt_len as i32))
.expect("OpenSSL error");
} else {
signer
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
.expect("OpenSSL error");
}

signer.update(data).expect("Unreachable");
let signed_data = signer.sign_to_vec().expect("Unable to sign a message");
Expand Down Expand Up @@ -382,9 +421,6 @@ impl SequesterVerifyKeyDer {
verifier
.set_rsa_padding(Padding::PKCS1_PSS)
.expect("OpenSSL error");
verifier
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
.expect("OpenSSL error");

verifier
.update(contents)
Expand Down
15 changes: 15 additions & 0 deletions oxidation/libparsec/crates/crypto/tests/sequester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,18 @@ fn test_encrypt_compat() {

assert_eq!(priv_key.decrypt(&encrypted).unwrap(), b"Hello world");
}

#[test]
fn verify_with_different_salt_len() {
let (signing_key94, verify_key94) =
SequesterSigningKeyDer::generate_pair_with_salt_len(SequesterKeySize::_1024Bits, 94);
let (signing_key32, verify_key32) =
SequesterSigningKeyDer::generate_pair_with_salt_len(SequesterKeySize::_1024Bits, 32);
let data = b"Hello world";

let ciphered = signing_key94.sign(data);
assert_eq!(verify_key94.verify(&ciphered).unwrap(), data);

let ciphered = signing_key32.sign(data);
assert_eq!(verify_key32.verify(&ciphered).unwrap(), data);
}

0 comments on commit 91f88ca

Please sign in to comment.