From 013af97c2313b4368e2c494edce3d5d30c5b60cf Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Sun, 22 Aug 2021 18:59:54 +0200 Subject: [PATCH] Implement get_private() and set_private(). --- card-functionality/src/other.rs | 10 +++++++--- card-functionality/src/tests.rs | 33 +++++++++++++++++++++++++++++++ openpgp-card/src/apdu/commands.rs | 10 ++++++++++ openpgp-card/src/card_app.rs | 25 +++++++++++++++++++++-- 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/card-functionality/src/other.rs b/card-functionality/src/other.rs index 01c8936..03c527f 100644 --- a/card-functionality/src/other.rs +++ b/card-functionality/src/other.rs @@ -40,9 +40,13 @@ fn main() -> Result<()> { // let verify_out = run_test(&mut card, test_verify, &[])?; // println!(" {:x?}", verify_out); - print!("PW Status bytes"); - let pw_out = run_test(&mut card, test_pw_status, &[])?; - println!(" {:x?}", pw_out); + // print!("PW Status bytes"); + // let pw_out = run_test(&mut card, test_pw_status, &[])?; + // println!(" {:x?}", pw_out); + + print!("Private data"); + let priv_out = run_test(&mut card, test_private_data, &[])?; + println!(" {:x?}", priv_out); println!(); } diff --git a/card-functionality/src/tests.rs b/card-functionality/src/tests.rs index 582a9a3..54e5853 100644 --- a/card-functionality/src/tests.rs +++ b/card-functionality/src/tests.rs @@ -352,6 +352,39 @@ pub fn test_set_user_data( Ok(vec![]) } +pub fn test_private_data( + ca: &mut CardApp, + _param: &[&str], +) -> Result { + let mut out = vec![]; + + println!(); + + let d = ca.get_private(1)?; + println!("data 1 {:?}", d); + + ca.verify_pw1("123456")?; + + ca.set_private(1, "Foo bar1!".as_bytes().to_vec())?; + ca.set_private(3, "Foo bar3!".as_bytes().to_vec())?; + + ca.verify_pw3("12345678")?; + + ca.set_private(2, "Foo bar2!".as_bytes().to_vec())?; + ca.set_private(4, "Foo bar4!".as_bytes().to_vec())?; + + let d = ca.get_private(1)?; + println!("data 1 {:?}", d); + let d = ca.get_private(2)?; + println!("data 2 {:?}", d); + let d = ca.get_private(3)?; + println!("data 3 {:?}", d); + let d = ca.get_private(4)?; + println!("data 4 {:?}", d); + + Ok(out) +} + pub fn test_pw_status( ca: &mut CardApp, _param: &[&str], diff --git a/openpgp-card/src/apdu/commands.rs b/openpgp-card/src/apdu/commands.rs index aafeed1..c552f7a 100644 --- a/openpgp-card/src/apdu/commands.rs +++ b/openpgp-card/src/apdu/commands.rs @@ -35,6 +35,11 @@ pub(crate) fn get_application_data() -> Command { get_data(&[0x6E]) } +/// Get DO "private use" +pub(crate) fn get_private_do(num: u8) -> Command { + get_data(&[0x01, num]) +} + /// Get DO "Uniform resource locator" pub(crate) fn get_url() -> Command { get_data(&[0x5F, 0x50]) @@ -98,6 +103,11 @@ pub(crate) fn put_data(tag: &[u8], data: Vec) -> Command { Command::new(0x00, 0xda, p1, p2, data) } +/// Put DO "private use" +pub(crate) fn put_private_do(num: u8, data: Vec) -> Command { + put_data(&[0x01, num], data) +} + /// PUT DO Name pub(crate) fn put_name(name: Vec) -> Command { put_data(&[0x5b], name) diff --git a/openpgp-card/src/card_app.rs b/openpgp-card/src/card_app.rs index f14fe7f..0b023b8 100644 --- a/openpgp-card/src/card_app.rs +++ b/openpgp-card/src/card_app.rs @@ -93,7 +93,7 @@ impl CardApp { .try_into() } - // --- application data --- + // --- get data --- /// Load "application related data". /// @@ -110,7 +110,15 @@ impl CardApp { Ok(ApplicationRelatedData(Tlv(Tag::from([0x6E]), entry))) } - // --- + /// Get data from "private use" DO, `num` must be between 1 and 4. + pub fn get_private(&mut self, num: u8) -> Result> { + assert!(num >= 1 && num <= 4); + + let cmd = commands::get_private_do(num); + let resp = apdu::send_command(&mut self.card_client, cmd, true)?; + + Ok(resp.data()?.to_vec()) + } pub fn get_ca_fingerprints() { unimplemented!() @@ -385,6 +393,19 @@ impl CardApp { // --- admin --- + /// Set data of "private use" DO, `num` must be between 1 and 4. + /// Access condition: + /// - 1/3 need PW1 (82) + /// - 2/4 need PW3 + pub fn set_private(&mut self, num: u8, data: Vec) -> Result> { + assert!(num >= 1 && num <= 4); + + let cmd = commands::put_private_do(num, data); + let resp = apdu::send_command(&mut self.card_client, cmd, true)?; + + Ok(resp.data()?.to_vec()) + } + pub fn set_name( &mut self, name: &str,