Skip to content

Commit 5d903ea

Browse files
authored
der: conversions between BitStringRef/OctetStringRef and [u8; N] (#1731)
These are helpful for custom drive when struct fields are byte arrays
1 parent 4bbb640 commit 5d903ea

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

Diff for: der/src/asn1/bit_string.rs

+18
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,24 @@ impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
193193
}
194194
}
195195

196+
impl<'a, const N: usize> TryFrom<&'a [u8; N]> for BitStringRef<'a> {
197+
type Error = Error;
198+
199+
fn try_from(bytes: &'a [u8; N]) -> Result<BitStringRef<'a>> {
200+
BitStringRef::from_bytes(bytes)
201+
}
202+
}
203+
204+
impl<'a, const N: usize> TryFrom<BitStringRef<'a>> for [u8; N] {
205+
type Error = Error;
206+
207+
fn try_from(bit_string: BitStringRef<'a>) -> Result<Self> {
208+
let bytes: &[u8] = TryFrom::try_from(bit_string)?;
209+
210+
bytes.try_into().map_err(|_| Tag::BitString.length_error())
211+
}
212+
}
213+
196214
impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
197215
type Error = Error;
198216

Diff for: der/src/asn1/octet_string.rs

+19
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,25 @@ impl<'a> TryFrom<&&'a [u8]> for OctetStringRef<'a> {
113113
}
114114
}
115115

116+
impl<'a, const N: usize> TryFrom<&'a [u8; N]> for OctetStringRef<'a> {
117+
type Error = Error;
118+
119+
fn try_from(byte_slice: &'a [u8; N]) -> Result<Self, Error> {
120+
OctetStringRef::new(byte_slice)
121+
}
122+
}
123+
124+
impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for [u8; N] {
125+
type Error = Error;
126+
127+
fn try_from(octet_string: OctetStringRef<'a>) -> Result<Self, Self::Error> {
128+
octet_string
129+
.as_bytes()
130+
.try_into()
131+
.map_err(|_| Tag::OctetString.length_error())
132+
}
133+
}
134+
116135
#[cfg(feature = "alloc")]
117136
pub use self::allocating::OctetString;
118137

Diff for: der/tests/derive.rs

+80-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ mod sequence {
528528
pub owned_optional_implicit_bytes: Option<Vec<u8>>,
529529

530530
#[asn1(
531-
type = "OCTET STRING",
531+
type = "BIT STRING",
532532
context_specific = "6",
533533
optional = "true",
534534
tag_mode = "EXPLICIT"
@@ -568,6 +568,85 @@ mod sequence {
568568
assert_eq!(obj, obj_decoded);
569569
}
570570

571+
#[derive(Sequence, Default, Eq, PartialEq, Debug)]
572+
#[asn1(tag_mode = "IMPLICIT")]
573+
pub struct TypeCheckArraysSequenceFieldAttributeCombinations {
574+
#[asn1(type = "OCTET STRING", deref = "true")]
575+
pub array_bytes: [u8; 2],
576+
577+
#[asn1(type = "BIT STRING", deref = "true")]
578+
pub array_bits: [u8; 2],
579+
580+
#[asn1(type = "OCTET STRING", context_specific = "0", deref = "true")]
581+
pub array_implicit_bytes: [u8; 2],
582+
583+
#[asn1(type = "BIT STRING", context_specific = "1", deref = "true")]
584+
pub array_implicit_bits: [u8; 2],
585+
586+
#[asn1(
587+
type = "OCTET STRING",
588+
context_specific = "2",
589+
tag_mode = "EXPLICIT",
590+
deref = "true"
591+
)]
592+
pub array_explicit_bytes: [u8; 2],
593+
594+
#[asn1(
595+
type = "BIT STRING",
596+
context_specific = "3",
597+
tag_mode = "EXPLICIT",
598+
deref = "true"
599+
)]
600+
pub array_explicit_bits: [u8; 2],
601+
602+
#[asn1(type = "BIT STRING", context_specific = "4", optional = "true")]
603+
pub array_optional_implicit_bits: Option<[u8; 2]>,
604+
605+
#[asn1(type = "OCTET STRING", context_specific = "5", optional = "true")]
606+
pub array_optional_implicit_bytes: Option<[u8; 2]>,
607+
608+
#[asn1(
609+
type = "BIT STRING",
610+
context_specific = "6",
611+
optional = "true",
612+
tag_mode = "EXPLICIT"
613+
)]
614+
pub array_optional_explicit_bits: Option<[u8; 2]>,
615+
616+
#[asn1(
617+
type = "OCTET STRING",
618+
context_specific = "7",
619+
optional = "true",
620+
tag_mode = "EXPLICIT"
621+
)]
622+
pub array_optional_explicit_bytes: Option<[u8; 2]>,
623+
}
624+
625+
#[test]
626+
fn type_combinations_arrays_instance() {
627+
let obj = TypeCheckArraysSequenceFieldAttributeCombinations {
628+
array_bytes: [0xAA, 0xBB],
629+
array_bits: [0xCC, 0xDD],
630+
631+
array_implicit_bytes: [0, 1],
632+
array_implicit_bits: [2, 3],
633+
634+
array_explicit_bytes: [4, 5],
635+
array_explicit_bits: [6, 7],
636+
637+
array_optional_implicit_bits: Some([8, 9]),
638+
array_optional_implicit_bytes: Some([10, 11]),
639+
640+
array_optional_explicit_bits: Some([12, 13]),
641+
array_optional_explicit_bytes: Some([14, 15]),
642+
};
643+
644+
let der_encoded = obj.to_der().unwrap();
645+
let obj_decoded =
646+
TypeCheckArraysSequenceFieldAttributeCombinations::from_der(&der_encoded).unwrap();
647+
assert_eq!(obj, obj_decoded);
648+
}
649+
571650
#[derive(Sequence)]
572651
#[asn1(error = CustomError)]
573652
pub struct TypeWithCustomError {

0 commit comments

Comments
 (0)