Skip to content

Commit b611358

Browse files
authored
PIV unlock should fetch management key alg instead of using firmware default (#36)
* PIV unlock should fetch management key alg instead of using firmware default * Handle unsupported metadata * Comment
1 parent 0ba3b06 commit b611358

1 file changed

Lines changed: 22 additions & 3 deletions

File tree

src/yubikey/piv/management.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use crate::{PublicKey, TouchRequirement};
33
use ring::digest;
44

55
use yubikey::certificate::Certificate;
6-
use yubikey::piv::{attest, sign_data as yk_sign_data, AlgorithmId, SlotId};
6+
use yubikey::piv::{
7+
attest, sign_data as yk_sign_data, AlgorithmId, ManagementSlotId, SlotAlgorithmId, SlotId,
8+
};
79
use yubikey::{MgmAlgorithmId, MgmKey, Serial, YubiKey};
810
use yubikey::{PinPolicy, TouchPolicy};
911

@@ -209,11 +211,28 @@ impl super::Yubikey {
209211
Ok(())
210212
}
211213

212-
fn management_key_from_bytes(&self, mgm_key: &[u8]) -> Result<MgmKey> {
213-
let alg = MgmKey::get_default(&self.yk)?.algorithm_id();
214+
fn management_key_from_bytes(&mut self, mgm_key: &[u8]) -> Result<MgmKey> {
215+
// Use the configured algorithm when metadata is available. Older
216+
// devices fall back to their default algorithm.
217+
let alg = match self.management_key_algorithm()? {
218+
Some(alg) => alg,
219+
None => MgmKey::get_default(&self.yk)?.algorithm_id(),
220+
};
214221
MgmKey::from_bytes(mgm_key, Some(alg)).map_err(|_| Error::InvalidManagementKey)
215222
}
216223

224+
/// The algorithm the management key is currently set to, if the device
225+
/// exposes it via metadata.
226+
fn management_key_algorithm(&mut self) -> Result<Option<MgmAlgorithmId>> {
227+
let slot = SlotId::Management(ManagementSlotId::Management);
228+
match yubikey::piv::metadata(&mut self.yk, slot).map(|m| m.algorithm) {
229+
Ok(SlotAlgorithmId::Management(alg)) => Ok(Some(alg)),
230+
Ok(_) => Ok(None),
231+
Err(yubikey::Error::NotSupported) => Ok(None),
232+
Err(e) => Err(e.into()),
233+
}
234+
}
235+
217236
/// Fetch the serial number of the Yubikey
218237
pub fn serial(&mut self) -> Result<Serial> {
219238
let serial = self.yk.serial();

0 commit comments

Comments
 (0)