extern crate alloc;
#[cfg(not(feature = "validate"))]
use alloc::vec;
use arbitrary_int::{u10, u6};
use nom::{
bytes::streaming::take,
combinator::{into, map, map_res},
error::{ErrorKind, FromExternalError, ParseError},
ErrorConvert, Needed, Parser,
};
use num::{FromPrimitive, Integer};
#[allow(clippy::wildcard_imports)]
use crate::{util::cast_nom_err, *};
/// Returns the value of a decoding attempt
#[derive(Debug, PartialEq)]
pub struct Decoded<T: Debug + PartialEq> {
/// indicates the number of bytes that were consumed by the decoder
pub bytes_consumed: usize,
/// the decoded return value
pub decoded: T,
}
/// Decoder for individual fields of the GeoNetworking header from binary data
///
/// This trait is implemented for all higher-order fields of the GeoNetworking header:
///
/// - [`Packet`]
/// - [`en302636_4_1::BasicHeader`]
/// - [`en302636_4_1::CommonHeader`]
/// - [`ieee1609dot2::Ieee1609Dot2Data`] (a.k.a. Secured Header)
/// - [`en302636_4_1::GeoUnicast`]
/// - [`en302636_4_1::TopologicallyScopedBroadcast`]
/// - [`en302636_4_1::SingleHopBroadcast`]
/// - [`en302636_4_1::GeoBroadcast`]
/// - [`en302636_4_1::GeoAnycast`]
/// - [`en302636_4_1::Beacon`]
/// - [`en302636_4_1::LSRequest`]
/// - [`en302636_4_1::LSReply`]
///
/// # Example
/// ```rust
/// use geonetworking::*;
/// let data: &'static [u8] = &[
/// 0x12, 0x00, 0x15, 0x01, 0x03, 0x81, 0x00, 0x40, 0x03, 0x80, 0x82, 0x02, 0x7c, 0x20,
/// 0x51, 0x01, 0x00, 0x02, 0x58, 0x01, 0x00, 0x12, 0x52, 0x00, 0x00, 0x3c, 0x00, 0x04,
/// 0xe5, 0x48, 0x10, 0xc7, 0x2e, 0x71, 0x25, 0xab, 0x00, 0x1f, 0xeb, 0xef, 0x74, 0x05,
/// 0xf2, 0xaf, 0x27, 0x80, 0x00, 0x00, 0x00,
/// ];
/// let result = en302636_4_1::BasicHeader::decode(data).unwrap();
/// assert_eq!(
/// result,
/// Decoded {
/// bytes_consumed: 4,
/// decoded: en302636_4_1::BasicHeader::try_new(
/// 1,
/// en302636_4_1::NextAfterBasic::SecuredPacket,
/// en302636_4_1::Lifetime(21),
/// 1
/// ).expect("Failed to create BasicHeader")
/// }
/// );
/// ```
pub trait Decode<'s>: Sized + Debug + PartialEq {
/// Decodes the data type from a binary buffer
///
/// # Errors
/// Returns a [`DecodeError`] when parsing has failed
fn decode<'input: 's, I: Into<&'input [u8]>>(
input: I,
) -> Result<Decoded<Self>, DecodeError<&'input [u8]>>;
}
macro_rules! decode {
($typ:ty) => {
impl<'s> Decode<'s> for $typ {
fn decode<'input: 's, I: Into<&'input [u8]>>(
input: I,
) -> Result<Decoded<Self>, DecodeError<&'input [u8]>> {
let input = input.into();
let (remaining, header) = <$typ>::decode_bytewise(input)?;
Ok(Decoded {
bytes_consumed: input.len() - remaining.len(),
decoded: header,
})
}
}
};
}
decode!(Packet<'s>);
decode!(en302636_4_1::BasicHeader);
decode!(en302636_4_1::CommonHeader);
decode!(ieee1609dot2::Ieee1609Dot2Data<'s>);
decode!(en302636_4_1::GeoUnicast);
decode!(en302636_4_1::TopologicallyScopedBroadcast);
decode!(en302636_4_1::SingleHopBroadcast);
decode!(en302636_4_1::GeoBroadcast);
decode!(en302636_4_1::Beacon);
decode!(en302636_4_1::LSRequest);
decode!(en302636_4_1::LSReply);
decode!(ieee1609dot2::Certificate<'s>);
decode!(ieee1609dot2::ToBeSignedData<'s>);
/// Helper struct for decoding unsecured GeoNetworking headers from JSON.
/// This crate focuses on zero-copy decoding from binary packets,
/// therefore, JSON deserialization features are limited to a
/// subset of GeoNetworking types.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
pub struct UnsecuredHeader {
pub basic: en302636_4_1::BasicHeader,
pub common: en302636_4_1::CommonHeader,
pub extended: Option<en302636_4_1::ExtendedHeader>,
}
impl UnsecuredHeader {
#[cfg(feature = "json")]
/// Tries to deserialize an unsecured GeoNetworking header from JSON.
/// ### Usage
/// ```rust
/// # use geonetworking::*;
/// let json_header = r#"{"basic":{"version":1,"next_header":"CommonHeader","reserved":0,"lifetime":80,"remaining_hop_limit":1},"secured":null,"common":{"next_header":"BTPB","reserved_1":0,"header_type_and_subtype":{"TopologicallyScopedBroadcast":"SingleHop"},"traffic_class":{"store_carry_forward":false,"channel_offload":false,"traffic_class_id":2},"flags":[false,false,false,false,false,false,false,false],"payload_length":8,"maximum_hop_limit":1,"reserved_2":0},"extended":{"SHB":{"source_position_vector":{"gn_address":{"manually_configured":false,"station_type":"Unknown","reserved":262,"address":[0,96,224,105,87,141]},"timestamp":542947520,"latitude":535574568,"longitude":99765648,"position_accuracy":false,"speed":680,"heading":2122},"media_dependent_data":[127,0,184,0]}}}"#;
/// let payload: &'static [u8] = &[0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03];
/// let unsecured_header = UnsecuredHeader::from_json(json_header).unwrap();
/// let unsecured_packet: Packet = unsecured_header.with_payload(payload).expect("REASON");
/// ```
///
/// # Errors
/// Returns a [`DecodeError`] when parsing failed
pub fn from_json(json: &str) -> Result<Self, DecodeError<&str>> {
serde_json::from_str(json).map_err(|e| DecodeError::Json(alloc::format!("{e:?}")))
}
/// Converts the `UnsecuredHeader` helper struct into a regular `Packet::Unsecured`.
/// Takes a payload of the length specified in the GeoNetworking's Common Header.
///
/// # Errors
/// Returns an [`EncodeError`] when parsing failed
pub fn with_payload(self, payload: &[u8]) -> Result<Packet<'_>, EncodeError> {
if self.common.payload_length as usize == payload.len() {
Ok(Packet::Unsecured {
basic: self.basic,
common: self.common,
extended: self.extended,
payload,
})
} else {
Err(EncodeError::Common(alloc::format!(
"Payload length {} does not match `payload_length` field {} in Common Header",
payload.len(),
self.common.payload_length
)))
}
}
}
#[derive(Debug, PartialEq)]
pub enum DecodeError<I> {
IntegerError(alloc::string::String),
EnumError(alloc::string::String),
StringError(alloc::string::String),
ArrayError(alloc::string::String),
ParserError(alloc::string::String),
Nom(I, ErrorKind),
#[cfg(feature = "json")]
Json(alloc::string::String),
}
impl<T> From<nom::Err<DecodeError<T>>> for DecodeError<T> {
fn from(value: nom::Err<DecodeError<T>>) -> Self {
match value {
nom::Err::Incomplete(Needed::Size(n)) => DecodeError::ParserError(alloc::format!(
"Unexpected end of input: Needs at least other {n} bytes!"
)),
nom::Err::Incomplete(_) => DecodeError::ParserError("Unexpected end of input!".into()),
nom::Err::Error(e) | nom::Err::Failure(e) => e,
}
}
}
impl ErrorConvert<DecodeError<&[u8]>> for nom::error::Error<(&[u8], usize)> {
fn convert(self) -> DecodeError<&'static [u8]> {
DecodeError::Nom(&[], self.code)
}
}
impl From<DecodeError<&'_ [u8]>> for DecodeError<(&'_ [u8], usize)> {
fn from(value: DecodeError<&'_ [u8]>) -> Self {
match value {
DecodeError::IntegerError(s) => Self::IntegerError(s),
DecodeError::EnumError(s) => Self::EnumError(s),
DecodeError::StringError(s) => Self::StringError(s),
DecodeError::ArrayError(s) => Self::ArrayError(s),
DecodeError::ParserError(s) => Self::ParserError(s),
DecodeError::Nom(_, k) => Self::Nom((&[], 0), k),
#[cfg(feature = "json")]
DecodeError::Json(s) => Self::Json(s),
}
}
}
impl<I> ParseError<I> for DecodeError<I> {
fn from_error_kind(input: I, kind: ErrorKind) -> Self {
DecodeError::Nom(input, kind)
}
fn append(_: I, _: ErrorKind, other: Self) -> Self {
other
}
}
impl<I, E> FromExternalError<I, E> for DecodeError<I> {
fn from_external_error(input: I, kind: ErrorKind, _: E) -> Self {
DecodeError::Nom(input, kind)
}
}
pub type IResult<I, T> = nom::IResult<I, T, DecodeError<I>>;
trait InternalDecode<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized;
}
macro_rules! decode_integer {
($typ:ty, $size:literal) => {
impl<'s> InternalDecode<'s> for $typ {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, bytes) = take($size)(input)?;
let value = <$typ>::from_be_bytes(bytes.try_into().expect(concat!(
"took",
$size,
"bytes, but result has different size"
)));
Ok((input, value))
}
}
};
}
decode_integer!(i16, 2usize);
decode_integer!(u16, 2usize);
decode_integer!(u32, 4usize);
decode_integer!(i32, 4usize);
impl<'s, const SIZE: usize> InternalDecode<'s> for [u8; SIZE] {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let mut output = [0u8; SIZE];
let mut input = input;
for item in &mut output {
(input, *item) = take(1usize)(input).map(|(rem, bytes)| (rem, bytes[0]))?;
}
Ok((input, output))
}
}
impl<'s, const SIZE: usize> InternalDecode<'s> for [bool; SIZE] {
/// Note: The remaining input stream won't contain not consumed bits (behavior of `nom::bits`).
/// All remaining bits of a "started" byte will be lost!
///
/// It's recommended to only use this with `SIZE` in multiples of 8.
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
nom::bits::bits::<_, _, nom::error::Error<(&[u8], usize)>, _, _>(|data| {
let mut output = [false; SIZE];
let mut data = data;
for item in &mut output {
(data, *item) = nom::bits::streaming::bool(data)?;
}
Ok((data, output))
})(input)
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::Address {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, bytes) = take(1usize)(input)?;
let manually_configured = (bytes[0] & 0x80) > 1; // first bit
let station_type_int = (bytes[0] & 0x7c) >> 2; // next 5 bits
let station_type = en302636_4_1::StationType::try_from(station_type_int)
.map_err(|err| nom::Err::Error(DecodeError::EnumError(err)))?;
let msb_part = bytes[0] & 0x03; // remaining 2 bits
let (input, bytes) = take(1usize)(input)?;
let reserved_u16 = (u16::from(msb_part) << 8) | u16::from(bytes[0]);
let reserved = u10::from_u16(reserved_u16);
let (input, address) = <[u8; 6]>::decode_bytewise(input)?;
Ok((
input,
Self {
manually_configured,
station_type,
reserved,
address,
},
))
}
}
impl From<(bool, en302636_4_1::StationType, u10, [u8; 6])> for en302636_4_1::Address {
fn from(value: (bool, en302636_4_1::StationType, u10, [u8; 6])) -> Self {
Self {
manually_configured: value.0,
station_type: value.1,
reserved: value.2,
address: value.3,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::BasicHeader {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, bytes) = take(1usize)(input)?;
let byte = bytes[0];
let version = u4::from_u8((byte >> 4) & 0x0F);
let next_header = en302636_4_1::NextAfterBasic::try_from(byte & 0x0F)
.map_err(|err| nom::Err::Error(DecodeError::EnumError(err)))?;
let (input, bytes) = take(1usize)(input)?;
let reserved = bytes[0];
let (input, bytes) = take(1usize)(input)?;
let lifetime = en302636_4_1::Lifetime::from_raw(bytes[0]);
let (input, bytes) = take(1usize)(input)?;
let remaining_hop_limit = bytes[0];
Ok((
input,
Self {
version,
next_header,
reserved,
lifetime,
remaining_hop_limit,
},
))
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::Timestamp {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, value) = u32::decode_bytewise(input)?;
Ok((input, Self(value)))
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::LongPositionVector {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, gn_address) = en302636_4_1::Address::decode_bytewise(input)?;
let (input, timestamp) = en302636_4_1::Timestamp::decode_bytewise(input)?;
let (input, latitude) = i32::decode_bytewise(input)?;
let (input, longitude) = i32::decode_bytewise(input)?;
let (input, bytes) = take(2usize)(input)?;
let position_accuracy = (bytes[0] & 0x80) > 0;
let speed_i16 = (i16::from(bytes[0]) << 8) | i16::from(bytes[1]);
let speed = i15::from_i16(speed_i16 & 0x7FFF);
let (input, heading) = u16::decode_bytewise(input)?;
Ok((
input,
Self {
gn_address,
timestamp,
latitude,
longitude,
position_accuracy,
speed,
heading,
},
))
}
}
impl
From<(
en302636_4_1::Address,
en302636_4_1::Timestamp,
i32,
i32,
bool,
i15,
u16,
)> for en302636_4_1::LongPositionVector
{
fn from(
value: (
en302636_4_1::Address,
en302636_4_1::Timestamp,
i32,
i32,
bool,
i15,
u16,
),
) -> Self {
Self {
gn_address: value.0,
timestamp: value.1,
latitude: value.2,
longitude: value.3,
position_accuracy: value.4,
speed: value.5,
heading: value.6,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::ShortPositionVector {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, gn_address) = en302636_4_1::Address::decode_bytewise(input)?;
let (input, timestamp) = en302636_4_1::Timestamp::decode_bytewise(input)?;
let (input, latitude) = i32::decode_bytewise(input)?;
let (input, longitude) = i32::decode_bytewise(input)?;
Ok((
input,
Self {
gn_address,
timestamp,
latitude,
longitude,
},
))
}
}
impl From<(en302636_4_1::Address, en302636_4_1::Timestamp, i32, i32)>
for en302636_4_1::ShortPositionVector
{
fn from(value: (en302636_4_1::Address, en302636_4_1::Timestamp, i32, i32)) -> Self {
Self {
gn_address: value.0,
timestamp: value.1,
latitude: value.2,
longitude: value.3,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::TrafficClass {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
nom::bits::bits::<_, _, nom::error::Error<(&[u8], usize)>, _, _>(|data| {
let (data, scf) = nom::bits::streaming::bool(data)?;
let (data, choff) = nom::bits::streaming::bool(data)?;
let (data, traffic_class_u8) = nom::bits::streaming::take(6usize)(data)?;
Ok((
data,
Self {
store_carry_forward: scf,
channel_offload: choff,
traffic_class_id: u6::from_u8(traffic_class_u8),
},
))
})(input)
}
}
impl From<(u8, u8, u6)> for en302636_4_1::TrafficClass {
fn from(value: (u8, u8, u6)) -> Self {
Self {
store_carry_forward: value.0 > 0,
channel_offload: value.1 > 0,
traffic_class_id: value.2,
}
}
}
impl From<(bool, bool, u6)> for en302636_4_1::TrafficClass {
fn from(value: (bool, bool, u6)) -> Self {
Self {
store_carry_forward: value.0,
channel_offload: value.1,
traffic_class_id: value.2,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::CommonHeader {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, bytes) = take(1usize)(input)?;
let byte = bytes[0];
let next_header = en302636_4_1::NextAfterCommon::try_from((byte >> 4) & 0x0F)
.map_err(|err| nom::Err::Error(DecodeError::EnumError(err)))?;
let reserved_1 = u4::from_u8(byte & 0x0F);
let (input, bytes) = take(1usize)(input)?;
let header_type_and_subtype = en302636_4_1::HeaderType::try_from(bytes[0])
.map_err(|err| nom::Err::Error(DecodeError::EnumError(err)))?;
let (input, traffic_class) = en302636_4_1::TrafficClass::decode_bytewise(input)?;
let (input, flags) = <[bool; 8]>::decode_bytewise(input)?;
let (input, payload_length) = u16::decode_bytewise(input)?;
let (input, bytes) = take(1usize)(input)?;
let maximum_hop_limit = bytes[0];
let (input, bytes) = take(1usize)(input)?;
let reserved_2 = bytes[0];
Ok((
input,
Self {
next_header,
reserved_1,
header_type_and_subtype,
traffic_class,
flags,
payload_length,
maximum_hop_limit,
reserved_2,
},
))
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::GeoAnycast {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, sequence_number) = u16::decode_bytewise(input)?;
let (input, reserved_1) = u16::decode_bytewise(input)?;
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
let (input, geo_area_position_latitude) = i32::decode_bytewise(input)?;
let (input, geo_area_position_longitude) = i32::decode_bytewise(input)?;
let (input, distance_a) = u16::decode_bytewise(input)?;
let (input, distance_b) = u16::decode_bytewise(input)?;
let (input, angle) = u16::decode_bytewise(input)?;
let (input, reserved_2) = u16::decode_bytewise(input)?;
Ok((
input,
Self {
sequence_number,
reserved_1,
source_position_vector,
geo_area_position_latitude,
geo_area_position_longitude,
distance_a,
distance_b,
angle,
reserved_2,
},
))
}
}
impl
From<(
u16,
u16,
en302636_4_1::LongPositionVector,
i32,
i32,
u16,
u16,
u16,
u16,
)> for en302636_4_1::GeoAnycast
{
fn from(
value: (
u16,
u16,
en302636_4_1::LongPositionVector,
i32,
i32,
u16,
u16,
u16,
u16,
),
) -> Self {
Self {
sequence_number: value.0,
reserved_1: value.1,
source_position_vector: value.2,
geo_area_position_latitude: value.3,
geo_area_position_longitude: value.4,
distance_a: value.5,
distance_b: value.6,
angle: value.7,
reserved_2: value.8,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::GeoUnicast {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, sequence_number) = u16::decode_bytewise(input)?;
let (input, reserved) = u16::decode_bytewise(input)?;
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
let (input, destination_position_vector) =
en302636_4_1::ShortPositionVector::decode_bytewise(input)?;
Ok((
input,
Self {
sequence_number,
reserved,
source_position_vector,
destination_position_vector,
},
))
}
}
impl
From<(
u16,
u16,
en302636_4_1::LongPositionVector,
en302636_4_1::ShortPositionVector,
)> for en302636_4_1::GeoUnicast
{
fn from(
value: (
u16,
u16,
en302636_4_1::LongPositionVector,
en302636_4_1::ShortPositionVector,
),
) -> Self {
Self {
sequence_number: value.0,
reserved: value.1,
source_position_vector: value.2,
destination_position_vector: value.3,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::TopologicallyScopedBroadcast {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, sequence_number) = u16::decode_bytewise(input)?;
let (input, reserved) = u16::decode_bytewise(input)?;
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
Ok((
input,
Self {
sequence_number,
reserved,
source_position_vector,
},
))
}
}
impl From<(u16, u16, en302636_4_1::LongPositionVector)>
for en302636_4_1::TopologicallyScopedBroadcast
{
fn from(value: (u16, u16, en302636_4_1::LongPositionVector)) -> Self {
Self {
sequence_number: value.0,
reserved: value.1,
source_position_vector: value.2,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::SingleHopBroadcast {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
let (input, media_dependent_data) = <[u8; 4]>::decode_bytewise(input)?;
Ok((
input,
Self {
source_position_vector,
media_dependent_data,
},
))
}
}
impl From<(en302636_4_1::LongPositionVector, [u8; 4])> for en302636_4_1::SingleHopBroadcast {
fn from(value: (en302636_4_1::LongPositionVector, [u8; 4])) -> Self {
Self {
source_position_vector: value.0,
media_dependent_data: value.1,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::Beacon {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
Ok((
input,
Self {
source_position_vector,
},
))
}
}
impl From<en302636_4_1::LongPositionVector> for en302636_4_1::Beacon {
fn from(value: en302636_4_1::LongPositionVector) -> Self {
Self {
source_position_vector: value,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::LSRequest {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, sequence_number) = u16::decode_bytewise(input)?;
let (input, reserved) = u16::decode_bytewise(input)?;
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
let (input, request_gn_address) = en302636_4_1::Address::decode_bytewise(input)?;
Ok((
input,
Self {
sequence_number,
reserved,
source_position_vector,
request_gn_address,
},
))
}
}
impl
From<(
u16,
u16,
en302636_4_1::LongPositionVector,
en302636_4_1::Address,
)> for en302636_4_1::LSRequest
{
fn from(
value: (
u16,
u16,
en302636_4_1::LongPositionVector,
en302636_4_1::Address,
),
) -> Self {
Self {
sequence_number: value.0,
reserved: value.1,
source_position_vector: value.2,
request_gn_address: value.3,
}
}
}
impl<'s> InternalDecode<'s> for en302636_4_1::LSReply {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, sequence_number) = u16::decode_bytewise(input)?;
let (input, reserved) = u16::decode_bytewise(input)?;
let (input, source_position_vector) =
en302636_4_1::LongPositionVector::decode_bytewise(input)?;
let (input, destination_position_vector) =
en302636_4_1::ShortPositionVector::decode_bytewise(input)?;
Ok((
input,
Self {
sequence_number,
reserved,
source_position_vector,
destination_position_vector,
},
))
}
}
impl
From<(
u16,
u16,
en302636_4_1::LongPositionVector,
en302636_4_1::ShortPositionVector,
)> for en302636_4_1::LSReply
{
fn from(
value: (
u16,
u16,
en302636_4_1::LongPositionVector,
en302636_4_1::ShortPositionVector,
),
) -> Self {
Self {
sequence_number: value.0,
reserved: value.1,
source_position_vector: value.2,
destination_position_vector: value.3,
}
}
}
fn wrap_in_some<'input, T, F>(
parser: F,
) -> impl FnMut(&'input [u8]) -> IResult<&'input [u8], Option<T>>
where
F: FnMut(&'input [u8]) -> IResult<&'input [u8], T>,
{
map(parser, |res| Some(res))
}
fn read_extended(
header_type_and_subclass: en302636_4_1::HeaderType,
input: &'_ [u8],
) -> IResult<&'_ [u8], Option<en302636_4_1::ExtendedHeader>> {
match header_type_and_subclass {
en302636_4_1::HeaderType::Any => Ok((input, None)),
en302636_4_1::HeaderType::Beacon => wrap_in_some(map(
en302636_4_1::Beacon::decode_bytewise,
en302636_4_1::ExtendedHeader::Beacon,
))(input),
en302636_4_1::HeaderType::GeoUnicast => wrap_in_some(map(
en302636_4_1::GeoUnicast::decode_bytewise,
en302636_4_1::ExtendedHeader::GUC,
))(input),
en302636_4_1::HeaderType::GeoAnycast(_) => wrap_in_some(map(
en302636_4_1::GeoAnycast::decode_bytewise,
en302636_4_1::ExtendedHeader::GAC,
))(input),
en302636_4_1::HeaderType::GeoBroadcast(_) => wrap_in_some(map(
en302636_4_1::GeoAnycast::decode_bytewise,
en302636_4_1::ExtendedHeader::GBC,
))(input),
en302636_4_1::HeaderType::TopologicallyScopedBroadcast(
en302636_4_1::BroadcastType::SingleHop,
) => wrap_in_some(map(
en302636_4_1::SingleHopBroadcast::decode_bytewise,
en302636_4_1::ExtendedHeader::SHB,
))(input),
en302636_4_1::HeaderType::TopologicallyScopedBroadcast(_) => wrap_in_some(map(
en302636_4_1::TopologicallyScopedBroadcast::decode_bytewise,
en302636_4_1::ExtendedHeader::TSB,
))(input),
en302636_4_1::HeaderType::LocationService(en302636_4_1::LocationServiceType::Request) => {
wrap_in_some(map(
en302636_4_1::LSRequest::decode_bytewise,
en302636_4_1::ExtendedHeader::LSRequest,
))(input)
}
en302636_4_1::HeaderType::LocationService(_) => wrap_in_some(map(
en302636_4_1::LSReply::decode_bytewise,
en302636_4_1::ExtendedHeader::LSReply,
))(input),
}
}
impl<'s> InternalDecode<'s> for Packet<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, basic) = en302636_4_1::BasicHeader::decode_bytewise(input)?;
if basic.next_header == en302636_4_1::NextAfterBasic::SecuredPacket {
let (remaining, secured) = ieee1609dot2::Ieee1609Dot2Data::decode_bytewise(input)?;
let data_payload = secured.data_payload().ok_or_else(|| {
nom::Err::Error(DecodeError::<&[u8]>::ParserError(
"Could not retrieve payload from IEEE1609.2 Data!".into(),
))
})?;
let (input, common) =
en302636_4_1::CommonHeader::decode_bytewise(data_payload).map_err(cast_nom_err)?;
let (_, extended) =
read_extended(common.header_type_and_subtype, input).map_err(cast_nom_err)?;
Ok((
remaining,
Self::Secured {
basic,
secured,
common,
extended,
},
))
} else {
let (remaining, common) =
en302636_4_1::CommonHeader::decode_bytewise(input).map_err(cast_nom_err)?;
let (remaining, extended) =
read_extended(common.header_type_and_subtype, remaining).map_err(cast_nom_err)?;
let (input, payload) = take(common.payload_length)(remaining)?;
Ok((
input,
Self::Unsecured {
basic,
common,
extended,
payload,
},
))
}
}
}
// =====================================================
// ETSI TS 103 097/ IEEE 1609.2
// =====================================================
struct Slice<'i>(&'i [u8]);
impl<'i> From<&'i [u8]> for Slice<'i> {
fn from(value: &'i [u8]) -> Self {
Self(value)
}
}
impl<'i, const SIZE: usize> TryInto<[u8; SIZE]> for Slice<'i> {
type Error = nom::Err<DecodeError<&'i [u8]>>;
fn try_into(self) -> Result<[u8; SIZE], Self::Error> {
match self.0.len() {
len if len == SIZE => Ok(self.0.try_into().unwrap()),
len if len > SIZE => Err(nom::Err::Error(DecodeError::IntegerError(
"Length exceeds supported integer range!".into(),
))),
len => {
let mut padding = alloc::vec![0; SIZE - len];
padding.extend_from_slice(self.0);
padding.try_into().map_err(|e| {
nom::Err::Error(DecodeError::IntegerError(alloc::format!(
"Failed to read length: {e:?}"
)))
})
}
}
}
}
fn decode_bytewise_length(input: &[u8]) -> IResult<&[u8], usize> {
let (input, byte) = take(1usize)(input)?;
match byte[0] {
len if len < 128 => Ok((input, len.into())),
len => {
let (input, bytes): (&[u8], Slice) =
into(take::<u8, &[u8], DecodeError<&[u8]>>(len & 0b0111_1111))(input)?;
let length = bytes.try_into().map(usize::from_be_bytes)?;
Ok((input, length))
}
}
}
macro_rules! int {
($typ:ty, $count:expr, $from:path) => {
map_res(take($count), |bytes: &[u8]| {
Slice::from(bytes)
.try_into()
.map(<$typ>::from_be_bytes)
.map_err(|e| alloc::format!("Failed to read length: {e:?}"))
.and_then(|int| $from(int).ok_or("Failed to fit value into integer type!".into()))
.map_err(|e| nom::Err::Error(DecodeError::<&[u8]>::IntegerError(e)))
})
};
}
fn decode_bytewise_integer<I: Integer + FromPrimitive>(
min: Option<i128>,
max: Option<i128>,
extensible: bool,
input: &[u8],
) -> IResult<&[u8], I> {
match (min, max, extensible) {
(Some(min), Some(max), false) if min >= 0 && max <= 255 => {
int!(u8, 1usize, I::from_u8)(input)
}
(Some(min), Some(max), false) if min >= 0 && max <= 65535 => {
int!(u16, 2usize, I::from_u16)(input)
}
(Some(min), Some(max), false) if min >= 0 && max <= 4_294_967_295 => {
int!(u32, 4usize, I::from_u32)(input)
}
(Some(min), Some(max), false) if min >= 0 && max <= 18_446_744_073_709_551_615 => {
int!(u64, 8usize, I::from_u64)(input)
}
(Some(min), _, false) if min >= 0 => {
let (input, length) = decode_bytewise_length(input)?;
int!(u128, length, I::from_u128)(input)
}
(Some(min), Some(max), false) if min >= -128 && max <= 127 => {
int!(i8, 1usize, I::from_i8)(input)
}
(Some(min), Some(max), false) if min >= -32768 && max <= 32767 => {
int!(i16, 2usize, I::from_i16)(input)
}
(Some(min), Some(max), false) if min >= -2_147_483_648 && max <= 2_147_483_647 => {
int!(i32, 4usize, I::from_i32)(input)
}
(Some(min), Some(max), false)
if min >= -9_223_372_036_854_775_808 && max <= 9_223_372_036_854_775_807 =>
{
int!(i64, 8usize, I::from_i64)(input)
}
_ => {
let (input, length) = decode_bytewise_length(input)?;
int!(i128, length, I::from_i128)(input)
}
}
}
fn decode_bytewise_enumerated<E: TryFrom<i128>>(input: &[u8]) -> IResult<&[u8], E> {
let (input, byte) = take(1usize)(input)?;
match byte[0] {
len if len < 128 => i128::from(len)
.try_into()
.map(|variant| (input, variant))
.map_err(|_| nom::Err::Error(DecodeError::EnumError("Invalid enum index!".into()))),
len => {
let (input, bytes): (&[u8], Slice) =
into(take::<u8, &[u8], DecodeError<&[u8]>>(len & 0b0111_1111))(input)?;
let length = bytes.try_into().map(i128::from_be_bytes)?;
length
.try_into()
.map(|variant| (input, variant))
.map_err(|_| nom::Err::Error(DecodeError::EnumError("Invalid enum index!".into())))
}
}
}
/// Extracts bits from ASN.1 buffer
///
/// First bit is the MSB of the first byte in ASN.1
fn bitslice_to_bitvec(buffer: &[u8], offset: usize, count: usize) -> Vec<bool> {
let mut bitvec = vec![];
// iterate using 0-based index
for i in offset..(offset + count) {
let byte_idx = Integer::div_floor(&i, &8);
let bit_idx = (8 - (i % 8)) - 1;
bitvec.push((buffer[byte_idx] >> bit_idx & 0x01) > 0);
}
bitvec
}
/// Decodes ASN.1 SEQUENCE preamble
///
/// Note: Only execute, if there is either an extension bit or optional values present!
/// (Otherwise the sequence preamble will be omitted.)
fn decode_bytewise_sequence_preamble(
has_extension: bool,
presence_bits: usize,
input: &[u8],
) -> IResult<&[u8], (bool, Vec<bool>)> {
let (input, preamble) = take(util::bitstring_buffer_size(presence_bits))(input)?;
let (ext, bitmap) = if has_extension {
let extension = (preamble[0] & 0b1000_0000) > 0;
let bitstring = bitslice_to_bitvec(preamble, 1, presence_bits);
(extension, bitstring)
} else {
let bitstring = bitslice_to_bitvec(preamble, 0, presence_bits);
(false, bitstring)
};
Ok((input, (ext, bitmap)))
}
// ASN.1 OER "bitstring" values
// ASN.1 OER "extension addition presence bitmap", if used without constraints or as extensible
fn decode_bytewise_bitstring(
min: Option<usize>,
max: Option<usize>,
extensible: bool,
input: &[u8],
) -> IResult<&[u8], Vec<bool>> {
match (min, max, extensible) {
(Some(min), Some(max), false) if min == max => {
let (input, bytes) = take(util::bitstring_buffer_size(max))(input)?;
let mut bitstring = vec![];
for byte in bytes {
for i in (0..8).rev() {
bitstring.push((byte >> i & 0x01) > 0);
}
}
let to_pop = 8 - max % 8;
if to_pop != 8 {
(0..to_pop).for_each(|_| {
bitstring.pop();
});
}
Ok((input, bitstring))
}
_ => {
// length includes second (unused_bits) byte and subsequent bytes
let (input, length) = decode_bytewise_length(input)?;
// Note: using integer encoding is not 100% correct, but leads to same result in this case
let (input, unused_bits) =
decode_bytewise_integer::<usize>(Some(0), Some(8), false, input)?;
if unused_bits > 7 {
return Err(nom::Err::Error(DecodeError::ParserError(
alloc::format!("Extension addition presence bitmap contains invalid unused bits indication: {unused_bits}"),
)));
}
let (input, bytes) = take(length - 1)(input)?;
let mut bitstring = vec![];
for byte in bytes {
for i in (0..8).rev() {
bitstring.push((byte >> i & 0x01) > 0);
}
}
// remove padding bits
(0..unused_bits).for_each(|_| {
bitstring.pop();
});
Ok((input, bitstring))
}
}
}
impl<'s, const SIZE: usize> InternalDecode<'s> for ieee1609dot2::BitString<SIZE> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (rem, bitvec) = decode_bytewise_bitstring(Some(SIZE), Some(SIZE), false, input)?;
Ok((rem, Self::from(bitvec)))
}
}
fn decode_bytewise_octetstring(
min: Option<usize>,
max: Option<usize>,
extensible: bool,
input: &[u8],
) -> IResult<&[u8], &[u8]> {
match (min, max, extensible) {
(Some(min), Some(max), false) if min == max => {
into(take::<usize, &[u8], DecodeError<&[u8]>>(max))(input)
}
_ => {
let (input, length) = decode_bytewise_length(input)?;
take::<usize, &[u8], DecodeError<&[u8]>>(length)(input)
}
}
}
fn decode_bytewise_tag(input: &[u8]) -> IResult<&[u8], u64> {
let (input, byte) = take(1usize)(input)?;
match byte[0] & 0b0011_1111 {
len if len < 63 => Ok((input, len.into())),
_ => unimplemented!(),
}
}
fn decode_bytewise_open_type<'input, T, F>(
decoder: F,
input: &'input [u8],
) -> IResult<&'input [u8], T>
where
F: Fn(&'input [u8]) -> IResult<&'input [u8], T>,
{
let (input, length) = decode_bytewise_length(input)?;
take(length).and_then(decoder).parse(input)
}
macro_rules! uint {
($typ:ty, $max:expr) => {
impl<'s> InternalDecode<'s> for $typ {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, inner) = decode_bytewise_integer(Some(0), $max, false, input)?;
Ok((input, Self(inner)))
}
}
};
}
uint!(ieee1609dot2::Uint3, Some(7));
uint!(ieee1609dot2::Uint8, Some(255));
uint!(ieee1609dot2::ExtId, Some(255));
uint!(ieee1609dot2::HeaderInfoContributorId, Some(255));
uint!(ieee1609dot2::PduFunctionalType, Some(255));
uint!(ieee1609dot2::Uint16, Some(65535));
uint!(ieee1609dot2::Uint32, Some(4_294_967_295));
uint!(ieee1609dot2::Uint64, Some(18_446_744_073_709_551_615));
uint!(ieee1609dot2::Psid, None);
macro_rules! octets {
($typ:ty, $min:expr, $max:expr) => {
impl<'s> InternalDecode<'s> for $typ {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, inner) = decode_bytewise_octetstring($min, $max, false, input)?;
Ok((input, Self(inner)))
}
}
};
}
octets!(ieee1609dot2::HashedId3<'s>, Some(3), Some(3));
octets!(ieee1609dot2::HashedId8<'s>, Some(8), Some(8));
octets!(ieee1609dot2::HashedId10<'s>, Some(10), Some(10));
octets!(ieee1609dot2::HashedId32<'s>, Some(32), Some(32));
octets!(ieee1609dot2::HashedId48<'s>, Some(48), Some(48));
octets!(ieee1609dot2::Opaque<'s>, Some(0), None);
octets!(ieee1609dot2::BitmapSsp<'s>, Some(0), Some(31));
octets!(ieee1609dot2::SubjectAssurance<'s>, Some(1), Some(1));
octets!(ieee1609dot2::LinkageValue<'s>, Some(9), Some(9));
octets!(ieee1609dot2::LaId<'s>, Some(2), Some(2));
octets!(ieee1609dot2::LinkageSeed<'s>, Some(16), Some(16));
macro_rules! enumerated {
($typ:ty) => {
impl<'s> InternalDecode<'s> for $typ {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
decode_bytewise_enumerated(input)
}
}
};
}
enumerated!(ieee1609dot2::HashAlgorithm);
enumerated!(ieee1609dot2::SymmAlgorithm);
enumerated!(ieee1609dot2::CertificateType);
macro_rules! sequence_of {
($typ:ty, $inner:ty, $min:expr, $max:expr) => {
impl<'s> InternalDecode<'s> for $typ {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let mut sequence_of = alloc::vec![];
let (mut input, count) = decode_bytewise_integer($min, $max, false, input)?;
for _ in (0..count) {
let (rem, item) = <$inner>::decode_bytewise(input)?;
input = rem;
sequence_of.push(item);
}
Ok((input, Self(sequence_of)))
}
}
};
}
sequence_of!(
ieee1609dot2::SequenceOfUint8,
ieee1609dot2::Uint8,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfUint16,
ieee1609dot2::Uint16,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfHashedId3<'s>,
ieee1609dot2::HashedId3,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfRectangularRegion,
ieee1609dot2::RectangularRegion,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfIdentifiedRegion,
ieee1609dot2::IdentifiedRegion,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfRegionAndSubregions,
ieee1609dot2::RegionAndSubregions,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfPsidSsp<'s>,
ieee1609dot2::PsidSsp,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfPsidSspRange<'s>,
ieee1609dot2::PsidSspRange,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfPsid,
ieee1609dot2::Psid,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfLinkageSeed<'s>,
ieee1609dot2::LinkageSeed,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfRecipientInfo<'s>,
ieee1609dot2::RecipientInfo,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfAppExtensions<'s>,
ieee1609dot2::AppExtension,
Some(1),
None
);
sequence_of!(
ieee1609dot2::SequenceOfCertIssueExtensions<'s>,
ieee1609dot2::CertIssueExtension,
Some(1),
None
);
sequence_of!(
ieee1609dot2::SequenceOfCertRequestExtensions<'s>,
ieee1609dot2::CertRequestExtension,
Some(1),
None
);
sequence_of!(
ieee1609dot2::SequenceOfCertificate<'s>,
ieee1609dot2::Certificate,
Some(0),
None
);
sequence_of!(
ieee1609dot2::SequenceOfPsidGroupPermissions<'s>,
ieee1609dot2::PsidGroupPermissions,
Some(0),
None
);
sequence_of!(
ieee1609dot2::PolygonalRegion,
ieee1609dot2::TwoDLocation,
Some(3),
None
);
sequence_of!(
ieee1609dot2::ContributedExtensionBlocks<'s>,
ieee1609dot2::ContributedExtensionBlock,
Some(1),
None
);
impl<'s> InternalDecode<'s> for ieee1609dot2::SequenceOfOctetString<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let mut sequence_of = alloc::vec![];
let (mut input, count) = decode_bytewise_integer(Some(0), None, false, input)?;
for _ in 0..count {
let (rem, item) = decode_bytewise_octetstring(Some(0), None, false, input)?;
input = rem;
sequence_of.push(item);
}
Ok((input, Self(sequence_of)))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::Duration {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
let (input, inner) = ieee1609dot2::Uint16::decode_bytewise(input)?;
match tag {
0 => Ok((input, Self::Microseconds(inner))),
1 => Ok((input, Self::Milliseconds(inner))),
2 => Ok((input, Self::Seconds(inner))),
3 => Ok((input, Self::Minutes(inner))),
4 => Ok((input, Self::Hours(inner))),
5 => Ok((input, Self::SixtyHours(inner))),
6 => Ok((input, Self::Years(inner))),
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::ValidityPeriod {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, start) = ieee1609dot2::Time32::decode_bytewise(input)?;
let (input, duration) = ieee1609dot2::Duration::decode_bytewise(input)?;
Ok((input, Self { start, duration }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EccP256CurvePointUncompressedP256<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, x) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
let (input, y) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self { x, y }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EccP256CurvePoint<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, bytes) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self::XOnly(bytes)))
}
1 => Ok((input, Self::Fill(()))),
2 => {
let (input, bytes) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self::CompressedY0(bytes)))
}
3 => {
let (input, bytes) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self::CompressedY1(bytes)))
}
4 => {
let (input, inner) =
ieee1609dot2::EccP256CurvePointUncompressedP256::decode_bytewise(input)?;
Ok((input, Self::UncompressedP256(inner)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EccP384CurvePointUncompressedP384<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, x) = decode_bytewise_octetstring(Some(48), Some(48), false, input)?;
let (input, y) = decode_bytewise_octetstring(Some(48), Some(48), false, input)?;
Ok((input, Self { x, y }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EccP384CurvePoint<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, bytes) = decode_bytewise_octetstring(Some(48), Some(48), false, input)?;
Ok((input, Self::XOnly(bytes)))
}
1 => Ok((input, Self::Fill(()))),
2 => {
let (input, bytes) = decode_bytewise_octetstring(Some(48), Some(48), false, input)?;
Ok((input, Self::CompressedY0(bytes)))
}
3 => {
let (input, bytes) = decode_bytewise_octetstring(Some(48), Some(48), false, input)?;
Ok((input, Self::CompressedY1(bytes)))
}
4 => {
let (input, inner) =
ieee1609dot2::EccP384CurvePointUncompressedP384::decode_bytewise(input)?;
Ok((input, Self::UncompressedP384(inner)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EcencP256EncryptedKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, v) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
let (input, c) = decode_bytewise_octetstring(Some(16), Some(16), false, input)?;
let (input, t) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self { v, c, t }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EciesP256EncryptedKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, v) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
let (input, c) = decode_bytewise_octetstring(Some(16), Some(16), false, input)?;
let (input, t) = decode_bytewise_octetstring(Some(16), Some(16), false, input)?;
Ok((input, Self { v, c, t }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::BasePublicEncryptionKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, pt) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
Ok((input, Self::EciesNistP256(pt)))
}
1 => {
let (input, pt) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
Ok((input, Self::EciesBrainpoolP256r1(pt)))
}
2 => {
let (input, pt) = decode_bytewise_open_type(
ieee1609dot2::EccP256CurvePoint::decode_bytewise,
input,
)?;
Ok((input, Self::EcencSm2(pt)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::PublicEncryptionKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, supported_symm_alg) = ieee1609dot2::SymmAlgorithm::decode_bytewise(input)?;
let (input, public_key) = ieee1609dot2::BasePublicEncryptionKey::decode_bytewise(input)?;
Ok((
input,
Self {
supported_symm_alg,
public_key,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SymmetricEncryptionKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, aes) = decode_bytewise_octetstring(Some(16), Some(16), false, input)?;
Ok((input, Self::Aes128Ccm(aes)))
}
1 => {
let (input, sm) = decode_bytewise_open_type(
|i| decode_bytewise_octetstring(Some(16), Some(16), false, i),
input,
)?;
Ok((input, Self::Sm4Ccm(sm)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EncryptionKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, public) = ieee1609dot2::PublicEncryptionKey::decode_bytewise(input)?;
Ok((input, Self::Public(public)))
}
1 => {
let (input, symm) = ieee1609dot2::SymmetricEncryptionKey::decode_bytewise(input)?;
Ok((input, Self::Symmetric(symm)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::GeographicRegion {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, region) = ieee1609dot2::CircularRegion::decode_bytewise(input)?;
Ok((input, Self::CircularRegion(region)))
}
1 => {
let (input, region) =
ieee1609dot2::SequenceOfRectangularRegion::decode_bytewise(input)?;
Ok((input, Self::RectangularRegion(region)))
}
2 => {
let (input, region) = ieee1609dot2::PolygonalRegion::decode_bytewise(input)?;
Ok((input, Self::PolygonalRegion(region)))
}
3 => {
let (input, region) =
ieee1609dot2::SequenceOfIdentifiedRegion::decode_bytewise(input)?;
Ok((input, Self::IdentifiedRegion(region)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CircularRegion {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, center) = ieee1609dot2::TwoDLocation::decode_bytewise(input)?;
let (input, radius) = ieee1609dot2::Uint16::decode_bytewise(input)?;
Ok((input, Self { center, radius }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::RectangularRegion {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, north_west) = ieee1609dot2::TwoDLocation::decode_bytewise(input)?;
let (input, south_east) = ieee1609dot2::TwoDLocation::decode_bytewise(input)?;
Ok((
input,
Self {
north_west,
south_east,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::TwoDLocation {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, latitude) = ieee1609dot2::Latitude::decode_bytewise(input)?;
let (input, longitude) = ieee1609dot2::Longitude::decode_bytewise(input)?;
Ok((
input,
Self {
latitude,
longitude,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::IdentifiedRegion {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, region) = ieee1609dot2::UnCountryId::decode_bytewise(input)?;
Ok((input, Self::CountryOnly(region)))
}
1 => {
let (input, region) = ieee1609dot2::CountryAndRegions::decode_bytewise(input)?;
Ok((input, Self::CountryAndRegions(region)))
}
2 => {
let (input, region) = ieee1609dot2::CountryAndSubregions::decode_bytewise(input)?;
Ok((input, Self::CountryAndSubregions(region)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CountryAndRegions {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, country_only) = ieee1609dot2::UnCountryId::decode_bytewise(input)?;
let (input, regions) = ieee1609dot2::SequenceOfUint8::decode_bytewise(input)?;
Ok((
input,
Self {
country_only,
regions,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CountryAndSubregions {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, country_only) = ieee1609dot2::UnCountryId::decode_bytewise(input)?;
let (input, region_and_subregions) =
ieee1609dot2::SequenceOfRegionAndSubregions::decode_bytewise(input)?;
Ok((
input,
Self {
country_only,
region_and_subregions,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::RegionAndSubregions {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, region) = ieee1609dot2::Uint8::decode_bytewise(input)?;
let (input, subregions) = ieee1609dot2::SequenceOfUint16::decode_bytewise(input)?;
Ok((input, Self { region, subregions }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::ThreeDLocation {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, latitude) = ieee1609dot2::Latitude::decode_bytewise(input)?;
let (input, longitude) = ieee1609dot2::Longitude::decode_bytewise(input)?;
let (input, elevation) = ieee1609dot2::Elevation::decode_bytewise(input)?;
Ok((
input,
Self {
latitude,
longitude,
elevation,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::NinetyDegreeInt {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, int) =
decode_bytewise_integer(Some(-900_000_000), Some(900_000_001), false, input)?;
Ok((input, Self(int)))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::OneEightyDegreeInt {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, int) =
decode_bytewise_integer(Some(-1_799_999_999), Some(1_800_000_001), false, input)?;
Ok((input, Self(int)))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::GroupLinkageValue<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, j_value) = decode_bytewise_octetstring(Some(4), Some(4), false, input)?;
let (input, value) = decode_bytewise_octetstring(Some(9), Some(9), false, input)?;
Ok((input, Self { j_value, value }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::Hostname {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, utf8) = decode_bytewise_octetstring(Some(0), Some(255), false, input)?;
let hostname = alloc::string::String::from_utf8(utf8.to_vec()).map_err(|_| {
nom::Err::Error(DecodeError::StringError(
"Unable to decode UTF8 bytes!".into(),
))
})?;
Ok((input, Self(hostname)))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::PsidSsp<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (_, bitmap)) = decode_bytewise_sequence_preamble(false, 1, input)?;
let (input, psid) = ieee1609dot2::Psid::decode_bytewise(input)?;
let (input, ssp) = if bitmap[0] {
map(
ieee1609dot2::ServiceSpecificPermissions::decode_bytewise,
Some,
)(input)?
} else {
(input, None)
};
Ok((input, Self { psid, ssp }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::ServiceSpecificPermissions<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, opaque) = decode_bytewise_octetstring(Some(0), None, false, input)?;
Ok((input, Self::Opaque(opaque)))
}
1 => {
let (input, bitmap_ssp) =
decode_bytewise_open_type(ieee1609dot2::BitmapSsp::decode_bytewise, input)?;
Ok((input, Self::BitmapSsp(bitmap_ssp)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::PsidSspRange<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (_, bitmap)) = decode_bytewise_sequence_preamble(false, 1, input)?;
let (input, psid) = ieee1609dot2::Psid::decode_bytewise(input)?;
let (input, ssp_range) = if bitmap[0] {
map(ieee1609dot2::SspRange::decode_bytewise, Some)(input)?
} else {
(input, None)
};
Ok((input, Self { psid, ssp_range }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SspRange<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, opaque) = ieee1609dot2::SequenceOfOctetString::decode_bytewise(input)?;
Ok((input, Self::Opaque(opaque)))
}
1 => Ok((input, Self::All(()))),
2 => {
let (input, bitmap_ssp) = decode_bytewise_open_type(
ieee1609dot2::BitmapSspRange::decode_bytewise,
input,
)?;
Ok((input, Self::BitmapSspRange(bitmap_ssp)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::BitmapSspRange<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, ssp_value) = decode_bytewise_octetstring(Some(1), Some(32), false, input)?;
let (input, ssp_bitmask) = decode_bytewise_octetstring(Some(1), Some(32), false, input)?;
Ok((
input,
Self {
ssp_value,
ssp_bitmask,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::PublicVerificationKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, point) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
Ok((input, Self::EcdsaNistP256(point)))
}
1 => {
let (input, point) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
Ok((input, Self::EcdsaBrainpoolP256r1(point)))
}
2 => {
let (input, point) = decode_bytewise_open_type(
ieee1609dot2::EccP384CurvePoint::decode_bytewise,
input,
)?;
Ok((input, Self::EcdsaBrainpoolP384r1(point)))
}
3 => {
let (input, point) = decode_bytewise_open_type(
ieee1609dot2::EccP384CurvePoint::decode_bytewise,
input,
)?;
Ok((input, Self::EcdsaNistP384(point)))
}
4 => {
let (input, point) = decode_bytewise_open_type(
ieee1609dot2::EccP256CurvePoint::decode_bytewise,
input,
)?;
Ok((input, Self::EcsigSm2(point)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::Signature<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, sig) = ieee1609dot2::EcdsaP256Signature::decode_bytewise(input)?;
Ok((input, Self::EcdsaNistP256Signature(sig)))
}
1 => {
let (input, sig) = ieee1609dot2::EcdsaP256Signature::decode_bytewise(input)?;
Ok((input, Self::EcdsaBrainpoolP256r1Signature(sig)))
}
2 => {
let (input, sig) = decode_bytewise_open_type(
ieee1609dot2::EcdsaP384Signature::decode_bytewise,
input,
)?;
Ok((input, Self::EcdsaBrainpoolP384r1Signature(sig)))
}
3 => {
let (input, sig) = decode_bytewise_open_type(
ieee1609dot2::EcdsaP384Signature::decode_bytewise,
input,
)?;
Ok((input, Self::EcdsaNistP384Signature(sig)))
}
4 => {
let (input, sig) = decode_bytewise_open_type(
ieee1609dot2::EcsigP256Signature::decode_bytewise,
input,
)?;
Ok((input, Self::Sm2Signature(sig)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EcdsaP256Signature<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, r_sig) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
let (input, s_sig) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self { r_sig, s_sig }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EcdsaP384Signature<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, r_sig) = ieee1609dot2::EccP384CurvePoint::decode_bytewise(input)?;
let (input, s_sig) = decode_bytewise_octetstring(Some(48), Some(48), false, input)?;
Ok((input, Self { r_sig, s_sig }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EcsigP256Signature<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, r_sig) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
let (input, s_sig) = decode_bytewise_octetstring(Some(32), Some(32), false, input)?;
Ok((input, Self { r_sig, s_sig }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::HashedData<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, hash) = ieee1609dot2::HashedId32::decode_bytewise(input)?;
Ok((input, Self::Sha256HashedData(hash)))
}
1 => {
let (input, hash) =
decode_bytewise_open_type(ieee1609dot2::HashedId48::decode_bytewise, input)?;
Ok((input, Self::Sha384HashedData(hash)))
}
2 => {
let (input, hash) =
decode_bytewise_open_type(ieee1609dot2::HashedId32::decode_bytewise, input)?;
Ok((input, Self::Sm3HashedData(hash)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::Ieee1609Dot2Data<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, protocol_version) = ieee1609dot2::Uint8::decode_bytewise(input)?;
let (input, content) = ieee1609dot2::Ieee1609Dot2Content::decode_bytewise(input)?;
Ok((
input,
Self {
protocol_version,
content,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::Ieee1609Dot2Content<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, content) = ieee1609dot2::Opaque::decode_bytewise(input)?;
Ok((input, Self::UnsecuredData(content)))
}
1 => {
let (input, content) = ieee1609dot2::SignedData::decode_bytewise(input)?;
Ok((input, Self::SignedData(alloc::boxed::Box::new(content))))
}
2 => {
let (input, content) = ieee1609dot2::EncryptedData::decode_bytewise(input)?;
Ok((input, Self::EncryptedData(content)))
}
3 => {
let (input, content) = ieee1609dot2::Opaque::decode_bytewise(input)?;
Ok((input, Self::SignedCertificateRequest(content)))
}
4 => {
let (input, content) =
decode_bytewise_open_type(ieee1609dot2::Opaque::decode_bytewise, input)?;
Ok((input, Self::SignedX509CertificateRequest(content)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SignedData<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, hash_id) = ieee1609dot2::HashAlgorithm::decode_bytewise(input)?;
let (input, tbs_data) = ieee1609dot2::ToBeSignedData::decode_bytewise(input)?;
let (input, signer) = ieee1609dot2::SignerIdentifier::decode_bytewise(input)?;
let (input, signature) = ieee1609dot2::Signature::decode_bytewise(input)?;
Ok((
input,
Self {
hash_id,
tbs_data,
signer,
signature,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::ToBeSignedData<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
#[cfg(feature = "validate")]
let (input_before, length_before) = (input, input.len());
let (input, payload) = ieee1609dot2::SignedDataPayload::decode_bytewise(input)?;
let (input, header_info) = ieee1609dot2::HeaderInfo::decode_bytewise(input)?;
Ok((
input,
Self {
payload,
header_info,
#[cfg(feature = "validate")]
raw: &input_before[..length_before - input.len()],
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SignedDataPayload<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (extended, bitmap)) = decode_bytewise_sequence_preamble(true, 2, input)?;
let (input, data) = if bitmap[0] {
map(ieee1609dot2::Ieee1609Dot2Data::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, ext_data_hash) = if bitmap[1] {
map(ieee1609dot2::HashedData::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, omitted) = if extended {
let (input, bitmap) = decode_bytewise_bitstring(Some(0), None, false, input)?;
#[allow(clippy::get_first, reason = "similarity to subsequent lines")]
let (mut input, omitted) = if bitmap.get(0).is_some_and(|bit| *bit) {
decode_bytewise_open_type(|i| Ok((i, Some(()))), input)?
} else {
(input, None)
};
// consume unknown extensions
for bit in bitmap.get(1..).unwrap_or_default() {
if *bit {
input = decode_bytewise_octetstring(Some(0), None, false, input)?.0;
}
}
(input, omitted)
} else {
(input, None)
};
Ok((
input,
Self {
data,
ext_data_hash,
omitted,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::RecipientInfo<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, info) =
ieee1609dot2::PreSharedKeyRecipientInfo::decode_bytewise(input)?;
Ok((input, Self::PskRecipInfo(info)))
}
1 => {
let (input, info) = ieee1609dot2::SymmRecipientInfo::decode_bytewise(input)?;
Ok((input, Self::SymmRecipInfo(info)))
}
2 => {
let (input, info) = ieee1609dot2::PKRecipientInfo::decode_bytewise(input)?;
Ok((input, Self::CertRecipInfo(info)))
}
3 => {
let (input, info) = ieee1609dot2::PKRecipientInfo::decode_bytewise(input)?;
Ok((input, Self::SignedDataRecipInfo(info)))
}
4 => {
let (input, info) = ieee1609dot2::PKRecipientInfo::decode_bytewise(input)?;
Ok((input, Self::RekRecipInfo(info)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SignerIdentifier<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, id) = ieee1609dot2::HashedId8::decode_bytewise(input)?;
Ok((input, Self::Digest(id)))
}
1 => {
let (input, id) = ieee1609dot2::SequenceOfCertificate::decode_bytewise(input)?;
Ok((input, Self::Certificate(id)))
}
2 => Ok((input, Self::RsSelf(()))),
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::MissingCrlIdentifier<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (extended, _)) = decode_bytewise_sequence_preamble(true, 0, input)?;
let (input, craca_id) = ieee1609dot2::HashedId3::decode_bytewise(input)?;
let (input, crl_series) = ieee1609dot2::CrlSeries::decode_bytewise(input)?;
let input = if extended {
let (mut input, bitmap) = decode_bytewise_bitstring(Some(0), None, false, input)?;
// consume unknown extensions
for bit in bitmap {
if bit {
input = decode_bytewise_octetstring(Some(0), None, false, input)?.0;
}
}
input
} else {
input
};
Ok((
input,
Self {
craca_id,
crl_series,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::HeaderInfo<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (extended, bitmap)) = decode_bytewise_sequence_preamble(true, 6, input)?;
let (input, psid) = ieee1609dot2::Psid::decode_bytewise(input)?;
let (input, generation_time) = if bitmap[0] {
map(ieee1609dot2::Time64::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, expiry_time) = if bitmap[1] {
map(ieee1609dot2::Time64::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, generation_location) = if bitmap[2] {
map(ieee1609dot2::ThreeDLocation::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, p2pcd_learning_request) = if bitmap[3] {
map(ieee1609dot2::HashedId3::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, missing_crl_identifier) = if bitmap[4] {
map(ieee1609dot2::MissingCrlIdentifier::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, encryption_key) = if bitmap[5] {
map(ieee1609dot2::EncryptionKey::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (
input,
inline_p2pcd_request,
requested_certificate,
pdu_functional_type,
contributed_extensions,
) = if extended {
let (input, bitmap) = decode_bytewise_bitstring(Some(0), None, false, input)?;
#[allow(clippy::get_first, reason = "similarity to subsequent lines")]
let (input, inline_p2pcd_request) = if bitmap.get(0).is_some_and(|bit| *bit) {
decode_bytewise_open_type(ieee1609dot2::SequenceOfHashedId3::decode_bytewise, input)
.map(|(rem, req)| (rem, Some(req)))?
} else {
(input, None)
};
let (input, requested_certificate) = if bitmap.get(1).is_some_and(|bit| *bit) {
decode_bytewise_open_type(ieee1609dot2::Certificate::decode_bytewise, input)
.map(|(rem, cert)| (rem, Some(cert)))?
} else {
(input, None)
};
let (input, pdu_functional_type) = if bitmap.get(2).is_some_and(|bit| *bit) {
decode_bytewise_open_type(ieee1609dot2::PduFunctionalType::decode_bytewise, input)
.map(|(rem, ty)| (rem, Some(ty)))?
} else {
(input, None)
};
let (mut input, contributed_extensions) = if bitmap.get(3).is_some_and(|bit| *bit) {
decode_bytewise_open_type(
ieee1609dot2::ContributedExtensionBlocks::decode_bytewise,
input,
)
.map(|(rem, extensions)| (rem, Some(extensions)))?
} else {
(input, None)
};
// consume unknown extensions
for bit in bitmap.get(4..).unwrap_or_default() {
if *bit {
input = decode_bytewise_octetstring(Some(0), None, false, input)?.0;
}
}
(
input,
inline_p2pcd_request,
requested_certificate,
pdu_functional_type,
contributed_extensions,
)
} else {
(input, None, None, None, None)
};
Ok((
input,
Self {
psid,
generation_time,
expiry_time,
generation_location,
p2pcd_learning_request,
missing_crl_identifier,
encryption_key,
inline_p2pcd_request,
requested_certificate,
pdu_functional_type,
contributed_extensions,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EncryptedData<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, recipients) = ieee1609dot2::SequenceOfRecipientInfo::decode_bytewise(input)?;
let (input, ciphertext) = ieee1609dot2::SymmetricCiphertext::decode_bytewise(input)?;
Ok((
input,
Self {
recipients,
ciphertext,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SymmRecipientInfo<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, recipient_id) = ieee1609dot2::HashedId8::decode_bytewise(input)?;
let (input, enc_key) = ieee1609dot2::SymmetricCiphertext::decode_bytewise(input)?;
Ok((
input,
Self {
recipient_id,
enc_key,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::PKRecipientInfo<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, recipient_id) = ieee1609dot2::HashedId8::decode_bytewise(input)?;
let (input, enc_key) = ieee1609dot2::EncryptedDataEncryptionKey::decode_bytewise(input)?;
Ok((
input,
Self {
recipient_id,
enc_key,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::One28BitCcmCiphertext<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, nonce) = decode_bytewise_octetstring(Some(12), Some(12), false, input)?;
let (input, ccm_ciphertext) = ieee1609dot2::Opaque::decode_bytewise(input)?;
Ok((
input,
Self {
nonce,
ccm_ciphertext,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EncryptedDataEncryptionKey<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, key) = ieee1609dot2::EciesP256EncryptedKey::decode_bytewise(input)?;
Ok((input, Self::EciesNistP256(key)))
}
1 => {
let (input, key) = ieee1609dot2::EciesP256EncryptedKey::decode_bytewise(input)?;
Ok((input, Self::EciesBrainpoolP256r1(key)))
}
2 => {
let (input, key) = decode_bytewise_open_type(
ieee1609dot2::EcencP256EncryptedKey::decode_bytewise,
input,
)?;
Ok((input, Self::EcencSm2256(key)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SymmetricCiphertext<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, cipher) = ieee1609dot2::One28BitCcmCiphertext::decode_bytewise(input)?;
Ok((input, Self::Aes128ccm(cipher)))
}
1 => {
let (input, cipher) = decode_bytewise_open_type(
ieee1609dot2::One28BitCcmCiphertext::decode_bytewise,
input,
)?;
Ok((input, Self::Sm4Ccm(cipher)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::IssuerIdentifier<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, id) = ieee1609dot2::HashedId8::decode_bytewise(input)?;
Ok((input, Self::Sha256AndDigest(id)))
}
1 => {
let (input, id) = ieee1609dot2::HashAlgorithm::decode_bytewise(input)?;
Ok((input, Self::RsSelf(id)))
}
2 => {
let (input, id) =
decode_bytewise_open_type(ieee1609dot2::HashedId8::decode_bytewise, input)?;
Ok((input, Self::Sha384AndDigest(id)))
}
3 => {
let (input, id) =
decode_bytewise_open_type(ieee1609dot2::HashedId8::decode_bytewise, input)?;
Ok((input, Self::Sm3AndDigest(id)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CertificateBase<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
#[cfg(feature = "validate")]
let (input_before, length_before) = (input, input.len());
let (input, (_, bitmap)) = decode_bytewise_sequence_preamble(false, 1, input)?;
let (input, version) = ieee1609dot2::Uint8::decode_bytewise(input)?;
let (input, r_type) = ieee1609dot2::CertificateType::decode_bytewise(input)?;
let (input, issuer) = ieee1609dot2::IssuerIdentifier::decode_bytewise(input)?;
let (input, to_be_signed) = ieee1609dot2::ToBeSignedCertificate::decode_bytewise(input)?;
let (input, signature) = if bitmap[0] {
map(ieee1609dot2::Signature::decode_bytewise, Some)(input)?
} else {
(input, None)
};
Ok((
input,
Self {
version,
r_type,
issuer,
to_be_signed,
signature,
#[cfg(feature = "validate")]
raw: &input_before[..length_before - input.len()],
},
))
}
}
#[allow(clippy::too_many_lines)]
impl<'s> InternalDecode<'s> for ieee1609dot2::ToBeSignedCertificate<'s> {
#[allow(clippy::too_many_lines)]
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (extended, bitmap)) = decode_bytewise_sequence_preamble(true, 7, input)?;
let (input, id) = ieee1609dot2::CertificateId::decode_bytewise(input)?;
let (input, craca_id) = ieee1609dot2::HashedId3::decode_bytewise(input)?;
let (input, crl_series) = ieee1609dot2::CrlSeries::decode_bytewise(input)?;
let (input, validity_period) = ieee1609dot2::ValidityPeriod::decode_bytewise(input)?;
let (input, region) = if bitmap[0] {
map(ieee1609dot2::GeographicRegion::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, assurance_level) = if bitmap[1] {
map(ieee1609dot2::SubjectAssurance::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, app_permissions) = if bitmap[2] {
map(ieee1609dot2::SequenceOfPsidSsp::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, cert_issue_permissions) = if bitmap[3] {
map(
ieee1609dot2::SequenceOfPsidGroupPermissions::decode_bytewise,
Some,
)(input)?
} else {
(input, None)
};
let (input, cert_request_permissions) = if bitmap[4] {
map(
ieee1609dot2::SequenceOfPsidGroupPermissions::decode_bytewise,
Some,
)(input)?
} else {
(input, None)
};
let (input, can_request_rollover) = (input, bitmap[5].then_some(()));
let (input, encryption_key) = if bitmap[6] {
map(ieee1609dot2::PublicEncryptionKey::decode_bytewise, Some)(input)?
} else {
(input, None)
};
let (input, verify_key_indicator) =
ieee1609dot2::VerificationKeyIndicator::decode_bytewise(input)?;
let (input, flags, app_extensions, cert_issue_extensions, cert_request_extension) =
if extended {
let (input, bitmap) = decode_bytewise_bitstring(Some(0), None, false, input)?;
#[allow(clippy::get_first, reason = "similarity to subsequent lines")]
let (input, flags) = if bitmap.get(0).is_some_and(|bit| *bit) {
decode_bytewise_open_type(ieee1609dot2::BitString::<8>::decode_bytewise, input)
.map(|(rem, flags)| (rem, Some(flags)))?
} else {
(input, None)
};
let (input, app_extensions) = if bitmap.get(1).is_some_and(|bit| *bit) {
decode_bytewise_open_type(
ieee1609dot2::SequenceOfAppExtensions::decode_bytewise,
input,
)
.map(|(rem, extensions)| (rem, Some(extensions)))?
} else {
(input, None)
};
let (input, cert_issue_extensions) = if bitmap.get(2).is_some_and(|bit| *bit) {
decode_bytewise_open_type(
ieee1609dot2::SequenceOfCertIssueExtensions::decode_bytewise,
input,
)
.map(|(rem, extensions)| (rem, Some(extensions)))?
} else {
(input, None)
};
let (mut input, cert_request_extensions) = if bitmap.get(3).is_some_and(|bit| *bit)
{
decode_bytewise_open_type(
ieee1609dot2::SequenceOfCertRequestExtensions::decode_bytewise,
input,
)
.map(|(rem, extensions)| (rem, Some(extensions)))?
} else {
(input, None)
};
// consume unknown extensions
for bit in bitmap.get(4..).unwrap_or_default() {
if *bit {
input = decode_bytewise_octetstring(Some(0), None, false, input)?.0;
}
}
(
input,
flags,
app_extensions,
cert_issue_extensions,
cert_request_extensions,
)
} else {
(input, None, None, None, None)
};
Ok((
input,
Self {
id,
craca_id,
crl_series,
validity_period,
region,
assurance_level,
app_permissions,
cert_issue_permissions,
cert_request_permissions,
can_request_rollover,
encryption_key,
verify_key_indicator,
flags,
app_extensions,
cert_issue_extensions,
cert_request_extension,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::AppExtension<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, id) = ieee1609dot2::ExtId::decode_bytewise(input)?;
let (input, content) = decode_bytewise_octetstring(Some(0), None, false, input)?;
Ok((input, Self { id, content }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::ContributedExtensionBlockExtns<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let mut sequence_of = alloc::vec![];
let (mut input, count) = decode_bytewise_integer(Some(1), None, false, input)?;
for _ in 0..count {
let (rem, item) = decode_bytewise_octetstring(Some(0), None, false, input)?;
input = rem;
sequence_of.push(ieee1609dot2::AnonymousContributedExtensionBlockExtns(item));
}
Ok((input, Self(sequence_of)))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::ContributedExtensionBlock<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, contributor_id) =
ieee1609dot2::HeaderInfoContributorId::decode_bytewise(input)?;
let (input, extns) = ieee1609dot2::ContributedExtensionBlockExtns::decode_bytewise(input)?;
Ok((
input,
Self {
contributor_id,
extns,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CertIssueExtension<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, id) = ieee1609dot2::ExtId::decode_bytewise(input)?;
let (input, permissions) =
ieee1609dot2::CertIssueExtensionPermissions::decode_bytewise(input)?;
Ok((input, Self { id, permissions }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CertIssueExtensionPermissions<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, data) = decode_bytewise_octetstring(Some(0), None, false, input)?;
Ok((input, Self::Specific(data)))
}
1 => Ok((input, Self::All(()))),
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CertRequestExtension<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, id) = ieee1609dot2::ExtId::decode_bytewise(input)?;
let (input, permissions) =
ieee1609dot2::CertRequestExtensionPermissions::decode_bytewise(input)?;
Ok((input, Self { id, permissions }))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CertRequestExtensionPermissions<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, data) = decode_bytewise_octetstring(Some(0), None, false, input)?;
Ok((input, Self::Content(data)))
}
1 => Ok((input, Self::All(()))),
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::CertificateId<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, id) = ieee1609dot2::LinkageData::decode_bytewise(input)?;
Ok((input, Self::LinkageData(id)))
}
1 => {
let (input, id) = ieee1609dot2::Hostname::decode_bytewise(input)?;
Ok((input, Self::Name(id)))
}
2 => {
let (input, id) = decode_bytewise_octetstring(Some(1), Some(64), false, input)?;
Ok((input, Self::BinaryId(id)))
}
3 => Ok((input, Self::None(()))),
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::LinkageData<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (_, bitmap)) = decode_bytewise_sequence_preamble(false, 1, input)?;
let (input, i_cert) = ieee1609dot2::IValue::decode_bytewise(input)?;
let (input, linkage_value) = ieee1609dot2::LinkageValue::decode_bytewise(input)?;
let (input, group_linkage_value) = if bitmap[0] {
map(ieee1609dot2::GroupLinkageValue::decode_bytewise, Some)(input)?
} else {
(input, None)
};
Ok((
input,
Self {
i_cert,
linkage_value,
group_linkage_value,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::PsidGroupPermissions<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, (_, bitmap)) = decode_bytewise_sequence_preamble(false, 3, input)?;
let (input, subject_permissions) =
ieee1609dot2::SubjectPermissions::decode_bytewise(input)?;
let (input, min_chain_length) = if bitmap[0] {
decode_bytewise_integer(None, None, false, input)?
} else {
(input, 1)
};
let (input, chain_length_range) = if bitmap[1] {
decode_bytewise_integer(None, None, false, input)?
} else {
(input, 0)
};
let (input, ee_type) = if bitmap[2] {
ieee1609dot2::EndEntityType::decode_bytewise(input)?
} else {
(
input,
ieee1609dot2::EndEntityType::from([
true, false, false, false, false, false, false, false,
]),
)
};
Ok((
input,
Self {
subject_permissions,
min_chain_length,
chain_length_range,
ee_type,
},
))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::EndEntityType {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, bitstring) = decode_bytewise_bitstring(Some(8), Some(8), false, input)?;
Ok((input, bitstring.into()))
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::SubjectPermissions<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, exp) = ieee1609dot2::SequenceOfPsidSspRange::decode_bytewise(input)?;
Ok((input, Self::Explicit(exp)))
}
1 => Ok((input, Self::All(()))),
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
impl<'s> InternalDecode<'s> for ieee1609dot2::VerificationKeyIndicator<'s> {
fn decode_bytewise<'input: 's>(input: &'input [u8]) -> IResult<&'input [u8], Self>
where
Self: Sized,
{
let (input, tag) = decode_bytewise_tag(input)?;
match tag {
0 => {
let (input, key) = ieee1609dot2::PublicVerificationKey::decode_bytewise(input)?;
Ok((input, Self::VerificationKey(key)))
}
1 => {
let (input, val) = ieee1609dot2::EccP256CurvePoint::decode_bytewise(input)?;
Ok((input, Self::ReconstructionValue(val)))
}
_ => Err(nom::Err::Error(DecodeError::EnumError(
"Invalid choice index!".into(),
))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn decodes_integer() {
assert_eq!(1u16, u16::decode_bytewise(&[0x00, 0x01]).unwrap().1);
assert_eq!(1i16, i16::decode_bytewise(&[0x00, 0x01]).unwrap().1);
assert_eq!(-1i16, i16::decode_bytewise(&[0xFF, 0xFF]).unwrap().1);
assert_eq!(
1u32,
u32::decode_bytewise(&[0x00, 0x00, 0x00, 0x01]).unwrap().1
);
assert_eq!(
0x1234_5678_u32,
u32::decode_bytewise(&[0x12, 0x34, 0x56, 0x78]).unwrap().1
);
}
#[test]
fn decodes_traffic_class() {
let (_, output) = en302636_4_1::TrafficClass::decode_bytewise(&[0x82]).unwrap();
assert_eq!(
en302636_4_1::TrafficClass {
store_carry_forward: true,
channel_offload: false,
traffic_class_id: u6::from_u8(0x02)
},
output
);
let (_, output) = en302636_4_1::TrafficClass::decode_bytewise(&[0x42]).unwrap();
assert_eq!(
en302636_4_1::TrafficClass {
store_carry_forward: false,
channel_offload: true,
traffic_class_id: u6::from_u8(0x02)
},
output
);
let (_, output) = en302636_4_1::TrafficClass::decode_bytewise(&[0x3f]).unwrap();
assert_eq!(
en302636_4_1::TrafficClass {
store_carry_forward: false,
channel_offload: false,
traffic_class_id: u6::from_u8(0x3f)
},
output
);
}
#[test]
fn decodes_oer_bitstring() {
let ref_val = vec![true];
let oer_input = &[0x80];
let (_, decoded) = decode_bytewise_bitstring(Some(1), Some(1), false, oer_input).unwrap();
assert_eq!(ref_val, decoded);
let ref_val = vec![false, true, false, false, false, false, true, false];
let oer_input = &[0x42];
let (_, decoded) = decode_bytewise_bitstring(Some(8), Some(8), false, oer_input).unwrap();
assert_eq!(ref_val, decoded);
let (_, decoded) = ieee1609dot2::BitString::<8>::decode_bytewise(oer_input).unwrap();
assert_eq!(ref_val, decoded.0);
let ref_val = vec![false, true];
let oer_input = &[2, 6, 0x42];
let (_, decoded) = decode_bytewise_bitstring(None, None, true, oer_input).unwrap();
assert_eq!(ref_val, decoded);
let ref_val = vec![
true, false, false, false, false, false, false, false, false, true,
];
let oer_input = &[3, 6, 0x80, 0x40];
let (_, decoded) = decode_bytewise_bitstring(None, None, true, oer_input).unwrap();
assert_eq!(ref_val, decoded);
}
#[test]
fn decodes_basic_header() {
let data: &'static [u8] = &[
0x12, 0x00, 0x15, 0x01, 0x03, 0x81, 0x00, 0x40, 0x03, 0x80, 0x82, 0x02, 0x7c, 0x20,
0x51, 0x01, 0x00, 0x02, 0x58, 0x01, 0x00, 0x12, 0x52, 0x00, 0x00, 0x3c, 0x00, 0x04,
0xe5, 0x48, 0x10, 0xc7, 0x2e, 0x71, 0x25, 0xab, 0x00, 0x1f, 0xeb, 0xef, 0x74, 0x05,
0xf2, 0xaf, 0x27, 0x80, 0x00, 0x00, 0x00,
];
let result = en302636_4_1::BasicHeader::decode(data).unwrap();
assert_eq!(
result,
Decoded {
bytes_consumed: 4,
decoded: en302636_4_1::BasicHeader::try_new(
1,
en302636_4_1::NextAfterBasic::SecuredPacket,
en302636_4_1::Lifetime(21),
1
)
.unwrap()
}
);
}
#[test]
#[allow(clippy::too_many_lines)]
fn decodes_secure_header() {
assert_eq!(
ieee1609dot2::Ieee1609Dot2Data::decode_bytewise(&[
0x03, 0x81, 0x00, 0x40, 0x03, 0x80, 0x78, 0x20, 0x50, 0x02, 0x80, 0x00, 0x54, 0x01,
0x00, 0x14, 0x00, 0xca, 0x83, 0x1a, 0x3f, 0x3d, 0x39, 0x70, 0xfc, 0x82, 0x80, 0x1f,
0xeb, 0x32, 0x0c, 0x05, 0xec, 0x3a, 0xfd, 0x80, 0x04, 0x0b, 0x90, 0x00, 0x00, 0x00,
0x00, 0x07, 0xd1, 0x00, 0x00, 0x02, 0x02, 0x1a, 0x3f, 0x3d, 0x39, 0x82, 0x80, 0x40,
0x5a, 0xb2, 0x03, 0x61, 0x8e, 0x26, 0xc1, 0x9f, 0xa0, 0xb4, 0x0b, 0x40, 0x00, 0x34,
0x8c, 0x8e, 0x48, 0xb9, 0x1f, 0xa0, 0x00, 0x91, 0x82, 0xe8, 0x92, 0x7f, 0x33, 0xff,
0x01, 0xff, 0xfa, 0x00, 0x28, 0x33, 0x00, 0x00, 0x4b, 0xff, 0x6a, 0xff, 0x15, 0x2e,
0x40, 0x0c, 0x89, 0xdf, 0xa4, 0x48, 0x24, 0x7e, 0x23, 0xd3, 0xc8, 0x1f, 0x02, 0x4a,
0xbe, 0xa5, 0xe8, 0xcf, 0x09, 0x69, 0xf8, 0x0d, 0xed, 0xf4, 0x24, 0x4c, 0x90, 0x33,
0x3f, 0x40, 0x01, 0x24, 0x00, 0x02, 0x30, 0x51, 0x5a, 0x60, 0xed, 0xfa, 0x81, 0x01,
0x01, 0x80, 0x03, 0x00, 0x80, 0x5d, 0x5d, 0xcb, 0xee, 0xfb, 0xe7, 0xd2, 0x2d, 0x30,
0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x81, 0xd9, 0x85, 0x86, 0x00, 0x01, 0xe0,
0x01, 0x07, 0x80, 0x01, 0x24, 0x81, 0x04, 0x03, 0x01, 0xff, 0xfc, 0x80, 0x01, 0x25,
0x81, 0x05, 0x04, 0x01, 0xff, 0xff, 0xff, 0x80, 0x01, 0x8c, 0x81, 0x05, 0x04, 0x02,
0xff, 0xff, 0xe0, 0x00, 0x01, 0x8d, 0x80, 0x02, 0x02, 0x7e, 0x81, 0x02, 0x01, 0x01,
0x80, 0x02, 0x02, 0x7f, 0x81, 0x02, 0x01, 0x01, 0x00, 0x02, 0x03, 0xff, 0x80, 0x80,
0x82, 0x13, 0x43, 0x08, 0xc4, 0x32, 0x4d, 0x5f, 0x47, 0xfc, 0xbe, 0x66, 0x5f, 0xb5,
0x5b, 0x40, 0x98, 0xb3, 0x8b, 0x9c, 0xaa, 0x48, 0x4b, 0xd4, 0x47, 0x4c, 0x6c, 0x52,
0x16, 0x00, 0xa7, 0x50, 0x8c, 0x81, 0x80, 0x3d, 0x9a, 0x96, 0x8a, 0xc1, 0x19, 0x6e,
0x46, 0xea, 0x98, 0x22, 0x6c, 0x55, 0x20, 0x81, 0xa7, 0x7c, 0xdf, 0xbe, 0xd5, 0x8c,
0x76, 0x9a, 0xf2, 0x8c, 0x9f, 0xf9, 0x06, 0xe9, 0x26, 0xd9, 0x22, 0x40, 0x5f, 0x18,
0x9a, 0x1c, 0x6a, 0x03, 0x19, 0x89, 0x68, 0x96, 0x0a, 0x93, 0x32, 0x50, 0x06, 0xaf,
0xfb, 0x84, 0x40, 0x4c, 0x93, 0x16, 0x80, 0x69, 0x8f, 0xff, 0x27, 0xc8, 0xf3, 0x12,
0x7e, 0x80, 0x83, 0xfc, 0xbf, 0x3a, 0x5b, 0xf9, 0x8c, 0x14, 0x06, 0x3f, 0xc3, 0x71,
0xff, 0xe0, 0xa7, 0x59, 0xc1, 0x58, 0x92, 0x13, 0x5d, 0x6a, 0xbb, 0x47, 0x1b, 0xa2,
0x4e, 0xce, 0x6f, 0x00, 0xd3, 0x92, 0xfb, 0xd9, 0x43, 0xc5, 0x65, 0x5d, 0xae, 0x46,
0x97, 0x1b, 0x3b, 0x09, 0x39, 0x59, 0x71, 0x15, 0x84, 0x10, 0x5b, 0x22, 0x30, 0x78,
0x3d, 0x91, 0x72, 0x00, 0xfb, 0x3e, 0x9d, 0xdb, 0x44, 0x0b, 0x1c
])
.unwrap()
.1,
ieee1609dot2::Ieee1609Dot2Data {
protocol_version: ieee1609dot2::Uint8(3),
content: ieee1609dot2::Ieee1609Dot2Content::SignedData(Box::new(
ieee1609dot2::SignedData {
hash_id: ieee1609dot2::HashAlgorithm::Sha256,
tbs_data: ieee1609dot2::ToBeSignedData {
#[cfg(feature = "validate")]
raw: &[
64, 3, 128, 120, 32, 80, 2, 128, 0, 84, 1, 0, 20, 0, 202, 131, 26,
63, 61, 57, 112, 252, 130, 128, 31, 235, 50, 12, 5, 236, 58, 253,
128, 4, 11, 144, 0, 0, 0, 0, 7, 209, 0, 0, 2, 2, 26, 63, 61, 57,
130, 128, 64, 90, 178, 3, 97, 142, 38, 193, 159, 160, 180, 11, 64,
0, 52, 140, 142, 72, 185, 31, 160, 0, 145, 130, 232, 146, 127, 51,
255, 1, 255, 250, 0, 40, 51, 0, 0, 75, 255, 106, 255, 21, 46, 64,
12, 137, 223, 164, 72, 36, 126, 35, 211, 200, 31, 2, 74, 190, 165,
232, 207, 9, 105, 248, 13, 237, 244, 36, 76, 144, 51, 63, 64, 1,
36, 0, 2, 48, 81, 90, 96, 237, 250
],
payload: ieee1609dot2::SignedDataPayload {
data: Some(ieee1609dot2::Ieee1609Dot2Data {
protocol_version: ieee1609dot2::Uint8(3),
content: ieee1609dot2::Ieee1609Dot2Content::UnsecuredData(
ieee1609dot2::Opaque(&[
32, 80, 2, 128, 0, 84, 1, 0, 20, 0, 202, 131, 26, 63,
61, 57, 112, 252, 130, 128, 31, 235, 50, 12, 5, 236,
58, 253, 128, 4, 11, 144, 0, 0, 0, 0, 7, 209, 0, 0, 2,
2, 26, 63, 61, 57, 130, 128, 64, 90, 178, 3, 97, 142,
38, 193, 159, 160, 180, 11, 64, 0, 52, 140, 142, 72,
185, 31, 160, 0, 145, 130, 232, 146, 127, 51, 255, 1,
255, 250, 0, 40, 51, 0, 0, 75, 255, 106, 255, 21, 46,
64, 12, 137, 223, 164, 72, 36, 126, 35, 211, 200, 31,
2, 74, 190, 165, 232, 207, 9, 105, 248, 13, 237, 244,
36, 76, 144, 51, 63
])
)
}),
ext_data_hash: None,
omitted: None
},
header_info: ieee1609dot2::HeaderInfo {
psid: ieee1609dot2::Psid(36),
generation_time: Some(ieee1609dot2::Uint64(616_075_920_207_354)),
expiry_time: None,
generation_location: None,
p2pcd_learning_request: None,
missing_crl_identifier: None,
encryption_key: None,
inline_p2pcd_request: None,
requested_certificate: None,
pdu_functional_type: None,
contributed_extensions: None
}
},
signer: ieee1609dot2::SignerIdentifier::Certificate(
ieee1609dot2::SequenceOfCertificate(vec![
ieee1609dot2::CertificateBase {
version: ieee1609dot2::Uint8(3),
r_type: ieee1609dot2::CertificateType::Explicit,
issuer: ieee1609dot2::IssuerIdentifier::Sha256AndDigest(
ieee1609dot2::HashedId8(&[
93, 93, 203, 238, 251, 231, 210, 45
])
),
to_be_signed: ieee1609dot2::ToBeSignedCertificate {
id: ieee1609dot2::CertificateId::None(()),
craca_id: ieee1609dot2::HashedId3(&[0, 0, 0]),
crl_series: ieee1609dot2::Uint16(0),
validity_period: ieee1609dot2::ValidityPeriod {
start: ieee1609dot2::Uint32(612_489_605),
duration: ieee1609dot2::Duration::Years(ieee1609dot2::Uint16(1))
},
region: None,
assurance_level: Some(ieee1609dot2::SubjectAssurance(&[224])),
app_permissions: Some(ieee1609dot2::SequenceOfPsidSsp(vec![
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(36),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1, 255, 252])
))
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(37),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1, 255, 255, 255])
))
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(140),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[2, 255, 255, 224])
))
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(141),
ssp: None
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(638),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1])
))
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(639),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1])
))
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(1023),
ssp: None
}
])),
cert_issue_permissions: None,
cert_request_permissions: None,
can_request_rollover: None,
encryption_key: None,
verify_key_indicator:
ieee1609dot2::VerificationKeyIndicator::VerificationKey(
ieee1609dot2::PublicVerificationKey::EcdsaNistP256(
ieee1609dot2::EccP256CurvePoint::CompressedY0(&[
19, 67, 8, 196, 50, 77, 95, 71, 252, 190,
102, 95, 181, 91, 64, 152, 179, 139, 156,
170, 72, 75, 212, 71, 76, 108, 82, 22, 0,
167, 80, 140
])
)
),
flags: None,
app_extensions: None,
cert_issue_extensions: None,
cert_request_extension: None
},
signature: Some(ieee1609dot2::Signature::EcdsaBrainpoolP256r1Signature(
ieee1609dot2::EcdsaP256Signature {
r_sig: ieee1609dot2::EccP256CurvePoint::XOnly(&[
61, 154, 150, 138, 193, 25, 110, 70, 234, 152, 34,
108, 85, 32, 129, 167, 124, 223, 190, 213, 140,
118, 154, 242, 140, 159, 249, 6, 233, 38, 217, 34
]),
s_sig: &[
64, 95, 24, 154, 28, 106, 3, 25, 137, 104, 150, 10,
147, 50, 80, 6, 175, 251, 132, 64, 76, 147, 22,
128, 105, 143, 255, 39, 200, 243, 18, 126
]
}
)),
#[cfg(feature = "validate")]
raw: &[
128, 3, 0, 128, 93, 93, 203, 238, 251, 231, 210, 45, 48,
131, 0, 0, 0, 0, 0, 36, 129, 217, 133, 134, 0, 1, 224, 1,
7, 128, 1, 36, 129, 4, 3, 1, 255, 252, 128, 1, 37, 129, 5,
4, 1, 255, 255, 255, 128, 1, 140, 129, 5, 4, 2, 255, 255,
224, 0, 1, 141, 128, 2, 2, 126, 129, 2, 1, 1, 128, 2, 2,
127, 129, 2, 1, 1, 0, 2, 3, 255, 128, 128, 130, 19, 67, 8,
196, 50, 77, 95, 71, 252, 190, 102, 95, 181, 91, 64, 152,
179, 139, 156, 170, 72, 75, 212, 71, 76, 108, 82, 22, 0,
167, 80, 140, 129, 128, 61, 154, 150, 138, 193, 25, 110,
70, 234, 152, 34, 108, 85, 32, 129, 167, 124, 223, 190,
213, 140, 118, 154, 242, 140, 159, 249, 6, 233, 38, 217,
34, 64, 95, 24, 154, 28, 106, 3, 25, 137, 104, 150, 10,
147, 50, 80, 6, 175, 251, 132, 64, 76, 147, 22, 128, 105,
143, 255, 39, 200, 243, 18, 126
]
}
])
),
signature: ieee1609dot2::Signature::EcdsaNistP256Signature(ieee1609dot2::EcdsaP256Signature {
r_sig: ieee1609dot2::EccP256CurvePoint::CompressedY1(&[
252, 191, 58, 91, 249, 140, 20, 6, 63, 195, 113, 255, 224, 167, 89,
193, 88, 146, 19, 93, 106, 187, 71, 27, 162, 78, 206, 111, 0, 211,
146, 251
]),
s_sig: &[
217, 67, 197, 101, 93, 174, 70, 151, 27, 59, 9, 57, 89, 113, 21,
132, 16, 91, 34, 48, 120, 61, 145, 114, 0, 251, 62, 157, 219, 68,
11, 28
]
})
}
))
}
);
}
#[test]
// test to ensure proper encoding of BIT STRING data
fn round_trip_to_be_signed_certificate() {
let ref_bytes = &[
0xb0, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x81, 0xd9, 0x85, 0x86, 0x00, 0x01,
0xe0, 0x01, 0x07, 0x80, 0x01, 0x24, 0x81, 0x04, 0x03, 0x01, 0xff, 0xfc, 0x80, 0x01,
0x25, 0x81, 0x05, 0x04, 0x01, 0xff, 0xff, 0xff, 0x80, 0x01, 0x8c, 0x81, 0x05, 0x04,
0x02, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x8d, 0x80, 0x02, 0x02, 0x7e, 0x81, 0x02, 0x01,
0x01, 0x80, 0x02, 0x02, 0x7f, 0x81, 0x02, 0x01, 0x01, 0x00, 0x02, 0x03, 0xff, 0x80,
0x80, 0x82, 0x13, 0x43, 0x08, 0xc4, 0x32, 0x4d, 0x5f, 0x47, 0xfc, 0xbe, 0x66, 0x5f,
0xb5, 0x5b, 0x40, 0x98, 0xb3, 0x8b, 0x9c, 0xaa, 0x48, 0x4b, 0xd4, 0x47, 0x4c, 0x6c,
0x52, 0x16, 0x00, 0xa7, 0x50, 0x8c,
0x02, // extension addition presence bitmap: length determinant
0x04, // extension addition presence bitmap: how many unused bits -> 4
0x80, // extension addition presence bitmap: bitmap -> ext. 1 present, 2-4 not present
0x01, // open type encoding: length
0x80, // fixed size BIT STRING: 0b1000.0000
];
let data = ieee1609dot2::ToBeSignedCertificate {
id: ieee1609dot2::CertificateId::None(()),
craca_id: ieee1609dot2::HashedId3(&[0, 0, 0]),
crl_series: ieee1609dot2::Uint16(0),
validity_period: ieee1609dot2::ValidityPeriod {
start: ieee1609dot2::Uint32(612_489_605),
duration: ieee1609dot2::Duration::Years(ieee1609dot2::Uint16(1)),
},
region: None,
assurance_level: Some(ieee1609dot2::SubjectAssurance(&[224])),
app_permissions: Some(ieee1609dot2::SequenceOfPsidSsp(vec![
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(36),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1, 255, 252]),
)),
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(37),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1, 255, 255, 255]),
)),
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(140),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[2, 255, 255, 224]),
)),
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(141),
ssp: None,
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(638),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1]),
)),
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(639),
ssp: Some(ieee1609dot2::ServiceSpecificPermissions::BitmapSsp(
ieee1609dot2::BitmapSsp(&[1]),
)),
},
ieee1609dot2::PsidSsp {
psid: ieee1609dot2::Psid(1023),
ssp: None,
},
])),
cert_issue_permissions: None,
cert_request_permissions: None,
can_request_rollover: None,
encryption_key: None,
verify_key_indicator: ieee1609dot2::VerificationKeyIndicator::VerificationKey(
ieee1609dot2::PublicVerificationKey::EcdsaNistP256(
ieee1609dot2::EccP256CurvePoint::CompressedY0(&[
19, 67, 8, 196, 50, 77, 95, 71, 252, 190, 102, 95, 181, 91, 64, 152, 179,
139, 156, 170, 72, 75, 212, 71, 76, 108, 82, 22, 0, 167, 80, 140,
]),
),
),
flags: Some(vec![true, false, false, false, false, false, false, false].into()),
app_extensions: None,
cert_issue_extensions: None,
cert_request_extension: None,
};
let decoded = ieee1609dot2::ToBeSignedCertificate::decode_bytewise(ref_bytes).unwrap();
pretty_assertions::assert_eq!(data, decoded.1);
let bytes = data.encode_to_vec().unwrap();
assert_eq!(*ref_bytes, *bytes);
}
}