Merge branch 'feature-mse' into 'main'

Implement support for the MANAGE SECURITY ENVIRONMENT command

See merge request openpgp-card/openpgp-card!8
This commit is contained in:
Heiko 2022-09-30 13:56:38 +00:00
commit aa754dfcc1
3 changed files with 61 additions and 1 deletions

View file

@ -349,6 +349,16 @@ impl<'a> Open<'a> {
self.opt.algorithm_information() self.opt.algorithm_information()
} }
/// "MANAGE SECURITY ENVIRONMENT"
/// Make `key_ref` usable for the operation normally done by the key designated by `for_operation`
pub fn manage_security_environment(
&mut self,
for_operation: KeyType,
key_ref: KeyType,
) -> Result<(), Error> {
self.opt.manage_security_environment(for_operation, key_ref)
}
/// Get "Attestation Certificate (Yubico)" /// Get "Attestation Certificate (Yubico)"
pub fn attestation_certificate(&mut self) -> Result<Vec<u8>, Error> { pub fn attestation_certificate(&mut self) -> Result<Vec<u8>, Error> {
self.opt.attestation_certificate() self.opt.attestation_certificate()

View file

@ -4,7 +4,7 @@
//! Pre-defined `Command` values for the OpenPGP card application //! Pre-defined `Command` values for the OpenPGP card application
use crate::apdu::command::Command; use crate::apdu::command::Command;
use crate::{ShortTag, Tags}; use crate::{KeyType, ShortTag, Tags};
/// 7.2.1 SELECT /// 7.2.1 SELECT
/// (select the OpenPGP application on the card) /// (select the OpenPGP application on the card)
@ -241,3 +241,19 @@ pub(crate) fn terminate_df() -> Command {
pub(crate) fn activate_file() -> Command { pub(crate) fn activate_file() -> Command {
Command::new(0x00, 0x44, 0x00, 0x00, vec![]) 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())?) 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 ---
/// Sign `hash`, on the card. /// Sign `hash`, on the card.