feat: update yubikey to v0.8

This commit is contained in:
2023-08-20 15:24:28 +08:00
parent 9fb0da7d33
commit 7f5a5a7d3c
7 changed files with 470 additions and 641 deletions

View File

@@ -1,9 +1,55 @@
use std::str::FromStr;
use rust_util::XResult;
use yubikey::piv::RetiredSlotId;
use spki::der::{Decode, Encode};
use spki::{ObjectIdentifier, SubjectPublicKeyInfoOwned};
use x509_parser::prelude::FromDer;
use x509_parser::public_key::RSAPublicKey;
use yubikey::piv::{AlgorithmId, RetiredSlotId};
use yubikey::piv::SlotId;
const RSA: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1");
const ECC: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.2.1");
// NIST recommended curves
// secp192r1 {1.2.840.10045.3.1.1}
// secp224r1 {1.3.132.0.33}
// secp256r1 {1.2.840.10045.3.1.7}
// secp384r1 {1.3.132.0.34}
// secp521r1 {1.3.132.0.35}
const ECC_P256: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
const ECC_P384: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.132.0.34");
pub fn get_algorithm_id(public_key_info: &SubjectPublicKeyInfoOwned) -> XResult<AlgorithmId> {
if public_key_info.algorithm.oid == RSA {
let rsa_public_key = opt_result!(
RSAPublicKey::from_der(public_key_info.subject_public_key.raw_bytes()), "Parse public key failed: {}");
let starts_with_0 = rsa_public_key.1.modulus.starts_with(&[0]);
let public_key_bits = (rsa_public_key.1.modulus.len() - if starts_with_0 { 1 } else { 0 }) * 8;
if public_key_bits == 1024 {
return Ok(AlgorithmId::Rsa1024);
}
if public_key_bits == 2048 {
return Ok(AlgorithmId::Rsa2048);
}
return simple_error!("Unknown rsa bits: {}", public_key_bits);
}
if public_key_info.algorithm.oid == ECC {
if let Some(any) = &public_key_info.algorithm.parameters {
let any_parameter_der = opt_result!(any.to_der(), "Bad any parameter: {}");
let any_parameter_oid = opt_result!(ObjectIdentifier::from_der(&any_parameter_der), "Bad any parameter der: {}");
if any_parameter_oid == ECC_P256 {
return Ok(AlgorithmId::EccP256);
}
if any_parameter_oid == ECC_P384 {
return Ok(AlgorithmId::EccP384);
}
return simple_error!("Unknown any parameter oid: {}", any_parameter_oid);
}
}
simple_error!("Unknown algorithm: {}", public_key_info.algorithm.oid)
}
pub fn slot_equals(slot_id: &SlotId, slot: &str) -> bool {
get_slot_id(slot).map(|sid| &sid == slot_id).unwrap_or(false)
}