openpgp-card: Add manage security environment command

This commit is contained in:
Sosthène Guédon 2022-09-28 17:06:36 +02:00
parent dc72a9c6c2
commit 3ca6a514f4
No known key found for this signature in database
GPG key ID: 36DA48A4C827B354
2 changed files with 51 additions and 1 deletions

View file

@ -4,7 +4,7 @@
//! Pre-defined `Command` values for the OpenPGP card application
use crate::apdu::command::Command;
use crate::{ShortTag, Tags};
use crate::{KeyType, ShortTag, Tags};
/// 7.2.1 SELECT
/// (select the OpenPGP application on the card)
@ -241,3 +241,19 @@ pub(crate) fn terminate_df() -> Command {
pub(crate) fn activate_file() -> Command {
Command::new(0x00, 0x44, 0x00, 0x00, vec![])
}
/// 7.2.18 MANAGE SECURITY ENVIRONMENT
pub(crate) fn manage_security_environment(for_operation: KeyType, key_ref: KeyType) -> Command {
let p2 = match for_operation {
KeyType::Authentication => 0xA4,
KeyType::Decryption => 0xB8,
_ => unreachable!(), //FIXME
};
let data = match key_ref {
KeyType::Decryption => vec![0x83, 0x01, 0x02],
KeyType::Authentication => vec![0x83, 0x01, 0x03],
_ => unreachable!(),
};
Command::new(0, 0x22, 0x41, p2, data)
}

View file

@ -588,6 +588,40 @@ impl<'a> OpenPgpTransaction<'a> {
Ok(resp.data().map(|d| d.to_vec())?)
}
/// Set the key to be used for the pso_decipher and the internal_authenticate commands.
///
/// Valid until next reset of of the card or the next call to `select`
/// The only keys that can be configured by this command are the `Decryption` and `Authentication` keys.
///
/// The following first sets the *Authentication* key to be used for [pso_decipher](OpenPgpTransaction::pso_decipher)
/// and then sets the *Decryption* key to be used for [internal_authenticate](OpenPgpTransaction::internal_authenticate).
///
/// ```no_run
/// # use openpgp_card::{KeyType, OpenPgpTransaction};
/// # let mut tx: OpenPgpTransaction<'static> = panic!();
/// tx.manage_security_environment(KeyType::Decryption, KeyType::Authentication)?;
/// tx.manage_security_environment(KeyType::Authentication, KeyType::Decryption)?;
/// # Result::<(), openpgp_card::Error>::Ok(())
/// ```
pub fn manage_security_environment(
&mut self,
for_operation: KeyType,
key_ref: KeyType,
) -> Result<(), Error> {
log::info!("OpenPgpTransaction: manage_security_environment");
if !matches!(for_operation, KeyType::Authentication | KeyType::Decryption)
|| !matches!(key_ref, KeyType::Authentication | KeyType::Decryption)
{
return Err(Error::UnsupportedAlgo("Only Decryption and Authentication keys can be manipulated by manage_security_environment".to_string()));
}
let cmd = commands::manage_security_environment(for_operation, key_ref);
let resp = apdu::send_command(self.tx(), cmd, false)?;
resp.check_ok()?;
Ok(())
}
// --- sign ---
/// Sign `hash`, on the card.