card-functionality: Perform the full set of tests in a single Card<Transaction>

This commit is contained in:
Heiko Schaefer 2023-08-28 20:38:19 +02:00
parent 746f2f647d
commit 566fd6f9a0
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
4 changed files with 47 additions and 47 deletions

View file

@ -28,16 +28,18 @@ fn main() -> Result<()> {
let mut c: Card<Open> = card.get_card()?; let mut c: Card<Open> = card.get_card()?;
println!(" -> Card opened"); println!(" -> Card opened");
let mut tx = c.transaction()?;
println!(" started transaction");
println!("Reset"); println!("Reset");
let _ = run_test(&mut c, test_reset, &[])?; let _ = run_test(&mut tx, test_reset, &[])?;
print!("Set user data"); print!("Set user data");
let userdata_out = run_test(&mut c, test_set_user_data, &[])?; let userdata_out = run_test(&mut tx, test_set_user_data, &[])?;
println!(" {userdata_out:x?}"); println!(" {userdata_out:x?}");
println!("Set login data"); println!("Set login data");
let login_data_out = run_test(&mut c, test_set_login_data, &[])?; let login_data_out = run_test(&mut tx, test_set_login_data, &[])?;
println!(" {login_data_out:x?}"); println!(" {login_data_out:x?}");
let key_files = { let key_files = {
@ -52,7 +54,7 @@ fn main() -> Result<()> {
for key_file in &key_files { for key_file in &key_files {
// upload keys // upload keys
print!("Upload key '{key_file}'"); print!("Upload key '{key_file}'");
let upload_res = run_test(&mut c, test_upload_keys, &[key_file]); let upload_res = run_test(&mut tx, test_upload_keys, &[key_file]);
if let Err(TestError::KeyUploadError(_file, err)) = &upload_res { if let Err(TestError::KeyUploadError(_file, err)) = &upload_res {
// The card doesn't support this key type, so skip to the // The card doesn't support this key type, so skip to the
@ -74,13 +76,13 @@ fn main() -> Result<()> {
let cert = Cert::from_str(&key)?; let cert = Cert::from_str(&key)?;
let ciphertext = util::encrypt_to("Hello world!\n", &cert)?; let ciphertext = util::encrypt_to("Hello world!\n", &cert)?;
let dec_out = run_test(&mut c, test_decrypt, &[&key, &ciphertext])?; let dec_out = run_test(&mut tx, test_decrypt, &[&key, &ciphertext])?;
println!(" {dec_out:x?}"); println!(" {dec_out:x?}");
// sign // sign
print!(" Sign"); print!(" Sign");
let sign_out = run_test(&mut c, test_sign, &[&key])?; let sign_out = run_test(&mut tx, test_sign, &[&key])?;
println!(" {sign_out:x?}"); println!(" {sign_out:x?}");
} }

View file

@ -28,6 +28,8 @@ fn main() -> Result<()> {
let mut c: Card<Open> = card.get_card()?; let mut c: Card<Open> = card.get_card()?;
println!(" -> Card opened"); println!(" -> Card opened");
let mut tx = c.transaction()?;
println!(" started transaction");
// println!("Get pubkey"); // println!("Get pubkey");
// let _ = run_test(&mut card, test_get_pub, &[])?; // let _ = run_test(&mut card, test_get_pub, &[])?;
@ -39,14 +41,14 @@ fn main() -> Result<()> {
// // continue; // only print caps // // continue; // only print caps
println!("Reset"); println!("Reset");
let _ = run_test(&mut c, test_reset, &[])?; let _ = run_test(&mut tx, test_reset, &[])?;
// println!("Algo info"); // println!("Algo info");
// let _ = run_test(&mut card, test_print_algo_info, &[])?; // let _ = run_test(&mut card, test_print_algo_info, &[])?;
// Set user data because keygen expects a name (for the user id) // Set user data because keygen expects a name (for the user id)
println!("Set user data"); println!("Set user data");
let _ = run_test(&mut c, test_set_user_data, &[])?; let _ = run_test(&mut tx, test_set_user_data, &[])?;
let algos = { let algos = {
let config = card.get_config(); let config = card.get_config();
@ -60,12 +62,12 @@ fn main() -> Result<()> {
for algo in algos { for algo in algos {
println!("Generate key [{algo}]"); println!("Generate key [{algo}]");
let res = run_test(&mut c, test_keygen, &[&algo])?; let res = run_test(&mut tx, test_keygen, &[&algo])?;
if let TestResult::Text(cert_str) = &res[0] { if let TestResult::Text(cert_str) = &res[0] {
// sign // sign
print!(" Sign"); print!(" Sign");
let sign_out = run_test(&mut c, test_sign, &[cert_str])?; let sign_out = run_test(&mut tx, test_sign, &[cert_str])?;
println!(" {sign_out:x?}"); println!(" {sign_out:x?}");
// decrypt // decrypt
@ -73,7 +75,7 @@ fn main() -> Result<()> {
let ciphertext = util::encrypt_to("Hello world!\n", &cert)?; let ciphertext = util::encrypt_to("Hello world!\n", &cert)?;
print!(" Decrypt"); print!(" Decrypt");
let dec_out = run_test(&mut c, test_decrypt, &[cert_str, &ciphertext])?; let dec_out = run_test(&mut tx, test_decrypt, &[cert_str, &ciphertext])?;
println!(" {dec_out:x?}"); println!(" {dec_out:x?}");
} else { } else {
panic!("Didn't get back a Cert from test_keygen"); panic!("Didn't get back a Cert from test_keygen");

View file

@ -18,6 +18,7 @@ fn main() -> Result<()> {
println!("** Run tests on card '{}' **", card.get_name()); println!("** Run tests on card '{}' **", card.get_name());
let mut c: Card<Open> = card.get_card()?; let mut c: Card<Open> = card.get_card()?;
let mut tx = c.transaction()?;
// println!("Caps"); // println!("Caps");
// let _ = run_test(&mut card, test_print_caps, &[])?; // let _ = run_test(&mut card, test_print_caps, &[])?;
@ -27,7 +28,7 @@ fn main() -> Result<()> {
// let _ = run_test(&mut card, test_print_algo_info, &[])?; // let _ = run_test(&mut card, test_print_algo_info, &[])?;
println!("Reset"); println!("Reset");
let _ = run_test(&mut c, test_reset, &[])?; let _ = run_test(&mut tx, test_reset, &[])?;
// --- // ---

View file

@ -10,7 +10,7 @@ use openpgp_card::algorithm::AlgoSimple;
use openpgp_card::card_do::{KeyGenerationTime, Sex}; use openpgp_card::card_do::{KeyGenerationTime, Sex};
use openpgp_card::{Error, KeyType, OpenPgp, StatusBytes}; use openpgp_card::{Error, KeyType, OpenPgp, StatusBytes};
use openpgp_card_sequoia::sq_util; use openpgp_card_sequoia::sq_util;
use openpgp_card_sequoia::state::{Admin, Open}; use openpgp_card_sequoia::state::{Admin, Open, Transaction};
use openpgp_card_sequoia::util::{ use openpgp_card_sequoia::util::{
make_cert, public_key_material_and_fp_to_key, public_key_material_to_key, make_cert, public_key_material_and_fp_to_key, public_key_material_to_key,
}; };
@ -52,7 +52,7 @@ pub enum TestError {
} }
/// Run after each "upload keys", if key *was* uploaded (?) /// Run after each "upload keys", if key *was* uploaded (?)
pub fn test_decrypt(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput, TestError> { pub fn test_decrypt(tx: &mut Card<Transaction>, param: &[&str]) -> Result<TestOutput, TestError> {
assert_eq!( assert_eq!(
param.len(), param.len(),
2, 2,
@ -63,9 +63,7 @@ pub fn test_decrypt(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput,
let p = StandardPolicy::new(); let p = StandardPolicy::new();
let mut transaction = card.transaction()?; let mut user = tx.to_user_card("123456")?;
let mut user = transaction.to_user_card("123456")?;
let d = user.decryptor(&|| {})?; let d = user.decryptor(&|| {})?;
let res = sq_util::decrypt(d, msg.into_bytes(), &p)?; let res = sq_util::decrypt(d, msg.into_bytes(), &p)?;
@ -77,14 +75,12 @@ pub fn test_decrypt(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput,
} }
/// Run after each "upload keys", if key *was* uploaded (?) /// Run after each "upload keys", if key *was* uploaded (?)
pub fn test_sign(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput, TestError> { pub fn test_sign(tx: &mut Card<Transaction>, param: &[&str]) -> Result<TestOutput, TestError> {
assert_eq!(param.len(), 1, "test_sign needs a filename for 'cert'"); assert_eq!(param.len(), 1, "test_sign needs a filename for 'cert'");
let cert = Cert::from_str(param[0])?; let cert = Cert::from_str(param[0])?;
let mut transaction = card.transaction()?; let mut sign = tx.to_signing_card("123456").unwrap();
let mut sign = transaction.to_signing_card("123456").unwrap();
let s = sign.signer(&|| {})?; let s = sign.signer(&|| {})?;
let msg = "Hello world, I am signed."; let msg = "Hello world, I am signed.";
@ -178,9 +174,10 @@ pub fn test_print_algo_info(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOu
Ok(vec![]) Ok(vec![])
} }
pub fn test_upload_keys(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput, TestError> { pub fn test_upload_keys(
let mut transaction = card.transaction()?; tx: &mut Card<Transaction>,
param: &[&str],
) -> Result<TestOutput, TestError> {
assert_eq!( assert_eq!(
param.len(), param.len(),
1, 1,
@ -190,7 +187,7 @@ pub fn test_upload_keys(card: &mut Card<Open>, param: &[&str]) -> Result<TestOut
let cert = Cert::from_file(param[0])?; let cert = Cert::from_file(param[0])?;
let p = StandardPolicy::new(); let p = StandardPolicy::new();
let mut admin = transaction.to_admin_card(b"12345678")?; let mut admin = tx.to_admin_card(b"12345678")?;
let meta = util::upload_subkeys(&mut admin, &cert, &p) let meta = util::upload_subkeys(&mut admin, &cert, &p)
.map_err(|e| TestError::KeyUploadError(param[0].to_string(), e))?; .map_err(|e| TestError::KeyUploadError(param[0].to_string(), e))?;
@ -204,9 +201,8 @@ pub fn test_upload_keys(card: &mut Card<Open>, param: &[&str]) -> Result<TestOut
} }
/// Generate keys for each of the three KeyTypes /// Generate keys for each of the three KeyTypes
pub fn test_keygen(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput, TestError> { pub fn test_keygen(tx: &mut Card<Transaction>, param: &[&str]) -> Result<TestOutput, TestError> {
let mut transaction = card.transaction()?; let mut admin = tx
let mut admin = transaction
.to_admin_card("12345678") .to_admin_card("12345678")
.expect("Couldn't get Admin card"); .expect("Couldn't get Admin card");
@ -233,9 +229,11 @@ pub fn test_keygen(card: &mut Card<Open>, param: &[&str]) -> Result<TestOutput,
let (pkm, ts) = admin.generate_key_simple(KeyType::Authentication, Some(alg))?; let (pkm, ts) = admin.generate_key_simple(KeyType::Authentication, Some(alg))?;
let key_aut = public_key_material_to_key(&pkm, KeyType::Authentication, &ts, None, None)?; let key_aut = public_key_material_to_key(&pkm, KeyType::Authentication, &ts, None, None)?;
tx.reload_ard()?;
// Generate a Cert for this set of generated keys // Generate a Cert for this set of generated keys
let cert = make_cert( let cert = make_cert(
&mut transaction, tx,
key_sig, key_sig,
Some(key_dec), Some(key_dec),
Some(key_aut), Some(key_aut),
@ -296,10 +294,8 @@ pub fn test_get_pub(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutput,
Ok(vec![]) Ok(vec![])
} }
pub fn test_reset(card: &mut Card<Open>, _param: &[&str]) -> Result<TestOutput, TestError> { pub fn test_reset(tx: &mut Card<Transaction>, _param: &[&str]) -> Result<TestOutput, TestError> {
let mut transaction = card.transaction()?; tx.factory_reset()?;
transaction.factory_reset()?;
Ok(vec![]) Ok(vec![])
} }
@ -308,10 +304,11 @@ pub fn test_reset(card: &mut Card<Open>, _param: &[&str]) -> Result<TestOutput,
/// ///
/// Returns an empty TestOutput, throws errors for unexpected Status codes /// Returns an empty TestOutput, throws errors for unexpected Status codes
/// and for unequal field values. /// and for unequal field values.
pub fn test_set_user_data(card: &mut Card<Open>, _param: &[&str]) -> Result<TestOutput, TestError> { pub fn test_set_user_data(
let mut transaction = card.transaction()?; tx: &mut Card<Transaction>,
_param: &[&str],
let mut admin = transaction.to_admin_card("12345678")?; ) -> Result<TestOutput, TestError> {
let mut admin = tx.to_admin_card("12345678")?;
// name // name
admin.set_name("Bar<<Foo")?; admin.set_name("Bar<<Foo")?;
@ -326,10 +323,10 @@ pub fn test_set_user_data(card: &mut Card<Open>, _param: &[&str]) -> Result<Test
admin.set_url("https://duckduckgo.com/")?; admin.set_url("https://duckduckgo.com/")?;
// reload application releated data // reload application releated data
transaction.reload_ard()?; tx.reload_ard()?;
// compare the reloaded fields, expect equal data // compare the reloaded fields, expect equal data
let ch = transaction.cardholder_related_data()?; let ch = tx.cardholder_related_data()?;
assert_eq!(ch.name(), Some("Bar<<Foo".as_bytes())); assert_eq!(ch.name(), Some("Bar<<Foo".as_bytes()));
assert_eq!( assert_eq!(
@ -338,25 +335,23 @@ pub fn test_set_user_data(card: &mut Card<Open>, _param: &[&str]) -> Result<Test
); );
assert_eq!(ch.sex(), Some(Sex::Female)); assert_eq!(ch.sex(), Some(Sex::Female));
let url = transaction.url()?; let url = tx.url()?;
assert_eq!(&url, "https://duckduckgo.com/"); assert_eq!(&url, "https://duckduckgo.com/");
Ok(vec![]) Ok(vec![])
} }
pub fn test_set_login_data( pub fn test_set_login_data(
card: &mut Card<Open>, tx: &mut Card<Transaction>,
_params: &[&str], _params: &[&str],
) -> std::result::Result<TestOutput, TestError> { ) -> std::result::Result<TestOutput, TestError> {
let mut transaction = card.transaction()?; let mut admin = tx.to_admin_card("12345678")?;
let mut admin = transaction.to_admin_card("12345678")?;
let test_login = "someone@somewhere.com"; let test_login = "someone@somewhere.com";
admin.set_login_data(test_login)?; admin.set_login_data(test_login)?;
// Read the previously set login data // Read the previously set login data
let read_login_data = transaction.login_data()?; let read_login_data = tx.login_data()?;
assert_eq!(read_login_data, test_login); assert_eq!(read_login_data, test_login);
@ -677,8 +672,8 @@ pub fn test_reset_retry_counter(
} }
pub fn run_test( pub fn run_test(
card: &mut Card<Open>, card: &mut Card<Transaction>,
t: fn(&mut Card<Open>, &[&str]) -> Result<TestOutput, TestError>, t: fn(&mut Card<Transaction>, &[&str]) -> Result<TestOutput, TestError>,
param: &[&str], param: &[&str],
) -> Result<TestOutput, TestError> { ) -> Result<TestOutput, TestError> {
t(card, param) t(card, param)