Add ShortTag type to model tags that are guaranteed to be 1 or 2 bytes long.
This commit is contained in:
parent
7854a40b5b
commit
861a051ff5
3 changed files with 59 additions and 15 deletions
|
@ -4,7 +4,7 @@
|
|||
//! Pre-defined `Command` values for the OpenPGP card application
|
||||
|
||||
use crate::apdu::command::Command;
|
||||
use crate::{Tag, Tags};
|
||||
use crate::{ShortTag, Tags};
|
||||
|
||||
/// 7.2.1 SELECT
|
||||
/// (select the OpenPGP application on the card)
|
||||
|
@ -19,11 +19,10 @@ pub(crate) fn select_openpgp() -> Command {
|
|||
}
|
||||
|
||||
/// 7.2.6 GET DATA
|
||||
fn get_data<T: Into<Tag>>(tag: T) -> Command {
|
||||
match *tag.into().get() {
|
||||
[tag0] => Command::new(0x00, 0xCA, 0, tag0, vec![]),
|
||||
[tag0, tag1] => Command::new(0x00, 0xCA, tag0, tag1, vec![]),
|
||||
_ => panic!("this should never happen"), // FIXME
|
||||
fn get_data<T: Into<ShortTag>>(tag: T) -> Command {
|
||||
match tag.into() {
|
||||
ShortTag::One(tag0) => Command::new(0x00, 0xCA, 0, tag0, vec![]),
|
||||
ShortTag::Two(tag0, tag1) => Command::new(0x00, 0xCA, tag0, tag1, vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,11 +103,10 @@ pub(crate) fn verify_pw3(pin: Vec<u8>) -> Command {
|
|||
}
|
||||
|
||||
/// 7.2.8 PUT DATA,
|
||||
pub(crate) fn put_data<T: Into<Tag>>(tag: T, data: Vec<u8>) -> Command {
|
||||
match *tag.into().get() {
|
||||
[tag0] => Command::new(0x00, 0xda, 0, tag0, data),
|
||||
[tag0, tag1] => Command::new(0x00, 0xda, tag0, tag1, data),
|
||||
_ => panic!("this should never happen"), // FIXME
|
||||
pub(crate) fn put_data<T: Into<ShortTag>>(tag: T, data: Vec<u8>) -> Command {
|
||||
match tag.into() {
|
||||
ShortTag::One(tag0) => Command::new(0x00, 0xda, 0, tag0, data),
|
||||
ShortTag::Two(tag0, tag1) => Command::new(0x00, 0xda, tag0, tag1, data),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -330,6 +330,12 @@ pub(crate) enum Tags {
|
|||
}
|
||||
|
||||
impl From<Tags> for Tag {
|
||||
fn from(t: Tags) -> Self {
|
||||
ShortTag::from(t).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Tags> for ShortTag {
|
||||
fn from(t: Tags) -> Self {
|
||||
match t {
|
||||
// BER identifiers https://en.wikipedia.org/wiki/X.690#BER_encoding
|
||||
|
@ -405,6 +411,39 @@ impl From<Tags> for Tag {
|
|||
}
|
||||
}
|
||||
|
||||
/// A ShortTag is a Tlv tag that is guaranteed to be either 1 or 2 bytes long.
|
||||
///
|
||||
/// This covers any tag that can be used in the OpenPGP card context (the spec doesn't describe how
|
||||
/// longer tags might be used.)
|
||||
///
|
||||
/// (The type tlv::Tag will usually/always contain 1 or 2 byte long tags, in this library.
|
||||
/// But its length is not guaranteed by the type system)
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
enum ShortTag {
|
||||
One(u8),
|
||||
Two(u8, u8),
|
||||
}
|
||||
|
||||
impl From<ShortTag> for Tag {
|
||||
fn from(n: ShortTag) -> Self {
|
||||
match n {
|
||||
ShortTag::One(t0) => [t0].into(),
|
||||
ShortTag::Two(t0, t1) => [t0, t1].into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[u8; 1]> for ShortTag {
|
||||
fn from(v: [u8; 1]) -> Self {
|
||||
ShortTag::One(v[0])
|
||||
}
|
||||
}
|
||||
impl From<[u8; 2]> for ShortTag {
|
||||
fn from(v: [u8; 2]) -> Self {
|
||||
ShortTag::Two(v[0], v[1])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum PinType {
|
||||
Sign,
|
||||
|
@ -434,7 +473,7 @@ pub enum KeyType {
|
|||
|
||||
impl KeyType {
|
||||
/// Get C1/C2/C3/DA values for this KeyTypes, to use as Tag
|
||||
fn algorithm_tag(&self) -> Tag {
|
||||
fn algorithm_tag(&self) -> ShortTag {
|
||||
match self {
|
||||
Self::Signing => Tags::AlgorithmAttributesSignature,
|
||||
Self::Decryption => Tags::AlgorithmAttributesDecryption,
|
||||
|
@ -448,7 +487,7 @@ impl KeyType {
|
|||
///
|
||||
/// (NOTE: these Tags are only used for "PUT DO", but GETting
|
||||
/// fingerprint information from the card uses the combined Tag C5)
|
||||
fn fingerprint_put_tag(&self) -> Tag {
|
||||
fn fingerprint_put_tag(&self) -> ShortTag {
|
||||
match self {
|
||||
Self::Signing => Tags::FingerprintSignature,
|
||||
Self::Decryption => Tags::FingerprintDecryption,
|
||||
|
@ -462,7 +501,7 @@ impl KeyType {
|
|||
///
|
||||
/// (NOTE: these Tags are only used for "PUT DO", but GETting
|
||||
/// timestamp information from the card uses the combined Tag CD)
|
||||
fn timestamp_put_tag(&self) -> Tag {
|
||||
fn timestamp_put_tag(&self) -> ShortTag {
|
||||
match self {
|
||||
Self::Signing => Tags::GenerationTimeSignature,
|
||||
Self::Decryption => Tags::GenerationTimeDecryption,
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
//! Tag in a TLV data structure
|
||||
//! Tag in a TLV data structure.
|
||||
//!
|
||||
//! A Tag can span multiple octets, in the OpenPGP card context, only Tags spanning 1 or 2 octets
|
||||
//! should come up. However, this type can deal with arbitrary length Tags.
|
||||
//!
|
||||
//! (The `ShortTag` type models tags that are exactly 1 or 2 octets long)
|
||||
//!
|
||||
//! https://en.wikipedia.org/wiki/X.690#Encoding
|
||||
|
||||
use nom::{branch, bytes::complete as bytes, combinator, number::complete as number, sequence};
|
||||
|
||||
|
|
Loading…
Reference in a new issue