use base64::{engine::general_purpose, Engine as _}; use devolutions_crypto::{ ciphertext::Ciphertext, key::PrivateKey, password_hash::PasswordHash, utils::{derive_key_argon2, derive_key_pbkdf2}, Argon2Parameters, }; use std::convert::TryFrom as _; #[test] fn test_derive_key_argon2() { let params = Argon2Parameters::try_from( general_purpose::STANDARD .decode("AQAAACAAAAABAAAAIAAAAAEAAAACEwAAAAAQAAAAimFBkm3f8+f+YfLRnF5OoQ==") .unwrap() .as_slice(), ) .unwrap(); let key = derive_key_argon2(b"password", ¶ms).unwrap(); assert_eq!( key, general_purpose::STANDARD .decode("AcEN6Cb1Om6tomZScAM725qiXMzaxaHlj3iMiT/Ukq0=") .unwrap() ); } #[test] fn test_derive_key_default() { let password = b"testpassword"; let salt = b""; let derived_password = derive_key_pbkdf2(password, salt, 10000, 32); assert_eq!( derived_password, general_purpose::STANDARD .decode("ImfGCyv6PwMYaJShGxR4MfVrjuUrsI0CSarJgOApwf8=") .unwrap() ); } #[test] fn test_derive_key_iterations() { let password = b"testPa$$"; let salt = b""; let derived_password = derive_key_pbkdf2(password, salt, 100, 32); assert_eq!( derived_password, general_purpose::STANDARD .decode("ev/GiJLvOgIkkWrnIrHSi2fdZE5qJBIrW+DLeMLIXK4=") .unwrap() ); } #[test] fn test_derive_key_salt() { let password = b"testPa$$"; let salt = general_purpose::STANDARD .decode("tdTt5wgeqQYLvkiXKkFirqy2hMbzadBtL+jekVeNCRA=") .unwrap(); let derived_password = derive_key_pbkdf2(password, &salt, 100, 32); assert_eq!( derived_password, general_purpose::STANDARD .decode("ZaYRZeQiIPJ+Jl511AgHZjv4/HbCFq4eUP9yNa3gowI=") .unwrap() ); } #[test] fn test_symmetric_decrypt_v1() { let key = general_purpose::STANDARD .decode("ozJVEme4+5e/4NG3C+Rl26GQbGWAqGc0QPX8/1xvaFM=") .unwrap(); let ciphertext = general_purpose::STANDARD.decode("DQwCAAAAAQCK1twEut+TeJfFbTWCRgHjyS6bOPOZUEQAeBtSFFRl2jHggM/34n68zIZWGbsZHkufVzU6mTN5N2Dx9bTplrycv5eNVevT4P9FdVHJ751D+A==").unwrap(); let ciphertext = Ciphertext::try_from(ciphertext.as_slice()).unwrap(); let result = ciphertext.decrypt(&key).unwrap(); assert_eq!(result, b"test Ciph3rtext~"); } #[test] fn test_symmetric_decrypt_aad_v1() { let key = general_purpose::STANDARD .decode("ozJVEme4+5e/4NG3C+Rl26GQbGWAqGc0QPX8/1xvaFM=") .unwrap(); let aad = b"this is some public data"; let ciphertext = general_purpose::STANDARD.decode("DQwCAAEAAQCeKfbTqYjfVCEPEiAJjiypBstPmZz0AnpliZKoR+WXTKdj2f/4ops0++dDBVZ+XdyE1KfqxViWVc9djy/HSCcPR4nDehtNI69heGCIFudXfQ==").unwrap(); let ciphertext = Ciphertext::try_from(ciphertext.as_slice()).unwrap(); let result = ciphertext.decrypt_with_aad(&key, aad).unwrap(); assert_eq!(result, b"test Ciph3rtext~"); } #[test] fn test_symmetric_decrypt_v2() { let key = general_purpose::STANDARD .decode("ozJVEme4+5e/4NG3C+Rl26GQbGWAqGc0QPX8/1xvaFM=") .unwrap(); let ciphertext = general_purpose::STANDARD.decode( "DQwCAAAAAgAA0iPpI4IEzcrWAQiy6tqDqLbRYduGvlMC32mVH7tpIN2CXDUu5QHF91I7pMrmjt/61pm5CeR/IcU=", ) .unwrap(); let ciphertext = Ciphertext::try_from(ciphertext.as_slice()).unwrap(); let result = ciphertext.decrypt(&key).unwrap(); assert_eq!(result, b"test Ciph3rtext~2"); } #[test] fn test_symmetric_decrypt_aad_v2() { let key = general_purpose::STANDARD .decode("ozJVEme4+5e/4NG3C+Rl26GQbGWAqGc0QPX8/1xvaFM=") .unwrap(); let aad = b"this is some public data"; let ciphertext = general_purpose::STANDARD.decode("DQwCAAEAAgA9bh989dao0Pvaz1NpJTI5m7M4br2qVjZtFwXXoXZOlkCjtqU/uif4pbNCcpEodzeP4YG1QvfKVQ==").unwrap(); let ciphertext = Ciphertext::try_from(ciphertext.as_slice()).unwrap(); let result = ciphertext.decrypt_with_aad(&key, aad).unwrap(); assert_eq!(result, b"test Ciph3rtext~"); } #[test] fn test_asymmetric_decrypt_v2() { let private_key = PrivateKey::try_from( general_purpose::STANDARD .decode("DQwBAAEAAQAAwQ3oJvU6bq2iZlJwAzvbmqJczNrFoeWPeIyJP9SSbQ==") .unwrap() .as_slice(), ) .unwrap(); let ciphertext = Ciphertext::try_from(general_purpose::STANDARD.decode("DQwCAAIAAgCIG9L2MTiumytn7H/p5I3aGVdhV3WUL4i8nIeMWIJ1YRbNQ6lEiQDAyfYhbs6gg1cD7+5Ft2Q5cm7ArsGfiFYWnscm1y7a8tAGfjFFTonzrg==").unwrap().as_slice()).unwrap(); let result = ciphertext.decrypt_asymmetric(&private_key).unwrap(); assert_eq!(result, b"testdata"); } #[test] fn test_asymmetric_decrypt_aad_v2() { let private_key = PrivateKey::try_from( general_purpose::STANDARD .decode("DQwBAAEAAQC9qf9UY1ovL/48ALGHL9SLVpVozbdjYsw0EPerUl3zYA==") .unwrap() .as_slice(), ) .unwrap(); let ciphertext = Ciphertext::try_from(general_purpose::STANDARD.decode("DQwCAAIAAgB1u62xYeyppWf83QdWwbwGUt5QuiAFZr+hIiFEvMRbXiNCE3RMBNbmgQkLr/vME0BeQa+uUTXZARvJcyNXHyAE4tSdw6o/psU/kw/Z/FbsPw==").unwrap().as_slice()).unwrap(); let aad = b"this is some public data"; let result = ciphertext .decrypt_asymmetric_with_aad(&private_key, aad) .unwrap(); assert_eq!(result, b"testdata"); } #[test] fn test_password_hashing_v1() { let hash1 = PasswordHash::try_from(general_purpose::STANDARD.decode("DQwDAAAAAQAQJwAAXCzLFoyeZhFSDYBAPiIWhCk04aoP/lalOoCl7D+skIY/i+3WT7dn6L8WvnfEq6flCd7i+IcKb3GEK4rCpzhDlw==").unwrap().as_slice()).unwrap(); let hash2 = PasswordHash::try_from(general_purpose::STANDARD.decode("DQwDAAAAAQAKAAAAmH1BBckBJYDD0xfiwkAk1xwKgw8a57YQT0Igm+Faa9LFamTeEJgqn/qHc2R/8XEyK2iLPkVy+IErdGLLtLKJ2g==").unwrap().as_slice()).unwrap(); assert!(hash1.verify_password(b"password1")); assert!(hash2.verify_password(b"password1")); } #[test] fn test_signature_v1() { use devolutions_crypto::signature::Signature; use devolutions_crypto::signing_key::SigningPublicKey; use std::convert::TryInto; let data = b"this is a test"; let wrong_data = b"this is wrong"; let public_key: SigningPublicKey = (general_purpose::STANDARD .decode("DQwFAAIAAQDeEvwlEigK5AXoTorhmlKP6+mbiUU2rYrVQ25JQ5xang==") .unwrap() .as_slice()) .try_into() .unwrap(); let signature: Signature = (general_purpose::STANDARD.decode("DQwGAAAAAQD82uRk4sFC8vEni6pDNw/vOdN1IEDg9cAVfprWJZ/JBls9Gi61cUt5u6uBJtseNGZFT7qKLvp4NUZrAOL8FH0K").unwrap().as_slice()).try_into().unwrap(); assert!(signature.verify(data, &public_key)); assert!(!signature.verify(wrong_data, &public_key)); } #[test] fn test_base64_url() { use devolutions_crypto::utils::{base64_decode_url, base64_encode_url}; assert_eq!(base64_encode_url(b"Ab6/"), "QWI2Lw"); assert_eq!(base64_encode_url(b"Ab6/75"), "QWI2Lzc1"); assert_eq!(base64_encode_url(&[0xff, 0xff, 0xfe, 0xff]), "___-_w"); assert_eq!(base64_decode_url("QWI2Lw").unwrap(), b"Ab6/"); assert_eq!(base64_decode_url("QWI2Lzc1").unwrap(), b"Ab6/75"); assert_eq!( base64_decode_url("___-_w").unwrap(), &[0xff, 0xff, 0xfe, 0xff] ); }