use rand::rngs::OsRng;
use rust_bottle::pkix;
use rust_bottle::BottleError;
use rust_bottle::*;
#[test]
fn test_marshal_rsa_pkix_placeholder() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let result =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::Rsa);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Serialization(_))));
if let Err(BottleError::Serialization(msg)) = result {
assert!(msg.contains("RSA PKIX serialization") || msg.contains("RsaPublicKey"));
}
}
#[test]
fn test_marshal_rsa_pkcs8_placeholder() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let result = pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::Rsa);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Serialization(_))));
if let Err(BottleError::Serialization(msg)) = result {
assert!(msg.contains("RSA PKCS#8 serialization"));
}
}
#[test]
fn test_parse_rsa_pkcs8_placeholder() {
let invalid_data = vec![0u8; 100];
let result = pkix::parse_pkcs8_private_key(&invalid_data, pkix::KeyType::Rsa);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
if let Err(BottleError::Deserialization(msg)) = result {
assert!(msg.contains("RSA PKCS#8 deserialization"));
}
}
#[test]
fn test_parse_pkix_public_key_pem_invalid_format() {
let result = pkix::parse_pkix_public_key_pem("not pem format");
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
}
#[test]
fn test_parse_pkix_public_key_pem_wrong_type() {
let wrong_pem = "-----BEGIN PRIVATE KEY-----\nMIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA\n-----END PRIVATE KEY-----";
let result = pkix::parse_pkix_public_key_pem(wrong_pem);
let _ = result;
}
#[test]
fn test_parse_pkix_public_key_pem_corrupted_base64() {
let corrupted_pem =
"-----BEGIN PUBLIC KEY-----\n!!!Invalid Base64!!!\n-----END PUBLIC KEY-----";
let result = pkix::parse_pkix_public_key_pem(corrupted_pem);
assert!(result.is_err());
}
#[test]
fn test_parse_pkcs8_private_key_pem_invalid() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let _pkcs8_der =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::Ed25519).unwrap();
let result = pkix::parse_pkcs8_private_key_pem("invalid pem", pkix::KeyType::Ed25519);
assert!(result.is_err());
let corrupted = "-----BEGIN PRIVATE KEY-----\n!!!\n-----END PRIVATE KEY-----";
let result = pkix::parse_pkcs8_private_key_pem(corrupted, pkix::KeyType::Ed25519);
assert!(result.is_err());
}
#[test]
fn test_parse_pkcs8_private_key_unsupported_type() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::Ed25519).unwrap();
let result = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::EcdsaP256);
assert!(result.is_err());
}
#[test]
fn test_parse_pkcs8_private_key_invalid_der() {
let invalid_der = vec![0u8; 10];
let result = pkix::parse_pkcs8_private_key(&invalid_der, pkix::KeyType::Ed25519);
assert!(result.is_err());
let mut corrupted = vec![0x30, 0x01]; corrupted.extend_from_slice(&[0u8; 100]);
let result = pkix::parse_pkcs8_private_key(&corrupted, pkix::KeyType::Ed25519);
assert!(result.is_err());
}
#[test]
fn test_marshal_pkix_public_key_unsupported_type() {
let invalid_key = vec![0u8; 50]; let result = pkix::marshal_pkix_public_key(&invalid_key);
assert!(result.is_err());
}
#[test]
fn test_marshal_pkcs8_private_key_unsupported_type() {
let invalid_key = vec![0u8; 50];
let result = pkix::marshal_pkcs8_private_key(&invalid_key, pkix::KeyType::EcdsaP384);
let _ = result; }
#[test]
fn test_rsa_public_key_bytes_placeholder() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let bytes = key.public_key_bytes();
assert_eq!(bytes, vec![]);
}
#[test]
fn test_rsa_private_key_bytes_placeholder() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let bytes = key.private_key_bytes();
assert_eq!(bytes, vec![]);
}
#[test]
fn test_rsa_from_private_key_bytes_placeholder() {
let data = vec![0u8; 100];
let result = RsaKey::from_private_key_bytes(&data);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[test]
fn test_encrypt_short_buffer_invalid_key_format() {
let rng = &mut OsRng;
let invalid_key = vec![0u8; 50];
let result = encrypt_short_buffer(rng, b"test", &invalid_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_encrypt_short_buffer_empty_key() {
let rng = &mut OsRng;
let result = encrypt_short_buffer(rng, b"test", &[]);
assert!(result.is_err());
}
#[test]
fn test_decrypt_short_buffer_invalid_key_format() {
let invalid_key = vec![0u8; 50];
let ciphertext = vec![0u8; 256]; let result = decrypt_short_buffer(&ciphertext, &invalid_key);
assert!(result.is_err());
}
#[test]
fn test_decrypt_short_buffer_empty_key() {
let ciphertext = vec![0u8; 256];
let result = decrypt_short_buffer(&ciphertext, &[]);
assert!(result.is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_decrypt_invalid_ciphertext_size() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
assert!(mlkem768_decrypt(&[], &key.private_key_bytes()).is_err());
let too_large = vec![0u8; 2000];
assert!(mlkem768_decrypt(&too_large, &key.private_key_bytes()).is_err());
let wrong_size = vec![0u8; 1000];
assert!(mlkem768_decrypt(&wrong_size, &key.private_key_bytes()).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_decrypt_invalid_ciphertext_size() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
assert!(mlkem1024_decrypt(&[], &key.private_key_bytes()).is_err());
let too_large = vec![0u8; 3000];
assert!(mlkem1024_decrypt(&too_large, &key.private_key_bytes()).is_err());
let wrong_size = vec![0u8; 1500];
assert!(mlkem1024_decrypt(&wrong_size, &key.private_key_bytes()).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_encrypt_invalid_public_key_size() {
let rng = &mut OsRng;
let wrong_size_key = vec![0u8; 100];
assert!(mlkem768_encrypt(rng, b"test", &wrong_size_key).is_err());
assert!(mlkem768_encrypt(rng, b"test", &[]).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_encrypt_invalid_public_key_size() {
let rng = &mut OsRng;
let wrong_size_key = vec![0u8; 100];
assert!(mlkem1024_encrypt(rng, b"test", &wrong_size_key).is_err());
assert!(mlkem1024_encrypt(rng, b"test", &[]).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_from_private_key_bytes_invalid_size() {
assert!(MlKem768Key::from_private_key_bytes(&[]).is_err());
assert!(MlKem768Key::from_private_key_bytes(&[0u8; 100]).is_err());
assert!(MlKem768Key::from_private_key_bytes(&[0u8; 1184]).is_err());
assert!(MlKem768Key::from_private_key_bytes(&[0u8; 2400]).is_err()); assert!(MlKem768Key::from_private_key_bytes(&[0u8; 2401]).is_err());
assert!(MlKem768Key::from_private_key_bytes(&[0u8; 3583]).is_err());
assert!(MlKem768Key::from_private_key_bytes(&[0u8; 3585]).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_from_private_key_bytes_invalid_size() {
assert!(MlKem1024Key::from_private_key_bytes(&[]).is_err());
assert!(MlKem1024Key::from_private_key_bytes(&[0u8; 100]).is_err());
assert!(MlKem1024Key::from_private_key_bytes(&[0u8; 1568]).is_err());
assert!(MlKem1024Key::from_private_key_bytes(&[0u8; 3168]).is_err()); assert!(MlKem1024Key::from_private_key_bytes(&[0u8; 3169]).is_err());
assert!(MlKem1024Key::from_private_key_bytes(&[0u8; 4735]).is_err());
assert!(MlKem1024Key::from_private_key_bytes(&[0u8; 4737]).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_marshal_mlkem768_pkix_roundtrip() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let pkix = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
assert!(!pkix.is_empty());
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_marshal_mlkem768_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::MlKem768).unwrap();
assert!(!pkcs8.is_empty());
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::MlKem768).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_marshal_mlkem1024_pkix_roundtrip() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
let pkix = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
assert!(!pkix.is_empty());
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_marshal_mlkem1024_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
let pkcs8 = pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::MlKem1024)
.unwrap();
assert!(!pkcs8.is_empty());
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::MlKem1024).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_mldsa44_pkix_roundtrip() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let pkix = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_mldsa44_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::MlDsa44).unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::MlDsa44).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_mldsa65_pkix_roundtrip() {
let rng = &mut OsRng;
let key = MlDsa65Key::generate(rng);
let pkix = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_mldsa65_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = MlDsa65Key::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::MlDsa65).unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::MlDsa65).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_mldsa87_pkix_roundtrip() {
let rng = &mut OsRng;
let key = MlDsa87Key::generate(rng);
let pkix = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_mldsa87_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = MlDsa87Key::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::MlDsa87).unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::MlDsa87).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_slhdsa128s_pkix_roundtrip() {
let rng = &mut OsRng;
let key = SlhDsa128sKey::generate(rng);
let pkix =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::SlhDsa128s)
.unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_slhdsa128s_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = SlhDsa128sKey::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::SlhDsa128s)
.unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::SlhDsa128s).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_slhdsa192s_pkix_roundtrip() {
let rng = &mut OsRng;
let key = SlhDsa192sKey::generate(rng);
let pkix =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::SlhDsa192s)
.unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_slhdsa192s_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = SlhDsa192sKey::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::SlhDsa192s)
.unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::SlhDsa192s).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_slhdsa256s_pkix_roundtrip() {
let rng = &mut OsRng;
let key = SlhDsa256sKey::generate(rng);
let pkix =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::SlhDsa256s)
.unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix).unwrap();
assert_eq!(parsed, key.public_key_bytes());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_marshal_slhdsa256s_pkcs8_roundtrip() {
let rng = &mut OsRng;
let key = SlhDsa256sKey::generate(rng);
let pkcs8 =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::SlhDsa256s)
.unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8, pkix::KeyType::SlhDsa256s).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[test]
fn test_bottle_from_bytes_invalid_bincode() {
let bottle = Bottle::new(b"test".to_vec());
let valid_bytes = bottle.to_bytes().unwrap();
let invalid_data = &valid_bytes[..valid_bytes.len().min(10)];
let result = Bottle::from_bytes(invalid_data);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
let random_data = vec![0xFFu8; 100];
let result2 = Bottle::from_bytes(&random_data);
assert!(result2.is_err());
}
#[test]
fn test_bottle_from_bytes_corrupted() {
let bottle = Bottle::new(b"test".to_vec());
let valid_bytes = bottle.to_bytes().unwrap();
let mut corrupted = valid_bytes.clone();
if corrupted.len() > 5 {
corrupted[5] ^= 0xFF;
}
if corrupted.len() > 20 {
corrupted[20] ^= 0xFF;
}
let result = Bottle::from_bytes(&corrupted);
assert!(
result.is_err(),
"Corrupted bincode data should fail to deserialize"
);
assert!(matches!(result, Err(BottleError::Deserialization(_))));
}
#[test]
fn test_bottle_encrypt_invalid_key() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"test".to_vec());
assert!(bottle.encrypt(rng, &[]).is_err());
let invalid_key = vec![0u8; 50];
assert!(bottle.encrypt(rng, &invalid_key).is_err());
}
#[test]
fn test_bottle_sign_invalid_signer() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"test".to_vec());
let x25519_key = X25519Key::generate(rng);
let _pub_key = x25519_key.public_key_bytes();
let ed25519_key = Ed25519Key::generate(rng);
let wrong_pub = ed25519_key.public_key_bytes();
bottle.sign(rng, &ed25519_key, &wrong_pub).unwrap();
}
#[test]
fn test_idcard_to_bytes_serialization_error() {
let key = Ed25519Key::generate(&mut OsRng);
let idcard = IDCard::new(&key.public_key_bytes());
let result = idcard.to_bytes();
assert!(result.is_ok());
}
#[test]
fn test_idcard_from_bytes_invalid() {
let key = Ed25519Key::generate(&mut OsRng);
let idcard = IDCard::new(&key.public_key_bytes());
let valid_bytes = idcard.to_bytes().unwrap();
let invalid_data = &valid_bytes[..valid_bytes.len().min(10)];
let result = IDCard::from_bytes(invalid_data);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
let random_data = vec![0xFFu8; 100];
let result2 = IDCard::from_bytes(&random_data);
assert!(result2.is_err());
}
#[test]
fn test_idcard_test_key_purpose_expired_key() {
use std::time::Duration;
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pub_key = key.public_key_bytes();
let mut idcard = IDCard::new(&pub_key);
idcard.set_key_duration(&pub_key, Duration::from_secs(3600));
assert!(idcard.test_key_purpose(&pub_key, "sign").is_ok());
}
#[test]
fn test_idcard_test_key_purpose_wrong_purpose() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pub_key = key.public_key_bytes();
let mut idcard = IDCard::new(&pub_key);
idcard.set_key_purposes(&pub_key, &["sign"]);
assert!(idcard.test_key_purpose(&pub_key, "decrypt").is_err());
assert!(matches!(
idcard.test_key_purpose(&pub_key, "decrypt"),
Err(BottleError::KeyUnfit)
));
}
#[test]
fn test_membership_to_bytes_serialization() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
let result = membership.to_bytes();
assert!(result.is_ok());
}
#[test]
fn test_membership_from_bytes_invalid() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
let valid_bytes = membership.to_bytes().unwrap();
let invalid_data = &valid_bytes[..valid_bytes.len().min(10)];
let result = Membership::from_bytes(invalid_data);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
let random_data = vec![0xFFu8; 100];
let result2 = Membership::from_bytes(&random_data);
assert!(result2.is_err());
}
#[test]
fn test_membership_verify_no_signature() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let group_idcard = IDCard::new(&group_key.public_key_bytes());
let membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
let result = membership.verify(&group_idcard);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::VerifyFailed)));
}
#[test]
fn test_keychain_get_signer_empty() {
let keychain = Keychain::new();
let key = Ed25519Key::generate(&mut OsRng);
let pub_key = key.public_key_bytes();
let result = keychain.get_signer(&pub_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::KeyNotFound)));
}
#[test]
fn test_keychain_sign_key_not_found() {
let keychain = Keychain::new();
let key = Ed25519Key::generate(&mut OsRng);
let pub_key = key.public_key_bytes();
let result = keychain.sign(&mut OsRng, &pub_key, b"test");
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::KeyNotFound)));
}
#[test]
fn test_ecdh_encrypt_invalid_key() {
let rng = &mut OsRng;
assert!(ecdh_encrypt(rng, b"test", &[]).is_err());
let invalid_key = vec![0u8; 50];
assert!(ecdh_encrypt(rng, b"test", &invalid_key).is_err());
}
#[test]
fn test_ecdh_decrypt_invalid_key() {
let ciphertext = vec![0u8; 100];
assert!(ecdh_decrypt(&ciphertext, &[]).is_err());
let invalid_key = vec![0u8; 50];
assert!(ecdh_decrypt(&ciphertext, &invalid_key).is_err());
}
#[test]
fn test_ecdh_decrypt_invalid_ciphertext() {
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
assert!(ecdh_decrypt(&[], &key.private_key_bytes()).is_err());
let too_short = vec![0u8; 10];
assert!(ecdh_decrypt(&too_short, &key.private_key_bytes()).is_err());
}
#[test]
fn test_rsa_encrypt_invalid_key() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let message = b"test";
let result = rsa_encrypt(rng, message, key.public_key());
assert!(result.is_ok());
}
#[test]
fn test_rsa_decrypt_invalid_ciphertext() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
assert!(rsa_decrypt(&[], &key).is_err());
let wrong_size = vec![0u8; 100];
assert!(rsa_decrypt(&wrong_size, &key).is_err());
let valid_ct = rsa_encrypt(rng, b"test", key.public_key()).unwrap();
let mut corrupted = valid_ct.clone();
corrupted[0] ^= 0xFF;
assert!(rsa_decrypt(&corrupted, &key).is_err());
}
#[test]
fn test_detect_key_type_from_public_key_invalid_sec1() {
let mut invalid_sec1 = vec![0u8; 65];
invalid_sec1[0] = 0x02; let result = pkix::marshal_pkix_public_key(&invalid_sec1);
assert!(result.is_err());
}
#[test]
fn test_marshal_ecdsa_p384_pkix_unsupported() {
let invalid_key = vec![0u8; 97]; let result = pkix::marshal_pkix_public_key(&invalid_key);
let _ = result;
}
#[test]
fn test_marshal_ecdsa_p521_pkix_unsupported() {
let invalid_key = vec![0u8; 133]; let result = pkix::marshal_pkix_public_key(&invalid_key);
let _ = result;
}
#[test]
fn test_marshal_ed25519_pkix_invalid_key_length() {
let too_short = vec![0u8; 31];
let result = pkix::marshal_pkix_public_key(&too_short);
assert!(result.is_err());
let too_long = vec![0u8; 33];
let result = pkix::marshal_pkix_public_key(&too_long);
assert!(result.is_err());
}
#[test]
fn test_marshal_ed25519_pkcs8_invalid_key_length() {
let too_short = vec![0u8; 31];
let result = pkix::marshal_pkcs8_private_key(&too_short, pkix::KeyType::Ed25519);
assert!(result.is_err());
let too_long = vec![0u8; 33];
let result = pkix::marshal_pkcs8_private_key(&too_long, pkix::KeyType::Ed25519);
assert!(result.is_err());
}
#[test]
fn test_marshal_x25519_pkix_invalid_key_length() {
let too_short = vec![0u8; 31];
let result = pkix::marshal_pkix_public_key_with_type(&too_short, pkix::KeyType::X25519);
assert!(result.is_err());
let too_long = vec![0u8; 33];
let result = pkix::marshal_pkix_public_key_with_type(&too_long, pkix::KeyType::X25519);
assert!(result.is_err());
}
#[test]
fn test_marshal_x25519_pkcs8_invalid_key_length() {
let too_short = vec![0u8; 31];
let result = pkix::marshal_pkcs8_private_key(&too_short, pkix::KeyType::X25519);
assert!(result.is_err());
let too_long = vec![0u8; 33];
let result = pkix::marshal_pkcs8_private_key(&too_long, pkix::KeyType::X25519);
assert!(result.is_err());
}
#[test]
fn test_parse_pkix_public_key_invalid_der() {
let invalid_der = vec![0u8; 10];
let result = pkix::parse_pkix_public_key(&invalid_der);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
}
#[test]
fn test_parse_pkcs8_private_key_ecdsa_p256_invalid_der() {
let invalid_der = vec![0u8; 10];
let result = pkix::parse_pkcs8_private_key(&invalid_der, pkix::KeyType::EcdsaP256);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
}
#[test]
fn test_parse_pkcs8_private_key_ed25519_invalid_der() {
let invalid_der = vec![0u8; 10];
let result = pkix::parse_pkcs8_private_key(&invalid_der, pkix::KeyType::Ed25519);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
}
#[test]
fn test_parse_pkcs8_private_key_x25519_invalid_der() {
let invalid_der = vec![0u8; 10];
let result = pkix::parse_pkcs8_private_key(&invalid_der, pkix::KeyType::X25519);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Deserialization(_))));
}
#[test]
fn test_encrypt_short_buffer_pkix_parse_failure() {
let rng = &mut OsRng;
let mut invalid_pkix = vec![0x30, 0x01, 0x00]; invalid_pkix.extend_from_slice(&vec![0u8; 50]);
let result = encrypt_short_buffer(rng, b"test", &invalid_pkix);
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_pkix_wrong_oid() {
let rng = &mut OsRng;
let invalid_pkix = vec![0x30, 0x05, 0x06, 0x03, 0x55, 0x04, 0x03]; let result = encrypt_short_buffer(rng, b"test", &invalid_pkix);
assert!(result.is_err());
}
#[test]
fn test_bottle_sign_with_wrong_key_type() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"test".to_vec());
let ed25519_key = Ed25519Key::generate(rng);
let pub_key = ed25519_key.public_key_bytes();
assert!(bottle.sign(rng, &ed25519_key, &pub_key).is_ok());
}
#[test]
fn test_bottle_encrypt_empty_message() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"".to_vec());
let key = X25519Key::generate(rng);
assert!(bottle.encrypt(rng, &key.public_key_bytes()).is_ok());
}
#[test]
fn test_bottle_metadata_very_long_key() {
let mut bottle = Bottle::new(b"test".to_vec());
let long_key = "a".repeat(10000);
bottle.set_metadata(&long_key, "value");
assert_eq!(bottle.metadata(&long_key), Some("value"));
}
#[test]
fn test_bottle_metadata_very_long_value() {
let mut bottle = Bottle::new(b"test".to_vec());
let long_value = "b".repeat(10000);
bottle.set_metadata("key", &long_value);
assert_eq!(bottle.metadata("key"), Some(long_value.as_str()));
}
#[test]
fn test_idcard_set_key_duration_zero() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pub_key = key.public_key_bytes();
let mut idcard = IDCard::new(&pub_key);
idcard.set_key_duration(&pub_key, std::time::Duration::from_secs(0));
let _ = idcard.test_key_purpose(&pub_key, "sign");
}
#[test]
fn test_idcard_get_keys_empty() {
let key = Ed25519Key::generate(&mut OsRng);
let idcard = IDCard::new(&key.public_key_bytes());
let keys = idcard.get_keys("nonexistent");
assert_eq!(keys.len(), 0);
}
#[test]
fn test_membership_set_info_empty_key() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let mut membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
membership.set_info("", "value");
assert_eq!(membership.info(""), Some("value"));
}
#[test]
fn test_membership_set_info_empty_value() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let mut membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
membership.set_info("key", "");
assert_eq!(membership.info("key"), Some(""));
}
#[test]
fn test_keychain_add_key_duplicate() {
let mut keychain = Keychain::new();
let key = Ed25519Key::generate(&mut OsRng);
keychain.add_key(key.clone());
keychain.add_key(key.clone());
let pub_key = key.public_key_bytes();
assert!(keychain.get_signer(&pub_key).is_ok());
}
#[test]
fn test_opener_open_info_unsigned_bottle() {
let bottle = Bottle::new(b"test".to_vec());
let opener = Opener::new();
let info = opener.open_info(&bottle).unwrap();
assert!(!info.is_signed);
assert!(info.signers.is_empty());
}
#[test]
fn test_opener_open_info_unencrypted_bottle() {
let bottle = Bottle::new(b"test".to_vec());
let opener = Opener::new();
let info = opener.open_info(&bottle).unwrap();
assert!(!info.is_encrypted);
assert!(info.recipients.is_empty());
}
#[test]
fn test_opener_open_unencrypted_bottle() {
let bottle = Bottle::new(b"test".to_vec());
let opener = Opener::new();
let decrypted = opener.open(&bottle, None).unwrap();
assert_eq!(decrypted, b"test");
}
#[test]
fn test_opener_open_encrypted_bottle_no_key() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"test".to_vec());
let key = X25519Key::generate(rng);
bottle.encrypt(rng, &key.public_key_bytes()).unwrap();
let opener = Opener::new();
let result = opener.open(&bottle, None);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::NoAppropriateKey)));
}
#[test]
fn test_opener_open_encrypted_bottle_wrong_key() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"test".to_vec());
let key1 = X25519Key::generate(rng);
let key2 = X25519Key::generate(rng);
bottle.encrypt(rng, &key1.public_key_bytes()).unwrap();
let opener = Opener::new();
let result = opener.open(&bottle, Some(&key2.private_key_bytes()));
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_invalid_key() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test message";
let result = utils::encrypt_short_buffer(rng, message, &[]);
assert!(result.is_err());
let invalid_key = vec![0u8; 10];
let result2 = utils::encrypt_short_buffer(rng, message, &invalid_key);
assert!(result2.is_err());
}
#[test]
fn test_decrypt_short_buffer_invalid_ciphertext() {
use rust_bottle::utils;
let result = utils::decrypt_short_buffer(&[], &[]);
assert!(result.is_err());
let short_ciphertext = vec![0u8; 10];
let result2 = utils::decrypt_short_buffer(&short_ciphertext, &[]);
assert!(result2.is_err());
}
#[test]
fn test_decrypt_short_buffer_wrong_key() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test";
let key1 = X25519Key::generate(rng);
let key2 = X25519Key::generate(rng);
let ciphertext = ecdh_encrypt(rng, message, &key1.public_key_bytes()).unwrap();
let result = ecdh_decrypt(&ciphertext, &key2.private_key_bytes());
assert!(result.is_err());
let result2 = utils::encrypt_short_buffer(rng, message, &key1.public_key_bytes());
assert!(result2.is_err());
assert!(matches!(result2, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_ecdh_decrypt_wrong_key() {
let rng = &mut OsRng;
let message = b"test";
let key1 = X25519Key::generate(rng);
let key2 = X25519Key::generate(rng);
let ciphertext = ecdh_encrypt(rng, message, &key1.public_key_bytes()).unwrap();
let result = ecdh_decrypt(&ciphertext, &key2.private_key_bytes());
assert!(result.is_err());
}
#[test]
fn test_keychain_get_signer_wrong_fingerprint() {
let mut keychain = Keychain::new();
let key = Ed25519Key::generate(&mut OsRng);
keychain.add_key(key);
let wrong_fingerprint = vec![0u8; 32];
let result = keychain.get_signer(&wrong_fingerprint);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::KeyNotFound)));
}
#[test]
fn test_idcard_get_key_nonexistent() {
let key = Ed25519Key::generate(&mut OsRng);
let idcard = IDCard::new(&key.public_key_bytes());
let wrong_pub_key = vec![0u8; 32];
let result = idcard.test_key_purpose(&wrong_pub_key, "sign");
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::KeyNotFound)));
let sign_keys = idcard.get_keys("sign");
assert_eq!(sign_keys.len(), 1);
}
#[test]
fn test_idcard_test_key_purpose_nonexistent_key() {
let key = Ed25519Key::generate(&mut OsRng);
let idcard = IDCard::new(&key.public_key_bytes());
let wrong_pub_key = vec![0u8; 32];
let result = idcard.test_key_purpose(&wrong_pub_key, "sign");
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::KeyNotFound)));
}
#[test]
fn test_membership_verify_invalid_signature() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let wrong_group_key = Ed25519Key::generate(rng);
let wrong_group_idcard = IDCard::new(&wrong_group_key.public_key_bytes());
let mut membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
membership.sign(rng, &group_key).unwrap();
let result = membership.verify(&wrong_group_idcard);
assert!(
result.is_ok(),
"Simplified verify passes if signature exists, regardless of validity"
);
}
#[test]
fn test_membership_verify_corrupted_signature() {
let rng = &mut OsRng;
let member_key = Ed25519Key::generate(rng);
let member_idcard = IDCard::new(&member_key.public_key_bytes());
let group_key = Ed25519Key::generate(rng);
let group_idcard = IDCard::new(&group_key.public_key_bytes());
let mut membership = Membership::new(&member_idcard, &group_key.public_key_bytes());
membership.sign(rng, &group_key).unwrap();
let mut bytes = membership.to_bytes().unwrap();
if bytes.len() > 10 {
let corrupt_pos = bytes.len() - 10;
bytes[corrupt_pos] ^= 0xFF;
}
let corrupted_membership = Membership::from_bytes(&bytes);
match corrupted_membership {
Ok(corrupted) => {
let result = corrupted.verify(&group_idcard);
let _ = result;
}
Err(_) => {
}
}
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_decrypt_invalid_key_size() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let message = b"test";
let ciphertext = mlkem768_encrypt(rng, message, &key.public_key_bytes()).unwrap();
let wrong_key = vec![0u8; 100];
let result = mlkem768_decrypt(&ciphertext, &wrong_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_decrypt_invalid_key_size() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
let message = b"test";
let ciphertext = mlkem1024_encrypt(rng, message, &key.public_key_bytes()).unwrap();
let wrong_key = vec![0u8; 100];
let result = mlkem1024_decrypt(&ciphertext, &wrong_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_hybrid_decrypt_mlkem768_x25519_invalid_format() {
let rng = &mut OsRng;
let mlkem_key = MlKem768Key::generate(rng);
let x25519_key = X25519Key::generate(rng);
let too_short = vec![0u8; 3];
let x25519_priv = x25519_key.private_key_bytes();
let x25519_priv_array: [u8; 32] = x25519_priv.try_into().unwrap();
let result = hybrid_decrypt_mlkem768_x25519(
&too_short,
&mlkem_key.private_key_bytes(),
&x25519_priv_array,
);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidFormat)));
let invalid = vec![0xFF, 0xFF, 0xFF, 0xFF]; let result2 = hybrid_decrypt_mlkem768_x25519(
&invalid,
&mlkem_key.private_key_bytes(),
&x25519_priv_array,
);
assert!(result2.is_err());
assert!(matches!(result2, Err(BottleError::InvalidFormat)));
}
#[test]
fn test_mem_clr_zeros_data() {
use rust_bottle::utils::mem_clr;
let mut data1 = vec![1, 2, 3, 4, 5];
mem_clr(&mut data1);
assert_eq!(data1, vec![0, 0, 0, 0, 0]);
let mut data2 = vec![0xFFu8; 100];
mem_clr(&mut data2);
assert_eq!(data2, vec![0u8; 100]);
let mut data3 = vec![];
mem_clr(&mut data3);
assert_eq!(data3, vec![]);
let mut data4 = vec![42u8];
mem_clr(&mut data4);
assert_eq!(data4, vec![0u8]);
}
#[test]
fn test_encrypt_short_buffer_non_pkix_format() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test";
let non_pkix_key = vec![0x01, 0x02, 0x03];
let result = utils::encrypt_short_buffer(rng, message, &non_pkix_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_encrypt_short_buffer_pkix_invalid_der() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test";
let invalid_der = vec![0x30, 0xFF, 0xFF]; let result = utils::encrypt_short_buffer(rng, message, &invalid_der);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_encrypt_short_buffer_pkix_empty_after_0x30() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test";
let empty_pkix = vec![0x30];
let result = utils::encrypt_short_buffer(rng, message, &empty_pkix);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_encrypt_short_buffer_pkix_short_sequence() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test";
let short_seq = vec![0x30, 0x01, 0x00]; let result = utils::encrypt_short_buffer(rng, message, &short_seq);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_encrypt_short_buffer_pkix_malformed_spki() {
use rust_bottle::utils;
let rng = &mut OsRng;
let message = b"test";
let mut malformed = vec![0x30]; malformed.push(0x82); malformed.push(0x00);
malformed.push(0x10); malformed.extend_from_slice(&[0xFFu8; 10]); let result = utils::encrypt_short_buffer(rng, message, &malformed);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_decrypt_short_buffer_placeholder() {
use rust_bottle::utils;
let ciphertext = vec![0u8; 100];
let private_key = vec![0u8; 100];
let result = utils::decrypt_short_buffer(&ciphertext, &private_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
let result2 = utils::decrypt_short_buffer(&[], &[]);
assert!(result2.is_err());
assert!(matches!(result2, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_encrypt_short_buffer_pkcs1_invalid_structure() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let invalid_pkcs1 = vec![0x30, 0x01, 0x00]; let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&invalid_pkcs1).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
assert!(matches!(
result,
Err(BottleError::UnsupportedAlgorithm) | Err(BottleError::Encryption(_))
));
}
#[test]
fn test_encrypt_short_buffer_pkcs1_empty_sequence() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let empty_seq = vec![0x30, 0x00]; let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&empty_seq).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_pkcs1_wrong_tag() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let wrong_tag = vec![0x02, 0x01, 0x00]; let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&wrong_tag).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_pkcs1_long_form_length_invalid() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let mut invalid_long = vec![0x30]; invalid_long.push(0x85); invalid_long.extend_from_slice(&[0u8; 10]);
let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&invalid_long).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_pkcs1_sequence_length_exceeds_data() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let mut invalid_len = vec![0x30]; invalid_len.push(0x82); invalid_len.push(0xFF);
invalid_len.push(0xFF); invalid_len.extend_from_slice(&[0u8; 10]); let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&invalid_len).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_pkcs1_integer_not_found() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let mut no_integer = vec![0x30, 0x05]; no_integer.push(0x01); no_integer.extend_from_slice(&[0u8; 4]);
let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&no_integer).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
}
#[test]
fn test_encrypt_short_buffer_pkcs1_second_integer_invalid() {
use const_oid::db::rfc5912;
use der::asn1::{AnyRef, BitString, Uint};
use der::Encode;
use rust_bottle::utils;
use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
let rng = &mut OsRng;
let message = b"test";
let n = Uint::new(&[1, 2, 3, 4]).unwrap();
let n_der = n.to_der().unwrap();
let mut seq = vec![0x30]; let seq_len = n_der.len() + 5; if seq_len < 128 {
seq.push(seq_len as u8);
} else {
seq.push(0x82);
seq.push((seq_len >> 8) as u8);
seq.push(seq_len as u8);
}
seq.extend_from_slice(&n_der);
seq.push(0x01); seq.extend_from_slice(&[0u8; 4]);
let spki = SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier {
oid: rfc5912::RSA_ENCRYPTION,
parameters: None::<AnyRef>,
},
subject_public_key: BitString::from_bytes(&seq).unwrap(),
};
let pkix_der = spki.to_der().unwrap();
let result = utils::encrypt_short_buffer(rng, message, &pkix_der);
assert!(result.is_err());
}
#[test]
fn test_signing_sign_function() {
use rust_bottle::signing;
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let message = b"test message";
let signature = signing::sign(rng, &key, message).unwrap();
assert!(!signature.is_empty());
assert!(key.verify(message, &signature).is_ok());
}
#[test]
fn test_signing_verify_function() {
use rust_bottle::signing;
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let message = b"test message";
let signature = key.sign(rng, message).unwrap();
let result = signing::verify(&key, message, &signature);
assert!(result.is_ok());
let wrong_sig = vec![0u8; signature.len()];
let result2 = signing::verify(&key, message, &wrong_sig);
assert!(result2.is_err());
assert!(matches!(result2, Err(BottleError::VerifyFailed)));
}
#[test]
fn test_signing_sign_with_ecdsa() {
use rust_bottle::signing;
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let message = b"test message";
let signature = signing::sign(rng, &key, message).unwrap();
assert!(!signature.is_empty());
let result = signing::verify(&key, message, &signature);
assert!(result.is_ok());
}
#[test]
fn test_signing_verify_with_ecdsa() {
use rust_bottle::signing;
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let message = b"test message";
let signature = key.sign(rng, message).unwrap();
let result = signing::verify(&key, message, &signature);
assert!(result.is_ok());
let mut corrupted_sig = signature.clone();
if corrupted_sig.len() > 0 {
corrupted_sig[0] ^= 0xFF;
}
let result2 = signing::verify(&key, message, &corrupted_sig);
assert!(result2.is_err());
assert!(matches!(result2, Err(BottleError::VerifyFailed)));
}
#[test]
fn test_keytype_oid_all_types() {
let rng = &mut OsRng;
let ecdsa256_key = EcdsaP256Key::generate(rng);
let _ = pkix::marshal_pkix_public_key_with_type(
&ecdsa256_key.public_key_bytes(),
pkix::KeyType::EcdsaP256,
);
let fake_p384_key = vec![0x04u8; 97]; let _ = pkix::marshal_pkix_public_key_with_type(&fake_p384_key, pkix::KeyType::EcdsaP384);
let fake_p521_key = vec![0x04u8; 133]; let _ = pkix::marshal_pkix_public_key_with_type(&fake_p521_key, pkix::KeyType::EcdsaP521);
let ed25519_key = Ed25519Key::generate(rng);
let _ = pkix::marshal_pkix_public_key_with_type(
&ed25519_key.public_key_bytes(),
pkix::KeyType::Ed25519,
);
let x25519_key = X25519Key::generate(rng);
let _ = pkix::marshal_pkix_public_key_with_type(
&x25519_key.public_key_bytes(),
pkix::KeyType::X25519,
);
let rsa_key = RsaKey::generate(rng, 2048).unwrap();
let _ =
pkix::marshal_pkix_public_key_with_type(&rsa_key.public_key_bytes(), pkix::KeyType::Rsa);
}
#[test]
fn test_marshal_pkix_public_key_with_type_ecdsa() {
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let result =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::EcdsaP256);
assert!(result.is_ok());
let fake_p384 = vec![0x04u8; 97]; let result2 = pkix::marshal_pkix_public_key_with_type(&fake_p384, pkix::KeyType::EcdsaP384);
let _ = result2;
let fake_p521 = vec![0x04u8; 133]; let result3 = pkix::marshal_pkix_public_key_with_type(&fake_p521, pkix::KeyType::EcdsaP521);
let _ = result3;
}
#[test]
fn test_marshal_pkix_public_key_with_type_ed25519() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let result =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::Ed25519);
assert!(result.is_ok());
assert!(!result.unwrap().is_empty());
}
#[test]
fn test_marshal_pkix_public_key_pem() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pem = pkix::marshal_pkix_public_key_pem(&key.public_key_bytes()).unwrap();
assert!(pem.contains("BEGIN PUBLIC KEY"));
assert!(pem.contains("END PUBLIC KEY"));
let ecdsa_key = EcdsaP256Key::generate(rng);
let pem2 = pkix::marshal_pkix_public_key_pem(&ecdsa_key.public_key_bytes()).unwrap();
assert!(pem2.contains("BEGIN PUBLIC KEY"));
}
#[test]
fn test_parse_pkix_public_key_return() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
let parsed = pkix::parse_pkix_public_key(&pkix_der).unwrap();
assert!(!parsed.is_empty());
}
#[test]
fn test_marshal_pkcs8_private_key_pem() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pem = pkix::marshal_pkcs8_private_key_pem(&key.private_key_bytes(), pkix::KeyType::Ed25519)
.unwrap();
assert!(pem.contains("BEGIN PRIVATE KEY"));
assert!(pem.contains("END PRIVATE KEY"));
let ecdsa_key = EcdsaP256Key::generate(rng);
let pem2 = pkix::marshal_pkcs8_private_key_pem(
&ecdsa_key.private_key_bytes(),
pkix::KeyType::EcdsaP256,
)
.unwrap();
assert!(pem2.contains("BEGIN PRIVATE KEY"));
let x25519_key = X25519Key::generate(rng);
let pem3 =
pkix::marshal_pkcs8_private_key_pem(&x25519_key.private_key_bytes(), pkix::KeyType::X25519)
.unwrap();
assert!(pem3.contains("BEGIN PRIVATE KEY"));
}
#[test]
fn test_parse_pkcs8_private_key_ecdsa_p256() {
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pkcs8_der =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::EcdsaP256)
.unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8_der, pkix::KeyType::EcdsaP256).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[test]
fn test_parse_pkcs8_private_key_ed25519() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pkcs8_der =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::Ed25519).unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8_der, pkix::KeyType::Ed25519).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[test]
fn test_parse_pkcs8_private_key_x25519() {
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let pkcs8_der =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::X25519).unwrap();
let parsed = pkix::parse_pkcs8_private_key(&pkcs8_der, pkix::KeyType::X25519).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[test]
fn test_parse_pkcs8_private_key_pem() {
let rng = &mut OsRng;
let key = Ed25519Key::generate(rng);
let pkcs8_pem =
pkix::marshal_pkcs8_private_key_pem(&key.private_key_bytes(), pkix::KeyType::Ed25519)
.unwrap();
let parsed = pkix::parse_pkcs8_private_key_pem(&pkcs8_pem, pkix::KeyType::Ed25519).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[test]
fn test_marshal_ecdsa_pkix_p256() {
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pkix_der =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::EcdsaP256)
.unwrap();
assert!(!pkix_der.is_empty());
let parsed = pkix::parse_pkix_public_key(&pkix_der).unwrap();
assert!(!parsed.is_empty());
}
#[test]
fn test_marshal_ecdsa_pkcs8_p256() {
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pkcs8_der =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::EcdsaP256)
.unwrap();
assert!(!pkcs8_der.is_empty());
let parsed = pkix::parse_pkcs8_private_key(&pkcs8_der, pkix::KeyType::EcdsaP256).unwrap();
assert_eq!(parsed, key.private_key_bytes());
}
#[test]
fn test_marshal_ecdsa_pkix_unsupported() {
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let result =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::EcdsaP384);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::UnsupportedAlgorithm)));
}
#[test]
fn test_marshal_ed25519_pkix_error_cases() {
let wrong_length = vec![0u8; 31]; let result = pkix::marshal_pkix_public_key_with_type(&wrong_length, pkix::KeyType::Ed25519);
assert!(result.is_err());
let too_long = vec![0u8; 33];
let result2 = pkix::marshal_pkix_public_key_with_type(&too_long, pkix::KeyType::Ed25519);
assert!(result2.is_err());
}
#[test]
fn test_marshal_ed25519_pkcs8_error() {
let wrong_length = vec![0u8; 31]; let result = pkix::marshal_pkcs8_private_key(&wrong_length, pkix::KeyType::Ed25519);
assert!(result.is_err());
}
#[test]
fn test_marshal_x25519_pkix() {
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let pkix_der =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::X25519)
.unwrap();
assert!(!pkix_der.is_empty());
let wrong_length = vec![0u8; 31];
let result = pkix::marshal_pkix_public_key_with_type(&wrong_length, pkix::KeyType::X25519);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Serialization(_))));
}
#[test]
fn test_marshal_x25519_pkcs8() {
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let pkcs8_der =
pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::X25519).unwrap();
assert!(!pkcs8_der.is_empty());
let wrong_length = vec![0u8; 31];
let result = pkix::marshal_pkcs8_private_key(&wrong_length, pkix::KeyType::X25519);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Serialization(_))));
}
#[test]
fn test_detect_key_type_from_public_key_32_bytes() {
let rng = &mut OsRng;
let ed25519_key = Ed25519Key::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&ed25519_key.public_key_bytes()).unwrap();
assert!(!pkix_der.is_empty());
let x25519_key = X25519Key::generate(rng);
let result = pkix::marshal_pkix_public_key(&x25519_key.public_key_bytes());
let _ = result;
let pkix_der2 = pkix::marshal_pkix_public_key_with_type(
&x25519_key.public_key_bytes(),
pkix::KeyType::X25519,
)
.unwrap();
assert!(!pkix_der2.is_empty());
}
#[test]
fn test_detect_key_type_from_public_key_ecdsa_p256() {
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
assert!(!pkix_der.is_empty());
let mut wrong_key = key.public_key_bytes();
if wrong_key.len() > 0 {
wrong_key[0] = 0x03; let result = pkix::marshal_pkix_public_key(&wrong_key);
assert!(result.is_err());
}
}
#[test]
fn test_detect_key_type_from_public_key_ecdsa_p384() {
let fake_p384 = vec![0x04u8; 97];
let pkix_der = pkix::marshal_pkix_public_key(&fake_p384);
let _ = pkix_der;
let wrong_key = vec![0x03u8; 97]; let result = pkix::marshal_pkix_public_key(&wrong_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[test]
fn test_detect_key_type_from_public_key_ecdsa_p521() {
let fake_p521 = vec![0x04u8; 133];
let pkix_der = pkix::marshal_pkix_public_key(&fake_p521);
let _ = pkix_der;
let wrong_key = vec![0x03u8; 133]; let result = pkix::marshal_pkix_public_key(&wrong_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[test]
fn test_detect_key_type_from_public_key_unknown_size() {
let unknown_key = vec![0u8; 50]; let result = pkix::marshal_pkix_public_key(&unknown_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_detect_key_type_from_public_key_mlkem768() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
assert!(!pkix_der.is_empty());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_detect_key_type_from_public_key_mlkem1024() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&key.public_key_bytes()).unwrap();
assert!(!pkix_der.is_empty());
}
#[cfg(not(feature = "ml-kem"))]
#[test]
fn test_detect_key_type_from_public_key_mlkem_without_feature() {
let mlkem768_key = vec![0u8; 1184];
let result = pkix::marshal_pkix_public_key(&mlkem768_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
let mlkem1024_key = vec![0u8; 1568];
let result2 = pkix::marshal_pkix_public_key(&mlkem1024_key);
assert!(result2.is_err());
assert!(matches!(result2, Err(BottleError::InvalidKeyType)));
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_detect_key_type_from_public_key_mldsa() {
let rng = &mut OsRng;
let mldsa44_key = MlDsa44Key::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&mldsa44_key.public_key_bytes()).unwrap();
assert!(!pkix_der.is_empty());
let mldsa65_key = MlDsa65Key::generate(rng);
let pkix_der2 = pkix::marshal_pkix_public_key(&mldsa65_key.public_key_bytes()).unwrap();
assert!(!pkix_der2.is_empty());
let mldsa87_key = MlDsa87Key::generate(rng);
let pkix_der3 = pkix::marshal_pkix_public_key(&mldsa87_key.public_key_bytes()).unwrap();
assert!(!pkix_der3.is_empty());
}
#[cfg(not(feature = "post-quantum"))]
#[test]
fn test_detect_key_type_from_public_key_mldsa_without_feature() {
let mldsa44_key = vec![0u8; 1312];
let result = pkix::marshal_pkix_public_key(&mldsa44_key);
assert!(result.is_err());
let mldsa65_key = vec![0u8; 1952];
let result2 = pkix::marshal_pkix_public_key(&mldsa65_key);
assert!(result2.is_err());
let mldsa87_key = vec![0u8; 2592];
let result3 = pkix::marshal_pkix_public_key(&mldsa87_key);
assert!(result3.is_err());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_detect_key_type_from_public_key_slhdsa() {
let rng = &mut OsRng;
let slhdsa192_key = SlhDsa192sKey::generate(rng);
let pkix_der = pkix::marshal_pkix_public_key(&slhdsa192_key.public_key_bytes()).unwrap();
assert!(!pkix_der.is_empty());
let slhdsa256_key = SlhDsa256sKey::generate(rng);
let pkix_der2 = pkix::marshal_pkix_public_key(&slhdsa256_key.public_key_bytes()).unwrap();
assert!(!pkix_der2.is_empty());
}
#[cfg(not(feature = "post-quantum"))]
#[test]
fn test_detect_key_type_from_public_key_slhdsa_without_feature() {
let slhdsa192_key = vec![0u8; 48];
let result = pkix::marshal_pkix_public_key(&slhdsa192_key);
assert!(result.is_err());
let slhdsa256_key = vec![0u8; 64];
let result2 = pkix::marshal_pkix_public_key(&slhdsa256_key);
assert!(result2.is_err());
}
#[test]
fn test_parse_pkcs8_private_key_other_types() {
let invalid_der = vec![0u8; 10];
let result = pkix::parse_pkcs8_private_key(&invalid_der, pkix::KeyType::Rsa);
assert!(result.is_err());
}
#[test]
fn test_marshal_pkix_public_key_with_type_rsa() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let result =
pkix::marshal_pkix_public_key_with_type(&key.public_key_bytes(), pkix::KeyType::Rsa);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Serialization(_))));
}
#[test]
fn test_marshal_pkcs8_private_key_rsa() {
let rng = &mut OsRng;
let key = RsaKey::generate(rng, 2048).unwrap();
let result = pkix::marshal_pkcs8_private_key(&key.private_key_bytes(), pkix::KeyType::Rsa);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::Serialization(_))));
}
#[test]
fn test_multi_hash_with_levels() {
use rust_bottle::hash;
use sha2::Sha256;
let data = b"test data";
let result0 = hash::multi_hash::<Sha256>(data, 0);
assert_eq!(result0, data);
let result1 = hash::multi_hash::<Sha256>(data, 1);
assert_eq!(result1.len(), 32); assert_ne!(result1, data.to_vec());
let result3 = hash::multi_hash::<Sha256>(data, 3);
assert_eq!(result3.len(), 32);
assert_ne!(result3, result1);
let result5 = hash::multi_hash::<Sha256>(data, 5);
assert_eq!(result5.len(), 32);
assert_ne!(result5, result3);
}
#[test]
fn test_sha384() {
use rust_bottle::hash;
let data = b"test data for SHA-384";
let hash = hash::sha384(data);
assert_eq!(hash.len(), 48);
let hash2 = hash::sha384(data);
assert_eq!(hash, hash2);
let hash3 = hash::sha384(b"different data");
assert_ne!(hash, hash3);
}
#[test]
fn test_sha512() {
use rust_bottle::hash;
let data = b"test data for SHA-512";
let hash = hash::sha512(data);
assert_eq!(hash.len(), 64);
let hash2 = hash::sha512(data);
assert_eq!(hash, hash2);
let hash3 = hash::sha512(b"different data");
assert_ne!(hash, hash3);
}
#[test]
fn test_sha3_256() {
use rust_bottle::hash;
let data = b"test data for SHA3-256";
let hash = hash::sha3_256(data);
assert_eq!(hash.len(), 32);
let hash2 = hash::sha3_256(data);
assert_eq!(hash, hash2);
let hash3 = hash::sha3_256(b"different data");
assert_ne!(hash, hash3);
let sha256_hash = hash::sha256(data);
assert_ne!(hash, sha256_hash);
}
#[test]
fn test_sha3_384() {
use rust_bottle::hash;
let data = b"test data for SHA3-384";
let hash = hash::sha3_384(data);
assert_eq!(hash.len(), 48);
let hash2 = hash::sha3_384(data);
assert_eq!(hash, hash2);
let hash3 = hash::sha3_384(b"different data");
assert_ne!(hash, hash3);
let sha384_hash = hash::sha384(data);
assert_ne!(hash, sha384_hash);
}
#[test]
fn test_sha3_512() {
use rust_bottle::hash;
let data = b"test data for SHA3-512";
let hash = hash::sha3_512(data);
assert_eq!(hash.len(), 64);
let hash2 = hash::sha3_512(data);
assert_eq!(hash, hash2);
let hash3 = hash::sha3_512(b"different data");
assert_ne!(hash, hash3);
let sha512_hash = hash::sha512(data);
assert_ne!(hash, sha512_hash);
}
#[test]
fn test_ecdh_encrypt_p256() {
use p256::PublicKey;
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::EcdsaP256Key;
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pub_key = PublicKey::from_sec1_bytes(&key.public_key_bytes())
.expect("Failed to create P-256 public key");
let plaintext = b"Test message for P-256 ECDH";
let ciphertext = ecdh::ecdh_encrypt_p256(rng, plaintext, &pub_key).unwrap();
assert!(ciphertext.len() > 65);
assert_eq!(ciphertext.len() % 1, 0);
use p256::SecretKey;
let priv_key_bytes = key.private_key_bytes();
let priv_key = SecretKey::from_bytes(priv_key_bytes.as_slice().into())
.expect("Failed to create P-256 private key");
let decrypted = ecdh::ecdh_decrypt_p256(&ciphertext, &priv_key).unwrap();
assert_eq!(decrypted, plaintext);
}
#[test]
fn test_ecdh_decrypt_p256() {
use p256::{PublicKey, SecretKey};
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::EcdsaP256Key;
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pub_key = PublicKey::from_sec1_bytes(&key.public_key_bytes())
.expect("Failed to create P-256 public key");
let plaintext = b"Test message for P-256 decryption";
let ciphertext = ecdh::ecdh_encrypt_p256(rng, plaintext, &pub_key).unwrap();
let priv_key_bytes = key.private_key_bytes();
let priv_key = SecretKey::from_bytes(priv_key_bytes.as_slice().into())
.expect("Failed to create P-256 private key");
let decrypted = ecdh::ecdh_decrypt_p256(&ciphertext, &priv_key).unwrap();
assert_eq!(decrypted, plaintext);
let short_ciphertext = vec![0u8; 64];
let result = ecdh::ecdh_decrypt_p256(&short_ciphertext, &priv_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidFormat)));
}
#[test]
fn test_ecdh_decrypt_x25519_short_ciphertext() {
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::X25519Key;
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let priv_key_bytes: [u8; 32] = key.private_key_bytes().try_into().unwrap();
let short_ciphertext = vec![0u8; 31];
let result = ecdh::ecdh_decrypt_x25519(&short_ciphertext, &priv_key_bytes);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidFormat)));
}
#[test]
fn test_ecdh_encrypt_p256_path() {
use rand::rngs::OsRng;
use rust_bottle::keys::EcdsaP256Key;
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let pub_key_bytes = key.public_key_bytes();
let plaintext = b"Test message";
let ciphertext = ecdh_encrypt(rng, plaintext, &pub_key_bytes).unwrap();
assert!(!ciphertext.is_empty());
let mut compressed_key = pub_key_bytes.clone();
if compressed_key.len() == 65 && compressed_key[0] == 0x04 {
compressed_key[0] = 0x02; let result = ecdh_encrypt(rng, plaintext, &compressed_key);
let _ = result;
}
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_ecdh_encrypt_mlkem_paths() {
use rand::rngs::OsRng;
use rust_bottle::keys::{MlKem1024Key, MlKem768Key};
let rng = &mut OsRng;
let mlkem768_key = MlKem768Key::generate(rng);
let pub_key_768 = mlkem768_key.public_key_bytes();
assert_eq!(pub_key_768.len(), 1184); let plaintext = b"Test message for ML-KEM-768";
let ciphertext = ecdh_encrypt(rng, plaintext, &pub_key_768).unwrap();
assert!(!ciphertext.is_empty());
let mlkem1024_key = MlKem1024Key::generate(rng);
let pub_key_1024 = mlkem1024_key.public_key_bytes();
assert_eq!(pub_key_1024.len(), 1568); let plaintext2 = b"Test message for ML-KEM-1024";
let ciphertext2 = ecdh_encrypt(rng, plaintext2, &pub_key_1024).unwrap();
assert!(!ciphertext2.is_empty());
}
#[test]
fn test_ecdh_decrypt_x25519_path() {
use rand::rngs::OsRng;
use rust_bottle::keys::X25519Key;
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let plaintext = b"Test message for X25519";
let ciphertext = ecdh_encrypt(rng, plaintext, &key.public_key_bytes()).unwrap();
let decrypted = ecdh_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
}
#[test]
fn test_ecdh_decrypt_p256_path() {
use rand::rngs::OsRng;
use rust_bottle::keys::EcdsaP256Key;
let rng = &mut OsRng;
let key = EcdsaP256Key::generate(rng);
let plaintext = b"Test message for P-256";
let ciphertext = ecdh_encrypt(rng, plaintext, &key.public_key_bytes()).unwrap();
let decrypted = ecdh_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
}
#[test]
fn test_ecdh_decrypt_invalid_key_type() {
let invalid_key = vec![0u8; 50]; let ciphertext = vec![0u8; 100];
let result = ecdh_decrypt(&ciphertext, &invalid_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
}
#[test]
fn test_ecdh_decrypt_try_into_error() {
let invalid_32_byte_key = vec![0u8; 32];
let ciphertext = vec![0u8; 100];
let result = ecdh_decrypt(&ciphertext, &invalid_32_byte_key);
let _ = result;
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_encrypt_full() {
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::MlKem768Key;
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let plaintext = b"Test message for ML-KEM-768 encryption";
let pub_key_bytes = key.public_key_bytes();
assert_eq!(pub_key_bytes.len(), 1184);
let ciphertext = ecdh::mlkem768_encrypt(rng, plaintext, &pub_key_bytes).unwrap();
assert!(!ciphertext.is_empty());
assert!(ciphertext.len() > 1088);
assert!(ciphertext.len() >= 1088 + 28);
let wrong_key = vec![0u8; 1000];
let result = ecdh::mlkem768_encrypt(rng, plaintext, &wrong_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
let invalid_key = vec![0u8; 1184];
let _result2 = ecdh::mlkem768_encrypt(rng, plaintext, &invalid_key);
let decrypted = ecdh::mlkem768_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
let empty_ciphertext = ecdh::mlkem768_encrypt(rng, b"", &pub_key_bytes).unwrap();
let empty_decrypted =
ecdh::mlkem768_decrypt(&empty_ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(empty_decrypted, b"");
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_encrypt_full() {
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::MlKem1024Key;
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
let plaintext = b"Test message for ML-KEM-1024 encryption";
let pub_key_bytes = key.public_key_bytes();
assert_eq!(pub_key_bytes.len(), 1568);
let ciphertext = ecdh::mlkem1024_encrypt(rng, plaintext, &pub_key_bytes).unwrap();
assert!(!ciphertext.is_empty());
assert!(ciphertext.len() > 1568);
assert!(ciphertext.len() >= 1568 + 28);
let wrong_key = vec![0u8; 1000];
let result = ecdh::mlkem1024_encrypt(rng, plaintext, &wrong_key);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
let invalid_key = vec![0u8; 1568];
let _result2 = ecdh::mlkem1024_encrypt(rng, plaintext, &invalid_key);
let decrypted = ecdh::mlkem1024_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
let empty_ciphertext = ecdh::mlkem1024_encrypt(rng, b"", &pub_key_bytes).unwrap();
let empty_decrypted =
ecdh::mlkem1024_decrypt(&empty_ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(empty_decrypted, b"");
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_hybrid_encrypt_mlkem768_x25519() {
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::{MlKem768Key, X25519Key};
let rng = &mut OsRng;
let mlkem_key = MlKem768Key::generate(rng);
let x25519_key = X25519Key::generate(rng);
let plaintext = b"Test message for hybrid encryption";
let mlkem_pub = mlkem_key.public_key_bytes();
let x25519_pub = x25519_key.public_key_bytes();
assert_eq!(mlkem_pub.len(), 1184); assert_eq!(x25519_pub.len(), 32);
let ciphertext =
ecdh::hybrid_encrypt_mlkem768_x25519(rng, plaintext, &mlkem_pub, &x25519_pub).unwrap();
assert!(!ciphertext.is_empty());
assert!(ciphertext.len() > 4);
let mlkem_len = u32::from_le_bytes(ciphertext[..4].try_into().unwrap()) as usize;
assert!(mlkem_len > 0);
assert!(ciphertext.len() >= 4 + mlkem_len);
let invalid_x25519 = vec![0u8; 31]; let result = ecdh::hybrid_encrypt_mlkem768_x25519(rng, plaintext, &mlkem_pub, &invalid_x25519);
assert!(result.is_err());
assert!(matches!(result, Err(BottleError::InvalidKeyType)));
let x25519_priv: [u8; 32] = x25519_key.private_key_bytes().try_into().unwrap();
let decrypted = ecdh::hybrid_decrypt_mlkem768_x25519(
&ciphertext,
&mlkem_key.private_key_bytes(),
&x25519_priv,
)
.unwrap();
assert_eq!(decrypted, plaintext);
let empty_ciphertext =
ecdh::hybrid_encrypt_mlkem768_x25519(rng, b"", &mlkem_pub, &x25519_pub).unwrap();
let empty_decrypted = ecdh::hybrid_decrypt_mlkem768_x25519(
&empty_ciphertext,
&mlkem_key.private_key_bytes(),
&x25519_priv,
)
.unwrap();
assert_eq!(empty_decrypted, b"");
}
#[test]
fn test_decrypt_aes_gcm_short_ciphertext() {
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::X25519Key;
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let short_ciphertext = vec![0u8; 40]; let priv_key_bytes: [u8; 32] = key.private_key_bytes().try_into().unwrap();
let result = ecdh::ecdh_decrypt_x25519(&short_ciphertext, &priv_key_bytes);
assert!(result.is_err());
}
#[test]
fn test_decrypt_aes_gcm_success() {
use rand::rngs::OsRng;
use rust_bottle::ecdh;
use rust_bottle::keys::X25519Key;
let rng = &mut OsRng;
let key = X25519Key::generate(rng);
let plaintext = b"Test message for AES-GCM decryption";
let ciphertext = ecdh_encrypt(rng, plaintext, &key.public_key_bytes()).unwrap();
let priv_key_bytes: [u8; 32] = key.private_key_bytes().try_into().unwrap();
let decrypted = ecdh::ecdh_decrypt_x25519(&ciphertext, &priv_key_bytes).unwrap();
assert_eq!(decrypted, plaintext);
}