openpgp-card-sequoia: handle PINs as &str

According to the spec, PINs are supposed to be handled in utf8 format (not binary)
This commit is contained in:
Heiko Schaefer 2023-09-05 15:45:25 +02:00
parent f12b052d35
commit b6fef9511a
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
4 changed files with 51 additions and 49 deletions

View file

@ -193,7 +193,7 @@ pub fn test_upload_keys(
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 = tx.to_admin_card(b"12345678")?; let mut admin = tx.to_admin_card("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))?;
@ -246,7 +246,7 @@ pub fn test_keygen(tx: &mut Card<Transaction>, param: &[&str]) -> Result<TestOut
key_sig, key_sig,
Some(key_dec), Some(key_dec),
Some(key_aut), Some(key_aut),
Some(b"123456"), Some("123456"),
&|| {}, &|| {},
&|| {}, &|| {},
&[], &[],
@ -377,12 +377,12 @@ pub fn test_set_login_data(
// let d = transaction.private_use_do(1)?; // let d = transaction.private_use_do(1)?;
// println!("data 1 {d:?}"); // println!("data 1 {d:?}");
// //
// transaction.verify_pw1_user(b"123456")?; // transaction.verify_pw1_user("123456")?;
// //
// transaction.set_private_use_do(1, "Foo bar1!".as_bytes().to_vec())?; // transaction.set_private_use_do(1, "Foo bar1!".as_bytes().to_vec())?;
// transaction.set_private_use_do(3, "Foo bar3!".as_bytes().to_vec())?; // transaction.set_private_use_do(3, "Foo bar3!".as_bytes().to_vec())?;
// //
// transaction.verify_pw3(b"12345678")?; // transaction.verify_pw3("12345678")?;
// //
// transaction.set_private_use_do(2, "Foo bar2!".as_bytes().to_vec())?; // transaction.set_private_use_do(2, "Foo bar2!".as_bytes().to_vec())?;
// transaction.set_private_use_do(4, "Foo bar4!".as_bytes().to_vec())?; // transaction.set_private_use_do(4, "Foo bar4!".as_bytes().to_vec())?;
@ -513,7 +513,7 @@ pub fn test_verify(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutput,
panic!("Status should be 'SecurityStatusNotSatisfied'"); panic!("Status should be 'SecurityStatusNotSatisfied'");
} }
transaction.verify_admin(b"12345678")?; transaction.verify_admin("12345678")?;
match transaction.check_admin_verified() { match transaction.check_admin_verified() {
Err(Error::CardStatus(s)) => { Err(Error::CardStatus(s)) => {
@ -535,7 +535,7 @@ pub fn test_verify(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutput,
let cardholder = transaction.cardholder_related_data()?; let cardholder = transaction.cardholder_related_data()?;
assert_eq!(cardholder.name(), Some("Admin<<Hello".as_bytes())); assert_eq!(cardholder.name(), Some("Admin<<Hello".as_bytes()));
transaction.verify_user(b"123456")?; transaction.verify_user("123456")?;
match transaction.check_user_verified() { match transaction.check_user_verified() {
Err(Error::CardStatus(s)) => { Err(Error::CardStatus(s)) => {
@ -567,20 +567,20 @@ pub fn test_change_pw(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutpu
// first do admin-less pw1 on gnuk // first do admin-less pw1 on gnuk
// (NOTE: Gnuk requires a key to be loaded before allowing pw changes!) // (NOTE: Gnuk requires a key to be loaded before allowing pw changes!)
println!("change pw1"); println!("change pw1");
transaction.change_user_pin(b"123456", b"abcdef00")?; transaction.change_user_pin("123456", "abcdef00")?;
// also set admin pw, which means pw1 is now only user-pw again, on gnuk // also set admin pw, which means pw1 is now only user-pw again, on gnuk
println!("change pw3"); println!("change pw3");
// ca.change_pw3("abcdef00", "abcdefgh")?; // gnuk // ca.change_pw3("abcdef00", "abcdefgh")?; // gnuk
transaction.change_admin_pin(b"12345678", b"abcdefgh")?; transaction.change_admin_pin("12345678", "abcdefgh")?;
println!("change pw1"); println!("change pw1");
transaction.change_user_pin(b"abcdef00", b"abcdef")?; // gnuk transaction.change_user_pin("abcdef00", "abcdef")?; // gnuk
// ca.change_pw1("123456", "abcdef")?; // ca.change_pw1("123456", "abcdef")?;
println!("verify bad pw1"); println!("verify bad pw1");
match transaction.verify_user(b"123456ab") { match transaction.verify_user("123456ab") {
Err(Error::CardStatus(StatusBytes::SecurityStatusNotSatisfied)) => { Err(Error::CardStatus(StatusBytes::SecurityStatusNotSatisfied)) => {
// this is expected // this is expected
} }
@ -591,10 +591,10 @@ pub fn test_change_pw(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutpu
} }
println!("verify good pw1"); println!("verify good pw1");
transaction.verify_user(b"abcdef")?; transaction.verify_user("abcdef")?;
println!("verify bad pw3"); println!("verify bad pw3");
match transaction.verify_admin(b"00000000") { match transaction.verify_admin("00000000") {
Err(Error::CardStatus(StatusBytes::SecurityStatusNotSatisfied)) => { Err(Error::CardStatus(StatusBytes::SecurityStatusNotSatisfied)) => {
// this is expected // this is expected
} }
@ -605,13 +605,13 @@ pub fn test_change_pw(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutpu
} }
println!("verify good pw3"); println!("verify good pw3");
transaction.verify_admin(b"abcdefgh")?; transaction.verify_admin("abcdefgh")?;
println!("change pw3 back to default"); println!("change pw3 back to default");
transaction.change_admin_pin(b"abcdefgh", b"12345678")?; transaction.change_admin_pin("abcdefgh", "12345678")?;
println!("change pw1 back to default"); println!("change pw1 back to default");
transaction.change_user_pin(b"abcdef", b"123456")?; transaction.change_user_pin("abcdef", "123456")?;
Ok(out) Ok(out)
} }
@ -626,15 +626,15 @@ pub fn test_reset_retry_counter(
// set pw3, then pw1 (to bring gnuk into non-admin mode) // set pw3, then pw1 (to bring gnuk into non-admin mode)
println!("set pw3"); println!("set pw3");
transaction.change_admin_pin(b"12345678", b"12345678")?; transaction.change_admin_pin("12345678", "12345678")?;
println!("set pw1"); println!("set pw1");
transaction.change_user_pin(b"123456", b"123456")?; transaction.change_user_pin("123456", "123456")?;
println!("break pw1"); println!("break pw1");
let _ = transaction.verify_user(b"wrong0"); let _ = transaction.verify_user("wrong0");
let _ = transaction.verify_user(b"wrong0"); let _ = transaction.verify_user("wrong0");
let _ = transaction.verify_user(b"wrong0"); let _ = transaction.verify_user("wrong0");
let res = transaction.verify_user(b"wrong0"); let res = transaction.verify_user("wrong0");
match res { match res {
Err(Error::CardStatus(StatusBytes::AuthenticationMethodBlocked)) => { Err(Error::CardStatus(StatusBytes::AuthenticationMethodBlocked)) => {
@ -653,21 +653,21 @@ pub fn test_reset_retry_counter(
} }
println!("verify pw3"); println!("verify pw3");
transaction.verify_admin(b"12345678")?; transaction.verify_admin("12345678")?;
println!("set resetting code"); println!("set resetting code");
let mut admin = transaction.to_admin_card(None)?; let mut admin = transaction.to_admin_card(None)?;
admin.set_resetting_code(b"abcdefgh")?; admin.set_resetting_code("abcdefgh")?;
println!("reset retry counter"); println!("reset retry counter");
// ca.reset_retry_counter_pw1("abcdef".as_bytes().to_vec(), None)?; // ca.reset_retry_counter_pw1("abcdef".as_bytes().to_vec(), None)?;
let _res = transaction.reset_user_pin(b"abcdef", b"abcdefgh"); let _res = transaction.reset_user_pin("abcdef", "abcdefgh");
println!("verify good pw1"); println!("verify good pw1");
transaction.verify_user(b"abcdef")?; transaction.verify_user("abcdef")?;
println!("verify bad pw1"); println!("verify bad pw1");
match transaction.verify_user(b"00000000") { match transaction.verify_user("00000000") {
Err(Error::CardStatus(StatusBytes::SecurityStatusNotSatisfied)) => { Err(Error::CardStatus(StatusBytes::SecurityStatusNotSatisfied)) => {
// this is expected // this is expected
} }

View file

@ -93,7 +93,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("factory reset\n"); println!("factory reset\n");
transaction.factory_reset()?; transaction.factory_reset()?;
transaction.verify_admin(b"12345678")?; transaction.verify_admin("12345678")?;
println!("verify for admin ok"); println!("verify for admin ok");
let check = transaction.check_user_verified(); let check = transaction.check_user_verified();
@ -152,7 +152,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let check = transaction.check_user_verified(); let check = transaction.check_user_verified();
println!("has user (pw1/82) been verified yet?\n{check:x?}\n"); println!("has user (pw1/82) been verified yet?\n{check:x?}\n");
transaction.verify_user(b"123456")?; transaction.verify_user("123456")?;
println!("verify for user (pw1/82) ok"); println!("verify for user (pw1/82) ok");
let check = transaction.check_user_verified(); let check = transaction.check_user_verified();
@ -187,7 +187,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut transaction = card.transaction()?; let mut transaction = card.transaction()?;
// Sign // Sign
transaction.verify_user_for_signing(b"123456")?; transaction.verify_user_for_signing("123456")?;
println!("verify for sign (pw1/81) ok\n"); println!("verify for sign (pw1/81) ok\n");
// Use Sign access to card // Use Sign access to card

View file

@ -312,8 +312,8 @@ impl<'a> Card<Transaction<'a>> {
} }
/// Verify the User PIN (for operations such as decryption) /// Verify the User PIN (for operations such as decryption)
pub fn verify_user(&mut self, pin: &[u8]) -> Result<(), Error> { pub fn verify_user(&mut self, pin: &str) -> Result<(), Error> {
self.state.opt.verify_pw1_user(pin)?; self.state.opt.verify_pw1_user(pin.as_bytes())?;
self.state.pw1 = true; self.state.pw1 = true;
Ok(()) Ok(())
} }
@ -333,8 +333,8 @@ impl<'a> Card<Transaction<'a>> {
/// (Note that depending on the configuration of the card, this may enable /// (Note that depending on the configuration of the card, this may enable
/// performing just one signing operation, or an unlimited amount of /// performing just one signing operation, or an unlimited amount of
/// signing operations). /// signing operations).
pub fn verify_user_for_signing(&mut self, pin: &[u8]) -> Result<(), Error> { pub fn verify_user_for_signing(&mut self, pin: &str) -> Result<(), Error> {
self.state.opt.verify_pw1_sign(pin)?; self.state.opt.verify_pw1_sign(pin.as_bytes())?;
// FIXME: depending on card mode, pw1_sign is only usable once // FIXME: depending on card mode, pw1_sign is only usable once
@ -359,8 +359,8 @@ impl<'a> Card<Transaction<'a>> {
} }
/// Verify the Admin PIN. /// Verify the Admin PIN.
pub fn verify_admin(&mut self, pin: &[u8]) -> Result<(), Error> { pub fn verify_admin(&mut self, pin: &str) -> Result<(), Error> {
self.state.opt.verify_pw3(pin)?; self.state.opt.verify_pw3(pin.as_bytes())?;
self.state.pw3 = true; self.state.pw3 = true;
Ok(()) Ok(())
} }
@ -392,8 +392,8 @@ impl<'a> Card<Transaction<'a>> {
} }
/// Change the User PIN, based on the old User PIN. /// Change the User PIN, based on the old User PIN.
pub fn change_user_pin(&mut self, old: &[u8], new: &[u8]) -> Result<(), Error> { pub fn change_user_pin(&mut self, old: &str, new: &str) -> Result<(), Error> {
self.state.opt.change_pw1(old, new) self.state.opt.change_pw1(old.as_bytes(), new.as_bytes())
} }
/// Change the User PIN, based on the old User PIN, with a physical PIN /// Change the User PIN, based on the old User PIN, with a physical PIN
@ -404,13 +404,15 @@ impl<'a> Card<Transaction<'a>> {
} }
/// Change the User PIN, based on the resetting code `rst`. /// Change the User PIN, based on the resetting code `rst`.
pub fn reset_user_pin(&mut self, rst: &[u8], new: &[u8]) -> Result<(), Error> { pub fn reset_user_pin(&mut self, rst: &str, new: &str) -> Result<(), Error> {
self.state.opt.reset_retry_counter_pw1(new, Some(rst)) self.state
.opt
.reset_retry_counter_pw1(new.as_bytes(), Some(rst.as_bytes()))
} }
/// Change the Admin PIN, based on the old Admin PIN. /// Change the Admin PIN, based on the old Admin PIN.
pub fn change_admin_pin(&mut self, old: &[u8], new: &[u8]) -> Result<(), Error> { pub fn change_admin_pin(&mut self, old: &str, new: &str) -> Result<(), Error> {
self.state.opt.change_pw3(old, new) self.state.opt.change_pw3(old.as_bytes(), new.as_bytes())
} }
/// Change the Admin PIN, based on the old Admin PIN, with a physical PIN /// Change the Admin PIN, based on the old Admin PIN, with a physical PIN
@ -431,7 +433,7 @@ impl<'a> Card<Transaction<'a>> {
let pin: OptionalPin = pin.into(); let pin: OptionalPin = pin.into();
if let Some(pin) = pin.0 { if let Some(pin) = pin.0 {
self.verify_user(pin)?; self.verify_user(String::from_utf8_lossy(pin).as_ref())?;
} }
Ok(Card::<User> { Ok(Card::<User> {
@ -450,7 +452,7 @@ impl<'a> Card<Transaction<'a>> {
let pin: OptionalPin = pin.into(); let pin: OptionalPin = pin.into();
if let Some(pin) = pin.0 { if let Some(pin) = pin.0 {
self.verify_user_for_signing(pin)?; self.verify_user_for_signing(String::from_utf8_lossy(pin).as_ref())?;
} }
Ok(Card::<Sign> { Ok(Card::<Sign> {
@ -469,7 +471,7 @@ impl<'a> Card<Transaction<'a>> {
let pin: OptionalPin = pin.into(); let pin: OptionalPin = pin.into();
if let Some(pin) = pin.0 { if let Some(pin) = pin.0 {
self.verify_admin(pin)?; self.verify_admin(String::from_utf8_lossy(pin).as_ref())?;
} }
Ok(Card::<Admin> { Ok(Card::<Admin> {
@ -1137,16 +1139,16 @@ impl Card<Admin<'_, '_>> {
Ok(()) Ok(())
} }
pub fn set_resetting_code(&mut self, pin: &[u8]) -> Result<(), Error> { pub fn set_resetting_code(&mut self, pin: &str) -> Result<(), Error> {
self.card().set_resetting_code(pin) self.card().set_resetting_code(pin.as_bytes())
} }
pub fn set_pso_enc_dec_key(&mut self, key: &[u8]) -> Result<(), Error> { pub fn set_pso_enc_dec_key(&mut self, key: &[u8]) -> Result<(), Error> {
self.card().set_pso_enc_dec_key(key) self.card().set_pso_enc_dec_key(key)
} }
pub fn reset_user_pin(&mut self, new: &[u8]) -> Result<(), Error> { pub fn reset_user_pin(&mut self, new: &str) -> Result<(), Error> {
self.card().reset_retry_counter_pw1(new, None) self.card().reset_retry_counter_pw1(new.as_bytes(), None)
} }
/// Upload a ValidErasedKeyAmalgamation to the card as a specific KeyType. /// Upload a ValidErasedKeyAmalgamation to the card as a specific KeyType.

View file

@ -42,7 +42,7 @@ pub fn make_cert(
key_sig: PublicKey, key_sig: PublicKey,
key_dec: Option<PublicKey>, key_dec: Option<PublicKey>,
key_aut: Option<PublicKey>, key_aut: Option<PublicKey>,
pw1: Option<&[u8]>, pw1: Option<&str>,
pinpad_prompt: &dyn Fn(), pinpad_prompt: &dyn Fn(),
touch_prompt: &(dyn Fn() + Send + Sync), touch_prompt: &(dyn Fn() + Send + Sync),
user_ids: &[String], user_ids: &[String],