From f5a480f991d6be7a929e9d77086520918e189366 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:26:51 +0200 Subject: [PATCH 1/7] gss-api: change `NegHints::hint_name` to GeneralStringRef type --- gss-api/src/negotiation.rs | 51 ++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/gss-api/src/negotiation.rs b/gss-api/src/negotiation.rs index 22a22e59c..077319a75 100644 --- a/gss-api/src/negotiation.rs +++ b/gss-api/src/negotiation.rs @@ -1,6 +1,6 @@ //! Negotiation-related types use der::{ - AnyRef, Choice, Enumerated, Sequence, + Choice, DecodeValue, EncodeValue, Enumerated, FixedTag, Sequence, Tag, asn1::{BitString, OctetStringRef}, }; @@ -295,14 +295,8 @@ pub enum NegState { #[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)] pub struct NegHints<'a> { /// SHOULD<5> contain the string "not_defined_in_RFC4178@please_ignore". - /// This is currently `AnyRef` as `GeneralString` is not part of the `der` crate - #[asn1( - context_specific = "0", - optional = "true", - tag_mode = "IMPLICIT", - constructed = "true" - )] - pub hint_name: Option>, // TODO: GeneralString + #[asn1(context_specific = "0", optional = "true")] + pub hint_name: Option>, // TODO: der GeneralString /// Never present. MUST be omitted by the sender. Note that the encoding rules, as specified in [X690], require that this structure not be present at all, not just be zero. /// @@ -356,6 +350,37 @@ pub struct NegTokenInit2<'a> { pub mech_list_mic: Option>, } +/// This is currently `OctetStringRef` as `GeneralString` is not part of the `der` crate +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct GeneralStringRef<'a> { + /// Raw contents, unchecked + pub contents: OctetStringRef<'a>, +} +impl FixedTag for GeneralStringRef<'_> { + const TAG: Tag = Tag::GeneralString; +} +impl<'a> DecodeValue<'a> for GeneralStringRef<'a> { + type Error = der::Error; + + fn decode_value>( + reader: &mut R, + header: der::Header, + ) -> Result { + Ok(Self { + contents: OctetStringRef::decode_value(reader, header)?, + }) + } +} +impl EncodeValue for GeneralStringRef<'_> { + fn value_len(&self) -> der::Result { + self.contents.value_len() + } + + fn encode_value(&self, encoder: &mut impl der::Writer) -> der::Result<()> { + self.contents.encode_value(encoder) + } +} + #[cfg(test)] #[allow(clippy::unwrap_used)] mod tests { @@ -389,7 +414,13 @@ mod tests { ); assert_eq!( b"not_defined_in_RFC4178@please_ignore", - &neg_token.neg_hints.unwrap().hint_name.unwrap().value()[2..] + &neg_token + .neg_hints + .unwrap() + .hint_name + .unwrap() + .contents + .as_bytes() ); } From c7dc16e30d635e27b2dcc2df9f5a2a85228b3396 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Tue, 22 Apr 2025 22:42:21 +0200 Subject: [PATCH 2/7] remove TODO Co-authored-by: Arthur Gautier --- gss-api/src/negotiation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gss-api/src/negotiation.rs b/gss-api/src/negotiation.rs index 077319a75..654142440 100644 --- a/gss-api/src/negotiation.rs +++ b/gss-api/src/negotiation.rs @@ -296,7 +296,7 @@ pub enum NegState { pub struct NegHints<'a> { /// SHOULD<5> contain the string "not_defined_in_RFC4178@please_ignore". #[asn1(context_specific = "0", optional = "true")] - pub hint_name: Option>, // TODO: der GeneralString + pub hint_name: Option>, /// Never present. MUST be omitted by the sender. Note that the encoding rules, as specified in [X690], require that this structure not be present at all, not just be zero. /// From c2b95a074d37021826928b5f7e62c1820af2ed4a Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Thu, 24 Apr 2025 00:06:33 +0200 Subject: [PATCH 3/7] der: add minimal GeneralStringRef type --- der/src/asn1.rs | 2 ++ der/src/asn1/general_string.rs | 32 +++++++++++++++++++++++++++++ gss-api/src/negotiation.rs | 37 +++------------------------------- 3 files changed, 37 insertions(+), 34 deletions(-) create mode 100644 der/src/asn1/general_string.rs diff --git a/der/src/asn1.rs b/der/src/asn1.rs index 3bbd0a0f6..22cc4d0ad 100644 --- a/der/src/asn1.rs +++ b/der/src/asn1.rs @@ -11,6 +11,7 @@ mod bmp_string; mod boolean; mod choice; mod context_specific; +mod general_string; mod generalized_time; mod ia5_string; mod integer; @@ -35,6 +36,7 @@ pub use self::{ bit_string::{BitStringIter, BitStringRef}, choice::Choice, context_specific::{ContextSpecific, ContextSpecificRef}, + general_string::GeneralStringRef, generalized_time::GeneralizedTime, ia5_string::Ia5StringRef, integer::{int::IntRef, uint::UintRef}, diff --git a/der/src/asn1/general_string.rs b/der/src/asn1/general_string.rs new file mode 100644 index 000000000..8de41e4d1 --- /dev/null +++ b/der/src/asn1/general_string.rs @@ -0,0 +1,32 @@ +use crate::{DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer}; + +use super::OctetStringRef; + +/// This is currently `OctetStringRef` as `GeneralString` is not part of the `der` crate +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct GeneralStringRef<'a> { + /// Raw contents, unchecked + #[doc(hidden)] + pub __contents: OctetStringRef<'a>, +} +impl FixedTag for GeneralStringRef<'_> { + const TAG: Tag = Tag::GeneralString; +} +impl<'a> DecodeValue<'a> for GeneralStringRef<'a> { + type Error = crate::Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { + Ok(Self { + __contents: OctetStringRef::decode_value(reader, header)?, + }) + } +} +impl EncodeValue for GeneralStringRef<'_> { + fn value_len(&self) -> crate::Result { + self.__contents.value_len() + } + + fn encode_value(&self, encoder: &mut impl Writer) -> crate::Result<()> { + self.__contents.encode_value(encoder) + } +} diff --git a/gss-api/src/negotiation.rs b/gss-api/src/negotiation.rs index 654142440..4b303c053 100644 --- a/gss-api/src/negotiation.rs +++ b/gss-api/src/negotiation.rs @@ -1,7 +1,7 @@ //! Negotiation-related types use der::{ - Choice, DecodeValue, EncodeValue, Enumerated, FixedTag, Sequence, Tag, - asn1::{BitString, OctetStringRef}, + Choice, Enumerated, Sequence, + asn1::{BitString, GeneralStringRef, OctetStringRef}, }; use crate::MechType; @@ -350,37 +350,6 @@ pub struct NegTokenInit2<'a> { pub mech_list_mic: Option>, } -/// This is currently `OctetStringRef` as `GeneralString` is not part of the `der` crate -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct GeneralStringRef<'a> { - /// Raw contents, unchecked - pub contents: OctetStringRef<'a>, -} -impl FixedTag for GeneralStringRef<'_> { - const TAG: Tag = Tag::GeneralString; -} -impl<'a> DecodeValue<'a> for GeneralStringRef<'a> { - type Error = der::Error; - - fn decode_value>( - reader: &mut R, - header: der::Header, - ) -> Result { - Ok(Self { - contents: OctetStringRef::decode_value(reader, header)?, - }) - } -} -impl EncodeValue for GeneralStringRef<'_> { - fn value_len(&self) -> der::Result { - self.contents.value_len() - } - - fn encode_value(&self, encoder: &mut impl der::Writer) -> der::Result<()> { - self.contents.encode_value(encoder) - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] mod tests { @@ -419,7 +388,7 @@ mod tests { .unwrap() .hint_name .unwrap() - .contents + .__contents .as_bytes() ); } From 9f5391da07f99904f5aa9b19a8bd9c16266b3334 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Thu, 24 Apr 2025 00:13:52 +0200 Subject: [PATCH 4/7] der: docs GeneralStringRef --- der/src/asn1/general_string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/der/src/asn1/general_string.rs b/der/src/asn1/general_string.rs index 8de41e4d1..fc3a9a785 100644 --- a/der/src/asn1/general_string.rs +++ b/der/src/asn1/general_string.rs @@ -2,7 +2,7 @@ use crate::{DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Wri use super::OctetStringRef; -/// This is currently `OctetStringRef` as `GeneralString` is not part of the `der` crate +/// This is currently `OctetStringRef` internally, as `GeneralString` is not fully implemented yet #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct GeneralStringRef<'a> { /// Raw contents, unchecked From e37e4a8375eecef55e26c71f0ccf30b8f726e835 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Thu, 24 Apr 2025 21:28:32 +0200 Subject: [PATCH 5/7] der: change GeneralStringRef.__contents to &[u8] --- der/src/asn1/general_string.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/der/src/asn1/general_string.rs b/der/src/asn1/general_string.rs index fc3a9a785..9980daf8b 100644 --- a/der/src/asn1/general_string.rs +++ b/der/src/asn1/general_string.rs @@ -1,13 +1,11 @@ -use crate::{DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer}; - -use super::OctetStringRef; +use crate::{BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer}; /// This is currently `OctetStringRef` internally, as `GeneralString` is not fully implemented yet #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct GeneralStringRef<'a> { /// Raw contents, unchecked #[doc(hidden)] - pub __contents: OctetStringRef<'a>, + pub __contents: &'a [u8], } impl FixedTag for GeneralStringRef<'_> { const TAG: Tag = Tag::GeneralString; @@ -17,16 +15,16 @@ impl<'a> DecodeValue<'a> for GeneralStringRef<'a> { fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(Self { - __contents: OctetStringRef::decode_value(reader, header)?, + __contents: BytesRef::decode_value(reader, header)?.as_slice(), }) } } impl EncodeValue for GeneralStringRef<'_> { fn value_len(&self) -> crate::Result { - self.__contents.value_len() + BytesRef::new(self.__contents)?.value_len() } fn encode_value(&self, encoder: &mut impl Writer) -> crate::Result<()> { - self.__contents.encode_value(encoder) + BytesRef::new(self.__contents)?.encode_value(encoder) } } From 36e100b92aa5d3bad53d0e57c19cef71c6c02703 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Thu, 24 Apr 2025 21:35:03 +0200 Subject: [PATCH 6/7] gss-api: use __contents in test --- gss-api/src/negotiation.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gss-api/src/negotiation.rs b/gss-api/src/negotiation.rs index 4b303c053..6ac3b8e98 100644 --- a/gss-api/src/negotiation.rs +++ b/gss-api/src/negotiation.rs @@ -383,13 +383,7 @@ mod tests { ); assert_eq!( b"not_defined_in_RFC4178@please_ignore", - &neg_token - .neg_hints - .unwrap() - .hint_name - .unwrap() - .__contents - .as_bytes() + &neg_token.neg_hints.unwrap().hint_name.unwrap().__contents ); } From a3b26cc39362c47087801735ab90cc611d184d61 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Fri, 25 Apr 2025 11:24:34 +0200 Subject: [PATCH 7/7] der: change GeneralStringRef.inner to BytesRef --- der/src/asn1/general_string.rs | 18 ++++++++++++------ gss-api/src/negotiation.rs | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/der/src/asn1/general_string.rs b/der/src/asn1/general_string.rs index 9980daf8b..95b941503 100644 --- a/der/src/asn1/general_string.rs +++ b/der/src/asn1/general_string.rs @@ -1,12 +1,18 @@ use crate::{BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer}; -/// This is currently `OctetStringRef` internally, as `GeneralString` is not fully implemented yet +/// This is currently `&[u8]` internally, as `GeneralString` is not fully implemented yet #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct GeneralStringRef<'a> { /// Raw contents, unchecked - #[doc(hidden)] - pub __contents: &'a [u8], + inner: BytesRef<'a>, } +impl<'a> GeneralStringRef<'a> { + /// This is currently `&[u8]` internally, as `GeneralString` is not fully implemented yet + pub fn as_bytes(&self) -> &'a [u8] { + self.inner.as_slice() + } +} + impl FixedTag for GeneralStringRef<'_> { const TAG: Tag = Tag::GeneralString; } @@ -15,16 +21,16 @@ impl<'a> DecodeValue<'a> for GeneralStringRef<'a> { fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(Self { - __contents: BytesRef::decode_value(reader, header)?.as_slice(), + inner: BytesRef::decode_value(reader, header)?, }) } } impl EncodeValue for GeneralStringRef<'_> { fn value_len(&self) -> crate::Result { - BytesRef::new(self.__contents)?.value_len() + self.inner.value_len() } fn encode_value(&self, encoder: &mut impl Writer) -> crate::Result<()> { - BytesRef::new(self.__contents)?.encode_value(encoder) + self.inner.encode_value(encoder) } } diff --git a/gss-api/src/negotiation.rs b/gss-api/src/negotiation.rs index 6ac3b8e98..4e131c575 100644 --- a/gss-api/src/negotiation.rs +++ b/gss-api/src/negotiation.rs @@ -383,7 +383,7 @@ mod tests { ); assert_eq!( b"not_defined_in_RFC4178@please_ignore", - &neg_token.neg_hints.unwrap().hint_name.unwrap().__contents + &neg_token.neg_hints.unwrap().hint_name.unwrap().as_bytes() ); }