openpgp-card-sequoia: don't do automatic cardholder name encoding, and document this

Normalize fn name: set_name() -> set_cardholder_name().
This commit is contained in:
Heiko Schaefer 2023-09-04 17:02:20 +02:00
parent 21ba1aadbb
commit 858d91b1f8
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
3 changed files with 37 additions and 21 deletions

View file

@ -320,7 +320,7 @@ pub fn test_set_user_data(
let mut admin = tx.to_admin_card("12345678")?;
// name
admin.set_name("Bar<<Foo")?;
admin.set_cardholder_name("Bar<<Foo")?;
// lang
admin.set_lang(&[['d', 'e'].into(), ['e', 'n'].into()])?;
@ -505,7 +505,7 @@ pub fn test_verify(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutput,
// try to set name without verify, assert result is not ok!
let mut admin = transaction.to_admin_card(None)?;
let res = admin.set_name("Notverified<<Hello");
let res = admin.set_cardholder_name("Notverified<<Hello");
if let Err(Error::CardStatus(s)) = res {
assert_eq!(s, StatusBytes::SecurityStatusNotSatisfied);
@ -528,7 +528,7 @@ pub fn test_verify(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutput,
let mut admin = transaction.to_admin_card(None)?;
admin.set_name("Admin<<Hello")?;
admin.set_cardholder_name("Admin<<Hello")?;
transaction.reload_ard()?;
@ -550,7 +550,7 @@ pub fn test_verify(mut card: Card<Open>, _param: &[&str]) -> Result<TestOutput,
let mut admin = transaction.to_admin_card(None)?;
admin.set_name("There<<Hello")?;
admin.set_cardholder_name("There<<Hello")?;
transaction.reload_ard()?;
let cardholder = transaction.cardholder_related_data()?;

View file

@ -104,7 +104,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!();
admin.set_name("Bar<<Foo")?;
admin.set_cardholder_name("Bar<<Foo")?;
println!("set name - ok");
admin.set_sex(Sex::NotApplicable)?;

View file

@ -132,7 +132,7 @@
//! let mut admin = transaction.to_admin_card("12345678")?;
//!
//! // Set the Name and URL fields on the card
//! admin.set_name("Alice Adams")?;
//! admin.set_cardholder_name("Alice Adams")?;
//! admin.set_url("https://example.org/openpgp.asc")?;
//!
//! # Ok(())
@ -692,22 +692,25 @@ impl<'a> Card<Transaction<'a>> {
s.iter().map(|&c| c as char).collect()
}
/// Get cardholder name as a String (this also normalizes the "<" and "<<" filler chars)
pub fn cardholder_name(&mut self) -> Result<Option<String>, Error> {
/// Get cardholder name.
///
/// This is an ISO 8859-1 (Latin 1) String of up to 39 characters.
///
/// Note that the standard specifies that this field should be encoded
/// according to ISO/IEC 7501-1:
///
/// "The data element consists of surname (e. g. family name and given
/// name(s)) and forename(s) (including name suffix, e. g., Jr. and number).
/// Each item is separated by a ´<´ filler character (3C), the family- and
/// fore-name(s) are separated by two ´<<´ filler characters."
///
/// This library doesn't perform this encoding.
pub fn cardholder_name(&mut self) -> Result<String, Error> {
let crd = self.state.opt.cardholder_related_data()?;
if let Some(name) = crd.name() {
let name = Self::latin1_to_string(name);
// re-format name ("last<<first")
let name: Vec<_> = name.split("<<").collect();
let name = name.iter().cloned().rev().collect::<Vec<_>>().join(" ");
// replace item separators with spaces
let name = name.replace('<', " ");
Ok(Some(name))
} else {
Ok(None)
match crd.name() {
Some(name) => Ok(Self::latin1_to_string(name)),
None => Ok("".to_string()),
}
}
@ -996,7 +999,20 @@ impl<'app, 'open> Card<Admin<'app, 'open>> {
}
impl Card<Admin<'_, '_>> {
pub fn set_name(&mut self, name: &str) -> Result<(), Error> {
/// Set cardholder name.
///
/// This is an ISO 8859-1 (Latin 1) String of max. 39 characters.
///
/// Note that the standard specifies that this field should be encoded according
/// to ISO/IEC 7501-1:
///
/// "The data element consists of surname (e. g. family name and given
/// name(s)) and forename(s) (including name suffix, e. g., Jr. and number).
/// Each item is separated by a ´<´ filler character (3C), the family- and
/// fore-name(s) are separated by two ´<<´ filler characters."
///
/// This library doesn't perform this encoding.
pub fn set_cardholder_name(&mut self, name: &str) -> Result<(), Error> {
// All chars must be in ASCII7
if name.chars().any(|c| !c.is_ascii()) {
return Err(Error::InternalError("Invalid char in name".into()));