From 14143ee182208b7d2ec1de81bb6575bbe06bf34a Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Tue, 24 May 2022 14:24:22 +0200 Subject: [PATCH] Implement next_cardholder_certificate() to read successive cardholder certificates from the card. --- openpgp-card-sequoia/src/card.rs | 8 ++++++++ openpgp-card/src/apdu/commands.rs | 5 +++++ openpgp-card/src/openpgp.rs | 11 +++++++++++ 3 files changed, 24 insertions(+) diff --git a/openpgp-card-sequoia/src/card.rs b/openpgp-card-sequoia/src/card.rs index 238ab6e..1484f15 100644 --- a/openpgp-card-sequoia/src/card.rs +++ b/openpgp-card-sequoia/src/card.rs @@ -271,6 +271,14 @@ impl<'a> Open<'a> { self.opt.security_support_template() } + /// "GET NEXT DATA" for the DO cardholder certificate. + /// + /// Cardholder certificate data for multiple slots can be read from the card by first calling + /// cardholder_certificate(), followed by up to two calls to next_cardholder_certificate(). + pub fn next_cardholder_certificate(&mut self) -> Result, Error> { + self.opt.next_cardholder_certificate() + } + // DO "Algorithm Information" (0xFA) pub fn algorithm_information(&mut self) -> Result, Error> { // The DO "Algorithm Information" (Tag FA) shall be present if diff --git a/openpgp-card/src/apdu/commands.rs b/openpgp-card/src/apdu/commands.rs index 7f2fa8f..b50c193 100644 --- a/openpgp-card/src/apdu/commands.rs +++ b/openpgp-card/src/apdu/commands.rs @@ -62,6 +62,11 @@ pub(crate) fn cardholder_certificate() -> Command { get_data(Tags::CardholderCertificate) } +/// GET NEXT DATA for DO "Cardholder certificate" +pub(crate) fn get_next_cardholder_certificate() -> Command { + Command::new(0x00, 0xCC, 0x7f, 0x21, vec![]) +} + /// GET DO "Algorithm Information" pub(crate) fn algo_info() -> Command { get_data(Tags::AlgorithmInformation) diff --git a/openpgp-card/src/openpgp.rs b/openpgp-card/src/openpgp.rs index 338db43..1835a16 100644 --- a/openpgp-card/src/openpgp.rs +++ b/openpgp-card/src/openpgp.rs @@ -149,6 +149,17 @@ impl<'a> OpenPgpTransaction<'a> { apdu::send_command(self.tx(), cmd, true)?.try_into() } + /// Call "GET NEXT DATA" for the DO cardholder certificate. + /// + /// Cardholder certificate data for multiple slots can be read from the card by first calling + /// cardholder_certificate(), followed by up to two calls to next_cardholder_certificate(). + pub fn next_cardholder_certificate(&mut self) -> Result, Error> { + log::info!("OpenPgpTransaction: next_cardholder_certificate"); + + let cmd = commands::get_next_cardholder_certificate(); + apdu::send_command(self.tx(), cmd, true)?.try_into() + } + /// Get "Algorithm Information" pub fn algorithm_information(&mut self) -> Result, Error> { log::info!("OpenPgpTransaction: algorithm_information");