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
|
//! Pre-defined `Command` values for the OpenPGP card application
|
||||||
|
|
||||||
use crate::apdu::command::Command;
|
use crate::apdu::command::Command;
|
||||||
use crate::{Tag, Tags};
|
use crate::{ShortTag, Tags};
|
||||||
|
|
||||||
/// 7.2.1 SELECT
|
/// 7.2.1 SELECT
|
||||||
/// (select the OpenPGP application on the card)
|
/// (select the OpenPGP application on the card)
|
||||||
|
@ -19,11 +19,10 @@ pub(crate) fn select_openpgp() -> Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 7.2.6 GET DATA
|
/// 7.2.6 GET DATA
|
||||||
fn get_data<T: Into<Tag>>(tag: T) -> Command {
|
fn get_data<T: Into<ShortTag>>(tag: T) -> Command {
|
||||||
match *tag.into().get() {
|
match tag.into() {
|
||||||
[tag0] => Command::new(0x00, 0xCA, 0, tag0, vec![]),
|
ShortTag::One(tag0) => Command::new(0x00, 0xCA, 0, tag0, vec![]),
|
||||||
[tag0, tag1] => Command::new(0x00, 0xCA, tag0, tag1, vec![]),
|
ShortTag::Two(tag0, tag1) => Command::new(0x00, 0xCA, tag0, tag1, vec![]),
|
||||||
_ => panic!("this should never happen"), // FIXME
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,11 +103,10 @@ pub(crate) fn verify_pw3(pin: Vec<u8>) -> Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 7.2.8 PUT DATA,
|
/// 7.2.8 PUT DATA,
|
||||||
pub(crate) fn put_data<T: Into<Tag>>(tag: T, data: Vec<u8>) -> Command {
|
pub(crate) fn put_data<T: Into<ShortTag>>(tag: T, data: Vec<u8>) -> Command {
|
||||||
match *tag.into().get() {
|
match tag.into() {
|
||||||
[tag0] => Command::new(0x00, 0xda, 0, tag0, data),
|
ShortTag::One(tag0) => Command::new(0x00, 0xda, 0, tag0, data),
|
||||||
[tag0, tag1] => Command::new(0x00, 0xda, tag0, tag1, data),
|
ShortTag::Two(tag0, tag1) => Command::new(0x00, 0xda, tag0, tag1, data),
|
||||||
_ => panic!("this should never happen"), // FIXME
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -330,6 +330,12 @@ pub(crate) enum Tags {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Tags> for Tag {
|
impl From<Tags> for Tag {
|
||||||
|
fn from(t: Tags) -> Self {
|
||||||
|
ShortTag::from(t).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Tags> for ShortTag {
|
||||||
fn from(t: Tags) -> Self {
|
fn from(t: Tags) -> Self {
|
||||||
match t {
|
match t {
|
||||||
// BER identifiers https://en.wikipedia.org/wiki/X.690#BER_encoding
|
// 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)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum PinType {
|
pub enum PinType {
|
||||||
Sign,
|
Sign,
|
||||||
|
@ -434,7 +473,7 @@ pub enum KeyType {
|
||||||
|
|
||||||
impl KeyType {
|
impl KeyType {
|
||||||
/// Get C1/C2/C3/DA values for this KeyTypes, to use as Tag
|
/// 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 {
|
match self {
|
||||||
Self::Signing => Tags::AlgorithmAttributesSignature,
|
Self::Signing => Tags::AlgorithmAttributesSignature,
|
||||||
Self::Decryption => Tags::AlgorithmAttributesDecryption,
|
Self::Decryption => Tags::AlgorithmAttributesDecryption,
|
||||||
|
@ -448,7 +487,7 @@ impl KeyType {
|
||||||
///
|
///
|
||||||
/// (NOTE: these Tags are only used for "PUT DO", but GETting
|
/// (NOTE: these Tags are only used for "PUT DO", but GETting
|
||||||
/// fingerprint information from the card uses the combined Tag C5)
|
/// fingerprint information from the card uses the combined Tag C5)
|
||||||
fn fingerprint_put_tag(&self) -> Tag {
|
fn fingerprint_put_tag(&self) -> ShortTag {
|
||||||
match self {
|
match self {
|
||||||
Self::Signing => Tags::FingerprintSignature,
|
Self::Signing => Tags::FingerprintSignature,
|
||||||
Self::Decryption => Tags::FingerprintDecryption,
|
Self::Decryption => Tags::FingerprintDecryption,
|
||||||
|
@ -462,7 +501,7 @@ impl KeyType {
|
||||||
///
|
///
|
||||||
/// (NOTE: these Tags are only used for "PUT DO", but GETting
|
/// (NOTE: these Tags are only used for "PUT DO", but GETting
|
||||||
/// timestamp information from the card uses the combined Tag CD)
|
/// timestamp information from the card uses the combined Tag CD)
|
||||||
fn timestamp_put_tag(&self) -> Tag {
|
fn timestamp_put_tag(&self) -> ShortTag {
|
||||||
match self {
|
match self {
|
||||||
Self::Signing => Tags::GenerationTimeSignature,
|
Self::Signing => Tags::GenerationTimeSignature,
|
||||||
Self::Decryption => Tags::GenerationTimeDecryption,
|
Self::Decryption => Tags::GenerationTimeDecryption,
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
|
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// 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};
|
use nom::{branch, bytes::complete as bytes, combinator, number::complete as number, sequence};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue