Use byte-array data types for url, name, lang in openpgp-card.
This commit is contained in:
parent
80af7000e0
commit
574d7be765
6 changed files with 42 additions and 40 deletions
|
@ -331,29 +331,29 @@ pub fn test_set_user_data(
|
|||
card_client.verify_pw3("12345678")?;
|
||||
|
||||
// name
|
||||
card_client.set_name("Bar<<Foo")?;
|
||||
card_client.set_name(b"Bar<<Foo")?;
|
||||
|
||||
// lang
|
||||
card_client.set_lang("deen")?;
|
||||
card_client.set_lang(b"deen")?;
|
||||
|
||||
// sex
|
||||
card_client.set_sex(Sex::Female)?;
|
||||
|
||||
// url
|
||||
card_client.set_url("https://duckduckgo.com/")?;
|
||||
card_client.set_url(b"https://duckduckgo.com/")?;
|
||||
|
||||
// read all the fields back again, expect equal data
|
||||
let ch = card_client.cardholder_related_data()?;
|
||||
|
||||
assert_eq!(ch.name(), Some("Bar<<Foo"));
|
||||
assert_eq!(ch.name().as_deref(), Some("Bar<<Foo".as_bytes()));
|
||||
assert_eq!(
|
||||
ch.lang().expect("Language setting is None"),
|
||||
&[['d', 'e'], ['e', 'n']]
|
||||
&[[b'd', b'e'], [b'e', b'n']]
|
||||
);
|
||||
assert_eq!(ch.sex(), Some(Sex::Female));
|
||||
|
||||
let url = card_client.url()?;
|
||||
assert_eq!(url, "https://duckduckgo.com/".to_string());
|
||||
assert_eq!(&url, b"https://duckduckgo.com/");
|
||||
|
||||
Ok(vec![])
|
||||
}
|
||||
|
@ -498,7 +498,7 @@ pub fn test_verify(
|
|||
let mut out = vec![];
|
||||
|
||||
// try to set name without verify, assert result is not ok!
|
||||
let res = card_client.set_name("Notverified<<Hello");
|
||||
let res = card_client.set_name("Notverified<<Hello".as_bytes());
|
||||
|
||||
if let Err(Error::CardStatus(s)) = res {
|
||||
assert_eq!(s, StatusBytes::SecurityStatusNotSatisfied);
|
||||
|
@ -519,10 +519,13 @@ pub fn test_verify(
|
|||
Ok(_) => out.push(TestResult::StatusOk),
|
||||
}
|
||||
|
||||
card_client.set_name("Admin<<Hello")?;
|
||||
card_client.set_name(b"Admin<<Hello")?;
|
||||
|
||||
let cardholder = card_client.cardholder_related_data()?;
|
||||
assert_eq!(cardholder.name(), Some("Admin<<Hello"));
|
||||
assert_eq!(
|
||||
cardholder.name().as_deref(),
|
||||
Some("Admin<<Hello".as_bytes())
|
||||
);
|
||||
|
||||
card_client.verify_pw1("123456")?;
|
||||
|
||||
|
@ -537,10 +540,10 @@ pub fn test_verify(
|
|||
Ok(_) => out.push(TestResult::StatusOk),
|
||||
}
|
||||
|
||||
card_client.set_name("There<<Hello")?;
|
||||
card_client.set_name(b"There<<Hello")?;
|
||||
|
||||
let cardholder = card_client.cardholder_related_data()?;
|
||||
assert_eq!(cardholder.name(), Some("There<<Hello"));
|
||||
assert_eq!(cardholder.name(), Some("There<<Hello".as_bytes()));
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ impl<'a> Open<'a> {
|
|||
// --- URL (5f50) ---
|
||||
|
||||
pub fn url(&mut self) -> Result<String> {
|
||||
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<Response, Error> {
|
||||
|
@ -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<Response, Error> {
|
||||
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -284,8 +284,8 @@ pub struct ExtendedLengthInfo {
|
|||
/// Cardholder Related Data (see spec pg. 22)
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct CardholderRelatedData {
|
||||
name: Option<String>,
|
||||
lang: Option<Vec<[char; 2]>>,
|
||||
name: Option<Vec<u8>>,
|
||||
lang: Option<Vec<[u8; 2]>>,
|
||||
sex: Option<Sex>,
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> = tlv
|
||||
.find(&[0x5b].into())
|
||||
.map(|v| String::from_utf8_lossy(&v.serialize()).to_string());
|
||||
let name: Option<Vec<u8>> =
|
||||
tlv.find(&[0x5b].into()).map(|v| v.serialize().to_vec());
|
||||
|
||||
let lang: Option<Vec<[char; 2]>> =
|
||||
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<Vec<[u8; 2]>> = 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<<Foo".to_string()),
|
||||
lang: Some(vec![['d', 'e'], ['e', 'n']]),
|
||||
name: Some("Bar<<Foo".as_bytes().to_vec()),
|
||||
lang: Some(vec![[b'd', b'e'], [b'e', b'n']]),
|
||||
sex: Some(Sex::Female)
|
||||
}
|
||||
);
|
||||
|
|
|
@ -247,10 +247,10 @@ impl<'a> dyn CardClient + 'a {
|
|||
// --- login data (5e) ---
|
||||
|
||||
/// Get URL (5f50)
|
||||
pub fn url(&mut self) -> Result<String> {
|
||||
pub fn url(&mut self) -> Result<Vec<u8>> {
|
||||
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<Response, Error> {
|
||||
let put_name = commands::put_name(name.as_bytes().to_vec());
|
||||
pub fn set_name(&mut self, name: &[u8]) -> Result<Response, Error> {
|
||||
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<Response, Error> {
|
||||
let put_lang = commands::put_lang(lang.as_bytes().to_vec());
|
||||
pub fn set_lang(&mut self, lang: &[u8]) -> Result<Response, Error> {
|
||||
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<Response, Error> {
|
||||
let put_url = commands::put_url(url.as_bytes().to_vec());
|
||||
pub fn set_url(&mut self, url: &[u8]) -> Result<Response, Error> {
|
||||
let put_url = commands::put_url(url.to_vec());
|
||||
apdu::send_command(self, put_url, false)?.try_into()
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,8 @@ fn print_status(ident: Option<String>, 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<String>, verbose: bool) -> Result<()> {
|
|||
if let Some(lang) = crd.lang() {
|
||||
let lang = lang
|
||||
.iter()
|
||||
.map(|lang| lang.iter().collect::<String>())
|
||||
.map(|lang| {
|
||||
lang.iter().map(|&u| char::from(u)).collect::<String>()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
println!("Language preferences '{}'", lang);
|
||||
|
|
Loading…
Reference in a new issue