From a7a8faa23a1f37a09dd5fb88e56bb50e59bf59f6 Mon Sep 17 00:00:00 2001 From: kostiask Date: Fri, 27 Feb 2026 15:02:57 +0100 Subject: [PATCH 1/2] test: add negative cases and fix DER public-key verification --- src/commands/generate.rs | 16 ++++++++++++ src/commands/sign.rs | 13 ++++++++++ src/commands/verify.rs | 55 ++++++++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/commands/generate.rs b/src/commands/generate.rs index 05e6cc3..e0bfe46 100644 --- a/src/commands/generate.rs +++ b/src/commands/generate.rs @@ -249,4 +249,20 @@ mod tests { } } } + + #[test] + fn generate_with_invalid_entropy_returns_error() { + let generate = GenerateCmd::parse_from([ + "generate", + "--algorithm", + "dil2", + "--entropy", + "not_base64", + ]); + + assert!(matches!( + generate.run(), + Err(CryptoError::RequestQrngError(_)) + )); + } } diff --git a/src/commands/sign.rs b/src/commands/sign.rs index afb8821..85064cc 100644 --- a/src/commands/sign.rs +++ b/src/commands/sign.rs @@ -184,4 +184,17 @@ mod test { } } } + + #[test] + fn sign_with_missing_secret_key_returns_io_error() { + let sign = SignCmd::parse_from([ + "sign", + "--sec", + "missing_secret_key.pem", + "--file", + "missing_input_file.bin", + ]); + + assert!(matches!(sign.run(), Err(CryptoError::Io(_)))); + } } diff --git a/src/commands/verify.rs b/src/commands/verify.rs index 8833013..d5d9119 100644 --- a/src/commands/verify.rs +++ b/src/commands/verify.rs @@ -8,7 +8,7 @@ use crate::commands::{ }; use clap::Parser; use crystals_dilithium::{dilithium2, dilithium3, dilithium5, ml_dsa_44, ml_dsa_65, ml_dsa_87}; -use der::{asn1::BitString, Decode, DecodePem}; +use der::{Decode, DecodePem}; // use sha2::{Digest, Sha256}; use std::{fs::File, io::Read}; @@ -34,20 +34,18 @@ impl VerifyCmd { let bytes = utils::read_file(&self.pub_path)?; let sig_bytes = utils::read_file(&self.sig_path)?; - let key: BitString; let algorithm: String; + let bytes_public_key: Vec; if self.inform == Format::Der { let public_key = SubjectPublicKeyInfoBorrowed::from_der(&bytes).unwrap(); algorithm = public_key.algorithm.algorithm.to_string(); - key = BitString::from_der(public_key.subject_public_key).unwrap(); + bytes_public_key = public_key.subject_public_key.to_vec(); } else { let public_key = SubjectPublicKeyInfoOwned::from_pem(&bytes).unwrap(); algorithm = public_key.algorithm.algorithm.to_string(); - key = public_key.subject_public_key; + bytes_public_key = public_key.subject_public_key.as_bytes().unwrap().to_vec(); } - let bytes_public_key = key.as_bytes().unwrap(); - let algorithm_str: &str = &algorithm; let mut file = File::open(&self.file_path)?; @@ -77,7 +75,7 @@ impl VerifyCmd { dilithium2::SIGNBYTES, ))); } - let public = dilithium2::PublicKey::from_bytes(bytes_public_key); + let public = dilithium2::PublicKey::from_bytes(&bytes_public_key); public.verify(&message, &sig_bytes) } OID_DILITHIUM3 => { @@ -88,7 +86,7 @@ impl VerifyCmd { dilithium2::SIGNBYTES, ))); } - let public = dilithium3::PublicKey::from_bytes(bytes_public_key); + let public = dilithium3::PublicKey::from_bytes(&bytes_public_key); public.verify(&message, &sig_bytes) } OID_DILITHIUM5 => { @@ -99,7 +97,7 @@ impl VerifyCmd { dilithium2::SIGNBYTES, ))); } - let public = dilithium5::PublicKey::from_bytes(bytes_public_key); + let public = dilithium5::PublicKey::from_bytes(&bytes_public_key); public.verify(&message, &sig_bytes) } OID_MLDSA44 => { @@ -110,7 +108,7 @@ impl VerifyCmd { ml_dsa_44::SIGNBYTES, ))); } - let public = ml_dsa_44::PublicKey::from_bytes(bytes_public_key); + let public = ml_dsa_44::PublicKey::from_bytes(&bytes_public_key); public.verify(&message, &sig_bytes, None) } OID_MLDSA65 => { @@ -121,7 +119,7 @@ impl VerifyCmd { ml_dsa_65::SIGNBYTES, ))); } - let public = ml_dsa_65::PublicKey::from_bytes(bytes_public_key); + let public = ml_dsa_65::PublicKey::from_bytes(&bytes_public_key); public.verify(&message, &sig_bytes, None) } OID_MLDSA87 => { @@ -132,7 +130,7 @@ impl VerifyCmd { ml_dsa_87::SIGNBYTES, ))); } - let public = ml_dsa_87::PublicKey::from_bytes(bytes_public_key); + let public = ml_dsa_87::PublicKey::from_bytes(&bytes_public_key); public.verify(&message, &sig_bytes, None) } _ => return Err(CryptoError::InvalidLengthSignature(sig_bytes.len())), @@ -203,7 +201,7 @@ mod test { #[test] fn verify_all_algorithms_all_formats() { let algorithms = ["dil2", "dil3", "dil5", "mldsa44", "mldsa65", "mldsa87"]; - let formats = ["PEM"]; + let formats = ["PEM", "DER"]; for alg in algorithms { for sec_format in formats { @@ -213,4 +211,35 @@ mod test { } } } + + #[test] + fn verify_with_missing_public_key_returns_io_error() { + let verify = VerifyCmd::parse_from([ + "verify", + "--pub", + "missing_public_key.pem", + "--sig", + "missing_signature.bin", + "--file", + "missing_message.bin", + ]); + + assert!(matches!(verify.run(), Err(CryptoError::Io(_)))); + } + + #[test] + fn verify_with_missing_signature_returns_io_error() { + let pub_file = "missing_pub_for_sig_test.pem".to_string(); + let verify = VerifyCmd::parse_from([ + "verify", + "--pub", + &pub_file, + "--sig", + "missing_signature.bin", + "--file", + "missing_message.bin", + ]); + + assert!(matches!(verify.run(), Err(CryptoError::Io(_)))); + } } From 5403214fa830922fb5e4cb2114373d65a3d69330 Mon Sep 17 00:00:00 2001 From: kostiask Date: Fri, 27 Feb 2026 15:21:31 +0100 Subject: [PATCH 2/2] ci: run PR checks jobs in parallel --- .github/workflows/pr-checks.yml | 2 -- src/commands/generate.rs | 9 ++------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 3ae0482..a037bb6 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -26,7 +26,6 @@ jobs: run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps test: - needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -36,7 +35,6 @@ jobs: - run: cargo test --all-targets --all-features --locked audit: - needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/src/commands/generate.rs b/src/commands/generate.rs index e0bfe46..48fda02 100644 --- a/src/commands/generate.rs +++ b/src/commands/generate.rs @@ -252,13 +252,8 @@ mod tests { #[test] fn generate_with_invalid_entropy_returns_error() { - let generate = GenerateCmd::parse_from([ - "generate", - "--algorithm", - "dil2", - "--entropy", - "not_base64", - ]); + let generate = + GenerateCmd::parse_from(["generate", "--algorithm", "dil2", "--entropy", "not_base64"]); assert!(matches!( generate.run(),