From 574d7be7650d35abd0ad3580c6eb7c55368e2c4f Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Tue, 15 Feb 2022 15:30:28 +0100 Subject: [PATCH] Use byte-array data types for url, name, lang in openpgp-card. --- card-functionality/src/tests.rs | 25 ++++++++++++++----------- openpgp-card-sequoia/src/card.rs | 8 ++++---- openpgp-card/src/card_do.rs | 4 ++-- openpgp-card/src/card_do/cardholder.rs | 23 +++++++++-------------- openpgp-card/src/lib.rs | 16 ++++++++-------- tools/src/bin/opgpcard/main.rs | 6 +++++- 6 files changed, 42 insertions(+), 40 deletions(-) diff --git a/card-functionality/src/tests.rs b/card-functionality/src/tests.rs index bded3a1..dcc4b9b 100644 --- a/card-functionality/src/tests.rs +++ b/card-functionality/src/tests.rs @@ -331,29 +331,29 @@ pub fn test_set_user_data( card_client.verify_pw3("12345678")?; // name - card_client.set_name("Bar< out.push(TestResult::StatusOk), } - card_client.set_name("Admin< out.push(TestResult::StatusOk), } - card_client.set_name("There< Open<'a> { // --- URL (5f50) --- pub fn url(&mut self) -> Result { - self.card_client.url() + Ok(String::from_utf8_lossy(&self.card_client.url()?).to_string()) } // --- cardholder related data (65) --- @@ -408,7 +408,7 @@ impl Admin<'_, '_> { return Err(anyhow!("Invalid char in name").into()); }; - self.oc.card_client.set_name(name) + self.oc.card_client.set_name(name.as_bytes()) } pub fn set_lang(&mut self, lang: &str) -> Result { @@ -416,7 +416,7 @@ impl Admin<'_, '_> { return Err(anyhow!("lang too long").into()); } - self.oc.card_client.set_lang(lang) + self.oc.card_client.set_lang(lang.as_bytes()) } pub fn set_sex(&mut self, sex: Sex) -> Result { @@ -438,7 +438,7 @@ impl Admin<'_, '_> { // or if it's within the acceptable length: // send the url update to the card. - self.oc.card_client.set_url(url) + self.oc.card_client.set_url(url.as_bytes()) } else { Err(anyhow!("URL too long").into()) } diff --git a/openpgp-card/src/card_do.rs b/openpgp-card/src/card_do.rs index 49bdb20..9e1aeef 100644 --- a/openpgp-card/src/card_do.rs +++ b/openpgp-card/src/card_do.rs @@ -284,8 +284,8 @@ pub struct ExtendedLengthInfo { /// Cardholder Related Data (see spec pg. 22) #[derive(Debug, PartialEq)] pub struct CardholderRelatedData { - name: Option, - lang: Option>, + name: Option>, + lang: Option>, sex: Option, } diff --git a/openpgp-card/src/card_do/cardholder.rs b/openpgp-card/src/card_do/cardholder.rs index 36fcf97..cd6834d 100644 --- a/openpgp-card/src/card_do/cardholder.rs +++ b/openpgp-card/src/card_do/cardholder.rs @@ -11,11 +11,11 @@ use crate::card_do::{CardholderRelatedData, Sex}; use crate::tlv::{value::Value, Tlv}; impl CardholderRelatedData { - pub fn name(&self) -> Option<&str> { + pub fn name(&self) -> Option<&[u8]> { self.name.as_deref() } - pub fn lang(&self) -> Option<&[[char; 2]]> { + pub fn lang(&self) -> Option<&[[u8; 2]]> { self.lang.as_deref() } @@ -31,17 +31,12 @@ impl TryFrom<&[u8]> for CardholderRelatedData { let value = Value::from(data, true)?; let tlv = Tlv::new([0x65], value); - let name: Option = tlv - .find(&[0x5b].into()) - .map(|v| String::from_utf8_lossy(&v.serialize()).to_string()); + let name: Option> = + tlv.find(&[0x5b].into()).map(|v| v.serialize().to_vec()); - let lang: Option> = - tlv.find(&[0x5f, 0x2d].into()).map(|v| { - v.serialize() - .chunks(2) - .map(|c| [c[0] as char, c[1] as char]) - .collect() - }); + let lang: Option> = tlv + .find(&[0x5f, 0x2d].into()) + .map(|v| v.serialize().chunks(2).map(|c| [c[0], c[1]]).collect()); let sex = tlv .find(&[0x5f, 0x35].into()) @@ -70,8 +65,8 @@ mod test { assert_eq!( ch, CardholderRelatedData { - name: Some("Bar< dyn CardClient + 'a { // --- login data (5e) --- /// Get URL (5f50) - pub fn url(&mut self) -> Result { + pub fn url(&mut self) -> Result> { let resp = apdu::send_command(self, commands::url(), true)?; - Ok(String::from_utf8_lossy(resp.data()?).to_string()) + Ok(resp.data()?.to_vec()) } /// Get cardholder related data (65) @@ -749,13 +749,13 @@ impl<'a> dyn CardClient + 'a { // --- admin --- - pub fn set_name(&mut self, name: &str) -> Result { - let put_name = commands::put_name(name.as_bytes().to_vec()); + pub fn set_name(&mut self, name: &[u8]) -> Result { + let put_name = commands::put_name(name.to_vec()); apdu::send_command(self, put_name, false)?.try_into() } - pub fn set_lang(&mut self, lang: &str) -> Result { - let put_lang = commands::put_lang(lang.as_bytes().to_vec()); + pub fn set_lang(&mut self, lang: &[u8]) -> Result { + let put_lang = commands::put_lang(lang.to_vec()); apdu::send_command(self, put_lang, false)?.try_into() } @@ -764,8 +764,8 @@ impl<'a> dyn CardClient + 'a { apdu::send_command(self, put_sex, false)?.try_into() } - pub fn set_url(&mut self, url: &str) -> Result { - let put_url = commands::put_url(url.as_bytes().to_vec()); + pub fn set_url(&mut self, url: &[u8]) -> Result { + let put_url = commands::put_url(url.to_vec()); apdu::send_command(self, put_url, false)?.try_into() } diff --git a/tools/src/bin/opgpcard/main.rs b/tools/src/bin/opgpcard/main.rs index e45ea6f..08f2f4b 100644 --- a/tools/src/bin/opgpcard/main.rs +++ b/tools/src/bin/opgpcard/main.rs @@ -189,6 +189,8 @@ fn print_status(ident: Option, verbose: bool) -> Result<()> { let crd = open.cardholder_related_data()?; if let Some(name) = crd.name() { + let name = String::from_utf8_lossy(name).to_string(); + print!("Cardholder: "); // This field is silly, maybe ignore it?! @@ -215,7 +217,9 @@ fn print_status(ident: Option, verbose: bool) -> Result<()> { if let Some(lang) = crd.lang() { let lang = lang .iter() - .map(|lang| lang.iter().collect::()) + .map(|lang| { + lang.iter().map(|&u| char::from(u)).collect::() + }) .collect::>() .join(", "); println!("Language preferences '{}'", lang);