Implement get_cardholder_certificate()/set_cardholder_certificate() and select_data().

This commit is contained in:
Heiko Schaefer 2021-08-25 13:59:53 +02:00
parent 20cfcead02
commit 780b6e724c
2 changed files with 62 additions and 8 deletions

View file

@ -30,32 +30,37 @@ fn get_data(tag: &[u8]) -> Command {
Command::new(0x00, 0xCA, p1, p2, vec![])
}
/// Get DO "Application related data"
/// GET DO "Application related data"
pub(crate) fn get_application_data() -> Command {
get_data(&[0x6E])
}
/// Get DO "private use"
/// GET DO "private use"
pub(crate) fn get_private_do(num: u8) -> Command {
get_data(&[0x01, num])
}
/// Get DO "Uniform resource locator"
/// GET DO "Uniform resource locator"
pub(crate) fn get_url() -> Command {
get_data(&[0x5F, 0x50])
}
/// Get DO "Cardholder related data"
/// GET DO "Cardholder related data"
pub(crate) fn cardholder_related_data() -> Command {
get_data(&[0x65])
}
/// Get DO "Security support template"
/// GET DO "Security support template"
pub(crate) fn get_security_support_template() -> Command {
get_data(&[0x7A])
}
/// Get DO "List of supported Algorithm attributes"
/// GET DO "Cardholder certificate"
pub(crate) fn get_cardholder_certificate() -> Command {
get_data(&[0x7F, 0x21])
}
/// GET DO "List of supported Algorithm attributes"
pub(crate) fn get_algo_list() -> Command {
get_data(&[0xFA])
}
@ -65,6 +70,11 @@ pub(crate) fn get_response() -> Command {
Command::new(0x00, 0xC0, 0x00, 0x00, vec![])
}
/// SELECT DATA
pub(crate) fn select_data(num: u8, data: Vec<u8>) -> Command {
Command::new(0x00, 0xA5, num, 0x04, data)
}
/// VERIFY pin for PW1 (81)
pub(crate) fn verify_pw1_81(pin: Vec<u8>) -> Command {
Command::new(0x00, 0x20, 0x00, 0x81, pin)
@ -103,7 +113,7 @@ pub(crate) fn put_data(tag: &[u8], data: Vec<u8>) -> Command {
Command::new(0x00, 0xda, p1, p2, data)
}
/// Put DO "private use"
/// PUT DO "private use"
pub(crate) fn put_private_do(num: u8, data: Vec<u8>) -> Command {
put_data(&[0x01, num], data)
}
@ -133,6 +143,11 @@ pub(crate) fn put_pw_status(data: Vec<u8>) -> Command {
put_data(&[0xc4], data)
}
/// PUT DO "Cardholder certificate"
pub(crate) fn put_cardholder_certificate(data: Vec<u8>) -> Command {
put_data(&[0x7F, 0x21], data)
}
/// Change PW1 (user pin).
/// This can be used to reset the counter and set a pin.
pub(crate) fn change_pw1(pin: Vec<u8>) -> Command {

View file

@ -195,7 +195,18 @@ impl CardApp {
}
}
// DO "Algorithm Information" (0xFA)
/// Get cardholder certificate (each for AUT, DEC and SIG).
///
/// Call select_data() before calling this fn, to select a particular
/// certificate (if the card supports multiple certificates).
pub fn get_cardholder_certificate(
&mut self,
) -> Result<Response, OpenpgpCardError> {
let cmd = commands::get_cardholder_certificate();
apdu::send_command(&mut self.card_client, cmd, true)?.try_into()
}
/// DO "Algorithm Information" (0xFA)
pub fn list_supported_algo(&mut self) -> Result<Option<AlgoInfo>> {
let resp = apdu::send_command(
&mut self.card_client,
@ -208,6 +219,22 @@ impl CardApp {
Ok(Some(ai))
}
pub fn select_data(
&mut self,
num: u8,
tag: &[u8],
) -> Result<Response, OpenpgpCardError> {
let tlv = Tlv(
Tag(vec![0x60]),
TlvEntry::C(vec![Tlv(Tag(vec![0x5c]), TlvEntry::S(tag.to_vec()))]),
);
let data = tlv.serialize();
let cmd = commands::select_data(num, data);
apdu::send_command(&mut self.card_client, cmd, true)?.try_into()
}
// ----------
/// Delete all state on this OpenPGP card
@ -493,6 +520,18 @@ impl CardApp {
apdu::send_command(self.card(), cmd, false)?.try_into()
}
/// Set cardholder certificate (for AUT, DEC or SIG).
///
/// Call select_data() before calling this fn, to select a particular
/// certificate (if the card supports multiple certificates).
pub fn set_cardholder_certificate(
&mut self,
data: Vec<u8>,
) -> Result<Response, OpenpgpCardError> {
let cmd = commands::put_cardholder_certificate(data);
apdu::send_command(&mut self.card_client, cmd, false)?.try_into()
}
/// Set algorithm attributes [4.4.3.9 Algorithm Attributes]
pub fn set_algorithm_attributes(
&mut self,