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
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
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::{
|
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,
|
cardholder::CardHolder, extended_cap::ExtendedCap, extended_cap::Features,
|
||||||
extended_length_info::ExtendedLengthInfo, fingerprint,
|
extended_length_info::ExtendedLengthInfo, fingerprint,
|
||||||
historical::Historical, pw_status::PWStatus, KeySet,
|
historical::Historical, pw_status::PWStatus, KeySet,
|
||||||
};
|
};
|
||||||
use tlv::Tlv;
|
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;
|
pub mod apdu;
|
||||||
mod card;
|
mod card;
|
||||||
pub mod card_app;
|
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
|
/// An OpenPGP key generation Time
|
||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
pub struct KeyGeneration(u32);
|
pub struct KeyGeneration(u32);
|
||||||
|
@ -133,6 +265,14 @@ pub trait CardUploadableKey {
|
||||||
pub enum PublicKeyMaterial {
|
pub enum PublicKeyMaterial {
|
||||||
R(RSAPub),
|
R(RSAPub),
|
||||||
E(EccPub),
|
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.
|
/// 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::combinator::map;
|
||||||
use nom::{branch, bytes::complete as bytes, number::complete as number};
|
use nom::{branch, bytes::complete as bytes, number::complete as number};
|
||||||
|
|
||||||
use crate::{parse, EccType};
|
use crate::{parse, Algo, Curve, EccAttrs, EccType, RsaAttrs};
|
||||||
|
|
||||||
#[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],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_oid_cv25519(input: &[u8]) -> nom::IResult<&[u8], Curve> {
|
fn parse_oid_cv25519(input: &[u8]) -> nom::IResult<&[u8], Curve> {
|
||||||
map(tag(Curve::Cv25519.oid()), |_| Curve::Cv25519)(input)
|
map(tag(Curve::Cv25519.oid()), |_| Curve::Cv25519)(input)
|
||||||
|
|
|
@ -7,10 +7,10 @@ use anyhow::Result;
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::{branch, bytes::complete as bytes, combinator, multi, sequence};
|
use nom::{branch, bytes::complete as bytes, combinator, multi, sequence};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use crate::parse::algo_attrs;
|
use crate::parse::algo_attrs;
|
||||||
use crate::parse::algo_attrs::Algo;
|
use crate::{Algo, KeyType};
|
||||||
use crate::KeyType;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct AlgoInfo(Vec<(KeyType, Algo)>);
|
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> {
|
fn key_type(input: &[u8]) -> nom::IResult<&[u8], KeyType> {
|
||||||
alt((
|
alt((
|
||||||
map(bytes::tag([0xc1]), |_| KeyType::Signing),
|
map(bytes::tag([0xc1]), |_| KeyType::Signing),
|
||||||
|
@ -88,12 +103,10 @@ impl TryFrom<&[u8]> for AlgoInfo {
|
||||||
mod test {
|
mod test {
|
||||||
use std::convert::TryFrom;
|
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::parse::algo_info::AlgoInfo;
|
||||||
use crate::EccType::*;
|
use crate::{
|
||||||
use crate::KeyType::*;
|
Algo::*, Curve::*, EccAttrs, EccType::*, KeyType::*, RsaAttrs,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gnuk() {
|
fn test_gnuk() {
|
||||||
|
|
Loading…
Reference in a new issue