Move 'Algo' and related data structures to lib.rs.
Implement the Display trait on Algo and AlgoInfo, for compact printing.
This commit is contained in:
parent
99be1fb7da
commit
608e6533a6
3 changed files with 168 additions and 92 deletions
|
@ -2,21 +2,20 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::fmt;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use apdu::response::Response;
|
||||
use apdu::{response::Response, PcscClient};
|
||||
use card_app::CardApp;
|
||||
use errors::{OpenpgpCardError, SmartcardError};
|
||||
use parse::{
|
||||
algo_attrs::Algo, algo_info::AlgoInfo, application_id::ApplicationId,
|
||||
algo_info::AlgoInfo, application_id::ApplicationId,
|
||||
cardholder::CardHolder, extended_cap::ExtendedCap, extended_cap::Features,
|
||||
extended_length_info::ExtendedLengthInfo, fingerprint,
|
||||
historical::Historical, pw_status::PWStatus, KeySet,
|
||||
};
|
||||
use tlv::Tlv;
|
||||
|
||||
use crate::apdu::PcscClient;
|
||||
use crate::card_app::CardApp;
|
||||
use crate::errors::{OpenpgpCardError, SmartcardError};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub mod apdu;
|
||||
mod card;
|
||||
pub mod card_app;
|
||||
|
@ -66,6 +65,139 @@ impl CardCaps {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Algo {
|
||||
Rsa(RsaAttrs),
|
||||
Ecc(EccAttrs),
|
||||
Unknown(Vec<u8>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Algo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Rsa(rsa) => {
|
||||
write!(f, "RSA {}, {} ", rsa.len_n, rsa.len_e)
|
||||
}
|
||||
Self::Ecc(ecc) => {
|
||||
write!(f, "{:?} ({:?})", ecc.curve, ecc.ecc_type)
|
||||
}
|
||||
Self::Unknown(u) => {
|
||||
write!(f, "Unknown: {:?}", u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct RsaAttrs {
|
||||
pub len_n: u16,
|
||||
pub len_e: u16,
|
||||
pub import_format: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct EccAttrs {
|
||||
pub ecc_type: EccType,
|
||||
pub curve: Curve,
|
||||
pub import_format: Option<u8>,
|
||||
}
|
||||
|
||||
impl EccAttrs {
|
||||
pub fn new(
|
||||
ecc_type: EccType,
|
||||
curve: Curve,
|
||||
import_format: Option<u8>,
|
||||
) -> Self {
|
||||
Self {
|
||||
ecc_type,
|
||||
curve,
|
||||
import_format,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn oid(&self) -> &[u8] {
|
||||
self.curve.oid()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Curve {
|
||||
NistP256r1,
|
||||
NistP384r1,
|
||||
NistP521r1,
|
||||
BrainpoolP256r1,
|
||||
BrainpoolP384r1,
|
||||
BrainpoolP512r1,
|
||||
Secp256k1,
|
||||
Ed25519,
|
||||
Cv25519,
|
||||
Ed448,
|
||||
X448,
|
||||
}
|
||||
|
||||
impl Curve {
|
||||
pub fn oid(&self) -> &[u8] {
|
||||
use Curve::*;
|
||||
match self {
|
||||
NistP256r1 => &[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07],
|
||||
NistP384r1 => &[0x2B, 0x81, 0x04, 0x00, 0x22],
|
||||
NistP521r1 => &[0x2B, 0x81, 0x04, 0x00, 0x23],
|
||||
BrainpoolP256r1 => {
|
||||
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07]
|
||||
}
|
||||
BrainpoolP384r1 => {
|
||||
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b]
|
||||
}
|
||||
BrainpoolP512r1 => {
|
||||
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d]
|
||||
}
|
||||
Secp256k1 => &[0x2B, 0x81, 0x04, 0x00, 0x0A],
|
||||
Ed25519 => &[0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
|
||||
Cv25519 => {
|
||||
&[0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01]
|
||||
}
|
||||
Ed448 => &[0x2b, 0x65, 0x71],
|
||||
X448 => &[0x2b, 0x65, 0x6f],
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME impl trait?
|
||||
pub fn from(oid: &[u8]) -> Option<Self> {
|
||||
use Curve::*;
|
||||
match oid {
|
||||
[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07] => {
|
||||
Some(NistP256r1)
|
||||
}
|
||||
[0x2B, 0x81, 0x04, 0x00, 0x22] => Some(NistP384r1),
|
||||
[0x2B, 0x81, 0x04, 0x00, 0x23] => Some(NistP521r1),
|
||||
|
||||
[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07] => {
|
||||
Some(BrainpoolP256r1)
|
||||
}
|
||||
[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b] => {
|
||||
Some(BrainpoolP384r1)
|
||||
}
|
||||
[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d] => {
|
||||
Some(BrainpoolP512r1)
|
||||
}
|
||||
|
||||
[0x2B, 0x81, 0x04, 0x00, 0x0A] => Some(Secp256k1),
|
||||
|
||||
[0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01] => {
|
||||
Some(Ed25519)
|
||||
}
|
||||
[0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01] => {
|
||||
Some(Cv25519)
|
||||
}
|
||||
|
||||
[0x2b, 0x65, 0x71] => Some(Ed448),
|
||||
[0x2b, 0x65, 0x6f] => Some(X448),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An OpenPGP key generation Time
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct KeyGeneration(u32);
|
||||
|
@ -133,6 +265,14 @@ pub trait CardUploadableKey {
|
|||
pub enum PublicKeyMaterial {
|
||||
R(RSAPub),
|
||||
E(EccPub),
|
||||
T(Tffon), // 25519
|
||||
}
|
||||
|
||||
/// ed25519/cv25519
|
||||
#[derive(Debug)]
|
||||
pub struct Tffon {
|
||||
/// Public key
|
||||
pub pk: Vec<u8>,
|
||||
}
|
||||
|
||||
/// RSA-specific container for public key material from an OpenPGP card.
|
||||
|
|
|
@ -9,84 +9,7 @@ use nom::bytes::complete::tag;
|
|||
use nom::combinator::map;
|
||||
use nom::{branch, bytes::complete as bytes, number::complete as number};
|
||||
|
||||
use crate::{parse, EccType};
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Algo {
|
||||
Rsa(RsaAttrs),
|
||||
Ecc(EccAttrs),
|
||||
Unknown(Vec<u8>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct RsaAttrs {
|
||||
pub len_n: u16,
|
||||
pub len_e: u16,
|
||||
pub import_format: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct EccAttrs {
|
||||
pub ecc_type: EccType,
|
||||
pub oid: Vec<u8>,
|
||||
pub import_format: Option<u8>,
|
||||
}
|
||||
|
||||
impl EccAttrs {
|
||||
pub fn new(
|
||||
ecc_type: EccType,
|
||||
curve: Curve,
|
||||
import_format: Option<u8>,
|
||||
) -> Self {
|
||||
Self {
|
||||
ecc_type,
|
||||
oid: curve.oid().to_vec(),
|
||||
import_format,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Curve {
|
||||
NistP256r1,
|
||||
NistP384r1,
|
||||
NistP521r1,
|
||||
BrainpoolP256r1,
|
||||
BrainpoolP384r1,
|
||||
BrainpoolP512r1,
|
||||
Secp256k1,
|
||||
Ed25519,
|
||||
Cv25519,
|
||||
Ed448,
|
||||
X448,
|
||||
}
|
||||
|
||||
impl Curve {
|
||||
pub fn oid(&self) -> &[u8] {
|
||||
use Curve::*;
|
||||
match self {
|
||||
NistP256r1 => &[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07],
|
||||
NistP384r1 => &[0x2B, 0x81, 0x04, 0x00, 0x22],
|
||||
NistP521r1 => &[0x2B, 0x81, 0x04, 0x00, 0x23],
|
||||
BrainpoolP256r1 => {
|
||||
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07]
|
||||
}
|
||||
BrainpoolP384r1 => {
|
||||
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b]
|
||||
}
|
||||
BrainpoolP512r1 => {
|
||||
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d]
|
||||
}
|
||||
Secp256k1 => &[0x2B, 0x81, 0x04, 0x00, 0x0A],
|
||||
Ed25519 => &[0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
|
||||
Cv25519 => {
|
||||
&[0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01]
|
||||
}
|
||||
Ed448 => &[0x2b, 0x65, 0x71],
|
||||
X448 => &[0x2b, 0x65, 0x6f],
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate::{parse, Algo, Curve, EccAttrs, EccType, RsaAttrs};
|
||||
|
||||
fn parse_oid_cv25519(input: &[u8]) -> nom::IResult<&[u8], Curve> {
|
||||
map(tag(Curve::Cv25519.oid()), |_| Curve::Cv25519)(input)
|
||||
|
|
|
@ -7,10 +7,10 @@ use anyhow::Result;
|
|||
use nom::branch::alt;
|
||||
use nom::combinator::map;
|
||||
use nom::{branch, bytes::complete as bytes, combinator, multi, sequence};
|
||||
use std::fmt;
|
||||
|
||||
use crate::parse::algo_attrs;
|
||||
use crate::parse::algo_attrs::Algo;
|
||||
use crate::KeyType;
|
||||
use crate::{Algo, KeyType};
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct AlgoInfo(Vec<(KeyType, Algo)>);
|
||||
|
@ -25,6 +25,21 @@ impl AlgoInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AlgoInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for (kt, a) in &self.0 {
|
||||
let kt = match kt {
|
||||
KeyType::Signing => "SIG",
|
||||
KeyType::Decryption => "DEC",
|
||||
KeyType::Authentication => "AUT",
|
||||
KeyType::Attestation => "ATT",
|
||||
};
|
||||
writeln!(f, "{}: {} ", kt, a)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn key_type(input: &[u8]) -> nom::IResult<&[u8], KeyType> {
|
||||
alt((
|
||||
map(bytes::tag([0xc1]), |_| KeyType::Signing),
|
||||
|
@ -88,12 +103,10 @@ impl TryFrom<&[u8]> for AlgoInfo {
|
|||
mod test {
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use crate::parse::algo_attrs::Algo::*;
|
||||
use crate::parse::algo_attrs::Curve::*;
|
||||
use crate::parse::algo_attrs::*;
|
||||
use crate::parse::algo_info::AlgoInfo;
|
||||
use crate::EccType::*;
|
||||
use crate::KeyType::*;
|
||||
use crate::{
|
||||
Algo::*, Curve::*, EccAttrs, EccType::*, KeyType::*, RsaAttrs,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_gnuk() {
|
||||
|
|
Loading…
Reference in a new issue